test

Dependencies:   mbed

Committer:
OscarLiao
Date:
Fri Dec 21 06:18:28 2018 +0000
Revision:
1:c6c07cb81c1a
Parent:
0:80f74d98d66f
test

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 1:c6c07cb81c1a 77 #define PWM_Hip 1460 //900~1550~2200 2050
OscarLiao 1:c6c07cb81c1a 78 #define PWM_Thigh 1330 //900~1550~2200 1300
OscarLiao 1:c6c07cb81c1a 79 #define PWM_Shin 1780 //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 1:c6c07cb81c1a 217 0, 0.2, 0 //{Hip, leg length, leg angle} original point
OscarLiao 0:80f74d98d66f 218 };
OscarLiao 1:c6c07cb81c1a 219
OscarLiao 1:c6c07cb81c1a 220 float q_0_E_1_gain = 0.2f/255.0f;
OscarLiao 1:c6c07cb81c1a 221 float q_0_E_2_gain = (pi/4)/128.0f;
OscarLiao 1:c6c07cb81c1a 222
OscarLiao 0:80f74d98d66f 223 float T_0[3] = { //"Controller Input" from upper controller in joint level
OscarLiao 0:80f74d98d66f 224 0, 0, 0 //{T_0_Hip, T_0_Tigh, F_0_Stretch} force feed foward
OscarLiao 0:80f74d98d66f 225 };
OscarLiao 0:80f74d98d66f 226 float q_err_E[3] = { //error in endpoint level
OscarLiao 0:80f74d98d66f 227 0, 0, 0
OscarLiao 0:80f74d98d66f 228 };
OscarLiao 0:80f74d98d66f 229 float q_err_D_E[3] = { //derivative error in endpoint level
OscarLiao 0:80f74d98d66f 230 0, 0, 0
OscarLiao 0:80f74d98d66f 231 };
OscarLiao 0:80f74d98d66f 232 float Cref_w[3][2] = { //filter storage
OscarLiao 0:80f74d98d66f 233 {0, 0},
OscarLiao 0:80f74d98d66f 234 {0, 0},
OscarLiao 0:80f74d98d66f 235 {0, 0},
OscarLiao 0:80f74d98d66f 236 };
OscarLiao 0:80f74d98d66f 237 const float Cref_a[2] = { //{a0, a1}
OscarLiao 0:80f74d98d66f 238 1.00, 0.70
OscarLiao 0:80f74d98d66f 239 };
OscarLiao 0:80f74d98d66f 240 const float Cref_b[2] = { //{b0, b1}
OscarLiao 0:80f74d98d66f 241 1.00, -1.00
OscarLiao 0:80f74d98d66f 242 };
OscarLiao 0:80f74d98d66f 243 float J32 = 0.0;
OscarLiao 0:80f74d98d66f 244 float J33 = 0.0;
OscarLiao 0:80f74d98d66f 245 float Phi1_0 = 0.0;
OscarLiao 0:80f74d98d66f 246 float Phi2_0 = 0.0;
OscarLiao 0:80f74d98d66f 247
OscarLiao 0:80f74d98d66f 248 //╔═════════════════╗
OscarLiao 0:80f74d98d66f 249 //║ Torque_reg ║
OscarLiao 0:80f74d98d66f 250 //╚═════════════════╝
OscarLiao 0:80f74d98d66f 251 /*
OscarLiao 0:80f74d98d66f 252 q_act_est T_ref_WD
OscarLiao 0:80f74d98d66f 253 q_ref = ----------- + -------------------------- + PI( T_ref - 2*K_spring*R^2*q_spring )
OscarLiao 0:80f74d98d66f 254 G1_rad_dc 2*K_spring*R^2*G1_rad_dc
OscarLiao 0:80f74d98d66f 255
OscarLiao 0:80f74d98d66f 256 PI(z) = P + I*dt / (z-1)
OscarLiao 0:80f74d98d66f 257 */
OscarLiao 0:80f74d98d66f 258 const float Kp[3] = { //P gain for Torque REG
OscarLiao 0:80f74d98d66f 259 Kpt, Kpt, Kpt //{Hip, Tigh, Shin}
OscarLiao 0:80f74d98d66f 260 };
OscarLiao 0:80f74d98d66f 261 const float Kit[3] = { //I gain for Torque REG Kit = Ki*Ts
OscarLiao 0:80f74d98d66f 262 Ki*dt, Ki*dt, Ki*dt //{Hip, Tigh, Shin}
OscarLiao 0:80f74d98d66f 263 };
OscarLiao 0:80f74d98d66f 264 float T_ref[3] = { //command to T_reg in joint level
OscarLiao 0:80f74d98d66f 265 0, 0, 0 //{Hip, Tigh, Shin}
OscarLiao 0:80f74d98d66f 266 };
OscarLiao 0:80f74d98d66f 267 float T_ref_E[3] = { //command to T_reg in end point level
OscarLiao 0:80f74d98d66f 268 0, 0, 0 //{Hip, Len, Phi}
OscarLiao 0:80f74d98d66f 269 };
OscarLiao 0:80f74d98d66f 270 float T_ref_WD[3] = { //command without damping reference in joint level
OscarLiao 0:80f74d98d66f 271 0, 0, 0
OscarLiao 0:80f74d98d66f 272 };
OscarLiao 0:80f74d98d66f 273 float T_ref_WD_E[3] = { //command without damping reference in endpoint level
OscarLiao 0:80f74d98d66f 274 0, 0, 0
OscarLiao 0:80f74d98d66f 275 };
OscarLiao 0:80f74d98d66f 276 float T_err[3] = { //T_ref - T_act_est, T_act_est = q_spring * K_q
OscarLiao 0:80f74d98d66f 277 0, 0, 0 //{Hip, Tigh, Shin}
OscarLiao 0:80f74d98d66f 278 };
OscarLiao 0:80f74d98d66f 279 float q_ref[3] = { //output of T_reg
OscarLiao 0:80f74d98d66f 280 0, 0, 0 //{Hip, Thigh, Shin}
OscarLiao 0:80f74d98d66f 281 };
OscarLiao 0:80f74d98d66f 282 float q_spring[3] = { //read in spring travel
OscarLiao 0:80f74d98d66f 283 0, 0, 0
OscarLiao 0:80f74d98d66f 284 };
OscarLiao 0:80f74d98d66f 285 float q_spring_0[3] = { //neutral point of VR
OscarLiao 0:80f74d98d66f 286 0, 0, 0
OscarLiao 0:80f74d98d66f 287 };
OscarLiao 0:80f74d98d66f 288 float T_reg_I[3] = { //PI_w
OscarLiao 0:80f74d98d66f 289 0, 0, 0
OscarLiao 0:80f74d98d66f 290 };
OscarLiao 0:80f74d98d66f 291
OscarLiao 0:80f74d98d66f 292 //╔═════════════════╗
OscarLiao 0:80f74d98d66f 293 //║ I/O Serial ║
OscarLiao 0:80f74d98d66f 294 //╚═════════════════╝
OscarLiao 0:80f74d98d66f 295 uint8_t Buff[Buff_size];
OscarLiao 0:80f74d98d66f 296 uint8_t Recieve_index = 0;
OscarLiao 0:80f74d98d66f 297 uint8_t Cmd_Flag = 0;
OscarLiao 0:80f74d98d66f 298 uint8_t Rx_enable = 0;
OscarLiao 0:80f74d98d66f 299 char buffer[128];
OscarLiao 0:80f74d98d66f 300 //■■■■■■■■■■■■■■■■■■■■■■■■■■■end of Varible registor■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■//
OscarLiao 0:80f74d98d66f 301
OscarLiao 0:80f74d98d66f 302
OscarLiao 0:80f74d98d66f 303 //≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡Function registor≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡//
OscarLiao 0:80f74d98d66f 304 void init_TIMER(); //set TT_main() rate
OscarLiao 0:80f74d98d66f 305 void TT_main(); //timebase function rated by TT
OscarLiao 0:80f74d98d66f 306 void init_q_spring_0(); //calibrating
OscarLiao 0:80f74d98d66f 307 void init_IO(); //initialize IO state
OscarLiao 0:80f74d98d66f 308
OscarLiao 0:80f74d98d66f 309 void q_spring_Est();
OscarLiao 0:80f74d98d66f 310 void q_act_Est();
OscarLiao 0:80f74d98d66f 311 void Impedence_Ref();
OscarLiao 0:80f74d98d66f 312 void Torque_Reg();
OscarLiao 0:80f74d98d66f 313
OscarLiao 0:80f74d98d66f 314 void Rx_irq();
OscarLiao 0:80f74d98d66f 315 void Rx_srt();
OscarLiao 0:80f74d98d66f 316 void Rx_end();
OscarLiao 0:80f74d98d66f 317 //void NVIC_DisableIRQ(USART1_IRQn);
OscarLiao 0:80f74d98d66f 318 //void NVIC_EnableIRQ(USART1_IRQn);
OscarLiao 0:80f74d98d66f 319 //■■■■■■■■■■■■■■■■■■■■■■■■■■■end of Function registor■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■//
OscarLiao 0:80f74d98d66f 320
OscarLiao 0:80f74d98d66f 321
OscarLiao 0:80f74d98d66f 322 //≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡main funtion≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡//
OscarLiao 0:80f74d98d66f 323 int main()
OscarLiao 0:80f74d98d66f 324 {
OscarLiao 0:80f74d98d66f 325 Debug.baud(115200); //set baud rate
OscarLiao 0:80f74d98d66f 326 Cmd.baud(115200); //set baud rate
OscarLiao 0:80f74d98d66f 327
OscarLiao 0:80f74d98d66f 328 wait_ms(10);
OscarLiao 0:80f74d98d66f 329 init_q_spring_0(); //calibrating q_spring reference point
OscarLiao 0:80f74d98d66f 330
OscarLiao 0:80f74d98d66f 331 wait_ms(600);
OscarLiao 0:80f74d98d66f 332 init_IO(); //initialized value
OscarLiao 0:80f74d98d66f 333 init_TIMER(); //start TT_main
OscarLiao 0:80f74d98d66f 334
OscarLiao 0:80f74d98d66f 335 Cmd.attach(&Rx_irq,Serial::RxIrq); //start recieving message
OscarLiao 0:80f74d98d66f 336 // NVIC_DisableIRQ(USART1_IRQn); //stay down before CS1 signal
OscarLiao 0:80f74d98d66f 337
OscarLiao 0:80f74d98d66f 338 CS1.fall(&Rx_srt); //attach the address of Rx_srt to falling edge as start signal of communication
OscarLiao 0:80f74d98d66f 339 CS1.rise(&Rx_end); //attach the address of Rx_end to rise edge
OscarLiao 0:80f74d98d66f 340
OscarLiao 1:c6c07cb81c1a 341 //for joint endpoint transform
OscarLiao 0:80f74d98d66f 342 Phi1_0 = (acos((L0*L0+L1*L1-L2*L2)/(2*L0*L1)));
OscarLiao 0:80f74d98d66f 343 Phi2_0 = (Phi1_0 + acos((L0*L0+L2*L2-L1*L1)/(2*L0*L2)));
OscarLiao 0:80f74d98d66f 344
OscarLiao 0:80f74d98d66f 345 while(1) { //main() loop
OscarLiao 0:80f74d98d66f 346
OscarLiao 0:80f74d98d66f 347 //Task judging start
OscarLiao 0:80f74d98d66f 348 if(Flag_1 == 1) { //check pending
OscarLiao 0:80f74d98d66f 349 //Task_1 start
OscarLiao 0:80f74d98d66f 350 //read in condition & estimate state
OscarLiao 0:80f74d98d66f 351 q_spring_Est();
OscarLiao 0:80f74d98d66f 352 q_act_Est();
OscarLiao 0:80f74d98d66f 353
OscarLiao 0:80f74d98d66f 354 //calculate control effort
OscarLiao 0:80f74d98d66f 355 Impedence_Ref();
OscarLiao 0:80f74d98d66f 356 Torque_Reg();
OscarLiao 0:80f74d98d66f 357
OscarLiao 0:80f74d98d66f 358 //PWM Drive out process
OscarLiao 0:80f74d98d66f 359 for(int i=0; i<3; i++) {
OscarLiao 0:80f74d98d66f 360 PWM[i] = PWM_base[i] + q_ref[i]; // X + Controll
OscarLiao 0:80f74d98d66f 361 }
OscarLiao 0:80f74d98d66f 362 //PWM[0] = 1460;
OscarLiao 0:80f74d98d66f 363 //PWM[1] = 1330;
OscarLiao 0:80f74d98d66f 364 //PWM[2] = 1830;
OscarLiao 0:80f74d98d66f 365
OscarLiao 0:80f74d98d66f 366 PWM[0] = constrain(PWM[0],800 ,2100);//safty constrain
OscarLiao 0:80f74d98d66f 367 PWM[1] = constrain(PWM[1],800 ,2100);//safty constrain
OscarLiao 0:80f74d98d66f 368 PWM[2] = constrain(PWM[2],800 ,2100);//safty constrain
OscarLiao 0:80f74d98d66f 369
OscarLiao 0:80f74d98d66f 370 Drive1.pulsewidth_us(PWM[0]); //drive command
OscarLiao 0:80f74d98d66f 371 Drive2.pulsewidth_us(PWM[1]);
OscarLiao 0:80f74d98d66f 372 Drive3.pulsewidth_us(PWM[2]);
OscarLiao 0:80f74d98d66f 373
OscarLiao 0:80f74d98d66f 374 //for Serial-Oscilloscope
OscarLiao 0:80f74d98d66f 375 #if DEBUG
OscarLiao 0:80f74d98d66f 376 // q_0[2] = -0.9;
OscarLiao 0:80f74d98d66f 377 // Debug.printf("%f\n", q_act_est[1]);
OscarLiao 0:80f74d98d66f 378 // Debug.printf("%f, %f, %f\r", q_0[0], q_0[1], q_0[2]);
OscarLiao 1:c6c07cb81c1a 379 // Debug.printf("%lf\r", adc3.read());
OscarLiao 0:80f74d98d66f 380 // Debug.printf("%f\n", 123.23);
OscarLiao 1:c6c07cb81c1a 381 Debug.printf("%d %f\r", Buff[2], q_0_E[2]);
OscarLiao 0:80f74d98d66f 382 // Debug.printf("%.f\r", q_ref[0]);L_act_est
OscarLiao 0:80f74d98d66f 383 // Debug.printf("%.2f\r", q_spring_0[0]);
OscarLiao 0:80f74d98d66f 384 // Debug.printf("%.2f\r", J33);
OscarLiao 0:80f74d98d66f 385 #endif
OscarLiao 0:80f74d98d66f 386
OscarLiao 0:80f74d98d66f 387 //Task_1 done
OscarLiao 0:80f74d98d66f 388 Flag_1 = 0; //clear pending
OscarLiao 0:80f74d98d66f 389 Task_1 = 0; //clear sign
OscarLiao 0:80f74d98d66f 390 }
OscarLiao 0:80f74d98d66f 391
OscarLiao 0:80f74d98d66f 392 if(Cmd_Flag == 1) {
OscarLiao 0:80f74d98d66f 393 //{...}{Hip, Len, Phi}, {'#'}
OscarLiao 0:80f74d98d66f 394 //Received some shit, start decoding
OscarLiao 0:80f74d98d66f 395 led = 1;
OscarLiao 0:80f74d98d66f 396 if(Buff[3] == 'Q') {
OscarLiao 0:80f74d98d66f 397 //q_0 command
OscarLiao 1:c6c07cb81c1a 398 q_0_E[0] = (Buff[0] - 128);
OscarLiao 1:c6c07cb81c1a 399 q_0_E[1] = 0.1f + q_0_E_1_gain * Buff[1];
OscarLiao 1:c6c07cb81c1a 400 q_0_E[2] = q_0_E_2_gain * (Buff[2]-128);
OscarLiao 0:80f74d98d66f 401 } else if(Buff[3] == 'T') {
OscarLiao 0:80f74d98d66f 402 //T_0 command
OscarLiao 0:80f74d98d66f 403 T_0[0] = 1.0f * (Buff[0] - 128);
OscarLiao 0:80f74d98d66f 404 T_0[1] = 1.0f * (Buff[1] - 128);
OscarLiao 0:80f74d98d66f 405 T_0[2] = 1.0f * (Buff[2] - 128);
OscarLiao 0:80f74d98d66f 406 } else if(Buff[3] == 'K') {
OscarLiao 0:80f74d98d66f 407 K_c[0] = 0.02f * Buff[0];
OscarLiao 0:80f74d98d66f 408 K_c[1] = 0.02f * Buff[1];
OscarLiao 0:80f74d98d66f 409 K_c[2] = 0.02f * Buff[2];
OscarLiao 0:80f74d98d66f 410 } else if (Buff[3] == 'B') {
OscarLiao 0:80f74d98d66f 411 B_c[0] = 0.02f * (Buff[0] - 128);
OscarLiao 0:80f74d98d66f 412 B_c[1] = 0.02f * (Buff[1] - 128);
OscarLiao 0:80f74d98d66f 413 B_c[2] = 0.02f * (Buff[2] - 128);
OscarLiao 0:80f74d98d66f 414 } else {
OscarLiao 0:80f74d98d66f 415 //Show error in communication
OscarLiao 1:c6c07cb81c1a 416 led2 = 1;
OscarLiao 0:80f74d98d66f 417 }
OscarLiao 0:80f74d98d66f 418
OscarLiao 0:80f74d98d66f 419 Buff[3] = 0x00; //clear end signals
OscarLiao 0:80f74d98d66f 420 Cmd_Flag = 0;
OscarLiao 0:80f74d98d66f 421 led = 0;
OscarLiao 0:80f74d98d66f 422 //Send out message threw Cmd
OscarLiao 0:80f74d98d66f 423 // Cmd.printf("%c %c %c\r", Dummy[0], Dummy[1], Dummy[2]);
OscarLiao 0:80f74d98d66f 424 }
OscarLiao 0:80f74d98d66f 425 }
OscarLiao 0:80f74d98d66f 426 }
OscarLiao 0:80f74d98d66f 427 //■■■■■■■■■■■■■■■■■■■■■■■■■■■end of main funtion■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■//
OscarLiao 0:80f74d98d66f 428
OscarLiao 0:80f74d98d66f 429
OscarLiao 0:80f74d98d66f 430 //≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡Timebase funtion≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡//
OscarLiao 0:80f74d98d66f 431 void init_TIMER() //set TT_main{} rate
OscarLiao 0:80f74d98d66f 432 {
OscarLiao 0:80f74d98d66f 433 TT.attach_us(&TT_main, Rms);
OscarLiao 0:80f74d98d66f 434 }
OscarLiao 0:80f74d98d66f 435 void TT_main() //interrupt function by TT
OscarLiao 0:80f74d98d66f 436 {
OscarLiao 0:80f74d98d66f 437 Task_1_count = Task_1_count + 1;
OscarLiao 0:80f74d98d66f 438 if(Task_1_count > Task_1_NN) {
OscarLiao 0:80f74d98d66f 439 Task_1_count = 0; //Task triggering
OscarLiao 0:80f74d98d66f 440 Flag_1 = 1;
OscarLiao 0:80f74d98d66f 441 Task_1 = 1; //show for indicator
OscarLiao 0:80f74d98d66f 442 }
OscarLiao 0:80f74d98d66f 443 Task_2_count = Task_2_count + 1;
OscarLiao 0:80f74d98d66f 444 if(Task_2_count > Task_2_NN) {
OscarLiao 0:80f74d98d66f 445 Task_2_count = 0;
OscarLiao 0:80f74d98d66f 446 //Task triggering
OscarLiao 0:80f74d98d66f 447 Flag_2 = 1;
OscarLiao 0:80f74d98d66f 448 Task_2 = 1; //show for indicator
OscarLiao 0:80f74d98d66f 449 }
OscarLiao 0:80f74d98d66f 450 }
OscarLiao 0:80f74d98d66f 451 //■■■■■■■■■■■■■■■■■■■■■■■■■■■end of Timebase funtion■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■//
OscarLiao 0:80f74d98d66f 452
OscarLiao 0:80f74d98d66f 453
OscarLiao 0:80f74d98d66f 454 //≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡init_IO funtion≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡//
OscarLiao 0:80f74d98d66f 455 void init_IO(void) //initialize
OscarLiao 0:80f74d98d66f 456 {
OscarLiao 0:80f74d98d66f 457 CS1.mode(PullUp); //A4
OscarLiao 0:80f74d98d66f 458 CS2.mode(PullUp); //A5
OscarLiao 0:80f74d98d66f 459 CSG = 0; //A6
OscarLiao 0:80f74d98d66f 460 led = 0;
OscarLiao 0:80f74d98d66f 461 Drive1.period_us(15000);
OscarLiao 0:80f74d98d66f 462 Drive2.period_us(15000);
OscarLiao 0:80f74d98d66f 463 Drive3.period_us(15000);
OscarLiao 0:80f74d98d66f 464 }
OscarLiao 0:80f74d98d66f 465 //■■■■■■■■■■■■■■■■■■■■■■■■■■■end of init_IO funtion■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■//
OscarLiao 0:80f74d98d66f 466
OscarLiao 0:80f74d98d66f 467
OscarLiao 0:80f74d98d66f 468 //≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡controller funtion≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡//
OscarLiao 0:80f74d98d66f 469
OscarLiao 0:80f74d98d66f 470 //follow steps for discrete process in j oder
OscarLiao 0:80f74d98d66f 471 //1.update w0[n] threw input x[n] & wi[n] from last sequence
OscarLiao 0:80f74d98d66f 472 // w0[n] = x[n] + Zigma( ai*wi[n] ), i = 1, 2, 3...j-1, j.
OscarLiao 0:80f74d98d66f 473 // y[n] = Zigma( bi*wi[n] ), i = 0, 1, 2...j-1, j.
OscarLiao 0:80f74d98d66f 474 //2.update wi[n+1] for next sequence
OscarLiao 0:80f74d98d66f 475 // wi[n] = wi-1[n], i = j, j-1...2, 1.
OscarLiao 0:80f74d98d66f 476
OscarLiao 0:80f74d98d66f 477 void q_spring_Est(void)
OscarLiao 0:80f74d98d66f 478 {
OscarLiao 0:80f74d98d66f 479 //read in from adc
OscarLiao 0:80f74d98d66f 480 q_spring[0] = Kadc * adc1.read() - q_spring_0[0];
OscarLiao 0:80f74d98d66f 481 q_spring[1] = Kadc * adc2.read() - q_spring_0[1];
OscarLiao 0:80f74d98d66f 482 q_spring[2] = Kadc * adc3.read() - q_spring_0[2];
OscarLiao 0:80f74d98d66f 483 }
OscarLiao 0:80f74d98d66f 484
OscarLiao 0:80f74d98d66f 485 void q_act_Est(void)
OscarLiao 0:80f74d98d66f 486 {
OscarLiao 0:80f74d98d66f 487 for(int i=0; i<3; i++) {
OscarLiao 0:80f74d98d66f 488 q_ref[i] = PWM[i] - PWM_base[i];
OscarLiao 0:80f74d98d66f 489 }
OscarLiao 0:80f74d98d66f 490 //q_act_est = q_ref*G1_rad_TUT(z) - q_spring
OscarLiao 0:80f74d98d66f 491 //G1_rad_TUT(z) is done below
OscarLiao 0:80f74d98d66f 492 for(int i=0; i<3; i++) {
OscarLiao 0:80f74d98d66f 493 //update w0[n] threw input x[n] & wi[n] from last sequence
OscarLiao 0:80f74d98d66f 494 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 495 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 496 q_act_est[i] = q_act_est[i]*0.0001f - q_spring[i];
OscarLiao 0:80f74d98d66f 497
OscarLiao 0:80f74d98d66f 498 //update wi[n+1]
OscarLiao 0:80f74d98d66f 499 G1_w_n[i][2] = G1_w_n[i][1];
OscarLiao 0:80f74d98d66f 500 G1_w_n[i][1] = G1_w_n[i][0];
OscarLiao 0:80f74d98d66f 501 }
OscarLiao 0:80f74d98d66f 502 //q_act_est[i] is now ready for following app
OscarLiao 0:80f74d98d66f 503 }
OscarLiao 0:80f74d98d66f 504
OscarLiao 0:80f74d98d66f 505 void Impedence_Ref(void)
OscarLiao 0:80f74d98d66f 506 {
OscarLiao 0:80f74d98d66f 507 //Transform q_act_est from joint to end point
OscarLiao 0:80f74d98d66f 508 q_act_est[1] -= Phi1_0;
OscarLiao 0:80f74d98d66f 509 q_act_est[2] += Phi2_0;
OscarLiao 0:80f74d98d66f 510
OscarLiao 0:80f74d98d66f 511
OscarLiao 0:80f74d98d66f 512
OscarLiao 0:80f74d98d66f 513 L_act_est = sqrt( LA + 2*LB*cos(q_act_est[2]) );
OscarLiao 0:80f74d98d66f 514 P_act_est = q_act_est[1] + asin( L2*sin(q_act_est[2]) / L_act_est );
OscarLiao 0:80f74d98d66f 515
OscarLiao 0:80f74d98d66f 516
OscarLiao 0:80f74d98d66f 517 //Calculate error in end point level
OscarLiao 0:80f74d98d66f 518 //q_0[i] => {Hip, Tigh, Shin}
OscarLiao 0:80f74d98d66f 519 q_err_E[0] = q_0_E[0] - q_act_est[0]; //Hip motor#1
OscarLiao 0:80f74d98d66f 520 q_err_E[1] = q_0_E[1] - L_act_est;
OscarLiao 0:80f74d98d66f 521 q_err_E[2] = q_0_E[2] - P_act_est;
OscarLiao 0:80f74d98d66f 522
OscarLiao 0:80f74d98d66f 523
OscarLiao 0:80f74d98d66f 524
OscarLiao 0:80f74d98d66f 525 for(int i=0; i<3; i++) {
OscarLiao 0:80f74d98d66f 526 //Generate T_ref in Operational Space (OSC control perhaps?)
OscarLiao 0:80f74d98d66f 527 //T_ref_E = PDn( q_err_E );
OscarLiao 0:80f74d98d66f 528
OscarLiao 0:80f74d98d66f 529 //Compliance
OscarLiao 0:80f74d98d66f 530 T_ref_WD_E[i] = K_c[i] * q_err_E[i];
OscarLiao 0:80f74d98d66f 531
OscarLiao 0:80f74d98d66f 532 //Damping
OscarLiao 0:80f74d98d66f 533 //update w0[n] threw input x[n] & wi[n] from last sequence
OscarLiao 0:80f74d98d66f 534 Cref_w[i][0] = q_err_E[i] + Cref_a[1]*Cref_w[i][1];
OscarLiao 0:80f74d98d66f 535 q_err_D_E[i] = Cref_b[0]*Cref_w[i][0] + Cref_b[1]*Cref_w[i][1];
OscarLiao 0:80f74d98d66f 536
OscarLiao 0:80f74d98d66f 537 //update wi[n+1]
OscarLiao 0:80f74d98d66f 538 Cref_w[i][1] = Cref_w[i][0];
OscarLiao 0:80f74d98d66f 539
OscarLiao 0:80f74d98d66f 540 //Generate T_ref in endpoint level
OscarLiao 0:80f74d98d66f 541 T_ref_E[i] = T_ref_WD_E[i] + B_c[i]*q_err_D_E[i];
OscarLiao 0:80f74d98d66f 542 }
OscarLiao 0:80f74d98d66f 543
OscarLiao 0:80f74d98d66f 544 //Transform torque to joint space, T_ref[i] = Σ( J[i][j] * T_ref_E[j] )
OscarLiao 0:80f74d98d66f 545 J32 = -LB*sin(q_act_est[2]) / L_act_est;
OscarLiao 0:80f74d98d66f 546 J33 = ( pow(J32,2)/LB + cos(q_act_est[2]) ) / (LC + cos(q_act_est[2]));
OscarLiao 0:80f74d98d66f 547
OscarLiao 0:80f74d98d66f 548 //Torque of Hip
OscarLiao 0:80f74d98d66f 549 T_ref[0] = T_ref_E[0];
OscarLiao 0:80f74d98d66f 550 T_ref_WD[0] = T_ref_WD_E[0];
OscarLiao 0:80f74d98d66f 551
OscarLiao 0:80f74d98d66f 552 //Torque of Tigh
OscarLiao 0:80f74d98d66f 553 T_ref[1] = T_ref_E[2] + T_0[1];
OscarLiao 0:80f74d98d66f 554 T_ref_WD[1] = T_ref_WD_E[2] + T_0[1];
OscarLiao 0:80f74d98d66f 555
OscarLiao 0:80f74d98d66f 556 //Torque of Shin
OscarLiao 0:80f74d98d66f 557 T_ref[2] = J32*T_ref_E[1] + J33*T_ref_E[2] + J32*T_0[1] + J33*T_0[2];
OscarLiao 0:80f74d98d66f 558 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 559
OscarLiao 0:80f74d98d66f 560 }
OscarLiao 0:80f74d98d66f 561
OscarLiao 0:80f74d98d66f 562 void Torque_Reg(void)
OscarLiao 0:80f74d98d66f 563 {
OscarLiao 0:80f74d98d66f 564 if(CS2 == 1) {
OscarLiao 0:80f74d98d66f 565
OscarLiao 0:80f74d98d66f 566 //Transform q_act_est from end point to joint
OscarLiao 0:80f74d98d66f 567 q_act_est[1] += Phi1_0;
OscarLiao 0:80f74d98d66f 568 q_act_est[2] -= Phi2_0;
OscarLiao 0:80f74d98d66f 569
OscarLiao 0:80f74d98d66f 570 //Normal command
OscarLiao 0:80f74d98d66f 571 for(int i=0; i<3; i++) {
OscarLiao 0:80f74d98d66f 572 //FeedFoward
OscarLiao 0:80f74d98d66f 573 q_ref[i] = q_act_est[i]*Kqff + T_ref_WD[i]*KTff; //full feedfoward
OscarLiao 0:80f74d98d66f 574 //q_ref[i] = 0; //w/o feedfoward
OscarLiao 0:80f74d98d66f 575
OscarLiao 0:80f74d98d66f 576 //FeedBack
OscarLiao 0:80f74d98d66f 577 T_err[i] = T_ref[i] - K_q*q_spring[i];
OscarLiao 0:80f74d98d66f 578 T_reg_I[i] = T_reg_I[i] + T_err[i]*Kit[i];
OscarLiao 0:80f74d98d66f 579 T_reg_I[i] = constrain(T_reg_I[i], -200, 200);
OscarLiao 0:80f74d98d66f 580 q_ref[i] = T_err[i]*Kp[i] + T_reg_I[i] + q_ref[i];
OscarLiao 0:80f74d98d66f 581 }
OscarLiao 1:c6c07cb81c1a 582 q_ref[0] = (q_0_E[0]/128.0f)*225;
OscarLiao 0:80f74d98d66f 583 q_ref[0] = constrain(q_ref[0], -650, 650);
OscarLiao 0:80f74d98d66f 584 q_ref[1] = constrain(q_ref[1], -650, 650);
OscarLiao 0:80f74d98d66f 585 q_ref[2] = constrain(q_ref[2], -650, 650);
OscarLiao 0:80f74d98d66f 586
OscarLiao 0:80f74d98d66f 587
OscarLiao 0:80f74d98d66f 588 } else {
OscarLiao 0:80f74d98d66f 589 //Stretch command
OscarLiao 0:80f74d98d66f 590 for(int i=0; i<3; i++) {
OscarLiao 0:80f74d98d66f 591 T_reg_I[i] = 0;
OscarLiao 0:80f74d98d66f 592 q_ref[i] = 0;
OscarLiao 0:80f74d98d66f 593 }
OscarLiao 0:80f74d98d66f 594 }
OscarLiao 0:80f74d98d66f 595 }
OscarLiao 0:80f74d98d66f 596 //■■■■■■■■■■■■■■■■■■■■■■■■■■■end of controller funtion■■■■■■■■■■■■■■■■■■■■■■■■■■■■■//
OscarLiao 0:80f74d98d66f 597
OscarLiao 0:80f74d98d66f 598
OscarLiao 0:80f74d98d66f 599 //≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡init_q_spring_0 funtion≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡//
OscarLiao 0:80f74d98d66f 600 void init_q_spring_0(void)
OscarLiao 0:80f74d98d66f 601 {
OscarLiao 0:80f74d98d66f 602 for(int i=0; i<1000; i++) {
OscarLiao 0:80f74d98d66f 603 q_spring_0[0] = q_spring_0[0] + Kadc * adc1.read();
OscarLiao 0:80f74d98d66f 604 q_spring_0[1] = q_spring_0[1] + Kadc * adc2.read();
OscarLiao 0:80f74d98d66f 605 q_spring_0[2] = q_spring_0[2] + Kadc * adc3.read();
OscarLiao 0:80f74d98d66f 606 wait_us(100);
OscarLiao 0:80f74d98d66f 607 }
OscarLiao 0:80f74d98d66f 608 q_spring_0[0] = q_spring_0[0] /1000.0f;
OscarLiao 0:80f74d98d66f 609 q_spring_0[1] = q_spring_0[1] /1000.0f;
OscarLiao 0:80f74d98d66f 610 q_spring_0[2] = q_spring_0[2] /1000.0f;
OscarLiao 0:80f74d98d66f 611 }
OscarLiao 0:80f74d98d66f 612 //■■■■■■■■■■■■■■■■■■■■■■■■■■■end of init_q_spring_0 funtion■■■■■■■■■■■■■■■■■■■■■■■■//
OscarLiao 0:80f74d98d66f 613
OscarLiao 0:80f74d98d66f 614
OscarLiao 0:80f74d98d66f 615 //≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡Rx_xxx funtion≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡//
OscarLiao 0:80f74d98d66f 616 void Rx_irq(void)
OscarLiao 0:80f74d98d66f 617 {
OscarLiao 0:80f74d98d66f 618 //Keep clear in Rx_irq and leave most work after Rx_end
OscarLiao 0:80f74d98d66f 619 Buff[Recieve_index] = Cmd.getc();
OscarLiao 0:80f74d98d66f 620 Recieve_index = Recieve_index + Rx_enable;
OscarLiao 0:80f74d98d66f 621 }
OscarLiao 0:80f74d98d66f 622
OscarLiao 0:80f74d98d66f 623 void Rx_srt(void)
OscarLiao 0:80f74d98d66f 624 {
OscarLiao 0:80f74d98d66f 625 //start receiving Serial message from Cmd
OscarLiao 0:80f74d98d66f 626 // NVIC_EnableIRQ(USART1_IRQn);
OscarLiao 0:80f74d98d66f 627 Rx_enable = 1;
OscarLiao 0:80f74d98d66f 628 }
OscarLiao 0:80f74d98d66f 629 void Rx_end(void)
OscarLiao 0:80f74d98d66f 630 {
OscarLiao 0:80f74d98d66f 631 //end of receiving Serial message from Cmd
OscarLiao 0:80f74d98d66f 632 // NVIC_DisableIRQ(USART1_IRQn);
OscarLiao 0:80f74d98d66f 633 Rx_enable = 0;
OscarLiao 0:80f74d98d66f 634 Recieve_index = 0;
OscarLiao 0:80f74d98d66f 635 Cmd_Flag = 1;
OscarLiao 0:80f74d98d66f 636 }
OscarLiao 0:80f74d98d66f 637 //■■■■■■■■■■■■■■■■■■■■■■■■■■■end of Rx_irq funtion■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■//