-
Notifications
You must be signed in to change notification settings - Fork 9
/
DCMotor.h
317 lines (275 loc) · 9.09 KB
/
DCMotor.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
/**
* @file DCMotor.h
* @brief This file defines the DCMotor class, which is used for controlling a DC motor.
*
* The DCMotor class provides functionality to set and control the velocity and rotation of a DC motor.
* It uses various components such as an EncoderCounter, FastPWM, Motion control, PID controller,
* and an IIR Filter for precise control. The class offers methods to set velocity, rotation, control gains,
* and retrieve the current state of the motor.
*
* @dependencies
* This class relies on external components:
* - EncoderCounter: For encoding the rotation counts.
* - FastPWM: For generating high-frequency PWM signals.
* - Motion: For handling motion control.
* - PID_Cntrl: For implementing PID control.
* - IIR_Filter: For filtering the velocity signals.
*
* Usage:
* To use the DCMotor class, create an instance with the required motor parameters.
* Set the desired velocity or rotation using the setVelocity() or setRotation() methods.
* Control gains can be adjusted using setVelocityCntrl() and setRotationCntrlGain() methods.
* Current motor status can be obtained using the get methods like getVelocity(), getRotation(), etc.
*
* Example:
* ```
* DCMotor motor(PIN_PWM, PIN_ENC_A, PIN_ENC_B, COUNTS_PER_TURN, KN, VOLTAGE_MAX);
* motor.setVelocity(1.5f); // command velocity to 1.5 rotations per second
* float currentVelocity = motor.getVelocity(); // read current velocity
* motor.setRotation(5.0f); // command rotation to 5
* motor.getRotation(); // read current rotation
* ```
*
* @author M. E. Peter
* @date 11.12.2023
*/
#ifndef DC_MOTOR_H_
#define DC_MOTOR_H_
#include <math.h>
#include "EncoderCounter.h"
#include "FastPWM/FastPWM.h"
#include "Motion.h"
#include "ThreadFlag.h"
#include "PID_Cntrl.h"
#include "IIR_Filter.h"
#define M_PIf 3.14159265358979323846f /* pi */
// IMPORTANT: only use GPA or Chirp, not both at the same time
#define PERFORM_GPA_MEAS false
#define PERFORM_CHIRP_MEAS false
#if PERFORM_GPA_MEAS
#include "GPA.h"
#endif
#if PERFORM_CHIRP_MEAS
#include "mbed.h"
#include "Chirp.h"
#define BUFFER_LENGTH 20 // 5 float values
#endif
class DCMotor
{
public:
/**
* @brief Construct a new DCMotor object.
*
* @param pin_pwm The pin name for PWM control of the motor.
* @param pin_enc_a The first pin name for the encoder.
* @param pin_enc_b The second pin name for the encoder.
* @param gear_ratio The gear ratio of the gear box.
* @param kn The motor constant.
* @param voltage_max The maximum voltage for the motor.
* @param counts_per_turn The number of encoder counts per turn of the motor.
*/
explicit DCMotor(PinName pin_pwm,
PinName pin_enc_a,
PinName pin_enc_b,
float gear_ratio,
float kn,
float voltage_max = 12.0f,
float counts_per_turn = 20.0f);
/**
* @brief Destroy the DCMotor object.
*/
virtual ~DCMotor();
/**
* @brief Set the target velocity of the motor.
*
* @param velocity The target velocity in units per second.
*/
void setVelocity(float velocity);
/**
* @brief Set the target rotation of the motor.
*
* @param rotation The target rotation in degrees.
*/
void setRotation(float rotation);
/**
* @brief Set the relative target rotation of the motor. Keep in mind that you do this only once.
*
* @param rotation_relative The relative target rotation in degrees.
*/
void setRotationRelative(float rotation_relative);
/**
* @brief Get the current rotation target of the motor.
*
* @return float The current rotation target in degrees.
*/
float getRotationTarget() const;
/**
* @brief Get the current rotation setpoint of the motor.
*
* @return float The current rotation setpoint in degrees.
*/
float getRotationSetpoint() const;
/**
* @brief Get the current rotation of the motor.
*
* @return float The current rotation in degrees.
*/
float getRotation() const;
/**
* @brief Get the current velocity target of the motor.
*
* @return float The current velocity target in units per second.
*/
float getVelocityTarget() const;
/**
* @brief Get the current velocity setpoint of the motor.
*
* @return float The current velocity setpoint in units per second.
*/
float getVelocitySetpoint() const;
/**
* @brief Get the current velocity of the motor.
*
* @return float The current velocity in units per second.
*/
float getVelocity() const;
/**
* @brief Get the current voltage applied to the motor.
*
* @return float The current voltage in volts.
*/
float getVoltage() const;
/**
* @brief Get the current PWM signal applied to the motor.
*
* @return float The current PWM signal value.
*/
float getPWM() const;
/**
* @brief Set the control parameters for the velocity PID controller.
*
* @param kp The proportional gain.
* @param ki The integral gain.
* @param kd The derivative gain.
*/
void setVelocityCntrl(float kp = KP, float ki = KI, float kd = KD);
/**
* @brief Set the integrator limits for the velocity PID controller.
*
* @param percent_of_max The percentage of the maximum output of the controller.
*/
void setVelocityCntrlIntegratorLimitsPercent(float percent_of_max = 30.0f);
/**
* @brief Set the gain for the rotation control.
*
* @param p The proportional gain for the rotation control.
*/
void setRotationCntrlGain(float p = P);
/**
* @brief Set the maximum velocity for the motor.
*
* @param velocity The maximum velocity in rotations per second.
*/
void setMaxVelocity(float velocity);
/**
* @brief Get the maximum velocity set for the motor.
*
* @return float The maximum velocity set in rotations per second.
*/
float getMaxVelocity() const;
/**
* @brief Get the maximum physical velocity for the motor.
*
* @return float The maximum physical velocity in rotations per second.
*/
float getMaxPhysicalVelocity() const;
/**
* @brief Set the maximum acceleration for the motor.
*
* @param acceleration The maximum acceleration in rotations per second squared.
*/
void setMaxAcceleration(float acceleration);
/**
* @brief Get the maximum acceleration for the motor.
*
* @return float The maximum acceleration in rotations per second squared.
*/
float getMaxAcceleration() const;
/**
* @brief Enable or disable the motion planner. Module is disabled by default.
*
* @param enable True to enable the motion planner, false to disable.
*/
void enableMotionPlanner(bool enable = true);
/**
* @brief Get the current encoder count.
*
* @return long The current encoder count.
*/
long getEncoderCount() const;
#if PERFORM_GPA_MEAS
void startGPA();
#endif
#if PERFORM_CHIRP_MEAS
void startChrip();
#endif
private:
static constexpr int64_t PERIOD_MUS = 500;
static constexpr float TS = 1.0e-6f * static_cast<float>(PERIOD_MUS);
static constexpr float PWM_MIN = 0.01f;
static constexpr float PWM_MAX = 0.99f;
static constexpr float ROTATION_ERROR_MAX = 5.0e-3f;
// Default controller parameters where found using a motor with gear ratio 78.125:1
static constexpr float KP = 4.2f;
static constexpr float KI = 140.0f;
static constexpr float KD = 0.0192f;
static constexpr float P = 16.0f;
FastPWM m_FastPWM;
EncoderCounter m_EncoderCounter;
Motion m_Motion;
PID_Cntrl m_PID_Cntrl_velocity;
IIR_Filter m_IIR_Filter_velocity;
#if PERFORM_GPA_MEAS
GPA m_GPA;
bool m_start_gpa = false;
#endif
#if PERFORM_CHIRP_MEAS
Chirp m_chirp;
BufferedSerial m_BufferedSerial;
Timer m_timer;
char m_buffer[BUFFER_LENGTH];
bool m_start_chirp = false;
#endif
Thread m_Thread;
Ticker m_Ticker;
ThreadFlag m_ThreadFlag;
enum CntrlMode {
Rotation = 0,
Velocity,
};
CntrlMode m_cntrlMode = CntrlMode::Velocity;
bool m_enable_motion_planner;
// motor parameters
float m_counts_per_turn;
float m_voltage_max;
float m_velocity_physical_max;
float m_velocity_max;
float m_acceleration_max;
// rotation controller parameter
float m_p;
// signals
long m_count;
short m_count_previous;
float m_rotation_initial;
float m_rotation_target;
float m_rotation_setpoint;
float m_rotation;
float m_velocity_target;
float m_velocity_setpoint;
float m_velocity;
float m_voltage;
float m_pwm;
void threadTask();
void sendThreadFlag();
};
#endif /* DC_MOTOR_H_ */