Statistics
| Branch: | Tag: | Revision:

amiro-os / include / amiro / MotorControl.h @ 81b48c66

History | View | Annotate | Download (8.606 KB)

1
#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
  struct motorGains
12
  {
13
    int pGain = 0;
14
    float iGain = 0.0;
15
    float dGain = 0.0;
16
  };
17

    
18
  class MotorControl : public chibios_rt::BaseStaticThread<512> {
19
  public:
20
    /**
21
     * Constructor
22
     *
23
     * @param pwm pulse width modulation driver (pwmd)
24
     *            Can be any free PWMDx in 'ChibiOS-RT/os/hal/platforms/STM32/TIMv1/pwm_lld.h'
25
     * @param mi object for retrieving the motor increments of the qei
26
     * @param port GPIO port for motor control (should be the macro 'GPIOB')
27
     * @param pad GPIO command for motor control (should be the macro 'GPIOB_POWER_EN' for enable)
28
     * @param memory Memory interface to load/store parameters
29
     */
30
    MotorControl(PWMDriver* pwm, MotorIncrements* mi, GPIO_TypeDef* port, int pad, fileSystemIo::FSIODiWheelDrive *memory);
31

    
32
    /**
33
     * Get the current speed of the left wheel in rounds/min
34
     *
35
     * @return speed of left wheel in rounds/min
36
     */
37
    int getCurrentRPMLeft();
38

    
39
    /**
40
     * Get the current speed of the right wheel in rounds/min
41
     *
42
     * @return speed of right wheel in rounds/min
43
     */
44
    int getCurrentRPMRight();
45

    
46
    chibios_rt::EvtSource* getEventSource();
47

    
48
    /**
49
     * Sets the target velocity
50
     *
51
     * @param targetVelocity Kartesian kinematic vector
52
     */
53
    void setTargetSpeed(const types::kinematic &targetVelocity);
54

    
55
    /**
56
     * Sets the target velocity in µ rounds per minute for every wheel
57
     *
58
     * @param targetURpmLeft Rounds per minute in µ1/min of the left wheel
59
     * @param targetURpmLeft Rounds per minute in µ1/min of the right wheel
60
     */
61
    void setTargetRPM(int32_t targetURpmLeft, int32_t targetURpmRight);
62

    
63
    /**
64
     * Get the current velocitiy as a kinematic struct
65
     *
66
     * @return Current velocity
67
     */
68
    types::kinematic getCurrentVelocity();
69

    
70
    /**
71
     * Sets the correction factor for the wheel diameter.
72
     * The factor Ed is the ratio of the wheel diameters
73
     * <Ed = wheelDiameterRight / wheelDiameterLeft> as
74
     * introduced in eq. 3 by J. Borenstein (Correction of
75
     * Systematic Odometry Errors in Mobile Robots). This
76
     * function calculates then the correction factors for every
77
     * wheel by eq. 17a and 17b.
78
     *
79
     * @param Ed Wheel diameter ratio
80
     * @param storeEbToMemory Do override Ed in the memory with the given value
81
     * @return Return value of the memory interface
82
     */
83
    msg_t setWheelDiameterCorrectionFactor(float Ed = 1.0f, bool_t storeEdToMemory = false);
84

    
85
    /**
86
     * Sets the correction factor for the wheel base width.
87
     * The factor Eb is the ratio of the actual and nominal
88
     * base width <Eb = bActual / bNominal> as introduced
89
     * in eq. 3 by J. Borenstein (Correction of
90
     * Systematic Odometry Errors in Mobile Robots). This
91
     * function calculates then the actual base width of the
92
     * robot using eq. 4.
93
     *
94
     * @param Eb Base width ratio
95
     * @param storeEbToMemory Do override Eb in the memory with the given value
96
     * @return Return value of the memory interface
97
     */
98
    msg_t setActualWheelBaseDistance(float Eb = 1.0f, bool_t storeEbToMemory = false);
99

    
100
    /**
101
     * Calculate the current increments of both wheels and
102
     * update oldIncrement and incrementsDifference,
103
     * which is the corrected difference between the current increments
104
     * and the old ones.
105
     * The corrected difference is the original difference between the old
106
     * increments and new increments, multiplied with the wheelDiameterCorrectionFactor.
107
     * The incremennt source is given by motorIncrements.
108
     *
109
     * @param motorIncrements Increment source
110
     * @param oldIncrement Old increments, which are updated
111
     * @param incrementDifference Corrected difference between old and current increments
112
     * @return Return value of the memory interface
113
     */
114
    static void updateIncrements(MotorIncrements* motorIncrements, int32_t (&oldIncrement)[2], float (&incrementDifference)[2]);
115

    
116
    /**
117
     * Calculate the current speed of both wheels and
118
     * updates actualSpeed.
119
     *
120
     * @param incrementDifference Difference between old and current increments
121
     * @param actualSpeed Actual speed of both wheels
122
     * @param Update period
123
     */
124
    static void updateSpeed(const float (&incrementDifference)[2], int32_t (&actualSpeed)[2], const uint32_t period);
125

    
126
    /**
127
     * Calculate the current driven distance of both wheels and
128
     * updates actualDistance.
129
     *
130
     * @param incrementDifference Difference between old and current increments
131
     * @param actualDistance Actual distance driven
132
     */
133
    static void updateDistance(const float (&incrementDifference)[2], float (&actualDistance)[2]);
134

    
135
    /**
136
     * Prints Control Gains
137
     */
138
    void printGains();
139

    
140
    /**
141
     * @brief Resets control gains.
142
     */
143
    void resetGains();
144

    
145
    void setMotorEnable(bool enable);
146
    bool getMotorEnable();
147
    
148
  protected:
149
    virtual msg_t main(void);
150

    
151
  private:
152

    
153
    /**
154
     * Calculate the velocitiy in the robot frame
155
     * and saves it to this->currentVelocity
156
     */
157
    void calcVelocity();
158

    
159
    /**
160
     * PID Controller that works directly on the forward velocity v of the robots center and its
161
     * angular velocity w around its z axis. The methods setLeftWheelSpeed() and setRightWheelSpeed()
162
     * are used to set the final pwm values.
163
     */
164
    void PIDController();
165

    
166
    /**
167
     * Deletes the oldest entry in lastVelocitiesV[] and lastVelocitiesW[], pushes the other values up and saves the currentVelocity.x(w_z) in the last entry.
168
     */
169
    void updateDerivativeLastVelocities();
170

    
171

    
172
    ////////////////////////////////////////////////
173
    /////////////////Calibration////////////////////
174
    ////////////////////////////////////////////////
175
    /**
176
     * Finds a prefactor for the stronger motor to match its power level to the weaker motor.
177
     */
178
    void calibrate();
179

    
180
    /**
181
     * Finds the P, I and D gains for the PID Controller using the Nichols-Ziegler Method.
182
     */
183
    void calibrateZiegler();
184

    
185
    /**
186
     * Counts the number of sign changes from the last 30 velocities.
187
     */
188
    int getNumberofSignChanges();
189

    
190
    /**
191
     * Update the past lastVelocitiesV array.
192
     */
193
    void updatePastVelocities();
194

    
195

    
196
    /**
197
     * Sets wheel speed according to the output of the PID Controller
198
     */
199
    void setLeftWheelSpeed(int diffv, int diffw);
200
    /**
201
     * Sets wheel speed according to the output of the PID Controller
202
     */
203
    void setRightWheelSpeed(int diffv, int diffw);
204

    
205
    int getLeftWheelSpeed();
206
    int getRightWheelSpeed();
207

    
208

    
209
    /**
210
     * Write the duty cicle from this->pwmPercentage
211
     * to the PWM driver
212
     */
213
    void writePulseWidthModulation();
214

    
215
    /**
216
     * Control logic to save space in main loop
217
     */
218
    void controllerAndCalibrationLogic();
219

    
220

    
221

    
222
    PWMDriver* pwmDriver;
223
    PWMConfig pwmConfig;
224
    MotorIncrements* motorIncrements;
225
    GPIO_TypeDef *powerEnablePort;
226
    const int powerEnablePad;
227
    chibios_rt::EvtSource eventSource;
228
    //const uint32_t period;
229
    uint32_t period;
230
    fileSystemIo::FSIODiWheelDrive *memory;
231
    int32_t actualSpeed[2];
232
    float actualDistance[2];
233
    float errorSum[2];
234
    int32_t increment[2];
235
    float incrementDifference[2];
236
    int pwmPercentage[2];
237
    types::kinematic targetVelocity;
238
    types::kinematic currentVelocity;
239
    types::kinematic lastVelocity;
240
    float errorSumDiff;
241
    bool newTargetVelocities;
242
    int delay = 0;
243
    float Ed;
244
    float Eb;
245

    
246
    int pGain = 1000;
247

    
248
    float iGain = 0.08;
249
    int antiWindupV = 7100000;
250
    int antiWindupW = 200000000;
251
    int accumulatedErrorV =0; // accumulated velocity error
252
    int accumulatedErrorW =0; // accumulated omega error
253

    
254
    float dGain =0.01;
255
    int lastVelocitiesV[6];
256
    int lastVelocitiesW[6];
257

    
258
    //motor calibration variables
259
    int numberOfLastVelocitiesV = 30;
260
    int lastVelocitiesVBig[30];
261
    int rightWValues[3];
262
    int leftWValues[3];
263
    float motorCalibrationFactor =1.0;
264
    //ziegler calibration variables
265
    int zieglerHelp= 1;
266
    int zieglerHelp2 = 0;
267
    bool ziegler= true;
268
    bool ziegler2 = true;
269
    float zieglerPeriod;
270
    int zieglerCalibrationTime = 0;
271
    int wheelCalibrationTime = 0;
272
    bool startedZieglerCalibration = false;
273
    bool startedWheelCalibration = false;
274
    bool motorCalibration = true;
275
    bool motorEnable = true;
276

    
277

    
278

    
279

    
280
  public:
281
    bool isCalibrating = false;
282
    static float wheelDiameterCorrectionFactor[2];
283
    static float actualWheelBaseDistanceSI;
284

    
285

    
286
  };
287
}
288

    
289
#endif /* AMIRO_MOTOR_CONTROL_H_ */