2016 catch robo
Dependencies: mbed WiiClassicController_kai
main.cpp
- Committer:
- kambara1415
- Date:
- 2019-06-24
- Revision:
- 0:7d81654c5ce8
File content as of revision 0:7d81654c5ce8:
//LEFT ARM #include "mbed.h" #include "WiiClassicController.h" #include "lancer_speaker.h" #include "SerialServo.h" #define PI 3.14159265 #define CONTROL_PERIOD_MS 10 #define L1 440 //第一腕長(mm) #define L2 350 //第二腕長(mm) #define MAX_LEN 770 //最大展開長 #define MIN_LEN 150 //最小縮小長 #define RC_CENTER 1500 //RCサーボ中心値(us) #define RC_MAX 2200 //RCサーボ最大値 #define RC_MIN 850 //RCサーボ最小値 #define SIGN 1 //左アームは1,右アームは-1 //初期位置 #define X_HOME 200 #define Y_HOME 550 #define Z_HOME 0 #define SERVO1_ZERO 415 //アーム第1関節零点 #define SERVO2_ZERO 598 //アーム第2関節零点 #define LX_CENTER 32 //クラコン左スティック左右中心値 #define LY_CENTER 32 //クラコン左スティック上下中心値 #define RY_CENTER 15 //右スティック中心値 #define LX_MARGIN 2 #define LY_MARGIN 2 #define FAST 0.2 #define SLOW 0.15 #define ADD_TEMP 0.1 RawSerial pc(USBTX, USBRX); DigitalIn sens_u(p17); DigitalIn sens_d(p15); DigitalOut led1(LED1); DigitalOut led2(LED2); DigitalOut pump(p25); //真空ポンプ DigitalOut valve(p26); //電磁弁 DigitalOut stby(p22); PwmOut motor(p21); Speaker speaker(p30); SerialServo servo2(p13,p14); SerialServo servo1(p9,p10); WiiClassicController wii(p28, p27); // SDA , SCL DigitalOut rc_servo(p24); Ticker soft_pwm; Timer timer; void generatePwm_us(int, int); int ang_c(double x, double y, int sign); bool isStart = false; //競技開始 bool isVacuum = false; //真空ポンプ bool isRelease = false; //負圧解放 bool isDash = false; //ダッシュモード(x, y) bool isZ_lLimit = false; //z軸高さ限界 bool isZ_uLimit = false; int z_nout_time = 0; double ang1; //根元角度(rad) double ang2; //関節角度(rad) float xy_speed = SLOW; int x_point; //各座標 int y_point; int z_point; int rc_angle; //RCサーボ角度 float angle_offset; float motor_power; //上下モータ出力 float angle; int pre_angle; int home; int minus; int plus; int bL; int bR; int bZL; int bZR; int bA; int bB; int bX; int bY; int bDU; int bDD; int bDL; int bDR; typedef union{ short i; char b[2]; }short_b; int init(); int check(); int output(); void generate_pwm_us(int, int); void beep_A(); void beep_B(); int main() { int count=0; init(); while(1) { check(); output(); while(timer.read_ms() < CONTROL_PERIOD_MS); //pc.printf("%d:%f\n", count, timer.read()); timer.reset(); count++; } } int init() { short s; char c; timer.start(); motor.period_us(80); pc.baud(9600); servo1.start(38400, 128); servo2.start(38400, 128); generatePwm_us(1500, 20000); stby = 1; x_point = X_HOME; y_point = Y_HOME; speaker.tone(415, 100); wait_ms(120); speaker.tone(659, 100); wait_ms(120); speaker.tone(831, 100); wait_ms(120); speaker.tone(1046, 100); wait_ms(500); return 0; } int check() { home = wii.button_home(); minus = wii.button_minus(); plus = wii.button_plus(); bL = wii.button_L(); bR = wii.button_R(); bZL = wii.button_ZL(); bZR = wii.button_ZR(); bA = wii.button_A(); bB = wii.button_B(); bX = wii.button_X(); bY = wii.button_Y(); bDU = wii.button_DU(); bDD = wii.button_DD(); bDL = wii.button_DL(); bDR = wii.button_DR(); static int pre_home = home; static int pre_minus = minus; static int pre_plus = plus; static int pre_bL = bL; static int pre_bR = bR; static int pre_bZL = bZL; static int pre_bZR = bZR; static int pre_bA = bA; static int pre_bB = bB; static int pre_bX = bX; static int pre_bY = bY; static int pre_bDU = bDU; static int pre_bDD = bDD; static int pre_bDL = bDL; static int pre_bDR = bDR; static int pre_x = x_point; static int pre_y = y_point; static int pre_z = z_point; char c; short s; /* servo1.sendShort('G', 0); if(servo1.readShort(&c, &s)==0){ if(c=='G'){ led1=!led1;pc.printf("SERVO1=%d\t", s);} else led1=0; } servo2.sendShort('G',0); if(servo2.readShort(&c, &s)==0){ if(c=='G'){ led2=!led2;pc.printf("SERVO2=%d\n", s);} else led2=0; } */ if(bR == 1) angle+=15; else if(bL == 1) angle-=15; int joyLX = wii.joy_LX() - LX_CENTER; int joyLY = wii.joy_LY() - LY_CENTER; if(joyLX < -LX_MARGIN || joyLX > LX_MARGIN) x_point = x_point - (float)joyLX*(float)xy_speed; if(joyLY < -LY_MARGIN || joyLY > LY_MARGIN) y_point = y_point - (float)joyLY*(float)xy_speed; //pc.printf("x_point=%d\ty_point=%d\nxy_speed=%f", x_point, y_point, xy_speed); pc.printf("u=%d\td=%d\n", sens_u.read(), sens_d.read()); /* if(x_point < -500){ x_point = -500; beep_B(); }else if(x_point > 700){ x_point = 700; beep_B(); } if(y_point > 560){ y_point = 560; beep_B(); }else if(y_point < -500){ y_point = -500; beep_B(); } if(x_point < 160 && y_point < 160){ x_point = pre_x; y_point = pre_y; beep_B(); } */ //MFTarea if(x_point < -400){ x_point = -400; beep_B(); }else if(x_point > 600){ x_point = 600; beep_B(); } if(y_point < 500){ y_point = 500; beep_B(); }else if(y_point > 770){ y_point = 770; beep_B(); } if(bX == 1 && pre_bX == 0) isVacuum = !isVacuum; if(bZL == 1 && pre_bZL == 0) isDash = !isDash; if(isDash == true){ if(xy_speed <= FAST) xy_speed += ADD_TEMP; } else{ if(xy_speed > SLOW) xy_speed -= ADD_TEMP; } if(bZR == 1 ) isRelease = 1; else isRelease = 0; /* if(sens_u) isZ_uLimit = false; else isZ_uLimit = true; if(sens_d) isZ_lLimit = false; else isZ_lLimit = true; */ //pc.printf("sens_u=%d\tsens_d=%d\n", isZ_uLimit, isZ_lLimit); int joyRY = wii.joy_RY() - RY_CENTER; //pc.printf("joyRY=%d\n", joyRY); if(wii.joy_LY() > 60 && wii.joy_LX() > 60){ x_point = pre_x; y_point = pre_y; motor_power = 0.5; beep_A(); }else motor_power = -(double)joyRY/100.0 + 0.5; //motor_power = (double)joyRY/150.0 + 0.5; if(isZ_uLimit && (motor_power > 0.5)){ motor_power = 0.5; }else if(isZ_lLimit && (motor_power < 0.5)) motor_power = 0.5; /* pc.printf("----------------\n"); pc.printf("LX:%d\tLY:%d\n", wii.joy_LX(), wii.joy_LY()); pc.printf("RX:%d\tRY:%d\n", wii.joy_RX(), wii.joy_RY()); pc.printf("home:%d\t-:%d\t+:%d\n", wii.button_home(), wii.button_minus(), wii.button_plus()); pc.printf("L:%d\tR:%d\tZL:%d\tZR:%d\n", wii.button_L(), wii.button_R(), wii.button_ZL(), wii.button_ZR()); pc.printf("A:%d\tB:%d\tX:%d\tY:%d\n", wii.button_A(), wii.button_B(), wii.button_X(), wii.button_Y()); pc.printf("DU:%d\tDD:%d\tDL:%d\tDR:%d\n", wii.button_DU(), wii.button_DD(), wii.button_DL(), wii.button_DR()); */ //ang1=PI; //ang2=0.0; if(ang_c(x_point,y_point,SIGN)==-1){ x_point = pre_x; y_point = pre_y; beep_B(); } pre_home = home; pre_minus = minus; pre_plus = plus; pre_bL = bL; pre_bR = bR; pre_bZL = bZL; pre_bZR = bZR; pre_bA = bA; pre_bB = bB; pre_bX = bX; pre_bY = bY; pre_bDU = bDU; pre_bDD = bDD; pre_bDL = bDL; pre_bDR = bDR; pre_x = x_point; pre_y = y_point; return 0; } int output() { char c; short s; int angle1 = ang1*442.0/PI + SERVO1_ZERO; int angle2 = -ang2*460.0/PI + SERVO2_ZERO; //int angle1 = SERVO1_ZERO; //int angle2 = SERVO2_ZERO; //int angle1 = ang1; //int angle2 = ang2; static int pre_angle1; static int pre_angle2; //double ang1a = (angle1-SERVO1_ZERO)*PI/442.0; //double ang2a = (angle2-SERVO2_ZERO)*PI/409.0; angle_offset = (float)(ang1 + ang2)*(float)1500.0/180.0; int x= L1*cos(ang1) + L2*cos(ang1+ang2); int y= L1*sin(ang1) + L2*sin(ang1+ang2); //pc.printf("x=%d\txp=%d\ny=%d\typ=%d\n", x, x_point, y, y_point); //pc.printf("angle=%f\n", angle); //pc.printf("angle1=%d\tangle2=%d\n", angle1, angle2); if(angle1 != pre_angle1){ servo1.sendShort('S', angle1); if(servo1.readShort(&c, &s)==0){ led1=!led1; if(c=='S'&&s==-1) angle1 = pre_angle1; } pre_angle1 = angle1; } if(angle2 != pre_angle2){ servo2.sendShort('S', angle2); if(servo2.readShort(&c, &s)==0){ led2 = !led2; if(c=='S'&&s==-1) angle2 = pre_angle2; } pre_angle2 = angle2; } int angle_output = RC_CENTER + angle; //+ angle_offset; if(angle_output > RC_MAX){ angle_output = RC_MAX; angle = RC_MAX - RC_CENTER; }else if(angle_output < RC_MIN){ angle_output = RC_MIN; angle = RC_MIN - RC_CENTER; } generatePwm_us(RC_CENTER + angle - angle_offset, 20000); if(isVacuum == 1) pump = 1; else pump = 0; //pc.printf("pump=%d\n", isVacuum); if(isRelease == 1) valve = 1; else valve = 0; //pc.printf("motor_p = %f\n", motor_power); if(motor_power == 0.5) z_nout_time++; else z_nout_time=0; if(motor_power == 0.5 && ((z_nout_time*CONTROL_PERIOD_MS) > 300)){ stby = 0; }else{ stby = 1; motor = motor_power; } return 0; } //角度計算 int ang_c(double x, double y,int sign) { static double pre_ang1=ang1; static double pre_ang2=ang2; ang2 = sign*acos((x*x + y*y - L1*L1 - L2*L2)/(2.0*L1*L2)); ang1 = atan(y/x) - atan((L2*sin(ang2))/(L1+L2*cos(ang2))); if(x<0) ang1=ang1+PI; if(ang1 > PI) ang1 -= 2*PI; if(ang2 > PI) ang2 -= 2*PI; if(sqrt(x*x+y*y) > MAX_LEN || sqrt(x*x+y*y) <= MIN_LEN){ ang1 = pre_ang1; ang2 = pre_ang2; return -1; } pre_ang1 = ang1; pre_ang2 = ang2; return 0; } //SOFT PWM SERVO #define SOFT_PWM_CYCLE 15 int soft_pwm_period=0; int soft_pulse_width=0; void generatePWM(){ static int count = 0; if ((count++)*SOFT_PWM_CYCLE < soft_pulse_width) rc_servo = 1; else rc_servo = 0; if (count*SOFT_PWM_CYCLE > soft_pwm_period) count = 0; } void generatePwm_us(int p_width, int p_period) { if(soft_pwm_period != p_period){ soft_pwm_period = p_period; soft_pulse_width = p_width; soft_pwm.attach_us(&generatePWM, SOFT_PWM_CYCLE); }else soft_pulse_width = p_width; } void beep_A(){ speaker.tone(2000, 300); } void beep_B(){ speaker.tone(1000, 300); }