sotsuken

Dependencies:   IncEncoder mbed

Files at this revision

API Documentation at this revision

Comitter:
koki_konishi
Date:
Mon Dec 12 05:50:18 2022 +0000
Commit message:
mecha

Changed in this revision

.gitignore Show annotated file Show diff for this revision Revisions of this file
IncEncoder.lib 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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.gitignore	Mon Dec 12 05:50:18 2022 +0000
@@ -0,0 +1,4 @@
+.build
+.mbed
+projectfiles
+*.py*
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IncEncoder.lib	Mon Dec 12 05:50:18 2022 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/koki_konishi/code/IncEncoder/#c40c29a063c0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon Dec 12 05:50:18 2022 +0000
@@ -0,0 +1,492 @@
+#include "mbed.h"
+#include "IncEncoder.h"
+#include <math.h>
+
+#define PI 3.14159265358979
+
+#define BELT_RPP 512
+#define ANG_RPP 512
+#define LIFT_RPP 256
+
+#define BELT_PER 1050
+#define BELT_Rratio 5
+
+#define LIFT_PCD 54 
+
+#define BELT_UC 30 //モータ出力オフセット
+#define ANG_UC 25
+#define LIFT_UC 36
+
+#define VELO_dt 0.010
+#define BELT_dt 0.010
+#define ANG_dt 0.010
+#define LIFT_dt 0.010
+
+#define VELO_Ke 1
+#define VELO_Kp 0.005
+#define VELO_Ki 0.000012
+#define VELO_Kd 0.0000
+
+#define BELT_Ke 1
+#define BELT_Kp 1.2
+#define BELT_Ki 0.005
+#define BELT_Kd 0.03
+
+#define ANG_Ke 4
+#define ANG_Kp 1.2
+#define ANG_Ki 0.005
+#define ANG_Kd 0.03
+
+#define LIFT_Ke 2
+#define LIFT_Kp 1.8
+#define LIFT_Ki 0.013
+#define LIFT_Kd 0.03
+
+#define ARM_SERVO_OFFSET 7500
+#define ARM_SERVO_VPA 29.6296296
+
+//モータードライバのアドレス
+#define beltR_MOTOR 0x02
+#define angR_MOTOR 0x04
+
+//モータードライバへの命令
+#define STOP 0
+#define CW 1
+#define CCW -1
+#define bSTOP 10
+#define bCW 11
+#define bCCW -11
+
+#define sCW 21
+#define sCCW -21
+#define sSTOP 20
+#define shCW 31
+#define shCCW -31
+
+#define lCW 51
+#define lCCW -51
+#define lSTOP 50
+#define lsCW 61
+#define lsCCW -61
+#define lsSTOP 60
+
+#define rON 41
+#define rOFF -41
+
+//通信初期化
+Serial mecha_ins(USBTX,USBRX,115200);
+I2C md_i2c_tx(PD_13,PD_12);
+
+//GPIO初期化
+InterruptIn beltR_i_(PC_1);
+
+DigitalIn angR_zero(PE_15);
+
+//QEI初期化
+IncEncoder beltR_RE(PC_2,PC_3,IncEncoder::x2_Resolution);
+IncEncoder angR_RE(PF_9,PC_0,IncEncoder::x2_Resolution);
+
+//プロトタイプ関数宣言
+void ins_recieve();
+void BELTR_PID();
+void ANGR_PID();
+void belt_reset();
+void beltR_reset();
+void md_setoutput(unsigned char address, int rotate, int duty);
+
+volatile char led_command = 0xFF;
+
+volatile char mecha_prep = 0;
+volatile int triggerR_flag = 0, triggerL_flag = 0;
+
+volatile int lift_pid_flag_R = 1, lift_pid_flag_L = 1;
+
+volatile int kick_R = 0, kick_L = 0;
+volatile int pid_off_R = 0, pid_off_L = 0;
+
+volatile int beltR_delaycnt = 0, beltL_delaycnt = 0;
+volatile int beltR_delayflag = 1, beltL_delayflag = 1;
+
+volatile int delayR_cnt = 0, delayL_cnt = 0;
+volatile int delayR_flag = 1, delayL_flag = 1;
+
+volatile int liftR_reset = 0, liftL_reset = 0;
+volatile int stateR_num = 0, stateL_num = 0;
+volatile int cntR = 0, cntL = 0;
+
+volatile int BELTR_flag = 0, BELTL_flag = 0;
+
+volatile int beltR_POWER = 0;
+volatile int beltL_POWER = 0;
+volatile int beltR_TRIGGER = 0;
+volatile int beltL_TRIGGER = 0;
+
+volatile int beltR_UMAX = 100;
+volatile int beltL_UMAX = 100;
+
+volatile int beltR_MOTOR_Rdir;
+volatile int beltL_MOTOR_Rdir;
+volatile double beltR_DES = 20;
+volatile double beltL_DES = 20;
+volatile double beltR_STATE = 0;
+volatile double beltL_STATE = 0;
+volatile double beltR_U;
+volatile double beltL_U;
+volatile double beltR_ERROR[2] = {};
+volatile double beltL_ERROR[2] = {};
+volatile double beltR_INTEGRAL = 0;
+volatile double beltL_INTEGRAL = 0;
+
+volatile int angR_MOTOR_Rdir;
+volatile int angL_MOTOR_Rdir;
+volatile double ANGR_DES = 0;
+volatile double ANGL_DES = 0;
+volatile double ANGR_STATE = 0;
+volatile double ANGL_STATE = 0;
+volatile double ANGR_U;
+volatile double ANGL_U;
+volatile double ANGR_ERROR[2] = {};
+volatile double ANGL_ERROR[2] = {};
+volatile double ANGR_INTEGRAL = 0;
+volatile double ANGL_INTEGRAL = 0;
+
+volatile int liftR_MOTOR_Rdir;
+volatile int liftL_MOTOR_Rdir;
+volatile double liftR_DES = 0;
+volatile double liftL_DES = 0;
+volatile double liftR_STATE = 0;
+volatile double liftL_STATE = 0;
+volatile double liftR_U;
+volatile double liftL_U;
+volatile double liftR_ERROR[2] = {};
+volatile double liftL_ERROR[2] = {};
+volatile double liftR_INTEGRAL = 0;
+volatile double liftL_INTEGRAL = 0;
+
+//main
+int main(){
+    md_i2c_tx.frequency(400000); //MD用I2C
+    
+    beltR_RE.reset();
+    angR_RE.reset();
+    
+    angR_zero.mode(PullUp);
+    
+    beltR_i_.mode(PullDown);
+    
+    beltR_i_.rise(&beltR_reset);
+    
+    wait_ms(300);
+    
+    while(!angR_zero){
+        if(!angR_zero){
+            md_setoutput(angR_MOTOR,bCCW,50);
+        }else{
+            md_setoutput(angR_MOTOR,bSTOP,0);
+        }
+    }
+    
+    angR_RE.reset();
+    
+    belt_reset();
+    
+    while(mecha_ins.readable()){
+        char dummy = mecha_ins.getc();
+    }
+    
+    mecha_ins.attach(&ins_recieve, Serial::RxIrq);
+    
+    while(1){
+        if(1){
+            //追従処理呼び出し なぜかTickerが新マザーで正常動作しないため\(^o^)/
+            if(!beltR_TRIGGER){
+                BELTR_PID();
+            }
+            
+            ANGR_PID();
+            
+            //発射処理
+            if(beltR_TRIGGER == 1){
+                
+                beltR_TRIGGER++;
+            }
+            
+            if(beltR_TRIGGER == 2){
+                if(pid_off_R){
+                    md_setoutput(beltR_MOTOR,CW,beltR_POWER);
+                }else{
+                    md_setoutput(beltR_MOTOR,sCW,beltR_POWER);
+                }
+                
+                triggerR_flag = 0; 
+            }
+            
+            if(kick_R){
+                if(beltR_RE.GetIncPulses()/(BELT_RPP*2) >= 2.0 && beltR_TRIGGER == 2){
+                    pid_off_R = 0;
+                    beltR_delaycnt = 50;
+                    beltR_delayflag = 0;
+                    beltR_TRIGGER++;
+                }
+            }else{
+                if(beltR_RE.GetIncPulses()/(BELT_RPP*2) >= 0.5 && beltR_TRIGGER == 2){
+                    pid_off_R = 0;
+                    beltR_delaycnt = 50;
+                    beltR_delayflag = 0;
+                    beltR_TRIGGER++;
+                }
+            }
+            
+            if(beltR_TRIGGER == 3){
+                kick_R = 0;
+                md_setoutput(beltR_MOTOR,bSTOP,0);
+            }
+            
+            if(beltR_delayflag && beltR_TRIGGER == 3){
+                beltR_TRIGGER++;
+            }
+            
+            if(beltR_TRIGGER == 4){
+                md_setoutput(beltR_MOTOR,bCW,70);
+            }
+            
+            if(beltR_RE.GetIncPulses()/(BELT_RPP*2) >= 5 && beltR_TRIGGER == 4){
+                BELTR_flag = 1;
+                beltR_TRIGGER++;
+            }
+            
+            if(beltR_TRIGGER == 5){
+                md_setoutput(beltR_MOTOR,bCCW,70);
+            }
+            
+            if(!BELTR_flag && beltR_TRIGGER == 5){
+                md_setoutput(beltR_MOTOR,bSTOP,0);
+                beltR_INTEGRAL = 0;
+                beltR_TRIGGER = 0;
+            }
+        }
+        
+        mecha_prep = 0x00;
+        
+        if(triggerR_flag){
+            mecha_prep = 0x80;
+        }
+        if(triggerL_flag){
+            mecha_prep = 0x40;
+        }
+        if(beltR_TRIGGER){
+            mecha_prep = 0x20;
+        }
+        if(beltL_TRIGGER){
+            mecha_prep = 0x10;
+        }
+        if(stateR_num){
+            mecha_prep = 0x08;
+        }
+        if(stateL_num){
+            mecha_prep = 0x04;
+        }
+        if(liftR_reset || liftL_reset){
+            mecha_prep = 0x02;
+        }
+        
+        mecha_ins.putc(mecha_prep);
+        
+        wait_ms(10);
+    }
+}
+
+//右発射角追従制御
+void ANGR_PID(){
+    ANGR_STATE = 360 * -angR_RE.GetIncPulses()/(ANG_RPP*2);
+    
+    ANGR_ERROR[0] = ANGR_ERROR[1];
+    ANGR_ERROR[1] = (double)ANG_Ke * (ANGR_STATE - ANGR_DES);
+    ANGR_INTEGRAL += ANGR_ERROR[1]*ANG_dt;
+    
+    ANGR_U = ANG_Kp * ANGR_ERROR[1] + ANG_Ki * ANGR_INTEGRAL + ANG_Kd * (ANGR_ERROR[1] - ANGR_ERROR[0])/ANG_dt;
+    
+    if(ANGR_U >= 0){
+        angR_MOTOR_Rdir = bCCW;
+    }else{
+        angR_MOTOR_Rdir = bCW;
+        ANGR_U *= -1;
+    }
+    
+    if(ANGR_U >= 100){
+        ANGR_U = 100;
+    }
+    
+    if(angR_zero && angR_MOTOR_Rdir == bCCW){
+        md_setoutput(angR_MOTOR,bSTOP,0);
+    }else{
+        md_setoutput(angR_MOTOR,angR_MOTOR_Rdir,ANGR_U+ANG_UC);
+    }
+}
+
+//右ベルト位置追従制御
+void BELTR_PID(){
+    beltR_STATE = BELT_PER * beltR_RE.GetIncPulses()/(BELT_RPP*2*BELT_Rratio);
+    
+    beltR_ERROR[0] = beltR_ERROR[1];
+    beltR_ERROR[1] = (double)BELT_Ke * (beltR_STATE - beltR_DES);
+    beltR_INTEGRAL += beltR_ERROR[1]*BELT_dt;
+    
+    beltR_U = BELT_Kp * beltR_ERROR[1] + BELT_Ki * beltR_INTEGRAL + BELT_Kd * (beltR_ERROR[1] - beltR_ERROR[0])/BELT_dt;
+    
+    if(beltR_U >= 0){
+        beltR_MOTOR_Rdir = bCCW;
+    }else{
+        beltR_MOTOR_Rdir = bCW;
+        beltR_U *= -1;
+    }
+    
+    if(beltR_U >= beltR_UMAX){
+        beltR_U = beltR_UMAX;
+    }
+    
+    md_setoutput(beltR_MOTOR,beltR_MOTOR_Rdir,beltR_U+BELT_UC);
+}
+
+void belt_reset(){
+    int beltR_flag = 1;
+    
+    while(beltR_flag){
+        if(360 * beltR_RE.GetIncPulses()/(BELT_RPP*2) < 180){
+            md_setoutput(beltR_MOTOR,bCW,70);
+        }else{
+            md_setoutput(beltR_MOTOR,bSTOP,0);
+            beltR_flag = 0;
+        }
+    }
+    
+    BELTR_flag = 1;
+    
+    while(BELTR_flag){
+        if(BELTR_flag){
+            md_setoutput(beltR_MOTOR,bCCW,70);
+        }else{
+            md_setoutput(beltR_MOTOR,bSTOP,0);
+        }
+    }
+    
+    wait_ms(10);
+}
+
+//命令受信処理
+void ins_recieve(){
+    char ins_byte = mecha_ins.getc();
+    
+    switch(ins_byte){
+        case 0x0F : 
+            cntR = mecha_ins.getc();
+            cntL = mecha_ins.getc();
+            liftR_reset = 1;
+            liftL_reset = 1;
+            break;
+        case 0xA1 : 
+            beltR_POWER = mecha_ins.getc();
+            beltR_TRIGGER = 1;
+            break;
+        case 0xA2 : 
+            cntR = mecha_ins.getc();
+            stateR_num = 1;
+            break;
+        case 0xA3 : 
+            ANGR_DES = mecha_ins.getc();
+            break;
+        case 0xB1 : 
+             beltL_POWER = mecha_ins.getc();
+             beltL_TRIGGER = 1;
+            break;
+        case 0xB2 : 
+            cntL = mecha_ins.getc();
+            stateL_num = 1;
+            break;
+        case 0xB3 : 
+            ANGL_DES = mecha_ins.getc();
+            break;
+        case 0xAA : 
+            beltR_POWER = mecha_ins.getc();
+            beltR_TRIGGER = 1;
+            pid_off_R = 1;
+            kick_R = 1;
+            break;
+        case 0xAB : 
+            beltR_POWER = mecha_ins.getc();
+            beltR_TRIGGER = 1;
+            kick_R = 1;
+            break;
+        case 0xBA : 
+            beltL_POWER = mecha_ins.getc();
+            beltL_TRIGGER = 1;
+            pid_off_L = 1;
+            kick_L = 1;
+            break;
+        case 0xBB : 
+            beltL_POWER = mecha_ins.getc();
+            beltL_TRIGGER = 1;
+            kick_L = 1;
+            break;
+        case 0xAF : 
+            beltR_POWER = mecha_ins.getc();
+            beltR_TRIGGER = 1;
+            pid_off_R = 1;
+            break;
+        case 0xBF : 
+            beltL_POWER = mecha_ins.getc();
+            beltL_TRIGGER = 1;
+            pid_off_L = 1;
+            break;
+        case 0xFF : 
+            led_command = mecha_ins.getc();
+            break;
+    }
+    
+    while(mecha_ins.readable()){
+        char dummy = mecha_ins.getc();
+    }
+}
+
+void beltR_reset(){
+    if(BELTR_flag){
+        beltR_RE.reset();
+        BELTR_flag = 0;
+    }
+}
+
+//MD用I2C通信処理
+void md_setoutput(unsigned char address, int rotate, int duty){
+    char data[2];
+
+    // モーター駆動制御モード
+    switch (rotate) {
+        case CW:    data[0] = 'F'; break;// 電圧比例制御モード(PWMがLの区間はフリー)
+        case CCW:   data[0] = 'R'; break;
+        case STOP:  data[0] = 'S'; break;
+    
+        case bCW:   data[0] = 'f'; break; // 電圧比例制御モード(PWMがLの区間はブレーキ)
+        case bCCW:  data[0] = 'r'; break;
+        case bSTOP: data[0] = 's'; break;
+    
+        case sCW:   data[0] = 'A'; break; // 速度比例制御モード
+        case sCCW:  data[0] = 'B'; break;
+        case sSTOP: data[0] = 'T'; break;
+    
+        case shCW:   data[0] = 'a'; break; // 速度比例制御モード(命令パケット最上位ビットに指令値9ビット目を入れることで分解能2倍)
+        case shCCW:  data[0] = 'b'; break;
+    
+        case lCW:   data[0] = 'L'; break; // 通常LAP
+        case lCCW:  data[0] = 'M'; break;
+        case lSTOP: data[0] = 'N'; break;
+        case lsCW:   data[0] = 'l'; break; // 速調LAP
+        case lsCCW:  data[0] = 'm'; break;
+        case lsSTOP: data[0] = 'n'; break;
+    
+        case rON: data[0] = 'P'; break; //リレー駆動モード
+        case rOFF: data[0] = 'p'; break;
+    }
+    
+    data[1] = duty & 0xFF;
+    md_i2c_tx.write(address << 1, data, 2); //duty送信
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Mon Dec 12 05:50:18 2022 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/mbed_official/code/mbed/builds/65be27845400
\ No newline at end of file