2016 catch robo
Dependencies: mbed WiiClassicController_kai
Revision 0:7d81654c5ce8, committed 2019-06-24
- Comitter:
- kambara1415
- Date:
- Mon Jun 24 07:51:58 2019 +0000
- Commit message:
- 2016 suiheitakannsetu
Changed in this revision
diff -r 000000000000 -r 7d81654c5ce8 SerialServo.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SerialServo.h Mon Jun 24 07:51:58 2019 +0000 @@ -0,0 +1,138 @@ +typedef struct{ + int front, rear, count, size; + char *buff; +}Queue; + +typedef union{ + short i; + char b[2]; +}int_b; + +class SerialServo { +public: + SerialServo(PinName tx, PinName rx); + int start(int,int); + int readShort(char*, short*); + void sendShort(char, short); + +private: + Queue *make_queue(int); + bool is_full(Queue *); + int get_count(Queue *); + bool enqueue(Queue *, char); + bool is_empty(Queue *); + char dequeue(Queue *, bool *); + void enqueueBuff(); + Queue *_q; + RawSerial _servo; + Ticker _timer; +}; + +SerialServo::SerialServo(PinName tx, PinName rx) + :_servo(tx,rx){ +} + +int SerialServo::start(int baud_rate, int buff_size) +{ + if((_q = make_queue(buff_size)) == NULL) return -1; + _servo.baud(baud_rate); + _servo.attach(this, &SerialServo::enqueueBuff, Serial::RxIrq); + return 0; +} + +void SerialServo::sendShort(char c, short data) +{ + int_b s_data; + s_data.i = data; + _servo.putc(c); + _servo.putc(s_data.b[0]); + _servo.putc(s_data.b[1]); +} + +int SerialServo::readShort(char *c, short *data) +{ + bool err; + if(get_count(_q) >= sizeof('A') + sizeof(short)){ + *c = dequeue(_q, &err); + if(*c >= 'A' && *c <= 'Z'){ + int_b x; + x.b[0] = dequeue(_q, &err); + x.b[1] = dequeue(_q, &err); + *data = x.i; + return 0; + }else readShort(c, data); + } + return -1; +} + +void SerialServo::enqueueBuff() +{ + if(_servo.readable() == 1) SerialServo::enqueue(_q,_servo.getc()); +} + + +//******************** +//Bufferに関する関数 +//******************** + +Queue *SerialServo::make_queue(int n) +{ + Queue *que; + que = (Queue *)malloc(sizeof(Queue)); + if (que != NULL) { + que->front = 0; + que->rear = 0; + que->count = 0; + que->size = n; + que->buff = (char *)malloc(sizeof(char) * n); + if (que->buff == NULL) { + free(que); + return NULL; + } + } + return que; +} + + +// キューは満杯か +bool SerialServo::is_full(Queue *que) +{ + return que->count == que->size; +} + +// データの挿入 +bool SerialServo::enqueue(Queue *que, char x) +{ + if (is_full(que)) return false; + que->buff[que->rear++] = x; + que->count++; + if (que->rear == que->size) + que->rear = 0; + return true; +} + +// キューは空か +bool SerialServo::is_empty(Queue *que) +{ + return que->count == 0; +} + +int SerialServo::get_count(Queue *que) +{ + return que->count; +} + +// データを取り出す +char SerialServo::dequeue(Queue *que, bool *err) +{ + if (is_empty(que)) { + *err = false; + return 0; + } + char x = que->buff[que->front++]; + que->count--; + *err = true; + if (que->front == que->size) + que->front = 0; + return x; +} \ No newline at end of file
diff -r 000000000000 -r 7d81654c5ce8 WiiClassicController.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WiiClassicController.lib Mon Jun 24 07:51:58 2019 +0000 @@ -0,0 +1,1 @@ +https://developer.mbed.org/users/kambara1415/code/WiiClassicController_kai/#5e09e9bd8e60
diff -r 000000000000 -r 7d81654c5ce8 lancer_speaker/lancer_speaker.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lancer_speaker/lancer_speaker.cpp Mon Jun 24 07:51:58 2019 +0000 @@ -0,0 +1,29 @@ +#include "mbed.h" +#include "lancer_speaker.h" + + +Speaker::Speaker(PinName pin): _pin(pin){ + _pin = 0; +} + +void Speaker::tone(int freq, int duration) +{ + _duration = duration; + _freq = freq; + _time.attach_us(this, &Speaker::flip, 500000/_freq); +} + +void Speaker::noTone() +{ + _time.detach(); +} + +void Speaker::flip() +{ + _pin = !_pin; + if(_duration < _count*500/_freq){ + _count = 0; + _time.detach(); + } + _count++; +} \ No newline at end of file
diff -r 000000000000 -r 7d81654c5ce8 lancer_speaker/lancer_speaker.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lancer_speaker/lancer_speaker.h Mon Jun 24 07:51:58 2019 +0000 @@ -0,0 +1,17 @@ +#ifndef LANCER_SPEAKER_H +#define LANCER_SPEAKER_H + +class Speaker +{ +public: + Speaker(PinName); + void tone(int, int); + void noTone(); + void flip(); +private: + DigitalOut _pin; + Ticker _time; + int _count, _duration, _freq; +}; + +#endif \ No newline at end of file
diff -r 000000000000 -r 7d81654c5ce8 main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Mon Jun 24 07:51:58 2019 +0000 @@ -0,0 +1,471 @@ +//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); +} \ No newline at end of file
diff -r 000000000000 -r 7d81654c5ce8 mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Mon Jun 24 07:51:58 2019 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/2e9cc70d1897 \ No newline at end of file