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
User.cpp
- Committer:
- ideguti
- Date:
- 2015-04-18
- Revision:
- 0:0805c5a1b328
- Child:
- 1:7b9e3032bb7b
File content as of revision 0:0805c5a1b328:
#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; }