2016 catch robo

Dependencies:   mbed WiiClassicController_kai

Files at this revision

API Documentation at this revision

Comitter:
kambara1415
Date:
Mon Jun 24 07:51:58 2019 +0000
Commit message:
2016 suiheitakannsetu

Changed in this revision

SerialServo.h Show annotated file Show diff for this revision Revisions of this file
WiiClassicController.lib Show annotated file Show diff for this revision Revisions of this file
lancer_speaker/lancer_speaker.cpp Show annotated file Show diff for this revision Revisions of this file
lancer_speaker/lancer_speaker.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
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