Oscar Liao
/
controller_test_endpoint_RF
test
Diff: main.cpp
- Revision:
- 0:b5f9b0530f25
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Fri Dec 21 05:53:27 2018 +0000 @@ -0,0 +1,636 @@ +/* +This is a program for localized controller of one leg +Endpoint space Impedence Control and Force/Torque feedforward +Two input was acceptable +q_0_E[3] Neutral point for Impedence reference +T_0[3] Feedforward of Force/Torque + +---------o------↺ q_act_est[0] + /| + L1 / | ⤸ q_act_est[1] + o | + L2 // + / / ⤸ q_act_est[2] +o / +MCU target: F303K8 +ADC config: 3.3 Vadc common source +*/ +//**************** Wiring Map ********************// +// |---------------| | |---------------| +// Srl| PA_9 | D1 |Cmd Serail | | VIN | VIN | +// Srl| PA_10 | D0 |Cmd Serial | | GND | GND | +// | NRST | NRST | | | NRST | NRST | +// | GND | GND | | | 5V | 5V | +// | PA_12 | D2 | |Srl| A7 | PA_2 |PC Serial +// PWM| PB_0 | D3 |Shing Drv |Dou| A6 | PA_7 |CSG +// Dou| PB_7 | D4 |Task1 |Din| A5 | PA_6 |CS2 Stretch Cmd +// Dou| PB_6 | D5 |Task2 |Din| A4 | PA_5 |CS1 Serial Sync +// PWM| PB_1 | D6 |Tigh Drv |Ain| A3 | PA_4 |Shing sense +// | PF_0 | D7 | |Ain| A2 | PA_3 |Tigh sense +// | PF_1 | D8 | |Ain| A1 | PA_1 |Hip sense +// PWM| PA_8 | D9 |Hip Drv | | A0 | PA_0 | +// | PA_11 | D10 | | | AREF | AREF |VR source +// | PB_5 | D11 | | | 3V3 | 3V3 | +// | PB_4 | D12 | |Dou| D13 | PB_3 |led / Serial error +// |---------------| | |---------------| +#include "mbed.h" +//#include "LSM9DS0_SH.h" +//#define DEBUG 1 +#define DEBUG 0 +#define pi 3.141592f +#define d2r 0.01745329f + +#define Rms 5000 //TT rate +#define dt 0.015f +#define Task_1_NN 2 +#define Task_2_NN 199 + +//Torque-Controller gain +#define G1_rad_dc 0.00157f +#define Kqff 636.7f //ffoward gain of q_act_est = 1 / G1_rad_dc +#define KTff 60.408f //ffoward gain of T_ref_WD = 1 / (K_q * G1_rad_dc) +#define Kpt 22.9f +#define Ki 151.9f + +//ADC reference constant +#define Kadc 5.817f //adc value to q_spring +#define K_spring 13180f //sping constant of single spring +#define K_q 10.544f //2*K_spring*R^2 +#define R 0.02f //wheely's radius + +//Endpoint Impedence Contorller coefficcient +#define Kpi_Hip 0 +#define Kpi_Thigh 2000 +#define Kpi_Shin 8 +#define Kd_Hip 0.0 +#define Kd_Thigh 0.0 +#define Kd_Shin 0.0 +#define KN 20 +#define L1 0.120f //Tigh length +#define L2 0.1480f //Shing lenth +#define LA (L1*L1+L2*L2) //L1^2 + L2^2 +#define LB (L1*L2) //L1*L2 +#define LC (L1/L2) //L1/L2 +#define L0 0.2f //Length of the leg + +//Structure +#define PWM_Hip 1550 //900~1550~2200 2050 +#define PWM_Thigh 1730 //900~1550~2200 1300 +#define PWM_Shin 1490 //900~1550~2200 1450 1740 + +#define Buff_size 16 //Serial Buffer + +#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) + +//≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡GPIO registor≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡// +//╔═════════════════╗ +//║ Structure ║ +//╚═════════════════╝ +DigitalOut led(D13); //detection +DigitalOut led2(D12); //detection +DigitalOut Task_1(D4); //Task indicate +DigitalOut Task_2(D5); +DigitalOut CSG(A6); //Stretch interrupt pull down + +AnalogIn adc1(A1); //adc +AnalogIn adc2(A2); //adc +AnalogIn adc3(A3); //adc + +InterruptIn CS1(D2); //Serial synchronizor +DigitalIn CS2(A5); //Stretch interrupt + + +//╔═════════════════╗ +//║ Servo out ║ +//╚═════════════════╝ +PwmOut Drive1(D9); //PWM 1/1 +PwmOut Drive2(D6); //PWM 1/2N +PwmOut Drive3(D3); //PWM 1/3N + +//╔═════════════════╗ +//║ Serial ║ +//╚═════════════════╝ +Serial Debug(PA_2, PA_15); //Serial reg(TX RX) USB port +Serial Cmd(D1, D0); //Serial reg(TX RX) +//■■■■■■■■■■■■■■■■■■■■■■■■■■■end of GPIO registor■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■// + + +//≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡Varible registor≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡// +//╔═════════════════╗ +//║ Structure ║ +//╚═════════════════╝ +Ticker TT; //call a timer +uint8_t Task_1_count = 0; //1st prior task count +uint8_t Task_2_count = 0; //2nd prior task count +uint8_t Flag_1 = 0; //1st prior task flag +uint8_t Flag_2 = 0; //2nd prior task flag + +//╔═════════════════╗ +//║ ADC ║ +//╚═════════════════╝ + +//╔═════════════════╗ +//║ PWM ║ +//╚═════════════════╝ +const int16_t PWM_base[3] = { //reference command at 0, -45, 45 deg + PWM_Hip,PWM_Thigh,PWM_Shin +}; +int16_t PWM[3] = { //command out PWM_base + q_ref + 0, 0, 0 //transfer: 10us to 1 deg +}; + +//╔═════════════════╗ +//║ q_actEstimator ║ +//╚═════════════════╝ +/* +q_act_est = q_ref*G1_rad_TUT(z) - q_spring + +G1_rad_TUT(z) is shown below + + y(z) 1.316 + 2.633*z^-1 + 1.316*z^-2 b0 + b1*z^-1 + b2*z^-2 +----- = ----------------------------------- * 1e-04 = ------------------------ + x(z) 1 - 0.8447*z^-1 + 0.1799*z^-2 1 - a1*z^-1 - a2*z^-2 + +q_ref═>[Σ]════════╦═>[b0]═>[Σ]═[1e-04]═>y + ⇑ ⇓w0 ⇑ + ║ [1/z] ║ + [Σ]<═[a1]<═╬═>[b1]═>[Σ] + ⇑ ⇓w1 ⇑ + ║ [1/z] ║ + ╚═══[a2]<═╩═>[b2]═══╝ + w2 +*/ +float q_act_est[3] = { //output of filter + 0, 0, 0 +}; + +float L_act_est = 0.0; +float P_act_est = 0.0; + +float G1_w_n[3][3] = { //G1_rad_TUT's + {0, 0, 0}, //{w0, w1, w2} + {0, 0, 0}, //second sea + {0, 0, 0}, +}; +const float G1_a[3] = { //{a0, a1, a2} + 1.00, 0.8447, -0.1799 +}; +const float G1_b[3] = { //{b0, b1, b2} + 1.316, 2.633, 1.316 +}; + +//╔═════════════════╗//╔══════════════════╗ +//║ Comp_ref ║//║ Controller Input ║ +//╚═════════════════╝//╚══════════════════╝ +/* + +---------o------↺ q_act_est[0] + /| + L1 / | ↻ q_act_est[1] + o | + L2 // + / / ↻ q_act_est[2] +o / + + 1 - z^-1 +PDn(z) = P + D*N*--------------------- + 1 - (1 - N*Ts)*z^-1 + + y(z) b0 + b1*z^-1 1 + (-1)*z^-1 +----- = -------------- = ------------------ + x(z) 1 - a1*z^-1 1 - 0.7*z^-1 + +x═>[Σ]═══════╦═>[b0]═>[Σ]═>[D*N]═>y + ⇑ ⇓w0 ⇑ + ║ [1/z] ║ + ╚══[a1]<═╩═>[b1]═══╝ + w1 +*/ + +float K_c[3] = { //K_c reference impedence + Kpi_Hip, Kpi_Thigh, Kpi_Shin //{Hip, Thigh, Shin} +}; +float B_c[3] = { //B_c = D*N (*20)reference damping (Dmax~0.4)(B_c_max~5) in joint!! + Kd_Hip*KN, Kd_Thigh*KN, Kd_Shin*KN //{Hip, Thigh, Shin} +}; +float q_0_E[3] = { //"Controller Input" from upper controller in endpoint level (Operational Space) + 0, 0.2, 0 //{Hip, leg length, leg angle} original point +}; + +float q_0_E_1_gain = 0.2f/255.0f; +float q_0_E_2_gain = (pi/4)/128.0f; + +float T_0[3] = { //"Controller Input" from upper controller in joint level + 0, 0, 0 //{T_0_Hip, T_0_Tigh, F_0_Stretch} force feed foward +}; +float q_err_E[3] = { //error in endpoint level + 0, 0, 0 +}; +float q_err_D_E[3] = { //derivative error in endpoint level + 0, 0, 0 +}; +float Cref_w[3][2] = { //filter storage + {0, 0}, + {0, 0}, + {0, 0}, +}; +const float Cref_a[2] = { //{a0, a1} + 1.00, 0.70 +}; +const float Cref_b[2] = { //{b0, b1} + 1.00, -1.00 +}; +float J32 = 0.0; +float J33 = 0.0; +float Phi1_0 = 0.0; +float Phi2_0 = 0.0; + +//╔═════════════════╗ +//║ Torque_reg ║ +//╚═════════════════╝ +/* + q_act_est T_ref_WD +q_ref = ----------- + -------------------------- + PI( T_ref - 2*K_spring*R^2*q_spring ) + G1_rad_dc 2*K_spring*R^2*G1_rad_dc + +PI(z) = P + I*dt / (z-1) +*/ +const float Kp[3] = { //P gain for Torque REG + Kpt, Kpt, Kpt //{Hip, Tigh, Shin} +}; +const float Kit[3] = { //I gain for Torque REG Kit = Ki*Ts + Ki*dt, Ki*dt, Ki*dt //{Hip, Tigh, Shin} +}; +float T_ref[3] = { //command to T_reg in joint level + 0, 0, 0 //{Hip, Tigh, Shin} +}; +float T_ref_E[3] = { //command to T_reg in end point level + 0, 0, 0 //{Hip, Len, Phi} +}; +float T_ref_WD[3] = { //command without damping reference in joint level + 0, 0, 0 +}; +float T_ref_WD_E[3] = { //command without damping reference in endpoint level + 0, 0, 0 +}; +float T_err[3] = { //T_ref - T_act_est, T_act_est = q_spring * K_q + 0, 0, 0 //{Hip, Tigh, Shin} +}; +float q_ref[3] = { //output of T_reg + 0, 0, 0 //{Hip, Thigh, Shin} +}; +float q_spring[3] = { //read in spring travel + 0, 0, 0 +}; +float q_spring_0[3] = { //neutral point of VR + 0, 0, 0 +}; +float T_reg_I[3] = { //PI_w + 0, 0, 0 +}; + +//╔═════════════════╗ +//║ I/O Serial ║ +//╚═════════════════╝ +uint8_t Buff[Buff_size]; +uint8_t Recieve_index = 0; +uint8_t Cmd_Flag = 0; +uint8_t Rx_enable = 0; +char buffer[128]; +//■■■■■■■■■■■■■■■■■■■■■■■■■■■end of Varible registor■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■// + + +//≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡Function registor≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡// +void init_TIMER(); //set TT_main() rate +void TT_main(); //timebase function rated by TT +void init_q_spring_0(); //calibrating +void init_IO(); //initialize IO state + +void q_spring_Est(); +void q_act_Est(); +void Impedence_Ref(); +void Torque_Reg(); + +void Rx_irq(); +void Rx_srt(); +void Rx_end(); +//void NVIC_DisableIRQ(USART1_IRQn); +//void NVIC_EnableIRQ(USART1_IRQn); +//■■■■■■■■■■■■■■■■■■■■■■■■■■■end of Function registor■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■// + + +//≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡main funtion≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡// +int main() +{ + Debug.baud(115200); //set baud rate + Cmd.baud(115200); //set baud rate + + wait_ms(10); + init_q_spring_0(); //calibrating q_spring reference point + + wait_ms(600); + init_IO(); //initialized value + init_TIMER(); //start TT_main + + Cmd.attach(&Rx_irq,Serial::RxIrq); //start recieving message +// NVIC_DisableIRQ(USART1_IRQn); //stay down before CS1 signal + + CS1.fall(&Rx_srt); //attach the address of Rx_srt to falling edge as start signal of communication + CS1.rise(&Rx_end); //attach the address of Rx_end to rise edge + + //for joint endpoint transform + Phi1_0 = (acos((L0*L0+L1*L1-L2*L2)/(2*L0*L1))); + Phi2_0 = (Phi1_0 + acos((L0*L0+L2*L2-L1*L1)/(2*L0*L2))); + + while(1) { //main() loop + + //Task judging start + if(Flag_1 == 1) { //check pending + //Task_1 start + //read in condition & estimate state + q_spring_Est(); + q_act_Est(); + + //calculate control effort + Impedence_Ref(); + Torque_Reg(); + + //PWM Drive out process + for(int i=0; i<3; i++) { + PWM[i] = PWM_base[i] + q_ref[i]; // X + Controll + } + //PWM[0] = 1550; + //PWM[1] = 1850; + //PWM[2] = 1670; + + PWM[0] = constrain(PWM[0],800 ,2100);//safty constrain + PWM[1] = constrain(PWM[1],800 ,2100);//safty constrain + PWM[2] = constrain(PWM[2],800 ,2100);//safty constrain + + Drive1.pulsewidth_us(PWM[0]); //drive command + Drive2.pulsewidth_us(PWM[1]); + Drive3.pulsewidth_us(PWM[2]); + + //for Serial-Oscilloscope +#if DEBUG +// q_0[2] = -0.9; + Debug.printf("%f\n", T_ref[2]); +// Debug.printf("%f, %f, %f\r", q_0[0], q_0[1], q_0[2]); +// Debug.printf("%lf\r", adc3.read()); +// Debug.printf("%f\n", 123.23); +// Debug.printf("%.f\r", q_ref[0]);L_act_est +// Debug.printf("%.2f\r", q_spring_0[0]); +// Debug.printf("%.2f\r", J33); +#endif + + //Task_1 done + Flag_1 = 0; //clear pending + Task_1 = 0; //clear sign + } + + if(Cmd_Flag == 1) { + //{...}{Hip, Len, Phi}, {'#'} + //Received some shit, start decoding + led = 1; + if(Buff[3] == 'Q') { + //q_0 command + q_0_E[0] = (Buff[0] - 128); + q_0_E[1] = 0.1f + q_0_E_1_gain * Buff[1]; + q_0_E[2] = q_0_E_2_gain * (Buff[2]-128); + } else if(Buff[3] == 'T') { + //T_0 command + T_0[0] = 1.0f * (Buff[0] - 128); + T_0[1] = 1.0f * (Buff[1] - 128); + T_0[2] = 1.0f * (Buff[2] - 128); + } else if(Buff[3] == 'K') { + K_c[0] = 0.02f * Buff[0]; + K_c[1] = 0.02f * Buff[1]; + K_c[2] = 0.02f * Buff[2]; + } else if (Buff[3] == 'B') { + B_c[0] = 0.02f * (Buff[0] - 128); + B_c[1] = 0.02f * (Buff[1] - 128); + B_c[2] = 0.02f * (Buff[2] - 128); + } else { + //Show error in communication + led2 = 1; + } + + Buff[3] = 0x00; //clear end signals + Cmd_Flag = 0; + led = 0; + //Send out message threw Cmd +// Cmd.printf("%c %c %c\r", Dummy[0], Dummy[1], Dummy[2]); + } + } +} +//■■■■■■■■■■■■■■■■■■■■■■■■■■■end of main funtion■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■// + + +//≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡Timebase funtion≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡// +void init_TIMER() //set TT_main{} rate +{ + TT.attach_us(&TT_main, Rms); +} +void TT_main() //interrupt function by TT +{ + Task_1_count = Task_1_count + 1; + if(Task_1_count > Task_1_NN) { + Task_1_count = 0; //Task triggering + Flag_1 = 1; + Task_1 = 1; //show for indicator + } + Task_2_count = Task_2_count + 1; + if(Task_2_count > Task_2_NN) { + Task_2_count = 0; + //Task triggering + Flag_2 = 1; + Task_2 = 1; //show for indicator + } +} +//■■■■■■■■■■■■■■■■■■■■■■■■■■■end of Timebase funtion■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■// + + +//≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡init_IO funtion≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡// +void init_IO(void) //initialize +{ + CS1.mode(PullUp); //A4 + CS2.mode(PullUp); //A5 + CSG = 0; //A6 + led = 0; + Drive1.period_us(15000); + Drive2.period_us(15000); + Drive3.period_us(15000); +} +//■■■■■■■■■■■■■■■■■■■■■■■■■■■end of init_IO funtion■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■// + + +//≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡controller funtion≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡// + +//follow steps for discrete process in j oder +//1.update w0[n] threw input x[n] & wi[n] from last sequence +// w0[n] = x[n] + Zigma( ai*wi[n] ), i = 1, 2, 3...j-1, j. +// y[n] = Zigma( bi*wi[n] ), i = 0, 1, 2...j-1, j. +//2.update wi[n+1] for next sequence +// wi[n] = wi-1[n], i = j, j-1...2, 1. + +void q_spring_Est(void) +{ + //read in from adc + q_spring[0] = -(Kadc * adc1.read() - q_spring_0[0]); + q_spring[1] = -(Kadc * adc2.read() - q_spring_0[1]); + q_spring[2] = -(Kadc * adc3.read() - q_spring_0[2]); +} + +void q_act_Est(void) +{ + for(int i=0; i<3; i++) { + q_ref[i] = -(PWM[i] - PWM_base[i]); + } + //q_act_est = q_ref*G1_rad_TUT(z) - q_spring + //G1_rad_TUT(z) is done below + for(int i=0; i<3; i++) { + //update w0[n] threw input x[n] & wi[n] from last sequence + G1_w_n[i][0] = q_ref[i] + G1_a[1]*G1_w_n[i][1] + G1_a[2]*G1_w_n[i][2]; + 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]; + q_act_est[i] = q_act_est[i]*0.0001f - q_spring[i]; + + //update wi[n+1] + G1_w_n[i][2] = G1_w_n[i][1]; + G1_w_n[i][1] = G1_w_n[i][0]; + } + //q_act_est[i] is now ready for following app +} + +void Impedence_Ref(void) +{ + //Transform q_act_est from joint to end point + q_act_est[1] -= Phi1_0; + q_act_est[2] += Phi2_0; + + + + L_act_est = sqrt( LA + 2*LB*cos(q_act_est[2]) ); + P_act_est = q_act_est[1] + asin( L2*sin(q_act_est[2]) / L_act_est ); + + + //Calculate error in end point level + //q_0[i] => {Hip, Tigh, Shin} + q_err_E[0] = q_0_E[0] - q_act_est[0]; //Hip motor#1 + q_err_E[1] = q_0_E[1] - L_act_est; + q_err_E[2] = q_0_E[2] - P_act_est; + + + + for(int i=0; i<3; i++) { + //Generate T_ref in Operational Space (OSC control perhaps?) + //T_ref_E = PDn( q_err_E ); + + //Compliance + T_ref_WD_E[i] = K_c[i] * q_err_E[i]; + + //Damping + //update w0[n] threw input x[n] & wi[n] from last sequence + Cref_w[i][0] = q_err_E[i] + Cref_a[1]*Cref_w[i][1]; + q_err_D_E[i] = Cref_b[0]*Cref_w[i][0] + Cref_b[1]*Cref_w[i][1]; + + //update wi[n+1] + Cref_w[i][1] = Cref_w[i][0]; + + //Generate T_ref in endpoint level + T_ref_E[i] = T_ref_WD_E[i] + B_c[i]*q_err_D_E[i]; + } + + //Transform torque to joint space, T_ref[i] = Σ( J[i][j] * T_ref_E[j] ) + J32 = -LB*sin(q_act_est[2]) / L_act_est; + J33 = ( pow(J32,2)/LB + cos(q_act_est[2]) ) / (LC + cos(q_act_est[2])); + + //Torque of Hip + T_ref[0] = T_ref_E[0]; + T_ref_WD[0] = T_ref_WD_E[0]; + + //Torque of Tigh + T_ref[1] = T_ref_E[2] + T_0[1]; + T_ref_WD[1] = T_ref_WD_E[2] + T_0[1]; + + //Torque of Shin + T_ref[2] = J32*T_ref_E[1] + J33*T_ref_E[2] + J32*T_0[1] + J33*T_0[2]; + T_ref_WD[2] = J32*T_ref_WD_E[1] + J33*T_ref_WD_E[2] + J32*T_0[1] + J33*T_0[2]; + +} + +void Torque_Reg(void) +{ + if(CS2 == 1) { + + //Transform q_act_est from end point to joint + q_act_est[1] += Phi1_0; + q_act_est[2] -= Phi2_0; + + //Normal command + for(int i=0; i<3; i++) { + //FeedFoward + q_ref[i] = q_act_est[i]*Kqff + T_ref_WD[i]*KTff; //full feedfoward + //q_ref[i] = 0; //w/o feedfoward + + //FeedBack + T_err[i] = T_ref[i] - K_q*q_spring[i]; + T_reg_I[i] = T_reg_I[i] + T_err[i]*Kit[i]; + T_reg_I[i] = constrain(T_reg_I[i], -200, 200); + q_ref[i] = -(T_err[i]*Kp[i] + T_reg_I[i] + q_ref[i]); + } + q_ref[0] = -(q_0_E[0]/128.0f)*225; + q_ref[0] = constrain(q_ref[0], -650, 650); + q_ref[1] = constrain(q_ref[1], -650, 650); + q_ref[2] = constrain(q_ref[2], -650, 650); + + + } else { + //Stretch command + for(int i=0; i<3; i++) { + T_reg_I[i] = 0; + q_ref[i] = 0; + } + } +} +//■■■■■■■■■■■■■■■■■■■■■■■■■■■end of controller funtion■■■■■■■■■■■■■■■■■■■■■■■■■■■■■// + + +//≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡init_q_spring_0 funtion≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡// +void init_q_spring_0(void) +{ + for(int i=0; i<1000; i++) { + q_spring_0[0] = q_spring_0[0] + Kadc * adc1.read(); + q_spring_0[1] = q_spring_0[1] + Kadc * adc2.read(); + q_spring_0[2] = q_spring_0[2] + Kadc * adc3.read(); + wait_us(100); + } + q_spring_0[0] = q_spring_0[0] /1000.0f; + q_spring_0[1] = q_spring_0[1] /1000.0f; + q_spring_0[2] = q_spring_0[2] /1000.0f; +} +//■■■■■■■■■■■■■■■■■■■■■■■■■■■end of init_q_spring_0 funtion■■■■■■■■■■■■■■■■■■■■■■■■// + + +//≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡Rx_xxx funtion≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡// +void Rx_irq(void) +{ + //Keep clear in Rx_irq and leave most work after Rx_end + Buff[Recieve_index] = Cmd.getc(); + Recieve_index = Recieve_index + Rx_enable; +} + +void Rx_srt(void) +{ + //start receiving Serial message from Cmd +// NVIC_EnableIRQ(USART1_IRQn); + Rx_enable = 1; +} +void Rx_end(void) +{ + //end of receiving Serial message from Cmd +// NVIC_DisableIRQ(USART1_IRQn); + Rx_enable = 0; + Recieve_index = 0; + Cmd_Flag = 1; +} +//■■■■■■■■■■■■■■■■■■■■■■■■■■■end of Rx_irq funtion■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■// \ No newline at end of file