amiro-os / include / amiro / MotorControl.h @ 2330e415
History | View | Annotate | Download (8.417 KB)
1 | 58fe0e0b | Thomas Schöpping | #ifndef AMIRO_MOTOR_CONTROL_H_
|
---|---|---|---|
2 | #define AMIRO_MOTOR_CONTROL_H_
|
||
3 | |||
4 | #include <amiro/MotorIncrements.h> |
||
5 | #include <amiro/Constants.h> |
||
6 | #include <Types.h> |
||
7 | #include <amiro/FileSystemInputOutput/FSIODiWheelDrive.hpp> |
||
8 | |||
9 | namespace amiro { |
||
10 | |||
11 | class MotorControl : public chibios_rt::BaseStaticThread<512> {
|
||
12 | public:
|
||
13 | /**
|
||
14 | * Constructor
|
||
15 | *
|
||
16 | * @param pwm pulse width modulation driver (pwmd)
|
||
17 | * Can be any free PWMDx in 'ChibiOS-RT/os/hal/platforms/STM32/TIMv1/pwm_lld.h'
|
||
18 | * @param mi object for retrieving the motor increments of the qei
|
||
19 | * @param port GPIO port for motor control (should be the macro 'GPIOB')
|
||
20 | * @param pad GPIO command for motor control (should be the macro 'GPIOB_POWER_EN' for enable)
|
||
21 | * @param memory Memory interface to load/store parameters
|
||
22 | */
|
||
23 | MotorControl(PWMDriver* pwm, MotorIncrements* mi, GPIO_TypeDef* port, int pad, fileSystemIo::FSIODiWheelDrive *memory);
|
||
24 | |||
25 | /**
|
||
26 | * Get the current speed of the left wheel in rounds/min
|
||
27 | *
|
||
28 | * @return speed of left wheel in rounds/min
|
||
29 | */
|
||
30 | int getCurrentRPMLeft();
|
||
31 | |||
32 | /**
|
||
33 | * Get the current speed of the right wheel in rounds/min
|
||
34 | *
|
||
35 | * @return speed of right wheel in rounds/min
|
||
36 | */
|
||
37 | int getCurrentRPMRight();
|
||
38 | |||
39 | chibios_rt::EvtSource* getEventSource(); |
||
40 | |||
41 | /**
|
||
42 | * Sets the target velocity
|
||
43 | *
|
||
44 | * @param targetVelocity Kartesian kinematic vector
|
||
45 | */
|
||
46 | void setTargetSpeed(const types::kinematic &targetVelocity); |
||
47 | |||
48 | /**
|
||
49 | * Sets the target velocity in µ rounds per minute for every wheel
|
||
50 | *
|
||
51 | * @param targetURpmLeft Rounds per minute in µ1/min of the left wheel
|
||
52 | * @param targetURpmLeft Rounds per minute in µ1/min of the right wheel
|
||
53 | */
|
||
54 | void setTargetRPM(int32_t targetURpmLeft, int32_t targetURpmRight);
|
||
55 | |||
56 | /**
|
||
57 | * Get the current velocitiy as a kinematic struct
|
||
58 | *
|
||
59 | * @return Current velocity
|
||
60 | */
|
||
61 | types::kinematic getCurrentVelocity(); |
||
62 | |||
63 | /**
|
||
64 | * Sets the correction factor for the wheel diameter.
|
||
65 | * The factor Ed is the ratio of the wheel diameters
|
||
66 | * <Ed = wheelDiameterRight / wheelDiameterLeft> as
|
||
67 | * introduced in eq. 3 by J. Borenstein (Correction of
|
||
68 | * Systematic Odometry Errors in Mobile Robots). This
|
||
69 | * function calculates then the correction factors for every
|
||
70 | * wheel by eq. 17a and 17b.
|
||
71 | *
|
||
72 | * @param Ed Wheel diameter ratio
|
||
73 | * @param storeEbToMemory Do override Ed in the memory with the given value
|
||
74 | * @return Return value of the memory interface
|
||
75 | */
|
||
76 | msg_t setWheelDiameterCorrectionFactor(float Ed = 1.0f, bool_t storeEdToMemory = false); |
||
77 | |||
78 | /**
|
||
79 | * Sets the correction factor for the wheel base width.
|
||
80 | * The factor Eb is the ratio of the actual and nominal
|
||
81 | * base width <Eb = bActual / bNominal> as introduced
|
||
82 | * in eq. 3 by J. Borenstein (Correction of
|
||
83 | * Systematic Odometry Errors in Mobile Robots). This
|
||
84 | * function calculates then the actual base width of the
|
||
85 | * robot using eq. 4.
|
||
86 | *
|
||
87 | * @param Eb Base width ratio
|
||
88 | * @param storeEbToMemory Do override Eb in the memory with the given value
|
||
89 | * @return Return value of the memory interface
|
||
90 | */
|
||
91 | msg_t setActualWheelBaseDistance(float Eb = 1.0f, bool_t storeEbToMemory = false); |
||
92 | |||
93 | /**
|
||
94 | * Calculate the current increments of both wheels and
|
||
95 | * update oldIncrement and incrementsDifference,
|
||
96 | * which is the corrected difference between the current increments
|
||
97 | * and the old ones.
|
||
98 | * The corrected difference is the original difference between the old
|
||
99 | * increments and new increments, multiplied with the wheelDiameterCorrectionFactor.
|
||
100 | * The incremennt source is given by motorIncrements.
|
||
101 | *
|
||
102 | * @param motorIncrements Increment source
|
||
103 | * @param oldIncrement Old increments, which are updated
|
||
104 | * @param incrementDifference Corrected difference between old and current increments
|
||
105 | * @return Return value of the memory interface
|
||
106 | */
|
||
107 | static void updateIncrements(MotorIncrements* motorIncrements, int32_t (&oldIncrement)[2], float (&incrementDifference)[2]); |
||
108 | |||
109 | /**
|
||
110 | * Calculate the current speed of both wheels and
|
||
111 | * updates actualSpeed.
|
||
112 | *
|
||
113 | * @param incrementDifference Difference between old and current increments
|
||
114 | * @param actualSpeed Actual speed of both wheels
|
||
115 | * @param Update period
|
||
116 | */
|
||
117 | static void updateSpeed(const float (&incrementDifference)[2], int32_t (&actualSpeed)[2], const uint32_t period); |
||
118 | |||
119 | /**
|
||
120 | * Calculate the current driven distance of both wheels and
|
||
121 | * updates actualDistance.
|
||
122 | *
|
||
123 | * @param incrementDifference Difference between old and current increments
|
||
124 | * @param actualDistance Actual distance driven
|
||
125 | */
|
||
126 | static void updateDistance(const float (&incrementDifference)[2], float (&actualDistance)[2]); |
||
127 | |||
128 | /**
|
||
129 | * Prints Control Gains
|
||
130 | */
|
||
131 | void printGains();
|
||
132 | |||
133 | ff7ad65b | Thomas Schöpping | /**
|
134 | * @brief Resets control gains.
|
||
135 | */
|
||
136 | void resetGains();
|
||
137 | |||
138 | 58fe0e0b | Thomas Schöpping | protected:
|
139 | virtual msg_t main(void);
|
||
140 | |||
141 | private:
|
||
142 | |||
143 | /**
|
||
144 | * Calculate the velocitiy in the robot frame
|
||
145 | * and saves it to this->currentVelocity
|
||
146 | */
|
||
147 | void calcVelocity();
|
||
148 | |||
149 | /**
|
||
150 | * PID Controller that works directly on the forward velocity v of the robots center and its
|
||
151 | * angular velocity w around its z axis. The methods setLeftWheelSpeed() and setRightWheelSpeed()
|
||
152 | * are used to set the final pwm values.
|
||
153 | */
|
||
154 | void PIDController();
|
||
155 | |||
156 | /**
|
||
157 | * Deletes the oldest entry in lastVelocitiesV[] and lastVelocitiesW[], pushes the other values up and saves the currentVelocity.x(w_z) in the last entry.
|
||
158 | */
|
||
159 | void updateDerivativeLastVelocities();
|
||
160 | |||
161 | |||
162 | ////////////////////////////////////////////////
|
||
163 | /////////////////Calibration////////////////////
|
||
164 | ////////////////////////////////////////////////
|
||
165 | /**
|
||
166 | * Finds a prefactor for the stronger motor to match its power level to the weaker motor.
|
||
167 | */
|
||
168 | void calibrate();
|
||
169 | |||
170 | /**
|
||
171 | * Finds the P, I and D gains for the PID Controller using the Nichols-Ziegler Method.
|
||
172 | */
|
||
173 | void calibrateZiegler();
|
||
174 | |||
175 | /**
|
||
176 | * Counts the number of sign changes from the last 30 velocities.
|
||
177 | */
|
||
178 | int getNumberofSignChanges();
|
||
179 | |||
180 | /**
|
||
181 | * Update the past lastVelocitiesV array.
|
||
182 | */
|
||
183 | void updatePastVelocities();
|
||
184 | |||
185 | |||
186 | /**
|
||
187 | * Sets wheel speed according to the output of the PID Controller
|
||
188 | */
|
||
189 | void setLeftWheelSpeed(int diffv, int diffw); |
||
190 | /**
|
||
191 | * Sets wheel speed according to the output of the PID Controller
|
||
192 | */
|
||
193 | void setRightWheelSpeed(int diffv, int diffw); |
||
194 | |||
195 | int getLeftWheelSpeed();
|
||
196 | int getRightWheelSpeed();
|
||
197 | |||
198 | |||
199 | /**
|
||
200 | * Write the duty cicle from this->pwmPercentage
|
||
201 | * to the PWM driver
|
||
202 | */
|
||
203 | void writePulseWidthModulation();
|
||
204 | |||
205 | /**
|
||
206 | * Control logic to save space in main loop
|
||
207 | */
|
||
208 | void controllerAndCalibrationLogic();
|
||
209 | |||
210 | |||
211 | |||
212 | PWMDriver* pwmDriver; |
||
213 | PWMConfig pwmConfig; |
||
214 | MotorIncrements* motorIncrements; |
||
215 | GPIO_TypeDef *powerEnablePort; |
||
216 | const int powerEnablePad; |
||
217 | chibios_rt::EvtSource eventSource; |
||
218 | //const uint32_t period;
|
||
219 | uint32_t period; |
||
220 | fileSystemIo::FSIODiWheelDrive *memory; |
||
221 | int32_t actualSpeed[2];
|
||
222 | float actualDistance[2]; |
||
223 | float errorSum[2]; |
||
224 | int32_t increment[2];
|
||
225 | float incrementDifference[2]; |
||
226 | int pwmPercentage[2]; |
||
227 | types::kinematic targetVelocity; |
||
228 | types::kinematic currentVelocity; |
||
229 | types::kinematic lastVelocity; |
||
230 | float errorSumDiff;
|
||
231 | bool newTargetVelocities;
|
||
232 | int delay = 0; |
||
233 | float Ed;
|
||
234 | float Eb;
|
||
235 | |||
236 | int pGain = 1000; |
||
237 | |||
238 | float iGain = 0.08; |
||
239 | int antiWindupV = 7100000; |
||
240 | int antiWindupW = 200000000; |
||
241 | int accumulatedErrorV =0; // accumulated velocity error |
||
242 | int accumulatedErrorW =0; // accumulated omega error |
||
243 | |||
244 | float dGain =0.01; |
||
245 | int lastVelocitiesV[6]; |
||
246 | int lastVelocitiesW[6]; |
||
247 | |||
248 | //motor calibration variables
|
||
249 | int numberOfLastVelocitiesV = 30; |
||
250 | int lastVelocitiesVBig[30]; |
||
251 | int rightWValues[3]; |
||
252 | int leftWValues[3]; |
||
253 | float motorCalibrationFactor =1.0; |
||
254 | //ziegler calibration variables
|
||
255 | int zieglerHelp= 1; |
||
256 | int zieglerHelp2 = 0; |
||
257 | bool ziegler= true; |
||
258 | bool ziegler2 = true; |
||
259 | float zieglerPeriod;
|
||
260 | int zieglerCalibrationTime = 0; |
||
261 | int wheelCalibrationTime = 0; |
||
262 | bool startedZieglerCalibration = false; |
||
263 | bool startedWheelCalibration = false; |
||
264 | bool motorCalibration = true; |
||
265 | |||
266 | |||
267 | |||
268 | |||
269 | public:
|
||
270 | bool isCalibrating = false; |
||
271 | static float wheelDiameterCorrectionFactor[2]; |
||
272 | static float actualWheelBaseDistanceSI; |
||
273 | |||
274 | |||
275 | }; |
||
276 | } |
||
277 | |||
278 | #endif /* AMIRO_MOTOR_CONTROL_H_ */ |