first publish not working
Dependencies: MODSERIAL mbed ttmath FastPWM Motor_with_encoder biquadFilter
main.cpp@3:b353ee86230a, 2017-10-31 (annotated)
- Committer:
- Arnoud113
- Date:
- Tue Oct 31 21:35:54 2017 +0000
- Revision:
- 3:b353ee86230a
- Parent:
- 2:2563d1d8461f
- Child:
- 4:5f7d1654108d
including new PID with PID for both motors
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Arnoud113 | 0:77ad62c61c78 | 1 | #include "mbed.h" |
Arnoud113 | 0:77ad62c61c78 | 2 | #include "QEI.h" |
Arnoud113 | 0:77ad62c61c78 | 3 | #include "MODSERIAL.h" |
Arnoud113 | 0:77ad62c61c78 | 4 | #include "math.h" |
Arnoud113 | 2:2563d1d8461f | 5 | #include "FastPWM.h" |
Arnoud113 | 3:b353ee86230a | 6 | #include "encoder.h" |
Arnoud113 | 0:77ad62c61c78 | 7 | |
Arnoud113 | 0:77ad62c61c78 | 8 | |
Arnoud113 | 0:77ad62c61c78 | 9 | |
Arnoud113 | 0:77ad62c61c78 | 10 | DigitalOut gpo(D0); |
Arnoud113 | 0:77ad62c61c78 | 11 | DigitalOut ledb(LED_BLUE); |
Arnoud113 | 0:77ad62c61c78 | 12 | DigitalOut ledr(LED_RED); |
Arnoud113 | 0:77ad62c61c78 | 13 | DigitalOut ledg(LED_GREEN); |
Arnoud113 | 0:77ad62c61c78 | 14 | DigitalOut motor1DC(D7); |
Arnoud113 | 3:b353ee86230a | 15 | DigitalOut motor2DC(D4); |
Arnoud113 | 2:2563d1d8461f | 16 | FastPWM motor1PWM(D6); |
Arnoud113 | 2:2563d1d8461f | 17 | FastPWM motor2PWM(D5); |
Arnoud113 | 0:77ad62c61c78 | 18 | |
Arnoud113 | 0:77ad62c61c78 | 19 | AnalogIn potMeter1(A0); |
Arnoud113 | 0:77ad62c61c78 | 20 | AnalogIn potMeter2(A1); |
Arnoud113 | 0:77ad62c61c78 | 21 | DigitalIn button1(D11); |
Arnoud113 | 0:77ad62c61c78 | 22 | DigitalIn button2(D12); |
Arnoud113 | 3:b353ee86230a | 23 | Encoder Encoder1(D12,D13); |
Arnoud113 | 3:b353ee86230a | 24 | Encoder Encoder2(D8,D9); |
Arnoud113 | 0:77ad62c61c78 | 25 | |
Arnoud113 | 0:77ad62c61c78 | 26 | MODSERIAL pc(USBTX,USBRX); |
Arnoud113 | 0:77ad62c61c78 | 27 | |
Arnoud113 | 0:77ad62c61c78 | 28 | Ticker controller; |
Arnoud113 | 0:77ad62c61c78 | 29 | |
Arnoud113 | 3:b353ee86230a | 30 | // ---- Motor Constants------- |
Arnoud113 | 3:b353ee86230a | 31 | float Pwmperiod = 0.0001f; |
Arnoud113 | 3:b353ee86230a | 32 | int potmultiplier = 800; // Multiplier for the pot meter reference which is normally between 0 and 1 |
Arnoud113 | 3:b353ee86230a | 33 | float gainM1 = 1/35.17; // encoder pulses per degree theta |
Arnoud113 | 3:b353ee86230a | 34 | float gainM2 = 0.01; // gain for radius r |
Arnoud113 | 0:77ad62c61c78 | 35 | |
Arnoud113 | 3:b353ee86230a | 36 | // new PID constants, will have to be determined trough trial and error. |
Arnoud113 | 2:2563d1d8461f | 37 | |
Arnoud113 | 3:b353ee86230a | 38 | double kp = 250; |
Arnoud113 | 3:b353ee86230a | 39 | double ki = 100; |
Arnoud113 | 3:b353ee86230a | 40 | double kd = 0; |
Arnoud113 | 3:b353ee86230a | 41 | |
Arnoud113 | 3:b353ee86230a | 42 | |
Arnoud113 | 3:b353ee86230a | 43 | volatile float motor1; |
Arnoud113 | 3:b353ee86230a | 44 | volatile float motor2; |
Arnoud113 | 3:b353ee86230a | 45 | |
Arnoud113 | 3:b353ee86230a | 46 | //Start constants PID ------------------------------- |
Arnoud113 | 0:77ad62c61c78 | 47 | const double pi = 3.1415926535897; |
Arnoud113 | 3:b353ee86230a | 48 | const double M1_TS = 0.001f; // (was 0.0001) 0.001 and 0.01 work without biquad filter. // // Sample time (motor - timestep) |
Arnoud113 | 0:77ad62c61c78 | 49 | |
Arnoud113 | 0:77ad62c61c78 | 50 | //verplaatst |
Arnoud113 | 3:b353ee86230a | 51 | const float RAD_PER_PULSE = (2*pi)/4200; |
Arnoud113 | 3:b353ee86230a | 52 | const float CONTROLLER_TS = 0.01; //TIME INTERVAL/ hZ |
Arnoud113 | 3:b353ee86230a | 53 | |
Arnoud113 | 3:b353ee86230a | 54 | //----PID constants |
Arnoud113 | 3:b353ee86230a | 55 | const float M1_KP = 10; |
Arnoud113 | 3:b353ee86230a | 56 | const float M1_KI = 0.5; |
Arnoud113 | 3:b353ee86230a | 57 | const float M1_KD = 0.5; //was KP=10 KI=0.5 KD=0.5 |
Arnoud113 | 3:b353ee86230a | 58 | double m1_err_int = 0; |
Arnoud113 | 3:b353ee86230a | 59 | double m1_prev_err = 0; |
Arnoud113 | 3:b353ee86230a | 60 | |
Arnoud113 | 3:b353ee86230a | 61 | const float M2_KP = 10; |
Arnoud113 | 3:b353ee86230a | 62 | const float M2_KI = 0.5; |
Arnoud113 | 3:b353ee86230a | 63 | const float M2_KD = 0.5; //was KP=10 KI=0.5 KD=0.5 |
Arnoud113 | 3:b353ee86230a | 64 | double m2_err_int = 0; |
Arnoud113 | 3:b353ee86230a | 65 | double m2_prev_err = 0; |
Arnoud113 | 3:b353ee86230a | 66 | |
Arnoud113 | 3:b353ee86230a | 67 | //---- Biquad constants--------- |
Arnoud113 | 3:b353ee86230a | 68 | const double M1_F_A1 = 1.0 ; |
Arnoud113 | 3:b353ee86230a | 69 | const double M1_F_A2 = 2.0; |
Arnoud113 | 3:b353ee86230a | 70 | const double M1_F_B0 = 1.0; |
Arnoud113 | 3:b353ee86230a | 71 | const double M1_F_B1 = 3.0; |
Arnoud113 | 3:b353ee86230a | 72 | const double M1_F_B2 = 4.0; |
Arnoud113 | 3:b353ee86230a | 73 | double m1_f_v1 = 0; |
Arnoud113 | 3:b353ee86230a | 74 | double m1_f_v2 = 0; |
Arnoud113 | 3:b353ee86230a | 75 | |
Arnoud113 | 0:77ad62c61c78 | 76 | |
Arnoud113 | 3:b353ee86230a | 77 | //-----------------Start PID part----------------------------START |
Arnoud113 | 3:b353ee86230a | 78 | double PID1(double e1, const double Kp1, const double Ki1, const double Kd1, double Ts, double &e_int1, double &e_prev1, double &f_v1, double &f_v2, const double f_a1, const double f_a2, const double f_b0, const double f_b1, const double f_b2){ |
Arnoud113 | 3:b353ee86230a | 79 | |
Arnoud113 | 3:b353ee86230a | 80 | double e_der1 = (e1 - e_prev1)/Ts; // Derivative, Ts = motor1-timestep |
Arnoud113 | 3:b353ee86230a | 81 | // biquad part, see slide |
Arnoud113 | 3:b353ee86230a | 82 | //e_der1 = biquad(e_der, f_v1, f_v2, f_a1, f_a2, f_b0, f_b1, f_b2); |
Arnoud113 | 3:b353ee86230a | 83 | e_prev1 = e1; |
Arnoud113 | 3:b353ee86230a | 84 | e_int1 += Ts*e1; // Integral |
Arnoud113 | 3:b353ee86230a | 85 | |
Arnoud113 | 3:b353ee86230a | 86 | return Kp1*e1 + Ki1*e_int1 + Kd1 * e_der1; |
Arnoud113 | 3:b353ee86230a | 87 | |
Arnoud113 | 3:b353ee86230a | 88 | } |
Arnoud113 | 0:77ad62c61c78 | 89 | |
Arnoud113 | 3:b353ee86230a | 90 | double PID2(double e2, const double Kp2, const double Ki2, const double Kd2, double Ts, double &e_int2, double &e_prev2, double &f_v1, double &f_v2, const double f_a1, const double f_a2, const double f_b0, const double f_b1, const double f_b2){ |
Arnoud113 | 3:b353ee86230a | 91 | |
Arnoud113 | 3:b353ee86230a | 92 | double e_der2 = (e2 - e_prev2)/Ts; // Derivative, Ts = motor1-timestep |
Arnoud113 | 3:b353ee86230a | 93 | // biquad part, see slide |
Arnoud113 | 3:b353ee86230a | 94 | //e_der2 = biquad(e_der, f_v1, f_v2, f_a1, f_a2, f_b0, f_b1, f_b2); |
Arnoud113 | 3:b353ee86230a | 95 | e_prev2 = e2; |
Arnoud113 | 3:b353ee86230a | 96 | e_int2 += Ts*e2; // Integral |
Arnoud113 | 3:b353ee86230a | 97 | |
Arnoud113 | 3:b353ee86230a | 98 | return Kp2*e2 + Ki2*e_int2 + Kd2 * e_der2; |
Arnoud113 | 3:b353ee86230a | 99 | |
Arnoud113 | 3:b353ee86230a | 100 | } |
Arnoud113 | 3:b353ee86230a | 101 | |
Arnoud113 | 3:b353ee86230a | 102 | //------------Get reference position-----------------START |
Arnoud113 | 0:77ad62c61c78 | 103 | float Get_X_Position(){ |
Arnoud113 | 1:13d8940f0fd4 | 104 | double X = potMeter1 * potmultiplier; |
Arnoud113 | 1:13d8940f0fd4 | 105 | return X; |
Arnoud113 | 0:77ad62c61c78 | 106 | } |
Arnoud113 | 0:77ad62c61c78 | 107 | |
Arnoud113 | 0:77ad62c61c78 | 108 | float Get_Y_Position(){ |
Arnoud113 | 1:13d8940f0fd4 | 109 | double Y = potMeter2 * potmultiplier; |
Arnoud113 | 1:13d8940f0fd4 | 110 | return Y; |
Arnoud113 | 0:77ad62c61c78 | 111 | } |
Arnoud113 | 3:b353ee86230a | 112 | //----------------------------------------------------END |
Arnoud113 | 0:77ad62c61c78 | 113 | |
Arnoud113 | 3:b353ee86230a | 114 | //-------------Get current Position-------------------START |
Arnoud113 | 3:b353ee86230a | 115 | double motor1_Position(){ // has as output Theta |
Arnoud113 | 3:b353ee86230a | 116 | double pos_m1 = gainM1*Encoder1.getPosition(); // current position for theta |
Arnoud113 | 3:b353ee86230a | 117 | return pos_m1; |
Arnoud113 | 0:77ad62c61c78 | 118 | } |
Arnoud113 | 3:b353ee86230a | 119 | double motor2_Position(){ //output R |
Arnoud113 | 3:b353ee86230a | 120 | double pos_m2 = gainM2 *Encoder2.getPosition(); // current position for the radius; |
Arnoud113 | 3:b353ee86230a | 121 | return pos_m2; |
Arnoud113 | 3:b353ee86230a | 122 | } |
Arnoud113 | 3:b353ee86230a | 123 | //-----------------------------------------------------END |
Arnoud113 | 0:77ad62c61c78 | 124 | |
Arnoud113 | 0:77ad62c61c78 | 125 | |
Arnoud113 | 3:b353ee86230a | 126 | //------------Controller-------------------------------START |
Arnoud113 | 0:77ad62c61c78 | 127 | void Controller(){ |
Arnoud113 | 3:b353ee86230a | 128 | |
Arnoud113 | 1:13d8940f0fd4 | 129 | double x = Get_X_Position(); |
Arnoud113 | 1:13d8940f0fd4 | 130 | double y = Get_Y_Position(); |
Arnoud113 | 3:b353ee86230a | 131 | |
Arnoud113 | 3:b353ee86230a | 132 | double reference_motor1 = (atan(y/x)*180)/pi; // reference for Theta |
Arnoud113 | 3:b353ee86230a | 133 | double reference_motor2 = sqrt((x*x+y*y)); // reference for radius |
Arnoud113 | 0:77ad62c61c78 | 134 | |
Arnoud113 | 3:b353ee86230a | 135 | float pos_M1 = motor1_Position(); // current position for theta |
Arnoud113 | 3:b353ee86230a | 136 | float pos_M2 = motor2_Position(); // current position for the radius |
Arnoud113 | 0:77ad62c61c78 | 137 | |
Arnoud113 | 3:b353ee86230a | 138 | double delta1 = PID1(reference_motor1 - pos_M1, M1_KP, M1_KI, M1_KD, M1_TS, m1_err_int, m1_prev_err, m1_f_v1, m1_f_v2, M1_F_A1, M1_F_A2, M1_F_B0, M1_F_B1, M1_F_B2); |
Arnoud113 | 3:b353ee86230a | 139 | double delta2 = PID2(reference_motor2 - pos_M2, M2_KP, M2_KI, M2_KD, M1_TS, m1_err_int, m1_prev_err, m1_f_v1, m1_f_v2, M1_F_A1, M1_F_A2, M1_F_B0, M1_F_B1, M1_F_B2); |
Arnoud113 | 3:b353ee86230a | 140 | |
Arnoud113 | 3:b353ee86230a | 141 | double dTheta = reference_motor1 - pos_M1; |
Arnoud113 | 3:b353ee86230a | 142 | double dRadius = reference_motor2 - pos_M2; |
Arnoud113 | 0:77ad62c61c78 | 143 | |
Arnoud113 | 3:b353ee86230a | 144 | |
Arnoud113 | 0:77ad62c61c78 | 145 | |
Arnoud113 | 0:77ad62c61c78 | 146 | pc.baud(115200); |
Arnoud113 | 3:b353ee86230a | 147 | pc.printf("\r DesPosition(X,Y):(%f,%f), pos Error(dTheta, dError):(%f,%f)\n",x,y, delta1 ,delta2); |
Arnoud113 | 0:77ad62c61c78 | 148 | |
Arnoud113 | 2:2563d1d8461f | 149 | //motor1PWM = motor1; |
Arnoud113 | 2:2563d1d8461f | 150 | //motor2PWM = motor2; |
Arnoud113 | 0:77ad62c61c78 | 151 | |
Arnoud113 | 3:b353ee86230a | 152 | if(delta1 > 10.0){ |
Arnoud113 | 3:b353ee86230a | 153 | motor1DC = 0; |
Arnoud113 | 0:77ad62c61c78 | 154 | |
Arnoud113 | 0:77ad62c61c78 | 155 | ledr = 1; |
Arnoud113 | 0:77ad62c61c78 | 156 | ledg = 1; //Blau |
Arnoud113 | 0:77ad62c61c78 | 157 | ledb = 0; |
Arnoud113 | 0:77ad62c61c78 | 158 | } |
Arnoud113 | 3:b353ee86230a | 159 | else if (delta1< -10.0) { |
Arnoud113 | 3:b353ee86230a | 160 | motor1DC = 1; |
Arnoud113 | 0:77ad62c61c78 | 161 | |
Arnoud113 | 0:77ad62c61c78 | 162 | ledb = 1; |
Arnoud113 | 0:77ad62c61c78 | 163 | ledr = 1; |
Arnoud113 | 0:77ad62c61c78 | 164 | ledg = 0; //Groen |
Arnoud113 | 0:77ad62c61c78 | 165 | |
Arnoud113 | 0:77ad62c61c78 | 166 | } |
Arnoud113 | 0:77ad62c61c78 | 167 | else{ |
Arnoud113 | 0:77ad62c61c78 | 168 | motor1PWM = 0; |
Arnoud113 | 0:77ad62c61c78 | 169 | |
Arnoud113 | 0:77ad62c61c78 | 170 | ledb = 1; //Rood |
Arnoud113 | 0:77ad62c61c78 | 171 | ledr = 0; |
Arnoud113 | 0:77ad62c61c78 | 172 | ledg = 1; |
Arnoud113 | 0:77ad62c61c78 | 173 | } |
Arnoud113 | 3:b353ee86230a | 174 | |
Arnoud113 | 3:b353ee86230a | 175 | motor1 = abs(delta1)/1000.0f; |
Arnoud113 | 3:b353ee86230a | 176 | if(motor1 >= 0.50f) { |
Arnoud113 | 3:b353ee86230a | 177 | motor1 = 0.50f; |
Arnoud113 | 3:b353ee86230a | 178 | } |
Arnoud113 | 0:77ad62c61c78 | 179 | |
Arnoud113 | 3:b353ee86230a | 180 | if(delta2 > 10.0){ |
Arnoud113 | 3:b353ee86230a | 181 | motor2DC = 0; |
Arnoud113 | 0:77ad62c61c78 | 182 | |
Arnoud113 | 0:77ad62c61c78 | 183 | ledr = 1; |
Arnoud113 | 0:77ad62c61c78 | 184 | ledg = 1; //Blau |
Arnoud113 | 0:77ad62c61c78 | 185 | ledb = 0; |
Arnoud113 | 0:77ad62c61c78 | 186 | } |
Arnoud113 | 3:b353ee86230a | 187 | else if (delta2<-10.0) { |
Arnoud113 | 3:b353ee86230a | 188 | motor2DC = 1; |
Arnoud113 | 0:77ad62c61c78 | 189 | |
Arnoud113 | 0:77ad62c61c78 | 190 | ledb = 1; |
Arnoud113 | 0:77ad62c61c78 | 191 | ledr = 1; |
Arnoud113 | 0:77ad62c61c78 | 192 | ledg = 0; //Groen |
Arnoud113 | 0:77ad62c61c78 | 193 | |
Arnoud113 | 0:77ad62c61c78 | 194 | } |
Arnoud113 | 0:77ad62c61c78 | 195 | else{ |
Arnoud113 | 0:77ad62c61c78 | 196 | motor2PWM = 0; |
Arnoud113 | 0:77ad62c61c78 | 197 | |
Arnoud113 | 0:77ad62c61c78 | 198 | ledb = 1; //Rood |
Arnoud113 | 0:77ad62c61c78 | 199 | ledr = 0; |
Arnoud113 | 0:77ad62c61c78 | 200 | ledg = 1; |
Arnoud113 | 0:77ad62c61c78 | 201 | } |
Arnoud113 | 3:b353ee86230a | 202 | |
Arnoud113 | 3:b353ee86230a | 203 | motor2 = abs(delta2)/1000.0f; |
Arnoud113 | 3:b353ee86230a | 204 | if(motor1 >= 0.50f) { |
Arnoud113 | 3:b353ee86230a | 205 | motor1 = 0.50f; |
Arnoud113 | 3:b353ee86230a | 206 | } |
Arnoud113 | 3:b353ee86230a | 207 | |
Arnoud113 | 3:b353ee86230a | 208 | motor1PWM = motor1 + 0.50f; |
Arnoud113 | 3:b353ee86230a | 209 | motor2PWM = motor1 + 0.50f; |
Arnoud113 | 3:b353ee86230a | 210 | |
Arnoud113 | 3:b353ee86230a | 211 | //pc.printf("\r motorvalues (M1,M2):(%f,%f), error:( \n", , motor1PWM, motor2PWM); |
Arnoud113 | 3:b353ee86230a | 212 | //pc.printf("\r |
Arnoud113 | 0:77ad62c61c78 | 213 | } |
Arnoud113 | 0:77ad62c61c78 | 214 | |
Arnoud113 | 0:77ad62c61c78 | 215 | int main() |
Arnoud113 | 0:77ad62c61c78 | 216 | { |
Arnoud113 | 0:77ad62c61c78 | 217 | controller.attach(&Controller, M1_TS); |
Arnoud113 | 3:b353ee86230a | 218 | //motor1PWM.period(Pwmperiod); |
Arnoud113 | 3:b353ee86230a | 219 | //motor2PWM.period(Pwmperiod); |
Arnoud113 | 0:77ad62c61c78 | 220 | |
Arnoud113 | 3:b353ee86230a | 221 | while(1){ |
Arnoud113 | 3:b353ee86230a | 222 | /* |
Arnoud113 | 3:b353ee86230a | 223 | double x = Get_X_Position(); |
Arnoud113 | 3:b353ee86230a | 224 | double y = Get_Y_Position(); |
Arnoud113 | 3:b353ee86230a | 225 | double reference_motor1 = atan(y/x); |
Arnoud113 | 3:b353ee86230a | 226 | int position_Motor1 = motor1_Position(); |
Arnoud113 | 3:b353ee86230a | 227 | double motor1 = PID(reference_motor1 - position_Motor1, M1_KP, M1_KI, M1_KD, M1_TS, m1_err_int, m1_prev_err, m1_f_v1, m1_f_v2, M1_F_A1, M1_F_A2, M1_F_B0, M1_F_B1, M1_F_B2); |
Arnoud113 | 3:b353ee86230a | 228 | |
Arnoud113 | 3:b353ee86230a | 229 | pc.baud(115200); |
Arnoud113 | 3:b353ee86230a | 230 | pc.printf("\r Position(X)=(%f), Ref(Theta,R): (%f,), Pos(Theta,R):(%i,), Motor Value(M1,M2):(%f,).\n",x, reference_motor1, position_Motor1, motor1); |
Arnoud113 | 3:b353ee86230a | 231 | */ |
Arnoud113 | 3:b353ee86230a | 232 | } |
Arnoud113 | 0:77ad62c61c78 | 233 | |
Arnoud113 | 0:77ad62c61c78 | 234 | } |