LDSC_Robotics_TAs
/
Bike_Sensor_Fusion
Version_1
Revision 1:235bfa26c5c1, committed 2016-09-05
- Comitter:
- noname001
- Date:
- Mon Sep 05 02:02:19 2016 +0000
- Parent:
- 0:0b8d14ed499f
- Commit message:
- Version_2 (Date:2016-09-05)
Changed in this revision
main.cpp | Show annotated file Show diff for this revision Revisions of this file |
--- a/main.cpp Wed Aug 31 08:55:00 2016 +0000 +++ b/main.cpp Mon Sep 05 02:02:19 2016 +0000 @@ -1,52 +1,56 @@ +// 導入需要之header檔 +//#include <p30f4011.h> #include "mbed.h" #include <math.h> #include "LSM9DS0.h" -//#include "can.h" -Ticker timer1; - -Serial uart_1(D10,D2); // TX : D10 RX : D2 // serial 1 -#define LOOPTIME 500 // 2 ms -unsigned long lastMilli = 0; -// sampling time -float T = 0.002; -Timer t; - +Ticker timer1; // 2 ms +Serial uart_1(D10,D2); // TX : D10 RX : D2 // serial 1 +LSM9DS0 sensor(SPI_MODE, D7, D6); // SPI_CS1 : D7 , SPI_CS2 : D6 +AnalogIn adc_switch(A0); // uart data int display[6] = {0,0,0,0,0,0}; -char num[14]= {254,255,0,0,0,0,0,0,0,0,0,0,0,0}; // char num[0] , num[1] : 2 start byte +char num[14]={254,255,0,0,0,0,0,0,0,0,0,0,0,0}; // char num[0] , num[1] : 2 start byte +// 等待sensor上電 int tcount = 0; int init_flag = 0; +int flag_d_1; +int flag_d_2; +int flag_d_3; +int flag_d_4; +int flag_d_5; +int flag_d_6; int i; int j; int k; - +int z; +float T = 0.002; // sensor gain , 由實驗測得 -#define Gyro_gain_x 0.001223735681818 -#define Gyro_gain_y 0.001223735681818 -#define Gyro_gain_z 0.001223735681818 -#define Acce_gainx -0.002386188420346 // -9.81 / ( 3264.287 - (-846.872) ) +//#define Gyro_gain_x 0.001223735681818 +#define Gyro_gain_x 0.001223735681818f +#define Gyro_gain_y 0.001223735681818f +#define Gyro_gain_z 0.001223735681818f +#define Acce_gainx -0.002386188420346f // -9.81 / ( 3264.287 - (-846.872) ) //#define Acce_gainy -0.002372964173321 // -9.81 / ( 3508 - (-626.07) ) -#define Acce_gainy -0.002512964173321 -#define Acce_gainz -0.002381154075718 // -9.81 / ( 4413.257 - (293.406) ) - - +#define Acce_gainy -0.002512964173321f +#define Acce_gainz -0.002381154075718f // -9.81 / ( 4413.257 - (293.406) ) // 宣告從sensor讀到的值要存入處理的變數 - +int16_t Gyro_axis_data[3]; // X, Y, Z axis float Gyro_axis_data_f[3]; float Gyro_axis_data_f_old[3]; float Gyro_scale[3]; // scale = (data - zero) * gain -float Gyro_axis_zero[3] = {0,-8,8}; +float Gyro_axis_zero[3] = {0,-8,8}; +int16_t Acce_axis_data[3]; // X, Y, Z axis float Acce_axis_data_f[3]; float Acce_axis_data_f_old[3]; float Acce_scale[3]; // scale = (data - zero) * gain //float Acce_axis_zero[3] = {-846.872,-626.07,293.406}; -float Acce_axis_zero[3] = {-907,-658,225}; +float Acce_axis_zero[3] = {-907,-658,225}; // final sensor output value float axm = 0; // Acce_scale @@ -57,7 +61,7 @@ float u2 = 0; // Gyro_scale float u3 = 0; // Gyro_scale -// counter for gyro bias +// counter for gyro bias //improve int gyro_count = 0; int gyro_flag = 0; float gyro_init_1[10] = {0,0,0,0,0,0,0,0,0,0}; @@ -69,21 +73,20 @@ float gyro_sum_3 = 0; // new defined direction -float ax = 0; -float ay = 0; +float ax = 0; +float ay = 0; float az = 0; -float w1 = 0; -float w2 = 0; +float w1 = 0; +float w2 = 0; float w3 = 0; -float w1_d = 0; -float w2_d = 0; +float w1_d = 0; +float w2_d = 0; float w3_d = 0; -// sampling time -//float T = 0.002; // 2ms -> 500Hz -char uart_read = 0; +//read weight +//char uart_read = 0; // 速度 , 向心加速度 int rotationspeed = 0; @@ -131,7 +134,7 @@ float theta_deg = 0; // normalized variables -float n = 0; +float n = 0; float gs1_hat_n = 0; float gs2_hat_n = 0; float gs3_hat_n = 0; @@ -155,6 +158,7 @@ int compensationrate = 0; int Mb = 25; // bicycle mass int M = 95; // total mass (25+70) +int adc = 0; int buttom_buf = 0; int buttom_buf_old = 0; // 開關安全措施 @@ -164,13 +168,25 @@ int open_flag = 0; int protect_flag = 0; -void timer1_interrupt(void); -void init_TIMER(void); + +// 函式宣告 void init_uart(void); -void uart_send(void); void separate(void); void init_Sensors(void); +void init_TIMER(); +void timer1_interrupt(void); // void _ISR _T1Interrupt(void); void read_sensor(void); + +//unsigned char SPI_operation(unsigned char data_send); +//void sensorG_setup(void); +//void sensorXM_setup(void); +//void sensorG_read_3axis(void); +//void sensorXM_read_3axis(void); +//void init_ADC(void); +//void _ISR _U2RXInterrupt(void); +//void init_IO(void); +// void init_spi(void); + float lpf(float input,float output_old,float frequency); float sinr(float input); float cosr(float input); @@ -178,60 +194,436 @@ float arccos(float input); float arctan(float input); -LSM9DS0 sensor(SPI_MODE, D7, D6); // SPI_CS1 : D7 , SPI_CS2 : D6 -// sensor data -int16_t Gyro_axis_data[3] = {0}; // X, Y, Z axis -int16_t Acce_axis_data[3] = {0}; // X, Y, Z axis -int16_t Magn_axis_data[3] = {0}; // X, Y, Z axis - -int main() -{ - +// Main routine +int main(void) +{ //init_IO(); - init_TIMER(); //t.strat(); +//init_spi(); + //init_ADC(); + init_TIMER(); init_uart(); - //init_spi(); - //init_can(); - //init_ADC(); - // t.start(); + + while(1) // 永久迴圈 + { + + } + +} // End of main() - while(1) { - - } +/* +void init_IO(void) +{ + // 1為數位,0為類比 + ADPCFG = 0xffff; + + //LED + TRISDbits.TRISD1 = 0; // 定義I/O腳位輸入輸出 0:output 1:input + TRISDbits.TRISD2 = 0; + TRISDbits.TRISD3 = 0; + LATDbits.LATD1 = 1; // 1:dark 0:light + LATDbits.LATD2 = 1; + LATDbits.LATD3 = 1; + + //SPI CS + TRISBbits.TRISB4 = 0; // CSXM + TRISBbits.TRISB5 = 0; // CSG + LATBbits.LATB4 = 1; + LATBbits.LATB5 = 1; + + //ADC + ADPCFGbits.PCFG6 = 1; // AN6 = digital + TRISBbits.TRISB6 = 1; // input 讀取電壓 +} +*/ +void init_TIMER(){ + i = 0; + timer1.attach_us(&timer1_interrupt, 2000.0); // 2 ms } -void init_uart() -{ - uart_1.baud(115200); // 設定baudrate -} - - -void uart_send(void) //uart_send() neen initial i (i=0) +//void _ISR1 _T1Interrupt(void) // 500Hz +void timer1_interrupt(void) { - // uart send data - display[0] = Gyro_axis_data[0]; - display[1] = Gyro_axis_data[1]; - display[2] = Gyro_axis_data[2]; - display[3] = Acce_axis_data[0]; - display[4] = Acce_axis_data[1]; - display[5] = Acce_axis_data[2]; + //LATDbits.LATD3 = 1; + + if(init_flag == 0) //用timer代替 數超過300次 開始讀植 + { + tcount = tcount + 1; + + if(tcount >= 300) + { + init_Sensors(); // 讓sensor完全上電後再初始化sensor + tcount = 0; + init_flag = 1; + } + } + + else + { + read_sensor(); + + // gyro filter + Gyro_axis_data_f[0] = lpf(Gyro_axis_data[0],Gyro_axis_data_f_old[0],18); + Gyro_axis_data_f_old[0] = Gyro_axis_data_f[0]; + Gyro_axis_data_f[1] = lpf(Gyro_axis_data[1],Gyro_axis_data_f_old[1],18); + Gyro_axis_data_f_old[1] = Gyro_axis_data_f[1]; + Gyro_axis_data_f[2] = lpf(Gyro_axis_data[2],Gyro_axis_data_f_old[2],18); + Gyro_axis_data_f_old[2] = Gyro_axis_data_f[2]; + + // gyro bias average + if(gyro_flag == 0) + { + gyro_count = gyro_count + 1; + + if(gyro_count == 500) + { + gyro_init_1[index_count] = Gyro_axis_data_f[0]; + gyro_init_2[index_count] = Gyro_axis_data_f[1]; + gyro_init_3[index_count] = Gyro_axis_data_f[2]; + index_count++; + } + else if(gyro_count == 505) + { + gyro_init_1[index_count] = Gyro_axis_data_f[0]; + gyro_init_2[index_count] = Gyro_axis_data_f[1]; + gyro_init_3[index_count] = Gyro_axis_data_f[2]; + index_count++; + } + else if(gyro_count == 510) + { + gyro_init_1[index_count] = Gyro_axis_data_f[0]; + gyro_init_2[index_count] = Gyro_axis_data_f[1]; + gyro_init_3[index_count] = Gyro_axis_data_f[2]; + index_count++; + } + else if(gyro_count == 520) + { + gyro_init_1[index_count] = Gyro_axis_data_f[0]; + gyro_init_2[index_count] = Gyro_axis_data_f[1]; + gyro_init_3[index_count] = Gyro_axis_data_f[2]; + index_count++; + } + else if(gyro_count == 530) + { + gyro_init_1[index_count] = Gyro_axis_data_f[0]; + gyro_init_2[index_count] = Gyro_axis_data_f[1]; + gyro_init_3[index_count] = Gyro_axis_data_f[2]; + index_count++; + } + else if(gyro_count == 550) + { + gyro_init_1[index_count] = Gyro_axis_data_f[0]; + gyro_init_2[index_count] = Gyro_axis_data_f[1]; + gyro_init_3[index_count] = Gyro_axis_data_f[2]; + index_count++; + } + else if(gyro_count == 560) + { + gyro_init_1[index_count] = Gyro_axis_data_f[0]; + gyro_init_2[index_count] = Gyro_axis_data_f[1]; + gyro_init_3[index_count] = Gyro_axis_data_f[2]; + index_count++; + } + else if(gyro_count == 570) + { + gyro_init_1[index_count] = Gyro_axis_data_f[0]; + gyro_init_2[index_count] = Gyro_axis_data_f[1]; + gyro_init_3[index_count] = Gyro_axis_data_f[2]; + index_count++; + } + else if(gyro_count == 580) + { + gyro_init_1[index_count] = Gyro_axis_data_f[0]; + gyro_init_2[index_count] = Gyro_axis_data_f[1]; + gyro_init_3[index_count] = Gyro_axis_data_f[2]; + index_count++; + } + else if(gyro_count >= 590) + { + gyro_init_1[index_count] = Gyro_axis_data_f[0]; + gyro_init_2[index_count] = Gyro_axis_data_f[1]; + gyro_init_3[index_count] = Gyro_axis_data_f[2]; + z = 0; + for(z=0 ; z<10 ; z++) + { + gyro_sum_1 = gyro_sum_1 + gyro_init_1[z]; + gyro_sum_2 = gyro_sum_2 + gyro_init_2[z]; + gyro_sum_3 = gyro_sum_3 + gyro_init_3[z]; + } + + Gyro_axis_zero[0] = gyro_sum_1 / 10; + Gyro_axis_zero[1] = gyro_sum_2 / 10; + Gyro_axis_zero[2] = gyro_sum_3 / 10; + index_count = 0; + gyro_count = 0; + gyro_flag = 1; + } + } + //831 2:20 + // acce filter + Acce_axis_data_f[0] = lpf(Acce_axis_data[0],Acce_axis_data_f_old[0],18); + Acce_axis_data_f_old[0] = Acce_axis_data_f[0]; + Acce_axis_data_f[1] = lpf(Acce_axis_data[1],Acce_axis_data_f_old[1],18); + Acce_axis_data_f_old[1] = Acce_axis_data_f[1]; + Acce_axis_data_f[2] = lpf(Acce_axis_data[2],Acce_axis_data_f_old[2],18); + Acce_axis_data_f_old[2] = Acce_axis_data_f[2]; + + Gyro_scale[0] = (Gyro_axis_data_f[0]-Gyro_axis_zero[0])*Gyro_gain_x; //88888 + Gyro_scale[1] = (Gyro_axis_data_f[1]-Gyro_axis_zero[1])*Gyro_gain_y; + Gyro_scale[2] = (Gyro_axis_data_f[2]-Gyro_axis_zero[2])*Gyro_gain_z; + + Acce_scale[0] = ((Acce_axis_data_f[0]-Acce_axis_zero[0]))*Acce_gainx; + Acce_scale[1] = ((Acce_axis_data_f[1]-Acce_axis_zero[1]))*Acce_gainy; + Acce_scale[2] = ((Acce_axis_data_f[2]-Acce_axis_zero[2]))*Acce_gainz; + + // final 6 axis data + axm = Acce_scale[0]; + aym = Acce_scale[1]; + azm = Acce_scale[2]; + + u1 = Gyro_scale[0]; + u2 = Gyro_scale[1]; + u3 = Gyro_scale[2]; + + // new defined direction + ax = -aym; + ay = axm; + az = azm; + + w1 = -u2; + w2 = u1; + w3 = u3; + + // w deadzone + flag_d_1 = 0; + flag_d_2 = 0; + flag_d_1 = w1 <= 0.015f; + flag_d_2 = w1 >= -0.015f; + if((flag_d_1 + flag_d_2) == 2) + w1_d = 0; + else + w1_d = w1; + + flag_d_3 = 0; + flag_d_4 = 0; + flag_d_3 = w2 <= 0.015f; + flag_d_4 = w2 >= -0.015f; + if((flag_d_3 + flag_d_4) == 2) + w2_d = 0; + else + w2_d = w2; + + flag_d_5 = 0; + flag_d_6 = 0; + flag_d_5 = w3 <= 0.015f; + flag_d_6 = w3 >= -0.015f; + if((flag_d_5 + flag_d_6) == 2) + w3_d = 0; + else + w3_d = w3; + } + + // velocity filter + v_f = lpf(v,v_f_old,18); + v_f_old = v_f; + + // 離心加速度 + acy_hat = 1.4f*v_f*w1_d; // 1.2 + acy_hat_f = lpf(acy_hat,acy_hat_f_old,18); + acy_hat_f_old = acy_hat_f; + + // sensor fusion by backward Euler method + gs1_hat = (gs1_hat_old + T*(-w2_d*alpf_hat + p*ax - w3_d*(acy_hat_f-ay) - w2_d*az)) / (1+p*T); + gs1_hat_old = gs1_hat; + + gs2_hat = (gs2_hat_old + T*(w1_d*alpf_hat - w3_d*ax - p*(acy_hat_f-ay) + w1_d*az)) / (1+p*T); + gs2_hat_old = gs2_hat; + + gs3_hat = (gs3_hat_old + T*(-b*alpf_hat + c*v_hat + w2_d*ax + w1_d*(acy_hat_f-ay) - b*az - c*v_f)) / (1-b*T); + gs3_hat_old = gs3_hat; + + alpf_hat = (alpf_hat_old + T*((a+d)*gs3_hat + e*v_hat - (a+d)*az - e*v_f)) / (1+(a+d)*T); + alpf_hat_old = alpf_hat; + + v_hat = (v_hat_old + T*((1+f)*gs3_hat - f*alpf_hat - (1+f)*az - g*v_f)) / (1-g*T); + v_hat_old = v_hat; + + /* + // 離心加速度 + acy_hat = 1.2*v_f*w1; + acy_hat_f = lpf(acy_hat,acy_hat_f_old,18); + acy_hat_f_old = acy_hat_f; + + // sensor fusion by backward Euler method + gs1_hat = (gs1_hat_old + T*(-w2*alpf_hat + p*ax - w3*(acy_hat_f-ay) - w2*az)) / (1+p*T); + gs1_hat_old = gs1_hat; + + gs2_hat = (gs2_hat_old + T*(w1*alpf_hat - w3*ax - p*(acy_hat_f-ay) + w1*az)) / (1+p*T); + gs2_hat_old = gs2_hat; + + gs3_hat = (gs3_hat_old + T*(-b*alpf_hat + c*v_hat + w2*ax + w1*(acy_hat_f-ay) - b*az - c*v_f)) / (1-b*T); + gs3_hat_old = gs3_hat; + + alpf_hat = (alpf_hat_old + T*((a+d)*gs3_hat + e*v_hat - (a+d)*az - e*v_f)) / (1+(a+d)*T); + alpf_hat_old = alpf_hat; + + v_hat = (v_hat_old + T*((1+f)*gs3_hat - f*alpf_hat - (1+f)*az - g*v_f)) / (1-g*T); + v_hat_old = v_hat; + */ + + // normalize gs1_hat , gs2_hat , gs3_hat to find pitch angle and roll angle + n = sqrt(gs1_hat*gs1_hat + gs2_hat*gs2_hat + gs3_hat*gs3_hat); + + gs1_hat_n = (gs1_hat / n) * 9.81f; + gs2_hat_n = (gs2_hat / n) * 9.81f; + gs3_hat_n = (gs3_hat / n) * 9.81f; + + psi = arcsin(-gs3_hat_n / 9.81f); + //theta = atan(-gs2_hat_n / gs1_hat_n); + + // psi correction + psi_m = psi - (0); // after correction + psi_deg = 57.3f * psi_m; + + // psi deadzone + flag_d_1 = 0; + flag_d_2 = 0; + flag_d_1 = psi_deg < 2.5f; // 在平地時 flag_d_1 = 1 + flag_d_2 = psi_deg > -3; // 在平地時 flag_d_2 = 1 + + if((flag_d_1 + flag_d_2) == 2) // 在平地時 flag_d_1 + flag_d_2 = 2 + psi_d = 0; + else + psi_d = psi_m; + // 去除負加速度 + if(alpf_hat < 0) + alpf_c = 0; + else + alpf_c = alpf_hat; + + // 速度為負時不考慮加速度 + if(v_f < 0) + alpf_v = 0; + else + alpf_v = alpf_c; + + // 加速度 deadzone + if(alpf_v <= 0.1f) + alpf_d = 0; + else + alpf_d = alpf_v; + + // 改button //improve //設定一個開關 + /* + // buttom filter + buttom_buf = lpf(ADCBUF0,buttom_buf_old,30); + buttom_buf_old = buttom_buf; + + // button control compensationrate + if(buttom_buf >= 450) + compensationrate = 1; + else + compensationrate = 0; + */ + + if(adc_switch.read() > 0.6f) + { + buttom_buf=1; + compensationrate = 1; + } + else + { + buttom_buf=0; + compensationrate = 0; + } + + // 電流命令 (T = k*i) + current_command = compensationrate * (Mb*alpf_d*1.1f + M*9.81f*sinr(psi_d)*1.35f + Df) * (R/Ki); + + // 電流命令上下限 + if(current_command >= 15) + current_command = 15; + else if(current_command <= -25) + current_command = -25; + //831 412 + // 開關安全措施 + b_count = b_count + 1; + + if(b_count >= 1500) // wait for buttom ADC buffer ready + { + b_init_flag = 1; + b_count = 0; + } + + if(b_init_flag == 0) + open_flag = 1; + else if(b_init_flag == 1) + { + if(compensationrate == 1 && open_flag == 1) // 初始 open_flag = 1 + protect_flag = 1; + + if(compensationrate == 0) // 初始 open_flag = 1 , 等 compensationrate = 0 時才將 open_flag = 0 + { + protect_flag = 0; // 初始 compensationrate = 0 時才將 protect_flag = 0 + open_flag = 0; + b_flag = 0; + } + // 要先有初始 compensationrate = 0 才能先將 protect_flag == 0 && open_flag == 0 成立 + // 之後由 compensationrate = 0 轉變成 compensationrate = 1 時才將 b_flag = 1(開始送命令) + if(compensationrate == 1 && protect_flag == 0 && open_flag == 0) + { + b_flag = 1; + } + } + + // 改CAN + // can 傳資料到大板子 + //C1TX0DLCbits.DLC = 8; + /* + if(b_flag == 1) + { + C1TX0B1 = current_command; + C1TX0B2 = compensationrate; + C1TX0B3 = 300; + } + else if(b_flag == 0) + { + C1TX0B1 = 0; + C1TX0B2 = 0; + C1TX0B3 = 300; + } + */ + //C1TX0CONbits.TXREQ = 1; + + // uart傳送資料 + + display[0] = 100*psi_deg; + display[1] = 100*gs2_hat; + display[2] = 100*gs3_hat; + display[3] = buttom_buf; + display[4] = current_command; + display[5] = rotationspeed; + + separate(); - + j = 0; k = 1; - while(k) { - if(uart_1.writeable()) { + while(k) + { + if(uart_1.writeable()) + { uart_1.putc(num[i]); i++; j++; } - if(j>1) { // send 2 bytes + if(j>1) // send 2 bytes + { k = 0; j = 0; } @@ -239,7 +631,449 @@ if(i>13) i = 0; + + //LATDbits.LATD3 = 0; + + //IFS0bits.T1IF = 0; // 重置中斷旗標 } + +void init_uart() +{ + uart_1.baud(115200); // 設定baudrate +} + +void separate(void) +{ + num[2] = display[0] >> 8; // HSB(8bit)資料存入陣列 + num[3] = display[0] & 0x00ff; // LSB(8bit)資料存入陣列 + num[4] = display[1] >> 8; + num[5] = display[1] & 0x00ff; + num[6] = display[2] >> 8; + num[7] = display[2] & 0x00ff; + num[8] = display[3] >> 8; + num[9] = display[3] & 0x00ff; + num[10] = display[4] >> 8; + num[11] = display[4] & 0x00ff; + num[12] = display[5] >> 8; + num[13] = display[5] & 0x00ff; +} + +/* +void init_spi(void) +{ + SPI1STATbits.SPISIDL = 1; // Stop in Idle Mode bit + SPI1CONbits.FRMEN = 0; // Framed SPI support disabled + SPI1CONbits.DISSDO = 0; // SDO1 pin is controlled by the module + SPI1CONbits.MODE16 = 0; // Communication is byte-wide (8 bits) + SPI1CONbits.SMP = 0; // Input data sampled at middle of data output time + SPI1CONbits.CKE = 0; // Serial output data changes on transition from Idle clock state to active clock state + SPI1CONbits.CKP = 1; // Idle state for clock is a high level; active state is a low level + SPI1CONbits.SSEN = 0; // Slave Select Unable + SPI1CONbits.MSTEN = 1; // Master mode + // Fsck = Fcy / (Secondary Prescale * Primary Prescale) + SPI1CONbits.SPRE = 0b111; // Secondary Prescale (Master Mode) bits , 111 = Secondary prescale 1:1 + SPI1CONbits.PPRE = 0b01; // Primary Prescale (Master Mode) bits , 01 = Primary prescale 16:1 + + // SPI enable 最後才能打開 + SPI1STATbits.SPIEN = 1; // Enables module and configures SCK1, SDO1, SDI1 and SS1 as serial port pins +} +*/ + +void init_Sensors(void) +{ + sensor.begin(); +// sensor.begin() setting : + // uint16_t begin(gyro_scale gScl = G_SCALE_2000DPS, + // accel_scale aScl = A_SCALE_8G, + // mag_scale mScl = M_SCALE_8GS, + // gyro_odr gODR = G_ODR_760_BW_100, + // accel_odr aODR = A_ODR_800, + // mag_odr mODR = M_ODR_100); + +//sensor_CSXM = 1; + //sensor_CSG = 1; + //Gyro_axis_data[0] = 0; // X + //Gyro_axis_data[1] = 0; // Y + //Gyro_axis_data[2] = 0; // Z + //Acce_axis_data[0] = 0; + //Acce_axis_data[1] = 0; + //Acce_axis_data[2] = 0; + //sensorG_setup(); + //sensorXM_setup(); +} +/* +void init_sensor(void) +{ + sensor.begin(); + // sensor.begin() setting : + // uint16_t begin(gyro_scale gScl = G_SCALE_2000DPS, + // accel_scale aScl = A_SCALE_8G, + // mag_scale mScl = M_SCALE_8GS, + // gyro_odr gODR = G_ODR_760_BW_100, + // accel_odr aODR = A_ODR_800, + // mag_odr mODR = M_ODR_100); +} +*/ +/* +unsigned char SPI_operation(unsigned char data_send) // 具有 write 跟 read 兩種功能 +{ + static unsigned char data_recived = 0; + + while(SPI1STATbits.SPITBF==1); // wait for SPI1STATbits.SPITBF = 0 (transmit start , SPI1TXB is empty) + SPI1BUF = data_send; // write SPI + + while(SPI1STATbits.SPIRBF==0); // wait for SPI1STATbits.SPIRBF = 1 (receive complete , SPI1RXB is full) + data_recived = SPI1BUF; // read SPI + + return data_recived; +} +*/ +/* +void sensorG_setup(void) +{ + static unsigned char sensorG_data_write; + static unsigned char sensorG_data_read; + + // 設定暫存器的值 + sensorG_CTRL_REG1 = 0b11111111; // ODR = 760Hz , BW = 100Hz + // Power-down mode is normal mode , XYZ enable + sensorG_CTRL_REG2 = 0b00001001; // High-pass filter mode is normal mode + // High-pass filter cutoff frequency = 0.09Hz + sensorG_CTRL_REG3 = 0b00000000; // no use , all 0 + sensorG_CTRL_REG4 = 0b00110000; // 2000dps + sensorG_CTRL_REG5 = 0b00000000; // no use , all 0 + + // 設定暫存器的位址 + // write mode (第8個bit = 0) + // auto increase address (第7個bit = 1) + sensorG_data_write = 0x20; // sensor_G_CTRL address + sensorG_data_write = (sensorG_data_write & 0b00111111) | 0b01000000; + // mask first two bits : sensorG_CTRL_REG1_address & 0b00111111 , 把最前面兩個bit清0 , 其他bit保留不動 + // write first two bits : (...) | 0b01000000 把最前面兩個bit寫成01 , 其他bit保留不動 + + // open + sensor_CSG = 0; + + // CS打開後 , 會先寫暫存器的位址 , 再寫暫存器的值 + // 寫入暫存器的位址後就完成write mode和auto increase address的功能 + // 接下來就會依序遞增暫存器的位址並做寫入的動作 + // start to write register address + sensorG_data_read = SPI_operation(sensorG_data_write); + + // start to set register value + sensorG_data_read = SPI_operation(sensorG_CTRL_REG1); + sensorG_data_read = SPI_operation(sensorG_CTRL_REG2); + sensorG_data_read = SPI_operation(sensorG_CTRL_REG3); + sensorG_data_read = SPI_operation(sensorG_CTRL_REG4); + sensorG_data_read = SPI_operation(sensorG_CTRL_REG5); + + // close + sensor_CSG = 1; +} +*/ +/* +void sensorXM_setup(void) +{ + static unsigned char sensorXM_data_write; + static unsigned char sensorXM_data_read; + + // 設定暫存器的值 + sensorXM_CTRL_REG0 = 0b00000000; // no use , all 0 + sensorXM_CTRL_REG1 = 0b10010111; // ODR = 800Hz , XYZ enable + sensorXM_CTRL_REG2 = 0b11011000; // anti-alias filter BW = 50Hz + // acceleration full scale = +-8 g + sensorXM_CTRL_REG3 = 0b00000000; // no use , all 0 + sensorXM_CTRL_REG4 = 0b00000000; // no use , all 0 + sensorXM_CTRL_REG5 = 0b01110100; // magnetic resolution is high resolution + // Power mode selection = 100Hz + sensorXM_CTRL_REG6 = 0b01000000; // Magnetic full scale = +-8 gauss + sensorXM_CTRL_REG7 = 0b00000000; // no use , all 0 + + // 設定暫存器的位址 + // write mode (第8個bit = 0) + // auto increase address (第7個bit = 1) + sensorXM_data_write = 0x1F; // sensor_XM_CTRL address + sensorXM_data_write = (sensorXM_data_write & 0b00111111) | 0b01000000; + // mask first two bits , write first two bits + + // open + sensor_CSXM = 0; + + // start to write register address + sensorXM_data_read = SPI_operation(sensorXM_data_write); + + // start to set register value + sensorXM_data_read = SPI_operation(sensorXM_CTRL_REG0); + sensorXM_data_read = SPI_operation(sensorXM_CTRL_REG1); + sensorXM_data_read = SPI_operation(sensorXM_CTRL_REG2); + sensorXM_data_read = SPI_operation(sensorXM_CTRL_REG3); + sensorXM_data_read = SPI_operation(sensorXM_CTRL_REG4); + sensorXM_data_read = SPI_operation(sensorXM_CTRL_REG5); + sensorXM_data_read = SPI_operation(sensorXM_CTRL_REG6); + sensorXM_data_read = SPI_operation(sensorXM_CTRL_REG7); + + // close + sensor_CSXM = 1; +} +*/ + +/* +void sensorG_read_3axis(void) +{ + static unsigned char sensorG_data_write; + static int sensorG_data_read[6]; + + // 設定暫存器的位址 + // read mode (第8個bit = 1) + // auto increase address (第7個bit = 1) + sensorG_data_write = 0x28; // gyroscope's address + sensorG_data_write = (sensorG_data_write & 0b00111111) | 0b11000000; + // mask first two bits , write first two bits + // 因為暫存器位址只有6個bit , 所以用mask和write來設定read mode , auto increase address + // 不會改變到暫存器位址的值 + + // open + sensor_CSG = 0; + + // CS打開後 , 會先寫暫存器的位址 , 再寫暫存器的值 + // 寫入暫存器的位址後就完成read mode和auto increase address的功能 + // 接下來就會依序遞增暫存器的位址並做讀取的動作 + // start to write register address + sensorG_data_read[0] = (int)SPI_operation(sensorG_data_write); + + // start to read register value + // gyroscope output + // 因為這邊的SPI函數是用來讀值 , 而SPI函數是把寫和讀功能寫在一起的函數 + // 所以寫入的值就任意設成0x00 , 反正寫入的值不重要 + sensorG_data_read[0] = (int)SPI_operation(0x00); // XL + sensorG_data_read[1] = (int)SPI_operation(0x00); // XH + sensorG_data_read[2] = (int)SPI_operation(0x00); // YL + sensorG_data_read[3] = (int)SPI_operation(0x00); // YH + sensorG_data_read[4] = (int)SPI_operation(0x00); // ZL + sensorG_data_read[5] = (int)SPI_operation(0x00); // ZH + + // close + sensor_CSG = 1; + + // data reconstruction + Gyro_axis_data[0] = (sensorG_data_read[1]<<8) | sensorG_data_read[0]; // X + Gyro_axis_data[1] = (sensorG_data_read[3]<<8) | sensorG_data_read[2]; // Y + Gyro_axis_data[2] = (sensorG_data_read[5]<<8) | sensorG_data_read[4]; // Z +} +*/ +/* +void sensorXM_read_3axis(void) +{ + static unsigned char sensorXM_data_write; + static int sensorXM_data_read[6]; + + // 設定暫存器的位址 + // read mode (第8個bit = 1) + // auto increase address (第7個bit = 1) + sensorXM_data_write = 0x28; // accelerometer's address + sensorXM_data_write = (sensorXM_data_write & 0b00111111) | 0b11000000; + // mask first two bits , write first two bits + + // open + sensor_CSXM = 0; + + // start to write register address + sensorXM_data_read[0] = (int)SPI_operation(sensorXM_data_write); + + // start to read register value + // accelerometer output + sensorXM_data_read[0] = (int)SPI_operation(0x00); // XL + sensorXM_data_read[1] = (int)SPI_operation(0x00); // XH + sensorXM_data_read[2] = (int)SPI_operation(0x00); // YL + sensorXM_data_read[3] = (int)SPI_operation(0x00); // YH + sensorXM_data_read[4] = (int)SPI_operation(0x00); // ZL + sensorXM_data_read[5] = (int)SPI_operation(0x00); // ZH + + // close + sensor_CSXM = 1; + + // data reconstruction + Acce_axis_data[0] = (sensorXM_data_read[1]<<8) | sensorXM_data_read[0]; // X + Acce_axis_data[1] = (sensorXM_data_read[3]<<8) | sensorXM_data_read[2]; // Y + Acce_axis_data[2] = (sensorXM_data_read[5]<<8) | sensorXM_data_read[4]; // Z +} +*/ +/* +void init_can(void) +{ + CAN1SetOperationMode( CAN_IDLE_CON & CAN_MASTERCLOCK_1 & + CAN_REQ_OPERMODE_CONFIG ); + + while ( C1CTRLbits.OPMODE <= 3 ); + + CAN1Initialize( CAN_SYNC_JUMP_WIDTH4 & CAN_BAUD_PRE_SCALE(2), + CAN_WAKEUP_BY_FILTER_DIS & + CAN_PHASE_SEG2_TQ(3) & + CAN_PHASE_SEG1_TQ(3) & + CAN_PROPAGATIONTIME_SEG_TQ(3) & + CAN_SEG2_TIME_LIMIT_SET & CAN_SAMPLE3TIMES ) ; + + CAN1SetFilter ( (char) 0 , CAN_FILTER_SID( 0x200 ) & CAN_RX_EID_DIS , + CAN_FILTER_EID( 0x00 ) ); + + + CAN1SetMask ( (char)0 , CAN_MASK_SID ( 0xFFF ) & CAN_MATCH_FILTER_TYPE , + CAN_MASK_EID( 0x00) ); + + + CAN1SetTXMode( (char) 0 , CAN_TX_STOP_REQ & CAN_TX_PRIORITY_HIGH ); + CAN1SetRXMode( (char) 0 , CAN_RXFUL_CLEAR & CAN_BUF0_DBLBUFFER_DIS ); + CAN1SetOperationMode( CAN_IDLE_CON & CAN_CAPTURE_DIS & CAN_MASTERCLOCK_1 & + CAN_REQ_OPERMODE_NOR ); + C1INTEbits.RX0IE = 1; + C1INTEbits.RX1IE = 1; + IEC1bits.C1IE = 1; + + C1TX0SID = 0x0000; + C1TX0EID = 0x0000; + C1RX0SID = 0x0000; + C1RXF0SID = 0x0010; +} +*/ +/* +void _ISR _C1Interrupt(void) +{ + // 讀取大板子傳來的資料 + if (C1RX0CONbits.RXFUL == 1) + { + rotationspeed = C1RX0B1; + omega = (float)rotationspeed * 0.4553 * 0.75; // 2pi * (10/138) (rad/s) + v = 0.33 * omega; // v = r*w (m/s) + + C1RX0CONbits.RXFUL = 0; + } + + C1INTFbits.RX0IF = 0; + + IFS1bits.C1IF = 0; +} +*/ +/* +void init_ADC(void) +{ + ADCON1bits.SSRC = 7; // Internal counter ends sampling and starts conversion (auto convert) + ADCON1bits.ASAM = 1; // Sampling begins immediately after last conversion completes + ADCON2bits.VCFG = 0; // A/D VREFH : AVDD(power) , A/D VREFL : AVSS(ground) + ADCON2bits.CHPS = 0; // 00 = Converts CH0 + ADCON3bits.ADRC = 1; // A/D internal RC clock + ADCON3bits.SAMC = 16; // 16*TAD + ADCON3bits.ADCS = 11; // (TCY/2)*(ADCS<5:0>+1)=6*TCY , where ADCS<5:0>=11 + + ADCHS = 0x0006;; // Connect RB6/AN6 as CH0 input + ADPCFGbits.PCFG6 = 0; // 0 = Analog input pin in Analog mode ; 1: Digital mode + + ADCON1bits.ADON = 1; + // 1 = A/D converter module is operating; 0 = A/D converter is off +} +*/ + +float lpf(float input,float output_old,float frequency) +{ + float output = 0; + + output = (output_old + frequency*T*input) / (1+frequency*T); + + return output; +} + + +float sinr(float input) +{ + float output = 0; + + output = input - input * input * input / 6; + return output; +} + + +float cosr(float input) +{ + float output = 0; + + output = 1 - input * input / 2; + return output; +} + + +float arcsin(float input) +{ + float output = 0; + + output = input + input * input * input / 6; + return output; +} + + +float arccos(float input) +{ + float output = 0; + + output = (3.14 / 2) - arcsin(input); + return output; +} + + +float arctan(float input) +{ + float output = 0; + + output = input - input * input * input / 3; + return output; +} + +/* +void _ISR _U2RXInterrupt(void) +{ + // 更改體重值 + uart_read = U2RXREG; + + switch(uart_read) + { + case 'q': + M = 45 + 25; // 人:45kg , 車:25kg + break; + + case 'w': + M = 50 + 25; + break; + + case 'e': + M = 55 + 25; + break; + + case 'a': + M = 60 + 25; + break; + + case 's': + M = 65 + 25; + break; + + case 'd': + M = 70 + 25; + break; + + case 'z': + M = 75 + 25; + break; + + case 'x': + M = 80 + 25; + break; + + case 'c': + M = 0; + break; + } + + IFS1bits.U2RXIF = 0; +} +*/ void read_sensor(void) { // sensor raw data @@ -250,413 +1084,8 @@ Acce_axis_data[0] = sensor.readRawAccelX(); Acce_axis_data[1] = sensor.readRawAccelY(); Acce_axis_data[2] = sensor.readRawAccelZ(); -} -void init_Sensors(void) -{ - //sensor_CSXM = 1; - //sensor_CSG = 1; - Gyro_axis_data[0] = 0; // X - Gyro_axis_data[1] = 0; // Y - Gyro_axis_data[2] = 0; // Z - Acce_axis_data[0] = 0; - Acce_axis_data[1] = 0; - Acce_axis_data[2] = 0; - //sensorG_setup(); - //sensorXM_setup(); -} -float lpf(float input,float output_old,float frequency) -{ - float output = 0; - output = (output_old + frequency*T*input) / (1+frequency*T); - - return output; -} - - -float sinr(float input) -{ - float output = 0; - - output = input - input * input * input / 6; - return output; -} - - -float cosr(float input) -{ - float output = 0; - - output = 1 - input * input / 2; - return output; -} - - -float arcsin(float input) -{ - float output = 0; - - output = input + input * input * input / 6; - return output; -} - - -float arccos(float input) -{ - float output = 0; - - output = (3.14 / 2) - arcsin(input); - return output; -} - - -float arctan(float input) -{ - float output = 0; - - output = input - input * input * input / 3; - return output; -} - -void separate(void) -{ - num[2] = display[0] >> 8; // HSB(8bit)資料存入陣列 - num[3] = display[0] & 0x00ff; // LSB(8bit)資料存入陣列 - num[4] = display[1] >> 8; - num[5] = display[1] & 0x00ff; - num[6] = display[2] >> 8; - num[7] = display[2] & 0x00ff; - num[8] = display[3] >> 8; - num[9] = display[3] & 0x00ff; - num[10] = display[4] >> 8; - num[11] = display[4] & 0x00ff; - num[12] = display[5] >> 8; - num[13] = display[5] & 0x00ff; + // Magn_axis_data[0] = sensor.readRawMagX(); + // Magn_axis_data[1] = sensor.readRawMagY(); + // Magn_axis_data[2] = sensor.readRawMagZ(); } - -void timer1_interrupt(void) -{ - if((t.read_us() - lastMilli) >= LOOPTIME) - { // 2000 us = 2 ms - lastMilli = t.read_us(); - - // sensor initial start - if(init_flag == 0) //用timer代替 數超過300次 開始讀植 - { - tcount = tcount + 1; - - if(tcount >= 300) - { - init_Sensors(); // 讓sensor完全上電後再初始化sensor - tcount = 0; - init_flag = 1; - } - } - else - { - read_sensor(); - - // gyro filter - Gyro_axis_data_f[0] = lpf(Gyro_axis_data[0],Gyro_axis_data_f_old[0],18); - Gyro_axis_data_f_old[0] = Gyro_axis_data_f[0]; - Gyro_axis_data_f[1] = lpf(Gyro_axis_data[1],Gyro_axis_data_f_old[1],18); - Gyro_axis_data_f_old[1] = Gyro_axis_data_f[1]; - Gyro_axis_data_f[2] = lpf(Gyro_axis_data[2],Gyro_axis_data_f_old[2],18); - Gyro_axis_data_f_old[2] = Gyro_axis_data_f[2]; - - - // gyro bias average - if(gyro_flag == 0) - { - gyro_count = gyro_count + 1; - - if(gyro_count == 500) { - gyro_init_1[index_count] = Gyro_axis_data_f[0]; - gyro_init_2[index_count] = Gyro_axis_data_f[1]; - gyro_init_3[index_count] = Gyro_axis_data_f[2]; - index_count++; - } else if(gyro_count == 505) { - gyro_init_1[index_count] = Gyro_axis_data_f[0]; - gyro_init_2[index_count] = Gyro_axis_data_f[1]; - gyro_init_3[index_count] = Gyro_axis_data_f[2]; - index_count++; - } else if(gyro_count == 510) { - gyro_init_1[index_count] = Gyro_axis_data_f[0]; - gyro_init_2[index_count] = Gyro_axis_data_f[1]; - gyro_init_3[index_count] = Gyro_axis_data_f[2]; - index_count++; - } else if(gyro_count == 520) { - gyro_init_1[index_count] = Gyro_axis_data_f[0]; - gyro_init_2[index_count] = Gyro_axis_data_f[1]; - gyro_init_3[index_count] = Gyro_axis_data_f[2]; - index_count++; - } else if(gyro_count == 530) { - gyro_init_1[index_count] = Gyro_axis_data_f[0]; - gyro_init_2[index_count] = Gyro_axis_data_f[1]; - gyro_init_3[index_count] = Gyro_axis_data_f[2]; - index_count++; - } else if(gyro_count == 550) { - gyro_init_1[index_count] = Gyro_axis_data_f[0]; - gyro_init_2[index_count] = Gyro_axis_data_f[1]; - gyro_init_3[index_count] = Gyro_axis_data_f[2]; - index_count++; - } else if(gyro_count == 560) { - gyro_init_1[index_count] = Gyro_axis_data_f[0]; - gyro_init_2[index_count] = Gyro_axis_data_f[1]; - gyro_init_3[index_count] = Gyro_axis_data_f[2]; - index_count++; - } else if(gyro_count == 570) { - gyro_init_1[index_count] = Gyro_axis_data_f[0]; - gyro_init_2[index_count] = Gyro_axis_data_f[1]; - gyro_init_3[index_count] = Gyro_axis_data_f[2]; - index_count++; - } else if(gyro_count == 580) { - gyro_init_1[index_count] = Gyro_axis_data_f[0]; - gyro_init_2[index_count] = Gyro_axis_data_f[1]; - gyro_init_3[index_count] = Gyro_axis_data_f[2]; - index_count++; - } else if(gyro_count >= 590) { - gyro_init_1[index_count] = Gyro_axis_data_f[0]; - gyro_init_2[index_count] = Gyro_axis_data_f[1]; - gyro_init_3[index_count] = Gyro_axis_data_f[2]; - int z = 0; - for(z=0 ; z<10 ; z++) { - gyro_sum_1 = gyro_sum_1 + gyro_init_1[z]; - gyro_sum_2 = gyro_sum_2 + gyro_init_2[z]; - gyro_sum_3 = gyro_sum_3 + gyro_init_3[z]; - } - - Gyro_axis_zero[0] = gyro_sum_1 / 10; - Gyro_axis_zero[1] = gyro_sum_2 / 10; - Gyro_axis_zero[2] = gyro_sum_3 / 10; - index_count = 0; - gyro_count = 0; - gyro_flag = 1; - } - } - - //831 2:20 - - // acce filter - Acce_axis_data_f[0] = lpf(Acce_axis_data[0],Acce_axis_data_f_old[0],18); - Acce_axis_data_f_old[0] = Acce_axis_data_f[0]; - Acce_axis_data_f[1] = lpf(Acce_axis_data[1],Acce_axis_data_f_old[1],18); - Acce_axis_data_f_old[1] = Acce_axis_data_f[1]; - Acce_axis_data_f[2] = lpf(Acce_axis_data[2],Acce_axis_data_f_old[2],18); - Acce_axis_data_f_old[2] = Acce_axis_data_f[2]; - - Gyro_scale[0] = (Gyro_axis_data_f[0]-Gyro_axis_zero[0])*Gyro_gain_x; - Gyro_scale[1] = (Gyro_axis_data_f[1]-Gyro_axis_zero[1])*Gyro_gain_y; - Gyro_scale[2] = (Gyro_axis_data_f[2]-Gyro_axis_zero[2])*Gyro_gain_z; - - Acce_scale[0] = ((Acce_axis_data_f[0]-Acce_axis_zero[0]))*Acce_gainx; - Acce_scale[1] = ((Acce_axis_data_f[1]-Acce_axis_zero[1]))*Acce_gainy; - Acce_scale[2] = ((Acce_axis_data_f[2]-Acce_axis_zero[2]))*Acce_gainz; - - // final 6 axis data - axm = Acce_scale[0]; - aym = Acce_scale[1]; - azm = Acce_scale[2]; - - u1 = Gyro_scale[0]; - u2 = Gyro_scale[1]; - u3 = Gyro_scale[2]; - - // new defined direction - ax = -aym; - ay = axm; - az = azm; - - w1 = -u2; - w2 = u1; - w3 = u3; - - // w deadzone - int flag_d_1 = 0; - int flag_d_2 = 0; - - flag_d_1 = w1 <= 0.015; - flag_d_2 = w1 >= -0.015; - - if((flag_d_1 + flag_d_2) == 2) - w1_d = 0; - else - w1_d = w1; - - int flag_d_3 = 0; - int flag_d_4 = 0; - flag_d_3 = w2 <= 0.015; - flag_d_4 = w2 >= -0.015; - if((flag_d_3 + flag_d_4) == 2) - w2_d = 0; - else - w2_d = w2; - - int flag_d_5 = 0; - int flag_d_6 = 0; - flag_d_5 = w3 <= 0.015; - flag_d_6 = w3 >= -0.015; - if((flag_d_5 + flag_d_6) == 2) - w3_d = 0; - else - w3_d = w3; - } - - // velocity filter - v_f = lpf(v,v_f_old,18); - v_f_old = v_f; - - // 離心加速度 - acy_hat = 1.4*v_f*w1_d; // 1.2 - acy_hat_f = lpf(acy_hat,acy_hat_f_old,18); - acy_hat_f_old = acy_hat_f; - - // sensor fusion by backward Euler method - gs1_hat = (gs1_hat_old + T*(-w2_d*alpf_hat + p*ax - w3_d*(acy_hat_f-ay) - w2_d*az)) / (1+p*T); - gs1_hat_old = gs1_hat; - - gs2_hat = (gs2_hat_old + T*(w1_d*alpf_hat - w3_d*ax - p*(acy_hat_f-ay) + w1_d*az)) / (1+p*T); - gs2_hat_old = gs2_hat; - - gs3_hat = (gs3_hat_old + T*(-b*alpf_hat + c*v_hat + w2_d*ax + w1_d*(acy_hat_f-ay) - b*az - c*v_f)) / (1-b*T); - gs3_hat_old = gs3_hat; - - alpf_hat = (alpf_hat_old + T*((a+d)*gs3_hat + e*v_hat - (a+d)*az - e*v_f)) / (1+(a+d)*T); - alpf_hat_old = alpf_hat; - - v_hat = (v_hat_old + T*((1+f)*gs3_hat - f*alpf_hat - (1+f)*az - g*v_f)) / (1-g*T); - v_hat_old = v_hat; - - /* - // 離心加速度 - acy_hat = 1.2*v_f*w1; - acy_hat_f = lpf(acy_hat,acy_hat_f_old,18); - acy_hat_f_old = acy_hat_f; - - // sensor fusion by backward Euler method - gs1_hat = (gs1_hat_old + T*(-w2*alpf_hat + p*ax - w3*(acy_hat_f-ay) - w2*az)) / (1+p*T); - gs1_hat_old = gs1_hat; - - gs2_hat = (gs2_hat_old + T*(w1*alpf_hat - w3*ax - p*(acy_hat_f-ay) + w1*az)) / (1+p*T); - gs2_hat_old = gs2_hat; - - gs3_hat = (gs3_hat_old + T*(-b*alpf_hat + c*v_hat + w2*ax + w1*(acy_hat_f-ay) - b*az - c*v_f)) / (1-b*T); - gs3_hat_old = gs3_hat; - - alpf_hat = (alpf_hat_old + T*((a+d)*gs3_hat + e*v_hat - (a+d)*az - e*v_f)) / (1+(a+d)*T); - alpf_hat_old = alpf_hat; - - v_hat = (v_hat_old + T*((1+f)*gs3_hat - f*alpf_hat - (1+f)*az - g*v_f)) / (1-g*T); - v_hat_old = v_hat; - */ - - // normalize gs1_hat , gs2_hat , gs3_hat to find pitch angle and roll angle - n = sqrt(gs1_hat*gs1_hat + gs2_hat*gs2_hat + gs3_hat*gs3_hat); - - gs1_hat_n = (gs1_hat / n) * 9.81; - gs2_hat_n = (gs2_hat / n) * 9.81; - gs3_hat_n = (gs3_hat / n) * 9.81; - - psi = arcsin(-gs3_hat_n / 9.81); - //theta = atan(-gs2_hat_n / gs1_hat_n); - - // psi correction - psi_m = psi - (0); // after correction - psi_deg = 57.3 * psi_m; - - // psi deadzone - int flag_d_1 = 0; - int flag_d_2 = 0; - flag_d_1 = psi_deg < 2.5; // 在平地時 flag_d_1 = 1 - flag_d_2 = psi_deg > -3; // 在平地時 flag_d_2 = 1 - - if((flag_d_1 + flag_d_2) == 2) // 在平地時 flag_d_1 + flag_d_2 = 2 - psi_d = 0; - else - psi_d = psi_m; - - - // 去除負加速度 - if(alpf_hat < 0) - alpf_c = 0; - else - alpf_c = alpf_hat; - - // 速度為負時不考慮加速度 - if(v_f < 0) - alpf_v = 0; - else - alpf_v = alpf_c; - - // 加速度 deadzone - if(alpf_v <= 0.1) - alpf_d = 0; - else - alpf_d = alpf_v; - - - // buttom filter // 改button - /* - buttom_buf = lpf(ADCBUF0,buttom_buf_old,30); - buttom_buf_old = buttom_buf; - - // button control compensationrate - if(buttom_buf >= 450) - compensationrate = 1; - else - compensationrate = 0; - */ - - // 電流命令 (T = k*i) - current_command = compensationrate * (Mb*alpf_d*1.1 + M*9.81*sinr(psi_d)*1.35 + Df) * R/Ki; - - // 電流命令上下限 - if(current_command >= 15) - current_command = 15; - else if(current_command <= -25) - current_command = -25; - //831 412 - - - // 開關安全措施 - b_count = b_count + 1; - - if(b_count >= 1500) // wait for buttom ADC buffer ready - { - b_init_flag = 1; - b_count = 0; - } - - if(b_init_flag == 0) - open_flag = 1; - else if(b_init_flag == 1) - { - if(compensationrate == 1 && open_flag == 1) // 初始 open_flag = 1 - protect_flag = 1; - - if(compensationrate == 0) // 初始 open_flag = 1 , 等 compensationrate = 0 時才將 open_flag = 0 - { - protect_flag = 0; // 初始 compensationrate = 0 時才將 protect_flag = 0 - open_flag = 0; - b_flag = 0; - } - // 要先有初始 compensationrate = 0 才能先將 protect_flag == 0 && open_flag == 0 成立 - // 之後由 compensationrate = 0 轉變成 compensationrate = 1 時才將 b_flag = 1(開始送命令) - if(compensationrate == 1 && protect_flag == 0 && open_flag == 0) - { - b_flag = 1; - } - } - - // 改CAN - - - i = 0; //uart_send() neen initial i (i=0) - uart_send(); - } -} - -void init_TIMER(void) -{ - timer1.attach_us(&timer1_interrupt, 2000); //20ms -} \ No newline at end of file