amiro-os / include / amiro / MotorControl.h @ 22b85da1
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_ */ |