controller_test_endpoint_LH

Dependencies:   mbed

Committer:
OscarLiao
Date:
Fri Nov 30 13:11:38 2018 +0000
Revision:
0:80f74d98d66f
LH_leg_controller

Who changed what in which revision?

UserRevisionLine numberNew contents of line
OscarLiao 0:80f74d98d66f 1 /*
OscarLiao 0:80f74d98d66f 2 This is a program for localized controller of one leg
OscarLiao 0:80f74d98d66f 3 Endpoint space Impedence Control and Force/Torque feedforward
OscarLiao 0:80f74d98d66f 4 Two input was acceptable
OscarLiao 0:80f74d98d66f 5 q_0_E[3] Neutral point for Impedence reference
OscarLiao 0:80f74d98d66f 6 T_0[3] Feedforward of Force/Torque
OscarLiao 0:80f74d98d66f 7
OscarLiao 0:80f74d98d66f 8 ---------o------↺ q_act_est[0]
OscarLiao 0:80f74d98d66f 9 /|
OscarLiao 0:80f74d98d66f 10 L1 / | ⤸ q_act_est[1]
OscarLiao 0:80f74d98d66f 11 o |
OscarLiao 0:80f74d98d66f 12 L2 //
OscarLiao 0:80f74d98d66f 13 / / ⤸ q_act_est[2]
OscarLiao 0:80f74d98d66f 14 o /
OscarLiao 0:80f74d98d66f 15 MCU target: F303K8
OscarLiao 0:80f74d98d66f 16 ADC config: 3.3 Vadc common source
OscarLiao 0:80f74d98d66f 17 */
OscarLiao 0:80f74d98d66f 18 //**************** Wiring Map ********************//
OscarLiao 0:80f74d98d66f 19 // |---------------| | |---------------|
OscarLiao 0:80f74d98d66f 20 // Srl| PA_9 | D1 |Cmd Serail | | VIN | VIN |
OscarLiao 0:80f74d98d66f 21 // Srl| PA_10 | D0 |Cmd Serial | | GND | GND |
OscarLiao 0:80f74d98d66f 22 // | NRST | NRST | | | NRST | NRST |
OscarLiao 0:80f74d98d66f 23 // | GND | GND | | | 5V | 5V |
OscarLiao 0:80f74d98d66f 24 // | PA_12 | D2 | |Srl| A7 | PA_2 |PC Serial
OscarLiao 0:80f74d98d66f 25 // PWM| PB_0 | D3 |Shing Drv |Dou| A6 | PA_7 |CSG
OscarLiao 0:80f74d98d66f 26 // Dou| PB_7 | D4 |Task1 |Din| A5 | PA_6 |CS2 Stretch Cmd
OscarLiao 0:80f74d98d66f 27 // Dou| PB_6 | D5 |Task2 |Din| A4 | PA_5 |CS1 Serial Sync
OscarLiao 0:80f74d98d66f 28 // PWM| PB_1 | D6 |Tigh Drv |Ain| A3 | PA_4 |Shing sense
OscarLiao 0:80f74d98d66f 29 // | PF_0 | D7 | |Ain| A2 | PA_3 |Tigh sense
OscarLiao 0:80f74d98d66f 30 // | PF_1 | D8 | |Ain| A1 | PA_1 |Hip sense
OscarLiao 0:80f74d98d66f 31 // PWM| PA_8 | D9 |Hip Drv | | A0 | PA_0 |
OscarLiao 0:80f74d98d66f 32 // | PA_11 | D10 | | | AREF | AREF |VR source
OscarLiao 0:80f74d98d66f 33 // | PB_5 | D11 | | | 3V3 | 3V3 |
OscarLiao 0:80f74d98d66f 34 // | PB_4 | D12 | |Dou| D13 | PB_3 |led / Serial error
OscarLiao 0:80f74d98d66f 35 // |---------------| | |---------------|
OscarLiao 0:80f74d98d66f 36 #include "mbed.h"
OscarLiao 0:80f74d98d66f 37 //#include "LSM9DS0_SH.h"
OscarLiao 0:80f74d98d66f 38 //#define DEBUG 1
OscarLiao 0:80f74d98d66f 39 #define DEBUG 0
OscarLiao 0:80f74d98d66f 40 #define pi 3.141592f
OscarLiao 0:80f74d98d66f 41 #define d2r 0.01745329f
OscarLiao 0:80f74d98d66f 42
OscarLiao 0:80f74d98d66f 43 #define Rms 5000 //TT rate
OscarLiao 0:80f74d98d66f 44 #define dt 0.015f
OscarLiao 0:80f74d98d66f 45 #define Task_1_NN 2
OscarLiao 0:80f74d98d66f 46 #define Task_2_NN 199
OscarLiao 0:80f74d98d66f 47
OscarLiao 0:80f74d98d66f 48 //Torque-Controller gain
OscarLiao 0:80f74d98d66f 49 #define G1_rad_dc 0.00157f
OscarLiao 0:80f74d98d66f 50 #define Kqff 636.7f //ffoward gain of q_act_est = 1 / G1_rad_dc
OscarLiao 0:80f74d98d66f 51 #define KTff 60.408f //ffoward gain of T_ref_WD = 1 / (K_q * G1_rad_dc)
OscarLiao 0:80f74d98d66f 52 #define Kpt 22.9f
OscarLiao 0:80f74d98d66f 53 #define Ki 151.9f
OscarLiao 0:80f74d98d66f 54
OscarLiao 0:80f74d98d66f 55 //ADC reference constant
OscarLiao 0:80f74d98d66f 56 #define Kadc 5.817f //adc value to q_spring
OscarLiao 0:80f74d98d66f 57 #define K_spring 13180f //sping constant of single spring
OscarLiao 0:80f74d98d66f 58 #define K_q 10.544f //2*K_spring*R^2
OscarLiao 0:80f74d98d66f 59 #define R 0.02f //wheely's radius
OscarLiao 0:80f74d98d66f 60
OscarLiao 0:80f74d98d66f 61 //Endpoint Impedence Contorller coefficcient
OscarLiao 0:80f74d98d66f 62 #define Kpi_Hip 0
OscarLiao 0:80f74d98d66f 63 #define Kpi_Thigh 2000
OscarLiao 0:80f74d98d66f 64 #define Kpi_Shin 8
OscarLiao 0:80f74d98d66f 65 #define Kd_Hip 0.0
OscarLiao 0:80f74d98d66f 66 #define Kd_Thigh 0.0
OscarLiao 0:80f74d98d66f 67 #define Kd_Shin 0.0
OscarLiao 0:80f74d98d66f 68 #define KN 20
OscarLiao 0:80f74d98d66f 69 #define L1 0.120f //Tigh length
OscarLiao 0:80f74d98d66f 70 #define L2 0.1480f //Shing lenth
OscarLiao 0:80f74d98d66f 71 #define LA (L1*L1+L2*L2) //L1^2 + L2^2
OscarLiao 0:80f74d98d66f 72 #define LB (L1*L2) //L1*L2
OscarLiao 0:80f74d98d66f 73 #define LC (L1/L2) //L1/L2
OscarLiao 0:80f74d98d66f 74 #define L0 0.2f //Length of the leg
OscarLiao 0:80f74d98d66f 75
OscarLiao 0:80f74d98d66f 76 //Structure
OscarLiao 0:80f74d98d66f 77 #define PWM_Hip 1410 //900~1550~2200 2050
OscarLiao 0:80f74d98d66f 78 #define PWM_Thigh 1490 //900~1550~2200 1300
OscarLiao 0:80f74d98d66f 79 #define PWM_Shin 1710 //900~1550~2200 1450 1740
OscarLiao 0:80f74d98d66f 80
OscarLiao 0:80f74d98d66f 81 #define Buff_size 16 //Serial Buffer
OscarLiao 0:80f74d98d66f 82
OscarLiao 0:80f74d98d66f 83 #define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
OscarLiao 0:80f74d98d66f 84
OscarLiao 0:80f74d98d66f 85 //≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡GPIO registor≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡//
OscarLiao 0:80f74d98d66f 86 //╔═════════════════╗
OscarLiao 0:80f74d98d66f 87 //║ Structure ║
OscarLiao 0:80f74d98d66f 88 //╚═════════════════╝
OscarLiao 0:80f74d98d66f 89 DigitalOut led(D13); //detection
OscarLiao 0:80f74d98d66f 90 DigitalOut led2(D12); //detection
OscarLiao 0:80f74d98d66f 91 DigitalOut Task_1(D4); //Task indicate
OscarLiao 0:80f74d98d66f 92 DigitalOut Task_2(D5);
OscarLiao 0:80f74d98d66f 93 DigitalOut CSG(A6); //Stretch interrupt pull down
OscarLiao 0:80f74d98d66f 94
OscarLiao 0:80f74d98d66f 95 AnalogIn adc1(A1); //adc
OscarLiao 0:80f74d98d66f 96 AnalogIn adc2(A2); //adc
OscarLiao 0:80f74d98d66f 97 AnalogIn adc3(A3); //adc
OscarLiao 0:80f74d98d66f 98
OscarLiao 0:80f74d98d66f 99 InterruptIn CS1(D2); //Serial synchronizor
OscarLiao 0:80f74d98d66f 100 DigitalIn CS2(A5); //Stretch interrupt
OscarLiao 0:80f74d98d66f 101
OscarLiao 0:80f74d98d66f 102
OscarLiao 0:80f74d98d66f 103 //╔═════════════════╗
OscarLiao 0:80f74d98d66f 104 //║ Servo out ║
OscarLiao 0:80f74d98d66f 105 //╚═════════════════╝
OscarLiao 0:80f74d98d66f 106 PwmOut Drive1(D9); //PWM 1/1
OscarLiao 0:80f74d98d66f 107 PwmOut Drive2(D6); //PWM 1/2N
OscarLiao 0:80f74d98d66f 108 PwmOut Drive3(D3); //PWM 1/3N
OscarLiao 0:80f74d98d66f 109
OscarLiao 0:80f74d98d66f 110 //╔═════════════════╗
OscarLiao 0:80f74d98d66f 111 //║ Serial ║
OscarLiao 0:80f74d98d66f 112 //╚═════════════════╝
OscarLiao 0:80f74d98d66f 113 Serial Debug(PA_2, PA_15); //Serial reg(TX RX) USB port
OscarLiao 0:80f74d98d66f 114 Serial Cmd(D1, D0); //Serial reg(TX RX)
OscarLiao 0:80f74d98d66f 115 //■■■■■■■■■■■■■■■■■■■■■■■■■■■end of GPIO registor■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■//
OscarLiao 0:80f74d98d66f 116
OscarLiao 0:80f74d98d66f 117
OscarLiao 0:80f74d98d66f 118 //≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡Varible registor≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡//
OscarLiao 0:80f74d98d66f 119 //╔═════════════════╗
OscarLiao 0:80f74d98d66f 120 //║ Structure ║
OscarLiao 0:80f74d98d66f 121 //╚═════════════════╝
OscarLiao 0:80f74d98d66f 122 Ticker TT; //call a timer
OscarLiao 0:80f74d98d66f 123 uint8_t Task_1_count = 0; //1st prior task count
OscarLiao 0:80f74d98d66f 124 uint8_t Task_2_count = 0; //2nd prior task count
OscarLiao 0:80f74d98d66f 125 uint8_t Flag_1 = 0; //1st prior task flag
OscarLiao 0:80f74d98d66f 126 uint8_t Flag_2 = 0; //2nd prior task flag
OscarLiao 0:80f74d98d66f 127
OscarLiao 0:80f74d98d66f 128 //╔═════════════════╗
OscarLiao 0:80f74d98d66f 129 //║ ADC ║
OscarLiao 0:80f74d98d66f 130 //╚═════════════════╝
OscarLiao 0:80f74d98d66f 131
OscarLiao 0:80f74d98d66f 132 //╔═════════════════╗
OscarLiao 0:80f74d98d66f 133 //║ PWM ║
OscarLiao 0:80f74d98d66f 134 //╚═════════════════╝
OscarLiao 0:80f74d98d66f 135 const int16_t PWM_base[3] = { //reference command at 0, -45, 45 deg
OscarLiao 0:80f74d98d66f 136 PWM_Hip,PWM_Thigh,PWM_Shin
OscarLiao 0:80f74d98d66f 137 };
OscarLiao 0:80f74d98d66f 138 int16_t PWM[3] = { //command out PWM_base + q_ref
OscarLiao 0:80f74d98d66f 139 0, 0, 0 //transfer: 10us to 1 deg
OscarLiao 0:80f74d98d66f 140 };
OscarLiao 0:80f74d98d66f 141
OscarLiao 0:80f74d98d66f 142 //╔═════════════════╗
OscarLiao 0:80f74d98d66f 143 //║ q_actEstimator ║
OscarLiao 0:80f74d98d66f 144 //╚═════════════════╝
OscarLiao 0:80f74d98d66f 145 /*
OscarLiao 0:80f74d98d66f 146 q_act_est = q_ref*G1_rad_TUT(z) - q_spring
OscarLiao 0:80f74d98d66f 147
OscarLiao 0:80f74d98d66f 148 G1_rad_TUT(z) is shown below
OscarLiao 0:80f74d98d66f 149
OscarLiao 0:80f74d98d66f 150 y(z) 1.316 + 2.633*z^-1 + 1.316*z^-2 b0 + b1*z^-1 + b2*z^-2
OscarLiao 0:80f74d98d66f 151 ----- = ----------------------------------- * 1e-04 = ------------------------
OscarLiao 0:80f74d98d66f 152 x(z) 1 - 0.8447*z^-1 + 0.1799*z^-2 1 - a1*z^-1 - a2*z^-2
OscarLiao 0:80f74d98d66f 153
OscarLiao 0:80f74d98d66f 154 q_ref═>[Σ]════════╦═>[b0]═>[Σ]═[1e-04]═>y
OscarLiao 0:80f74d98d66f 155 ⇑ ⇓w0 ⇑
OscarLiao 0:80f74d98d66f 156 ║ [1/z] ║
OscarLiao 0:80f74d98d66f 157 [Σ]<═[a1]<═╬═>[b1]═>[Σ]
OscarLiao 0:80f74d98d66f 158 ⇑ ⇓w1 ⇑
OscarLiao 0:80f74d98d66f 159 ║ [1/z] ║
OscarLiao 0:80f74d98d66f 160 ╚═══[a2]<═╩═>[b2]═══╝
OscarLiao 0:80f74d98d66f 161 w2
OscarLiao 0:80f74d98d66f 162 */
OscarLiao 0:80f74d98d66f 163 float q_act_est[3] = { //output of filter
OscarLiao 0:80f74d98d66f 164 0, 0, 0
OscarLiao 0:80f74d98d66f 165 };
OscarLiao 0:80f74d98d66f 166
OscarLiao 0:80f74d98d66f 167 float L_act_est = 0.0;
OscarLiao 0:80f74d98d66f 168 float P_act_est = 0.0;
OscarLiao 0:80f74d98d66f 169
OscarLiao 0:80f74d98d66f 170 float G1_w_n[3][3] = { //G1_rad_TUT's
OscarLiao 0:80f74d98d66f 171 {0, 0, 0}, //{w0, w1, w2}
OscarLiao 0:80f74d98d66f 172 {0, 0, 0}, //second sea
OscarLiao 0:80f74d98d66f 173 {0, 0, 0},
OscarLiao 0:80f74d98d66f 174 };
OscarLiao 0:80f74d98d66f 175 const float G1_a[3] = { //{a0, a1, a2}
OscarLiao 0:80f74d98d66f 176 1.00, 0.8447, -0.1799
OscarLiao 0:80f74d98d66f 177 };
OscarLiao 0:80f74d98d66f 178 const float G1_b[3] = { //{b0, b1, b2}
OscarLiao 0:80f74d98d66f 179 1.316, 2.633, 1.316
OscarLiao 0:80f74d98d66f 180 };
OscarLiao 0:80f74d98d66f 181
OscarLiao 0:80f74d98d66f 182 //╔═════════════════╗//╔══════════════════╗
OscarLiao 0:80f74d98d66f 183 //║ Comp_ref ║//║ Controller Input ║
OscarLiao 0:80f74d98d66f 184 //╚═════════════════╝//╚══════════════════╝
OscarLiao 0:80f74d98d66f 185 /*
OscarLiao 0:80f74d98d66f 186
OscarLiao 0:80f74d98d66f 187 ---------o------↺ q_act_est[0]
OscarLiao 0:80f74d98d66f 188 /|
OscarLiao 0:80f74d98d66f 189 L1 / | ↻ q_act_est[1]
OscarLiao 0:80f74d98d66f 190 o |
OscarLiao 0:80f74d98d66f 191 L2 //
OscarLiao 0:80f74d98d66f 192 / / ↻ q_act_est[2]
OscarLiao 0:80f74d98d66f 193 o /
OscarLiao 0:80f74d98d66f 194
OscarLiao 0:80f74d98d66f 195 1 - z^-1
OscarLiao 0:80f74d98d66f 196 PDn(z) = P + D*N*---------------------
OscarLiao 0:80f74d98d66f 197 1 - (1 - N*Ts)*z^-1
OscarLiao 0:80f74d98d66f 198
OscarLiao 0:80f74d98d66f 199 y(z) b0 + b1*z^-1 1 + (-1)*z^-1
OscarLiao 0:80f74d98d66f 200 ----- = -------------- = ------------------
OscarLiao 0:80f74d98d66f 201 x(z) 1 - a1*z^-1 1 - 0.7*z^-1
OscarLiao 0:80f74d98d66f 202
OscarLiao 0:80f74d98d66f 203 x═>[Σ]═══════╦═>[b0]═>[Σ]═>[D*N]═>y
OscarLiao 0:80f74d98d66f 204 ⇑ ⇓w0 ⇑
OscarLiao 0:80f74d98d66f 205 ║ [1/z] ║
OscarLiao 0:80f74d98d66f 206 ╚══[a1]<═╩═>[b1]═══╝
OscarLiao 0:80f74d98d66f 207 w1
OscarLiao 0:80f74d98d66f 208 */
OscarLiao 0:80f74d98d66f 209
OscarLiao 0:80f74d98d66f 210 float K_c[3] = { //K_c reference impedence
OscarLiao 0:80f74d98d66f 211 Kpi_Hip, Kpi_Thigh, Kpi_Shin //{Hip, Thigh, Shin}
OscarLiao 0:80f74d98d66f 212 };
OscarLiao 0:80f74d98d66f 213 float B_c[3] = { //B_c = D*N (*20)reference damping (Dmax~0.4)(B_c_max~5) in joint!!
OscarLiao 0:80f74d98d66f 214 Kd_Hip*KN, Kd_Thigh*KN, Kd_Shin*KN //{Hip, Thigh, Shin}
OscarLiao 0:80f74d98d66f 215 };
OscarLiao 0:80f74d98d66f 216 float q_0_E[3] = { //"Controller Input" from upper controller in endpoint level (Operational Space)
OscarLiao 0:80f74d98d66f 217 0, 0, 0 //{Hip, leg length, leg angle} original point
OscarLiao 0:80f74d98d66f 218 };
OscarLiao 0:80f74d98d66f 219 float T_0[3] = { //"Controller Input" from upper controller in joint level
OscarLiao 0:80f74d98d66f 220 0, 0, 0 //{T_0_Hip, T_0_Tigh, F_0_Stretch} force feed foward
OscarLiao 0:80f74d98d66f 221 };
OscarLiao 0:80f74d98d66f 222 float q_err_E[3] = { //error in endpoint level
OscarLiao 0:80f74d98d66f 223 0, 0, 0
OscarLiao 0:80f74d98d66f 224 };
OscarLiao 0:80f74d98d66f 225 float q_err_D_E[3] = { //derivative error in endpoint level
OscarLiao 0:80f74d98d66f 226 0, 0, 0
OscarLiao 0:80f74d98d66f 227 };
OscarLiao 0:80f74d98d66f 228 float Cref_w[3][2] = { //filter storage
OscarLiao 0:80f74d98d66f 229 {0, 0},
OscarLiao 0:80f74d98d66f 230 {0, 0},
OscarLiao 0:80f74d98d66f 231 {0, 0},
OscarLiao 0:80f74d98d66f 232 };
OscarLiao 0:80f74d98d66f 233 const float Cref_a[2] = { //{a0, a1}
OscarLiao 0:80f74d98d66f 234 1.00, 0.70
OscarLiao 0:80f74d98d66f 235 };
OscarLiao 0:80f74d98d66f 236 const float Cref_b[2] = { //{b0, b1}
OscarLiao 0:80f74d98d66f 237 1.00, -1.00
OscarLiao 0:80f74d98d66f 238 };
OscarLiao 0:80f74d98d66f 239 float J32 = 0.0;
OscarLiao 0:80f74d98d66f 240 float J33 = 0.0;
OscarLiao 0:80f74d98d66f 241 float Phi1_0 = 0.0;
OscarLiao 0:80f74d98d66f 242 float Phi2_0 = 0.0;
OscarLiao 0:80f74d98d66f 243
OscarLiao 0:80f74d98d66f 244 //╔═════════════════╗
OscarLiao 0:80f74d98d66f 245 //║ Torque_reg ║
OscarLiao 0:80f74d98d66f 246 //╚═════════════════╝
OscarLiao 0:80f74d98d66f 247 /*
OscarLiao 0:80f74d98d66f 248 q_act_est T_ref_WD
OscarLiao 0:80f74d98d66f 249 q_ref = ----------- + -------------------------- + PI( T_ref - 2*K_spring*R^2*q_spring )
OscarLiao 0:80f74d98d66f 250 G1_rad_dc 2*K_spring*R^2*G1_rad_dc
OscarLiao 0:80f74d98d66f 251
OscarLiao 0:80f74d98d66f 252 PI(z) = P + I*dt / (z-1)
OscarLiao 0:80f74d98d66f 253 */
OscarLiao 0:80f74d98d66f 254 const float Kp[3] = { //P gain for Torque REG
OscarLiao 0:80f74d98d66f 255 Kpt, Kpt, Kpt //{Hip, Tigh, Shin}
OscarLiao 0:80f74d98d66f 256 };
OscarLiao 0:80f74d98d66f 257 const float Kit[3] = { //I gain for Torque REG Kit = Ki*Ts
OscarLiao 0:80f74d98d66f 258 Ki*dt, Ki*dt, Ki*dt //{Hip, Tigh, Shin}
OscarLiao 0:80f74d98d66f 259 };
OscarLiao 0:80f74d98d66f 260 float T_ref[3] = { //command to T_reg in joint level
OscarLiao 0:80f74d98d66f 261 0, 0, 0 //{Hip, Tigh, Shin}
OscarLiao 0:80f74d98d66f 262 };
OscarLiao 0:80f74d98d66f 263 float T_ref_E[3] = { //command to T_reg in end point level
OscarLiao 0:80f74d98d66f 264 0, 0, 0 //{Hip, Len, Phi}
OscarLiao 0:80f74d98d66f 265 };
OscarLiao 0:80f74d98d66f 266 float T_ref_WD[3] = { //command without damping reference in joint level
OscarLiao 0:80f74d98d66f 267 0, 0, 0
OscarLiao 0:80f74d98d66f 268 };
OscarLiao 0:80f74d98d66f 269 float T_ref_WD_E[3] = { //command without damping reference in endpoint level
OscarLiao 0:80f74d98d66f 270 0, 0, 0
OscarLiao 0:80f74d98d66f 271 };
OscarLiao 0:80f74d98d66f 272 float T_err[3] = { //T_ref - T_act_est, T_act_est = q_spring * K_q
OscarLiao 0:80f74d98d66f 273 0, 0, 0 //{Hip, Tigh, Shin}
OscarLiao 0:80f74d98d66f 274 };
OscarLiao 0:80f74d98d66f 275 float q_ref[3] = { //output of T_reg
OscarLiao 0:80f74d98d66f 276 0, 0, 0 //{Hip, Thigh, Shin}
OscarLiao 0:80f74d98d66f 277 };
OscarLiao 0:80f74d98d66f 278 float q_spring[3] = { //read in spring travel
OscarLiao 0:80f74d98d66f 279 0, 0, 0
OscarLiao 0:80f74d98d66f 280 };
OscarLiao 0:80f74d98d66f 281 float q_spring_0[3] = { //neutral point of VR
OscarLiao 0:80f74d98d66f 282 0, 0, 0
OscarLiao 0:80f74d98d66f 283 };
OscarLiao 0:80f74d98d66f 284 float T_reg_I[3] = { //PI_w
OscarLiao 0:80f74d98d66f 285 0, 0, 0
OscarLiao 0:80f74d98d66f 286 };
OscarLiao 0:80f74d98d66f 287
OscarLiao 0:80f74d98d66f 288 //╔═════════════════╗
OscarLiao 0:80f74d98d66f 289 //║ sine signal ║
OscarLiao 0:80f74d98d66f 290 //╚═════════════════╝
OscarLiao 0:80f74d98d66f 291 int data = 0;
OscarLiao 0:80f74d98d66f 292 float amp = 0.1;
OscarLiao 0:80f74d98d66f 293 float freq = 55; //rad/s
OscarLiao 0:80f74d98d66f 294 int totalticks = 0;
OscarLiao 0:80f74d98d66f 295 int ticks = 0;
OscarLiao 0:80f74d98d66f 296
OscarLiao 0:80f74d98d66f 297 //╔═════════════════╗
OscarLiao 0:80f74d98d66f 298 //║ I/O Serial ║
OscarLiao 0:80f74d98d66f 299 //╚═════════════════╝
OscarLiao 0:80f74d98d66f 300 uint8_t Buff[Buff_size];
OscarLiao 0:80f74d98d66f 301 uint8_t Recieve_index = 0;
OscarLiao 0:80f74d98d66f 302 uint8_t Cmd_Flag = 0;
OscarLiao 0:80f74d98d66f 303 uint8_t Rx_enable = 0;
OscarLiao 0:80f74d98d66f 304 char buffer[128];
OscarLiao 0:80f74d98d66f 305 //■■■■■■■■■■■■■■■■■■■■■■■■■■■end of Varible registor■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■//
OscarLiao 0:80f74d98d66f 306
OscarLiao 0:80f74d98d66f 307
OscarLiao 0:80f74d98d66f 308 //≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡Function registor≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡//
OscarLiao 0:80f74d98d66f 309 void init_TIMER(); //set TT_main() rate
OscarLiao 0:80f74d98d66f 310 void TT_main(); //timebase function rated by TT
OscarLiao 0:80f74d98d66f 311 void init_q_spring_0(); //calibrating
OscarLiao 0:80f74d98d66f 312 void init_IO(); //initialize IO state
OscarLiao 0:80f74d98d66f 313
OscarLiao 0:80f74d98d66f 314 void q_spring_Est();
OscarLiao 0:80f74d98d66f 315 void q_act_Est();
OscarLiao 0:80f74d98d66f 316 void Impedence_Ref();
OscarLiao 0:80f74d98d66f 317 void Torque_Reg();
OscarLiao 0:80f74d98d66f 318
OscarLiao 0:80f74d98d66f 319 void Rx_irq();
OscarLiao 0:80f74d98d66f 320 void Rx_srt();
OscarLiao 0:80f74d98d66f 321 void Rx_end();
OscarLiao 0:80f74d98d66f 322 //void NVIC_DisableIRQ(USART1_IRQn);
OscarLiao 0:80f74d98d66f 323 //void NVIC_EnableIRQ(USART1_IRQn);
OscarLiao 0:80f74d98d66f 324 //■■■■■■■■■■■■■■■■■■■■■■■■■■■end of Function registor■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■//
OscarLiao 0:80f74d98d66f 325
OscarLiao 0:80f74d98d66f 326
OscarLiao 0:80f74d98d66f 327 //≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡main funtion≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡//
OscarLiao 0:80f74d98d66f 328 int main()
OscarLiao 0:80f74d98d66f 329 {
OscarLiao 0:80f74d98d66f 330 Debug.baud(115200); //set baud rate
OscarLiao 0:80f74d98d66f 331 Cmd.baud(115200); //set baud rate
OscarLiao 0:80f74d98d66f 332
OscarLiao 0:80f74d98d66f 333 wait_ms(10);
OscarLiao 0:80f74d98d66f 334 init_q_spring_0(); //calibrating q_spring reference point
OscarLiao 0:80f74d98d66f 335
OscarLiao 0:80f74d98d66f 336 wait_ms(600);
OscarLiao 0:80f74d98d66f 337 init_IO(); //initialized value
OscarLiao 0:80f74d98d66f 338 init_TIMER(); //start TT_main
OscarLiao 0:80f74d98d66f 339
OscarLiao 0:80f74d98d66f 340 //for sine signal
OscarLiao 0:80f74d98d66f 341 totalticks = ((2*pi)/freq)/((Rms/1E6)*(Task_2_NN+1));
OscarLiao 0:80f74d98d66f 342 Cmd.attach(&Rx_irq,Serial::RxIrq); //start recieving message
OscarLiao 0:80f74d98d66f 343 // NVIC_DisableIRQ(USART1_IRQn); //stay down before CS1 signal
OscarLiao 0:80f74d98d66f 344
OscarLiao 0:80f74d98d66f 345 CS1.fall(&Rx_srt); //attach the address of Rx_srt to falling edge as start signal of communication
OscarLiao 0:80f74d98d66f 346 CS1.rise(&Rx_end); //attach the address of Rx_end to rise edge
OscarLiao 0:80f74d98d66f 347
OscarLiao 0:80f74d98d66f 348 q_0_E[0] = 0;
OscarLiao 0:80f74d98d66f 349 q_0_E[1] = 0.2;
OscarLiao 0:80f74d98d66f 350 q_0_E[2] = 0.0;
OscarLiao 0:80f74d98d66f 351
OscarLiao 0:80f74d98d66f 352 Phi1_0 = (acos((L0*L0+L1*L1-L2*L2)/(2*L0*L1)));
OscarLiao 0:80f74d98d66f 353 Phi2_0 = (Phi1_0 + acos((L0*L0+L2*L2-L1*L1)/(2*L0*L2)));
OscarLiao 0:80f74d98d66f 354
OscarLiao 0:80f74d98d66f 355 while(1) { //main() loop
OscarLiao 0:80f74d98d66f 356
OscarLiao 0:80f74d98d66f 357 //Task judging start
OscarLiao 0:80f74d98d66f 358 if(Flag_1 == 1) { //check pending
OscarLiao 0:80f74d98d66f 359 //Task_1 start
OscarLiao 0:80f74d98d66f 360 //read in condition & estimate state
OscarLiao 0:80f74d98d66f 361 q_spring_Est();
OscarLiao 0:80f74d98d66f 362 q_act_Est();
OscarLiao 0:80f74d98d66f 363
OscarLiao 0:80f74d98d66f 364 //calculate control effort
OscarLiao 0:80f74d98d66f 365 Impedence_Ref();
OscarLiao 0:80f74d98d66f 366 Torque_Reg();
OscarLiao 0:80f74d98d66f 367
OscarLiao 0:80f74d98d66f 368 //PWM Drive out process
OscarLiao 0:80f74d98d66f 369 for(int i=0; i<3; i++) {
OscarLiao 0:80f74d98d66f 370 PWM[i] = PWM_base[i] + q_ref[i]; // X + Controll
OscarLiao 0:80f74d98d66f 371 }
OscarLiao 0:80f74d98d66f 372 //PWM[0] = 1460;
OscarLiao 0:80f74d98d66f 373 //PWM[1] = 1330;
OscarLiao 0:80f74d98d66f 374 //PWM[2] = 1830;
OscarLiao 0:80f74d98d66f 375
OscarLiao 0:80f74d98d66f 376 PWM[0] = constrain(PWM[0],800 ,2100);//safty constrain
OscarLiao 0:80f74d98d66f 377 PWM[1] = constrain(PWM[1],800 ,2100);//safty constrain
OscarLiao 0:80f74d98d66f 378 PWM[2] = constrain(PWM[2],800 ,2100);//safty constrain
OscarLiao 0:80f74d98d66f 379
OscarLiao 0:80f74d98d66f 380 Drive1.pulsewidth_us(PWM[0]); //drive command
OscarLiao 0:80f74d98d66f 381 Drive2.pulsewidth_us(PWM[1]);
OscarLiao 0:80f74d98d66f 382 Drive3.pulsewidth_us(PWM[2]);
OscarLiao 0:80f74d98d66f 383
OscarLiao 0:80f74d98d66f 384 //for Serial-Oscilloscope
OscarLiao 0:80f74d98d66f 385 #if DEBUG
OscarLiao 0:80f74d98d66f 386 // q_0[2] = -0.9;
OscarLiao 0:80f74d98d66f 387 // Debug.printf("%f\n", q_act_est[1]);
OscarLiao 0:80f74d98d66f 388 // Debug.printf("%f, %f, %f\r", q_0[0], q_0[1], q_0[2]);
OscarLiao 0:80f74d98d66f 389 Debug.printf("%lf\r", adc3.read());
OscarLiao 0:80f74d98d66f 390 // Debug.printf("%f\n", 123.23);
OscarLiao 0:80f74d98d66f 391 // Debug.printf("%.f\r", q_ref[0]);L_act_est
OscarLiao 0:80f74d98d66f 392 // Debug.printf("%.2f\r", q_spring_0[0]);
OscarLiao 0:80f74d98d66f 393 // Debug.printf("%.2f\r", J33);
OscarLiao 0:80f74d98d66f 394 #endif
OscarLiao 0:80f74d98d66f 395
OscarLiao 0:80f74d98d66f 396 //Task_1 done
OscarLiao 0:80f74d98d66f 397 Flag_1 = 0; //clear pending
OscarLiao 0:80f74d98d66f 398 Task_1 = 0; //clear sign
OscarLiao 0:80f74d98d66f 399 }
OscarLiao 0:80f74d98d66f 400 #if DEBUG
OscarLiao 0:80f74d98d66f 401 if(Flag_2 == 1) { //check pending
OscarLiao 0:80f74d98d66f 402 //Task_2 start
OscarLiao 0:80f74d98d66f 403
OscarLiao 0:80f74d98d66f 404 //%Debug.printf("%d, %d, %d\r", PWM[0], PWM[1], PWM[2]);
OscarLiao 0:80f74d98d66f 405 // Debug.printf("%f\n", q_act_est[2]);
OscarLiao 0:80f74d98d66f 406 //
OscarLiao 0:80f74d98d66f 407 // if(data)
OscarLiao 0:80f74d98d66f 408 // {
OscarLiao 0:80f74d98d66f 409 // //generate sine signal
OscarLiao 0:80f74d98d66f 410 // //q_0[2] = amp*sin((ticks/(float)totalticks)*(2*pi));
OscarLiao 0:80f74d98d66f 411 //// ticks++;
OscarLiao 0:80f74d98d66f 412 //// ticks = ticks%(totalticks+1);
OscarLiao 0:80f74d98d66f 413 // //Debug.printf("%f\n", q_act_est[2]);
OscarLiao 0:80f74d98d66f 414 // q_0[2] = 0.5;
OscarLiao 0:80f74d98d66f 415 // }
OscarLiao 0:80f74d98d66f 416 // else
OscarLiao 0:80f74d98d66f 417 // {
OscarLiao 0:80f74d98d66f 418 // q_0[2] = 0;
OscarLiao 0:80f74d98d66f 419 // }
OscarLiao 0:80f74d98d66f 420
OscarLiao 0:80f74d98d66f 421 //Task_2 done
OscarLiao 0:80f74d98d66f 422
OscarLiao 0:80f74d98d66f 423 Flag_2 = 0; //clear pending
OscarLiao 0:80f74d98d66f 424 Task_2 = 0;
OscarLiao 0:80f74d98d66f 425 }
OscarLiao 0:80f74d98d66f 426 #endif
OscarLiao 0:80f74d98d66f 427 //data test
OscarLiao 0:80f74d98d66f 428 if(Debug.readable()) {
OscarLiao 0:80f74d98d66f 429 // Debug.gets(buffer, 4);
OscarLiao 0:80f74d98d66f 430 // q_0[0] = ((pi/2)/256) * (buffer[0] - 238);
OscarLiao 0:80f74d98d66f 431 // q_0[1] = ((pi/2)/256) * (buffer[1] - 128);
OscarLiao 0:80f74d98d66f 432 // q_0[2] = ((pi/2)/256) * (buffer[2] - 128);
OscarLiao 0:80f74d98d66f 433 q_0_E[1] -= 0.05;
OscarLiao 0:80f74d98d66f 434 Debug.getc();
OscarLiao 0:80f74d98d66f 435 data = !data;
OscarLiao 0:80f74d98d66f 436 }
OscarLiao 0:80f74d98d66f 437
OscarLiao 0:80f74d98d66f 438 if(Cmd_Flag == 1) {
OscarLiao 0:80f74d98d66f 439 //{...}{Hip, Len, Phi}, {'#'}
OscarLiao 0:80f74d98d66f 440 //Received some shit, start decoding
OscarLiao 0:80f74d98d66f 441 led = 1;
OscarLiao 0:80f74d98d66f 442 if(Buff[3] == 'Q') {
OscarLiao 0:80f74d98d66f 443 //q_0 command
OscarLiao 0:80f74d98d66f 444 q_0_E[0] = (Buff[0]);
OscarLiao 0:80f74d98d66f 445 q_0_E[1] = 0.1f + 0.2f * (Buff[1]/255.0f);
OscarLiao 0:80f74d98d66f 446 q_0_E[2] = (Buff[2]);
OscarLiao 0:80f74d98d66f 447 //Debug.printf("%d %f\n", Buff[1], q_0_E[1]);
OscarLiao 0:80f74d98d66f 448 } else if(Buff[3] == 'T') {
OscarLiao 0:80f74d98d66f 449 //T_0 command
OscarLiao 0:80f74d98d66f 450 T_0[0] = 1.0f * (Buff[0] - 128);
OscarLiao 0:80f74d98d66f 451 T_0[1] = 1.0f * (Buff[1] - 128);
OscarLiao 0:80f74d98d66f 452 T_0[2] = 1.0f * (Buff[2] - 128);
OscarLiao 0:80f74d98d66f 453 } else if(Buff[3] == 'K') {
OscarLiao 0:80f74d98d66f 454 K_c[0] = 0.02f * Buff[0];
OscarLiao 0:80f74d98d66f 455 K_c[1] = 0.02f * Buff[1];
OscarLiao 0:80f74d98d66f 456 K_c[2] = 0.02f * Buff[2];
OscarLiao 0:80f74d98d66f 457 } else if (Buff[3] == 'B') {
OscarLiao 0:80f74d98d66f 458 B_c[0] = 0.02f * (Buff[0] - 128);
OscarLiao 0:80f74d98d66f 459 B_c[1] = 0.02f * (Buff[1] - 128);
OscarLiao 0:80f74d98d66f 460 B_c[2] = 0.02f * (Buff[2] - 128);
OscarLiao 0:80f74d98d66f 461 } else {
OscarLiao 0:80f74d98d66f 462 //Show error in communication
OscarLiao 0:80f74d98d66f 463 // led = 1;
OscarLiao 0:80f74d98d66f 464 }
OscarLiao 0:80f74d98d66f 465
OscarLiao 0:80f74d98d66f 466 Buff[3] = 0x00; //clear end signals
OscarLiao 0:80f74d98d66f 467 Cmd_Flag = 0;
OscarLiao 0:80f74d98d66f 468 led = 0;
OscarLiao 0:80f74d98d66f 469 //Send out message threw Cmd
OscarLiao 0:80f74d98d66f 470 // Cmd.printf("%c %c %c\r", Dummy[0], Dummy[1], Dummy[2]);
OscarLiao 0:80f74d98d66f 471 }
OscarLiao 0:80f74d98d66f 472 }
OscarLiao 0:80f74d98d66f 473 }
OscarLiao 0:80f74d98d66f 474 //■■■■■■■■■■■■■■■■■■■■■■■■■■■end of main funtion■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■//
OscarLiao 0:80f74d98d66f 475
OscarLiao 0:80f74d98d66f 476
OscarLiao 0:80f74d98d66f 477 //≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡Timebase funtion≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡//
OscarLiao 0:80f74d98d66f 478 void init_TIMER() //set TT_main{} rate
OscarLiao 0:80f74d98d66f 479 {
OscarLiao 0:80f74d98d66f 480 TT.attach_us(&TT_main, Rms);
OscarLiao 0:80f74d98d66f 481 }
OscarLiao 0:80f74d98d66f 482 void TT_main() //interrupt function by TT
OscarLiao 0:80f74d98d66f 483 {
OscarLiao 0:80f74d98d66f 484 Task_1_count = Task_1_count + 1;
OscarLiao 0:80f74d98d66f 485 if(Task_1_count > Task_1_NN) {
OscarLiao 0:80f74d98d66f 486 Task_1_count = 0; //Task triggering
OscarLiao 0:80f74d98d66f 487 Flag_1 = 1;
OscarLiao 0:80f74d98d66f 488 Task_1 = 1; //show for indicator
OscarLiao 0:80f74d98d66f 489 }
OscarLiao 0:80f74d98d66f 490 Task_2_count = Task_2_count + 1;
OscarLiao 0:80f74d98d66f 491 if(Task_2_count > Task_2_NN) {
OscarLiao 0:80f74d98d66f 492 Task_2_count = 0;
OscarLiao 0:80f74d98d66f 493 //Task triggering
OscarLiao 0:80f74d98d66f 494 Flag_2 = 1;
OscarLiao 0:80f74d98d66f 495 Task_2 = 1; //show for indicator
OscarLiao 0:80f74d98d66f 496 }
OscarLiao 0:80f74d98d66f 497 }
OscarLiao 0:80f74d98d66f 498 //■■■■■■■■■■■■■■■■■■■■■■■■■■■end of Timebase funtion■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■//
OscarLiao 0:80f74d98d66f 499
OscarLiao 0:80f74d98d66f 500
OscarLiao 0:80f74d98d66f 501 //≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡init_IO funtion≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡//
OscarLiao 0:80f74d98d66f 502 void init_IO(void) //initialize
OscarLiao 0:80f74d98d66f 503 {
OscarLiao 0:80f74d98d66f 504 CS1.mode(PullUp); //A4
OscarLiao 0:80f74d98d66f 505 CS2.mode(PullUp); //A5
OscarLiao 0:80f74d98d66f 506 CSG = 0; //A6
OscarLiao 0:80f74d98d66f 507 led = 0;
OscarLiao 0:80f74d98d66f 508 Drive1.period_us(15000);
OscarLiao 0:80f74d98d66f 509 Drive2.period_us(15000);
OscarLiao 0:80f74d98d66f 510 Drive3.period_us(15000);
OscarLiao 0:80f74d98d66f 511 }
OscarLiao 0:80f74d98d66f 512 //■■■■■■■■■■■■■■■■■■■■■■■■■■■end of init_IO funtion■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■//
OscarLiao 0:80f74d98d66f 513
OscarLiao 0:80f74d98d66f 514
OscarLiao 0:80f74d98d66f 515 //≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡controller funtion≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡//
OscarLiao 0:80f74d98d66f 516
OscarLiao 0:80f74d98d66f 517 //follow steps for discrete process in j oder
OscarLiao 0:80f74d98d66f 518 //1.update w0[n] threw input x[n] & wi[n] from last sequence
OscarLiao 0:80f74d98d66f 519 // w0[n] = x[n] + Zigma( ai*wi[n] ), i = 1, 2, 3...j-1, j.
OscarLiao 0:80f74d98d66f 520 // y[n] = Zigma( bi*wi[n] ), i = 0, 1, 2...j-1, j.
OscarLiao 0:80f74d98d66f 521 //2.update wi[n+1] for next sequence
OscarLiao 0:80f74d98d66f 522 // wi[n] = wi-1[n], i = j, j-1...2, 1.
OscarLiao 0:80f74d98d66f 523
OscarLiao 0:80f74d98d66f 524 void q_spring_Est(void)
OscarLiao 0:80f74d98d66f 525 {
OscarLiao 0:80f74d98d66f 526 //read in from adc
OscarLiao 0:80f74d98d66f 527 q_spring[0] = Kadc * adc1.read() - q_spring_0[0];
OscarLiao 0:80f74d98d66f 528 q_spring[1] = Kadc * adc2.read() - q_spring_0[1];
OscarLiao 0:80f74d98d66f 529 q_spring[2] = Kadc * adc3.read() - q_spring_0[2];
OscarLiao 0:80f74d98d66f 530 }
OscarLiao 0:80f74d98d66f 531
OscarLiao 0:80f74d98d66f 532 void q_act_Est(void)
OscarLiao 0:80f74d98d66f 533 {
OscarLiao 0:80f74d98d66f 534 for(int i=0; i<3; i++) {
OscarLiao 0:80f74d98d66f 535 q_ref[i] = PWM[i] - PWM_base[i];
OscarLiao 0:80f74d98d66f 536 }
OscarLiao 0:80f74d98d66f 537 //q_act_est = q_ref*G1_rad_TUT(z) - q_spring
OscarLiao 0:80f74d98d66f 538 //G1_rad_TUT(z) is done below
OscarLiao 0:80f74d98d66f 539 for(int i=0; i<3; i++) {
OscarLiao 0:80f74d98d66f 540 //update w0[n] threw input x[n] & wi[n] from last sequence
OscarLiao 0:80f74d98d66f 541 G1_w_n[i][0] = q_ref[i] + G1_a[1]*G1_w_n[i][1] + G1_a[2]*G1_w_n[i][2];
OscarLiao 0:80f74d98d66f 542 q_act_est[i] = G1_b[0]*G1_w_n[i][0] + G1_b[1]*G1_w_n[i][1] + G1_b[2]*G1_w_n[i][2];
OscarLiao 0:80f74d98d66f 543 q_act_est[i] = q_act_est[i]*0.0001f - q_spring[i];
OscarLiao 0:80f74d98d66f 544
OscarLiao 0:80f74d98d66f 545 //update wi[n+1]
OscarLiao 0:80f74d98d66f 546 G1_w_n[i][2] = G1_w_n[i][1];
OscarLiao 0:80f74d98d66f 547 G1_w_n[i][1] = G1_w_n[i][0];
OscarLiao 0:80f74d98d66f 548 }
OscarLiao 0:80f74d98d66f 549 //q_act_est[i] is now ready for following app
OscarLiao 0:80f74d98d66f 550 }
OscarLiao 0:80f74d98d66f 551
OscarLiao 0:80f74d98d66f 552 void Impedence_Ref(void)
OscarLiao 0:80f74d98d66f 553 {
OscarLiao 0:80f74d98d66f 554 //Transform q_act_est from joint to end point
OscarLiao 0:80f74d98d66f 555 q_act_est[1] -= Phi1_0;
OscarLiao 0:80f74d98d66f 556 q_act_est[2] += Phi2_0;
OscarLiao 0:80f74d98d66f 557
OscarLiao 0:80f74d98d66f 558
OscarLiao 0:80f74d98d66f 559
OscarLiao 0:80f74d98d66f 560 L_act_est = sqrt( LA + 2*LB*cos(q_act_est[2]) );
OscarLiao 0:80f74d98d66f 561 P_act_est = q_act_est[1] + asin( L2*sin(q_act_est[2]) / L_act_est );
OscarLiao 0:80f74d98d66f 562
OscarLiao 0:80f74d98d66f 563
OscarLiao 0:80f74d98d66f 564 //Calculate error in end point level
OscarLiao 0:80f74d98d66f 565 //q_0[i] => {Hip, Tigh, Shin}
OscarLiao 0:80f74d98d66f 566 q_err_E[0] = q_0_E[0] - q_act_est[0]; //Hip motor#1
OscarLiao 0:80f74d98d66f 567 q_err_E[1] = q_0_E[1] - L_act_est;
OscarLiao 0:80f74d98d66f 568 q_err_E[2] = q_0_E[2] - P_act_est;
OscarLiao 0:80f74d98d66f 569
OscarLiao 0:80f74d98d66f 570
OscarLiao 0:80f74d98d66f 571
OscarLiao 0:80f74d98d66f 572 for(int i=0; i<3; i++) {
OscarLiao 0:80f74d98d66f 573 //Generate T_ref in Operational Space (OSC control perhaps?)
OscarLiao 0:80f74d98d66f 574 //T_ref_E = PDn( q_err_E );
OscarLiao 0:80f74d98d66f 575
OscarLiao 0:80f74d98d66f 576 //Compliance
OscarLiao 0:80f74d98d66f 577 T_ref_WD_E[i] = K_c[i] * q_err_E[i];
OscarLiao 0:80f74d98d66f 578
OscarLiao 0:80f74d98d66f 579 //Damping
OscarLiao 0:80f74d98d66f 580 //update w0[n] threw input x[n] & wi[n] from last sequence
OscarLiao 0:80f74d98d66f 581 Cref_w[i][0] = q_err_E[i] + Cref_a[1]*Cref_w[i][1];
OscarLiao 0:80f74d98d66f 582 q_err_D_E[i] = Cref_b[0]*Cref_w[i][0] + Cref_b[1]*Cref_w[i][1];
OscarLiao 0:80f74d98d66f 583
OscarLiao 0:80f74d98d66f 584 //update wi[n+1]
OscarLiao 0:80f74d98d66f 585 Cref_w[i][1] = Cref_w[i][0];
OscarLiao 0:80f74d98d66f 586
OscarLiao 0:80f74d98d66f 587 //Generate T_ref in endpoint level
OscarLiao 0:80f74d98d66f 588 T_ref_E[i] = T_ref_WD_E[i] + B_c[i]*q_err_D_E[i];
OscarLiao 0:80f74d98d66f 589 }
OscarLiao 0:80f74d98d66f 590
OscarLiao 0:80f74d98d66f 591 //Transform torque to joint space, T_ref[i] = Σ( J[i][j] * T_ref_E[j] )
OscarLiao 0:80f74d98d66f 592 J32 = -LB*sin(q_act_est[2]) / L_act_est;
OscarLiao 0:80f74d98d66f 593 J33 = ( pow(J32,2)/LB + cos(q_act_est[2]) ) / (LC + cos(q_act_est[2]));
OscarLiao 0:80f74d98d66f 594
OscarLiao 0:80f74d98d66f 595 //Torque of Hip
OscarLiao 0:80f74d98d66f 596 T_ref[0] = T_ref_E[0];
OscarLiao 0:80f74d98d66f 597 T_ref_WD[0] = T_ref_WD_E[0];
OscarLiao 0:80f74d98d66f 598
OscarLiao 0:80f74d98d66f 599 //Torque of Tigh
OscarLiao 0:80f74d98d66f 600 T_ref[1] = T_ref_E[2] + T_0[1];
OscarLiao 0:80f74d98d66f 601 T_ref_WD[1] = T_ref_WD_E[2] + T_0[1];
OscarLiao 0:80f74d98d66f 602
OscarLiao 0:80f74d98d66f 603 //Torque of Shin
OscarLiao 0:80f74d98d66f 604 T_ref[2] = J32*T_ref_E[1] + J33*T_ref_E[2] + J32*T_0[1] + J33*T_0[2];
OscarLiao 0:80f74d98d66f 605 T_ref_WD[2] = J32*T_ref_WD_E[1] + J33*T_ref_WD_E[2] + J32*T_0[1] + J33*T_0[2];
OscarLiao 0:80f74d98d66f 606
OscarLiao 0:80f74d98d66f 607 }
OscarLiao 0:80f74d98d66f 608
OscarLiao 0:80f74d98d66f 609 void Torque_Reg(void)
OscarLiao 0:80f74d98d66f 610 {
OscarLiao 0:80f74d98d66f 611 if(CS2 == 1) {
OscarLiao 0:80f74d98d66f 612
OscarLiao 0:80f74d98d66f 613 //Transform q_act_est from end point to joint
OscarLiao 0:80f74d98d66f 614 q_act_est[1] += Phi1_0;
OscarLiao 0:80f74d98d66f 615 q_act_est[2] -= Phi2_0;
OscarLiao 0:80f74d98d66f 616
OscarLiao 0:80f74d98d66f 617 //Normal command
OscarLiao 0:80f74d98d66f 618 for(int i=0; i<3; i++) {
OscarLiao 0:80f74d98d66f 619 //FeedFoward
OscarLiao 0:80f74d98d66f 620 q_ref[i] = q_act_est[i]*Kqff + T_ref_WD[i]*KTff; //full feedfoward
OscarLiao 0:80f74d98d66f 621 //q_ref[i] = 0; //w/o feedfoward
OscarLiao 0:80f74d98d66f 622
OscarLiao 0:80f74d98d66f 623 //FeedBack
OscarLiao 0:80f74d98d66f 624 T_err[i] = T_ref[i] - K_q*q_spring[i];
OscarLiao 0:80f74d98d66f 625 T_reg_I[i] = T_reg_I[i] + T_err[i]*Kit[i];
OscarLiao 0:80f74d98d66f 626 T_reg_I[i] = constrain(T_reg_I[i], -200, 200);
OscarLiao 0:80f74d98d66f 627 q_ref[i] = T_err[i]*Kp[i] + T_reg_I[i] + q_ref[i];
OscarLiao 0:80f74d98d66f 628 }
OscarLiao 0:80f74d98d66f 629 q_ref[0] = q_0_E[0]*(550/(float)(0.5*pi));
OscarLiao 0:80f74d98d66f 630 q_ref[0] = constrain(q_ref[0], -650, 650);
OscarLiao 0:80f74d98d66f 631 q_ref[1] = constrain(q_ref[1], -650, 650);
OscarLiao 0:80f74d98d66f 632 q_ref[2] = constrain(q_ref[2], -650, 650);
OscarLiao 0:80f74d98d66f 633
OscarLiao 0:80f74d98d66f 634
OscarLiao 0:80f74d98d66f 635 } else {
OscarLiao 0:80f74d98d66f 636 //Stretch command
OscarLiao 0:80f74d98d66f 637 for(int i=0; i<3; i++) {
OscarLiao 0:80f74d98d66f 638 T_reg_I[i] = 0;
OscarLiao 0:80f74d98d66f 639 q_ref[i] = 0;
OscarLiao 0:80f74d98d66f 640 }
OscarLiao 0:80f74d98d66f 641 }
OscarLiao 0:80f74d98d66f 642 }
OscarLiao 0:80f74d98d66f 643 //■■■■■■■■■■■■■■■■■■■■■■■■■■■end of controller funtion■■■■■■■■■■■■■■■■■■■■■■■■■■■■■//
OscarLiao 0:80f74d98d66f 644
OscarLiao 0:80f74d98d66f 645
OscarLiao 0:80f74d98d66f 646 //≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡init_q_spring_0 funtion≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡//
OscarLiao 0:80f74d98d66f 647 void init_q_spring_0(void)
OscarLiao 0:80f74d98d66f 648 {
OscarLiao 0:80f74d98d66f 649 for(int i=0; i<1000; i++) {
OscarLiao 0:80f74d98d66f 650 q_spring_0[0] = q_spring_0[0] + Kadc * adc1.read();
OscarLiao 0:80f74d98d66f 651 q_spring_0[1] = q_spring_0[1] + Kadc * adc2.read();
OscarLiao 0:80f74d98d66f 652 q_spring_0[2] = q_spring_0[2] + Kadc * adc3.read();
OscarLiao 0:80f74d98d66f 653 wait_us(100);
OscarLiao 0:80f74d98d66f 654 }
OscarLiao 0:80f74d98d66f 655 q_spring_0[0] = q_spring_0[0] /1000.0f;
OscarLiao 0:80f74d98d66f 656 q_spring_0[1] = q_spring_0[1] /1000.0f;
OscarLiao 0:80f74d98d66f 657 q_spring_0[2] = q_spring_0[2] /1000.0f;
OscarLiao 0:80f74d98d66f 658 }
OscarLiao 0:80f74d98d66f 659 //■■■■■■■■■■■■■■■■■■■■■■■■■■■end of init_q_spring_0 funtion■■■■■■■■■■■■■■■■■■■■■■■■//
OscarLiao 0:80f74d98d66f 660
OscarLiao 0:80f74d98d66f 661
OscarLiao 0:80f74d98d66f 662 //≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡Rx_xxx funtion≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡//
OscarLiao 0:80f74d98d66f 663 void Rx_irq(void)
OscarLiao 0:80f74d98d66f 664 {
OscarLiao 0:80f74d98d66f 665 //Keep clear in Rx_irq and leave most work after Rx_end
OscarLiao 0:80f74d98d66f 666 Buff[Recieve_index] = Cmd.getc();
OscarLiao 0:80f74d98d66f 667 Recieve_index = Recieve_index + Rx_enable;
OscarLiao 0:80f74d98d66f 668 }
OscarLiao 0:80f74d98d66f 669
OscarLiao 0:80f74d98d66f 670 void Rx_srt(void)
OscarLiao 0:80f74d98d66f 671 {
OscarLiao 0:80f74d98d66f 672 //start receiving Serial message from Cmd
OscarLiao 0:80f74d98d66f 673 // NVIC_EnableIRQ(USART1_IRQn);
OscarLiao 0:80f74d98d66f 674 Rx_enable = 1;
OscarLiao 0:80f74d98d66f 675 }
OscarLiao 0:80f74d98d66f 676 void Rx_end(void)
OscarLiao 0:80f74d98d66f 677 {
OscarLiao 0:80f74d98d66f 678 //end of receiving Serial message from Cmd
OscarLiao 0:80f74d98d66f 679 // NVIC_DisableIRQ(USART1_IRQn);
OscarLiao 0:80f74d98d66f 680 Rx_enable = 0;
OscarLiao 0:80f74d98d66f 681 Recieve_index = 0;
OscarLiao 0:80f74d98d66f 682 Cmd_Flag = 1;
OscarLiao 0:80f74d98d66f 683 }
OscarLiao 0:80f74d98d66f 684 //■■■■■■■■■■■■■■■■■■■■■■■■■■■end of Rx_irq funtion■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■//