Statistics
| Branch: | Tag: | Revision:

amiro-os / include / amiro / MotorControl.h @ b8085493

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_ */