Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed
Fork of PS3conOut by
Diff: User.cpp
- Revision:
- 0:0805c5a1b328
- Child:
- 1:7b9e3032bb7b
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/User.cpp Sat Apr 18 06:27:36 2015 +0000 @@ -0,0 +1,749 @@ + + + +#include <math.h> +#include "Utils.h" +#include "USBHost.h" +#include "hci.h" +#include "ps3.h" +#include "TestShell.h" +#include "User.h" +#include "caninit.h" +#include "mbed.h" +#ifndef M_PI +#define M_PI 3.14159265f +#endif +#ifdef common +#define ab 15 +#define buf 14 +#define ga 13 +#define shdn 12 +#define LSXcent 128 +#define LSYcent 128 +#define RSXcent 128 +#define RSYcent 128 + +//Ticker ticker1; +Timer timer1; +CAN can1(p9, p10); +CANMessage msg; +// pin settings +DigitalOut air1(p5); +DigitalOut air2(p6); +//SPI settings// +SPI spi(p11,p12,p13); +DigitalOut ss1(p20); +DigitalOut ss2(p19); +DigitalOut ss3(p18); +DigitalOut ss4(p17); +//PINsettings +DigitalOut ldac1(p21); +DigitalOut ldac2(p22); +DigitalOut ldac3(p23); +DigitalOut ldac4(p24); +// LED settings// +DigitalOut led1(LED1); +DigitalOut led2(LED2); +DigitalOut led3(LED3); +DigitalOut led4(LED4); +// +int serial_counter = 0; +int dac_data=0; +double debug_val = 0, debug_val2 = 0; +double real_val[4] = {}; +double tar_val[4] = {}; +double val[4] = {}; +int send_val[4] = {}; +double c_accel=5000; +char teisu=13;//23; +char can_send_data[8]; + +int con_x; +int con_y; +int con_theta; +double val_ratio, math1; +double sai_time[5]={}, sai_hensa[5]={}; + +long angle_ulong; +float raw_angle; +float angle; +float axis_angle = 0; +double sin2, cos2; +float kitai_angle = 0; +bool caninit_triger = 0; +int can_counter = 0; +double avr_accel_x, avr_accel_y; + + +// +u8 RSX,RSY,LSX,LSY,BSU,BSL; +//コントローラ断線時対策用 +u8 accel[5]; +u8 accel_nowsub=0; +////////// +char cnt=0; + + +void UserLoopSetting(){ + spi.format(16,0); + spi.frequency(1000000);//1M + ss1=1; + ss2=1; + ss3=1; + ss4=1; + ldac1=1; + ldac2=1; + ldac3=1; + ldac4=1; +} + +void UserLoop(char n,const u8* data){ + //PS3conSTATE--->value + u16 ButtonState; + if(n==0){//有線Ps3USB.cpp + RSX = ((ps3report*)data)->RightStickX; + RSY = ((ps3report*)data)->RightStickY; + LSX = ((ps3report*)data)->LeftStickX; + LSY = ((ps3report*)data)->LeftStickY; + BSU = (u8)(((ps3report*)data)->ButtonState & 0x00ff); + BSL = (u8)(((ps3report*)data)->ButtonState >> 8); + //ボタンの処理 + ButtonState = ((ps3report*)data)->ButtonState; + }else {//無線TestShell.cpp + RSX = ((ps3report*)(data + 1))->RightStickX; + RSY = ((ps3report*)(data + 1))->RightStickY; + LSX = ((ps3report*)(data + 1))->LeftStickX; + LSY = ((ps3report*)(data + 1))->LeftStickY; + BSU = (u8)(((ps3report*)(data + 1))->ButtonState & 0x00ff); + BSL = (u8)(((ps3report*)(data + 1))->ButtonState >> 8); + //ボタンの処理 + ButtonState = ((ps3report*)(data + 1))->ButtonState; + } + + + + static long gyro_long; + static short accel_long_x, accel_long_y; + static double gyro_double, accel_double_x, accel_double_y; + static double accel_x[AVR_ACCEL]={}, accel_y[AVR_ACCEL]={}; + float proportion, hensa; + int i; + double time1, diff; + static bool timer1_init = 0; + static bool lr_on, lr_off; + static int lr_counter; + static double raketto_time1, raketto_time2; + static double accel_array[AVR_ACCEL]={}; + static bool down_state = 0; + static bool up_state = 0; + static bool start_state = 0, start_flag = 0; + static double start_time = 0; + + + for(int i = 0; i < 4; i++){ + real_val[i] = val[i]; + } + + + if(caninit_triger == 0){ + can1.frequency(125000); + caninit_triger = 1; + } + + + + + + can1.read(msg); //CAN読み取り + + if(msg.id == 700){ + static int angle_led; + angle_led ++; + if(angle_led > 2){ + led2 = !led2; + angle_led = 0; + } + angle_ulong = ((unsigned long)msg.data[0] << 24) | ((unsigned long)msg.data[1] << 16) | ((unsigned long)msg.data[2] << 8) | ((unsigned long)msg.data[3]); + raw_angle = -1.0*angle_ulong*180.0/(M_PI*100000.0); + angle = raw_angle - axis_angle; // 軸からの角度を計算 + if(angle < -180) angle += 360; + if(angle > 180) angle -= 360; + sin2 = sin((45-angle)*M_PI/180); + cos2 = cos((45-angle)*M_PI/180); + } + if(msg.id == 700){ + gyro_long = ((unsigned long)msg.data[0+4] << 24) | ((unsigned long)msg.data[1+4] << 16) | ((unsigned long)msg.data[2+4] << 8) | ((unsigned long)msg.data[3+4]); + gyro_double = gyro_long/100000.0; + } + if(msg.id == 710){ + static int accel_led; + accel_led ++; + if(accel_led > 2){ + led3 = !led3; + accel_led = 0; + } + accel_long_x = (msg.data[0] << 8) | (msg.data[1] ); + accel_long_y = ((unsigned long)msg.data[0+2] << 8) | ((unsigned long)msg.data[1+2]); + accel_double_x = accel_long_x/100.0; + accel_double_y = accel_long_y/100.0; + } + + float flt_buff = 0; + flt_buff = real_val[0]; + TypeDivider( &flt_buff, can_send_data); + + //can1.write(CANMessage(300, &can_send_data[0], 4)); + + + + + for(i=0;i<AVR_ACCEL-1;i++){ + accel_x[i] = accel_x[i+1]; + } + for(i=0;i<AVR_ACCEL-1;i++){ + accel_y[i] = accel_y[i+1]; + } + accel_x[AVR_ACCEL-1] = accel_double_x; + accel_y[AVR_ACCEL-1] = accel_double_y; + + for(i=0;i<AVR_ACCEL;i++){ + avr_accel_x += accel_x[i]; + } + avr_accel_x = avr_accel_x/(AVR_ACCEL+1); + for(i=0;i<AVR_ACCEL;i++){ + avr_accel_y += accel_y[i]; + } + avr_accel_y = avr_accel_y/(AVR_ACCEL+1); + + + if(timer1_init == 1){ + timer1.stop(); + time1 = timer1.read(); + timer1.reset(); + } + else time1 = 0.1; + timer1.start(); + timer1_init = 1; + + for(i=0;i<5;i++){ + sai_time[i] = time1*(i+1); + } + for(i=0;i<4;i++){ + sai_hensa[i] = sai_hensa[i+1]; + } + + + + if(lr_on == 1 && lr_off == 1){ + lr_counter ++; + kitai_angle = angle; + //con_theta = 0; + if(lr_counter > LR_YOKU){ + lr_on = 0; + lr_off = 0; + lr_counter = 0; + } + } + + if(ButtonState & (0x0001 << BUTTONTRIANGEL)){ //triangleで角度を初期化 + axis_angle = raw_angle; //座標軸の設定 + kitai_angle = raw_angle - axis_angle; //機体の維持角度 + + } + + + hensa = angle - kitai_angle; + if(hensa > 180)hensa -= 360; + if(hensa < -180)hensa += 360; + //if(hensa>60||hensa<-60)hensa = 0; + + proportion = hensa; + sai_hensa[4] = hensa; + //diff = sai1(sai_time,sai_hensa); + diff = gyro_double; + + + if(proportion < 4 && proportion > -4){ + con_theta = -1*KP*proportion -1*KD*diff; //機体の維持角度と現在の角度の差 + } + else{ + con_theta = -1*KP2*proportion -1*KD2*diff; + } + + + + + + //ボタンの処理 + //u16 ButtonState = ((ps3report*)(data + 1))->ButtonState; + if(start_flag == 1){ + if(ButtonState & 0x2000) { //circleで右を振る + air1=1; + } + if(air1 == 1){ + raketto_time1 += time1; + if(raketto_time1 > 1){ + raketto_time1 = 0; + air1 = 0; + } + } + if(ButtonState & 0x8000) { //squareで左を振る + air2=1; + } + if(air2 == 1){ + raketto_time2 += time1; + if(raketto_time2 > 1){ + raketto_time2 = 0; + air2 = 0; + } + } + if(ButtonState & 0x4000) { //crassで両方戻す + air1=0;air2=0; + } + } + + if(ButtonState & (1 << BUTTONUP)){ + up_state = 1; + } + else{ + if(up_state == 1){ + up_state = 0; + c_accel += 500; + if(c_accel > 6000) c_accel = 6000; + } + } + if(ButtonState & (1 << BUTTONDOWN)){ + down_state = 1; + } + else{ + if(down_state == 1){ + down_state = 0; + c_accel -= 500; + if(c_accel<1000) c_accel = 1000; + } + } + if(ButtonState & (1 << BUTTONSTART)){ + start_state = 1; + led1 = 1; + } + else{ + //if(start_time < 0.5) start_state = 0; + if(start_state == 1){ + if(start_flag == 0)start_flag = 1; + else{start_flag = 0;} + start_state = 0; + start_time = 0; + } + led1 = 0; + } + start_time += time1; + if(start_flag == 0){ + axis_angle = raw_angle; //座標軸の設定 + kitai_angle = raw_angle - axis_angle; //機体の維持角度 + led1 = 0; + } + else{led1 = 1;} + + //LeftStickの処理 + //if(LSX>=115&&LSX<=141) con_x = 0; + con_x = LSX - LSXcent; + //if(LSY>=115&&LSY<=141) con_y = 0; + con_y = LSYcent - LSY; + + math1 = pow(con_x,2.0)+pow(con_y,2.0); + math1 = sqrt(math1); + + if(math1 < 30){ + con_x = 0; con_y = 0; + } + + + + + + //LRの処理 + + if((ButtonState & 0x0400)){ //L1 + con_theta = KAITEN_VAL; + kitai_angle = angle; //機体の維持角度 + if(angle>30){ + con_theta = -1*KP*proportion -1*KD*diff; + } + lr_on = 1; + }else if(ButtonState & 0x0100){ //L2 + val_ratio = 0.5; + } + else if(ButtonState & 0x0800){ //R1 + con_theta = -1*KAITEN_VAL; + kitai_angle = angle; + if(angle<-30){ + con_theta = -1*KP*proportion -1*KD*diff; + } + lr_on = 1; + }else if(ButtonState & 0x0200){ //R2 + }else{ + + val_ratio = 1.0; + if(lr_on == 1)lr_off = 1; + } + + + + //ベクトル変換 + tar_val[3] = SCALE * val_ratio * ((cos2)*con_x - sin2*con_y) + SCALE * con_theta; + tar_val[2] = SCALE * val_ratio * ((-1*cos2)*con_y + (-1*sin2)*con_x) + SCALE * con_theta; + tar_val[1] = SCALE * val_ratio * ( -1*cos2*con_x + sin2*con_y) + SCALE * con_theta; + tar_val[0] = SCALE * val_ratio * ( cos2*con_y + sin2*con_x) + SCALE * con_theta; + //最大値の処理 + Saidaika(tar_val); + + + Filter(tar_val); + + // c_accel = 500; + AutoAccel(tar_val,real_val,val,time1,c_accel); + + if(start_flag == 0){ + for(int i=0; i<4; i++) val[i] = 0; + } + + for(int i=0; i<4; i++){ + send_val[i] = val[i]; + } + + SendDAC(send_val); + + if(ButtonState & 0x0200){ //R2 + static int accel_counter2; + double buffx1; + accel_counter2++; + if(avr_accel_x<0)buffx1 = -1*avr_accel_x; + else buffx1 = avr_accel_x; + for(i=0;i<AVR_ACCEL-1;i++){ + accel_array[i] = accel_array[i+1]; + } + accel_array[AVR_ACCEL-1] = buffx1; + c_accel += 10; + if(accel_counter2 > 5){ + if(accel_array[0] > accel_array[AVR_ACCEL-1]) c_accel -= 300; + else c_accel += 50; + accel_counter2 = 0; + } + if(c_accel < 1000)c_accel = 1000; + if(c_accel > 6000)c_accel = 6000; + } + + + + + serial_counter ++; + + +#ifdef DEBUG_MODE + if(serial_counter > REFRESHRATE_PRINTF){ + printf("angle %f",angle*180/M_PI); + printf("\t avr_accel_x %f",avr_accel_x); + printf("\t math1 %f",math1); + printf("\t c_accel %f",c_accel); + //printf("\t con_rtheta %f",con_rtheta*180/M_PI); + printf("\t kitai_angle %f",kitai_angle*180/M_PI); + printf("\n"); + + + printf("data[0] %f",val[0]); + printf("\t"); + printf("data[1] %f",val[1]); + printf("\t"); + printf("data[2] %f",val[2]); + printf("\t"); + printf("data[3] %f",val[3]); + printf("\n"); + + serial_counter = 0; + } +#endif + + + + + + + + + + ////////////////////////////// + //断線時安全対策用 + ////////////////////////////// +// accel[accel_nowsub]=((ps3report*)(data + 1))->AccelX; +// +// if(accel[0]==accel[1] && accel[0]==accel[2] && accel[0]==accel[3] && accel[0]==accel[4]){ +// data[0]=data[1]=data[2]=data[3]=0; +// } +// +// if(accel_nowsub==4) accel_nowsub=0; +// else accel_nowsub++; + //// end of 安全対策 ////////// + + + ////////////////////////////// + //send to DAC + ////////////////////////////// + //DCA1_A + + +} +#endif + + +void AutoAccel(double *tar_data, double *real_data, double *data, double roop_time, double accel){ + static int max_range, state[4]; + static double max[4], mini[4], range[4]={1,1,1,1}; + + for(int i=0; i<4; i++){ + if(tar_data[i] >= real_data[i]){ + if(state[i] == 0){ + mini[i] = real_data[i]; + range[i] = tar_data[i] - mini[i]; + } + if(state[i] == 1){ + range[i] = tar_data[i] - mini[i]; + } + state[i] = 1; + } + else{ + if(state[i] == 1){ + max[i] = real_data[i]; + range[i] = max[i] - tar_data[i]; + } + if(state[i] == 0){ + range[i] = max[i] - tar_data[i]; + } + state[i] = 0; + } + } + for(int i=0; i<4; i++){ + if(range[i] < 0) range[i] *= -1; + } + max_range = range[0]; + for(int i=1; i<4; i++){ + if(max_range < range[i]) max_range = range[i]; + } + + if(max_range == 0){ + for(int i=0; i<4; i++){ + range[i] = 0; + } + } + else { + for(int i=0; i<4; i++){ + range[i] = range[i] / max_range; + } + } + + + for(int i=0; i<4; i++){ + if(tar_data[i] - real_data[i] > 0){ + if(real_data[i] > 0) data[i] += range[i]*accel*roop_time; + else data[i] += 1*range[i]*accel*roop_time; + } + if(tar_data[i] - real_data[i] < 0){ + if(real_data[i] < 0) data[i] -= range[i]*accel*roop_time; + else data[i] -= 1*range[i]*accel*roop_time; + } + if(real_data[i] - tar_data[i] < range[i]*accel*roop_time && real_data[i] - tar_data[i] > -1*range[i]*accel*roop_time){ + data[i] = tar_data[i]; + } + } +} + +void Saidaika(double *data) +{ + double max = data[0]; + for(int i=1; i<4; i++){ + if(data[i] > max) max = data[i]; + } + if(max > 4095){ + for(int i=0; i<4; i++){ + data[i] = data[i]*4095/max; + } + } + double mini = data[0]; + for(int i=1; i<4; i++){ + if(data[i] < mini) mini = data[i]; + } + if(mini < -4095){ + for(int i=0; i<4; i++){ + data[i] = data[i]*4095/(-1*mini); + } + } +} + +void Filter(double *data) +{ + for(int i=0; i<4; i++){ + if(data[i] < CUTOFF && data[i] > -1*CUTOFF) data[i] = 0; + } +} + +void SendDAC(int *data) +{ + dac_data=0; + if(data[0]>0)dac_data += data[0]; + dac_data += (1<<ga);//gain1x + dac_data += (1<<shdn);//anarog on + + ldac1=1; + ss1=0; + wait_us(10); + spi.write(dac_data); + wait_us(10); + ss1=1; + ldac1=0; + //DAC1_B + dac_data=0; + if(data[0]<0)dac_data -= data[0]; + dac_data += (1<<ab);//OUTb + dac_data += (1<<ga);//gain1x + dac_data += (1<<shdn);//anarog on + + ldac1=1; + ss1=0; + wait_us(10); + spi.write(dac_data); + wait_us(10); + ss1=1; + ldac1=0; + //DCA2_A + dac_data=0; + if(data[1]>0)dac_data += data[1]; + dac_data += (1<<ga);//gain1x + dac_data += (1<<shdn);//anarog on + + ldac2=1; + ss2=0; + wait_us(10); + spi.write(dac_data); + wait_us(10); + ss2=1; + ldac2=0; + //DAC2_B + dac_data=0; + if(data[1]<0)dac_data -= data[1]; + dac_data += (1<<ab);//OUTb + dac_data += (1<<ga);//gain1x + dac_data += (1<<shdn);//anarog on + + ldac2=1; + ss2=0; + wait_us(10); + spi.write(dac_data); + wait_us(10); + ss2=1; + ldac2=0; + //DCA3_A + dac_data=0; + if(data[2]>0)dac_data += data[2]; + dac_data += (1<<ga);//gain1x + dac_data += (1<<shdn);//anarog on + + ldac3=1; + ss3=0; + wait_us(10); + spi.write(dac_data); + wait_us(10); + ss3=1; + ldac3=0; + //DAC3_B + dac_data=0; + if(data[2]<0)dac_data -= data[2]; + dac_data += (1<<ab);//OUTb + dac_data += (1<<ga);//gain1x + dac_data += (1<<shdn);//anarog on + + ldac3=1; + ss3=0; + wait_us(10); + spi.write(dac_data); + wait_us(10); + ss3=1; + ldac3=0; + //DCA4_A + dac_data=0; + if(data[3]>0)dac_data += data[3]; + dac_data += (1<<ga);//gain1x + dac_data += (1<<shdn);//anarog on + + ldac4=1; + ss4=0; + wait_us(10); + spi.write(dac_data); + wait_us(10); + ss4=1; + ldac4=0; + + //DAC4_B + dac_data=0; + if(data[3]<0)dac_data -= data[3]; + dac_data += (1<<ab);//OUTb + dac_data += (1<<ga);//gain1x + dac_data += (1<<shdn);//anarog on + + ldac4=1; + ss4=0; + wait_us(10); + spi.write(dac_data); + wait_us(10); + ss4=1; + ldac4=0; + //END of send to DAC +} + + +int TypeDivider(void *pType, char byte[]){ + short size = sizeof(pType); + if(size > sizeof(byte)){ + return -1; //Error + } + for(short i=0;i<size;i++){ + byte[i] = *(( (char*)pType ) + i); + } + return 0; +} + +int TypeConstructor(void *pType, char byte[]){ + short size = sizeof(pType); + for(short i=0;i<size;i++){ + *(( (char*)pType ) + i) = byte[i]; + } + return 0; +} + +double sai1(double x[],double y[]) +{ + + int i; + double a0,a1,p,q; + double A00,A01,A02,A11,A12; + + + + A00=A01=A02=A11=A12=0.0; + + for (i=0;i<5;i++) { + A00+=1.0; + A01+=x[i]; + A02+=y[i]; + A11+=x[i]*x[i]; + A12+=x[i]*y[i]; + } + +/*1次式の係数の計算*/ + a0=(A02*A11-A01*A12)/(A00*A11-A01*A01); + a1=(A00*A12-A01*A02)/(A00*A11-A01*A01); + + + +/*gnuplotでグラフ表示のために +計算で得られた1次式でデータ近辺のグラフデータを保存*/ + return a1; +} \ No newline at end of file