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.
Diff: main.cpp
- Revision:
- 0:b4b94eb28093
- Child:
- 1:b2bd1511307e
diff -r 000000000000 -r b4b94eb28093 main.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Sun Dec 19 05:53:03 2021 +0000
@@ -0,0 +1,1236 @@
+//2021/12/18更新
+//YUKA本番機用プログラム
+//入力切替確認済み
+//一定時間の入力なしで動作切替
+//ジグザグ動作実装前
+//エンコーダ読み取りによる入力
+//加減速度調整パラメータ実装
+//PID制御による機体角度補正_
+
+#include "mbed.h"
+#include "hcsr04.h"
+
+
+DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+DigitalOut led3(LED3);
+DigitalOut led4(LED4);
+
+Timer t;
+double Time = 0;
+#define Standby_Time 10
+Serial pc(USBTX, USBRX);
+char Serialdata;
+BusOut myled(LED1, LED2, LED3, LED4);
+
+//HCSR04 u1(p13, p14), u2(p11, p12), u3(p23, p24), u4(p25, p26); // Trigger(DO), Echo(PWMIN); LPC1768
+HCSR04 u1(PA_0, PA_1),u2(PA_5, PA_6),u3(PB_0, PA_10); // Trigger(DO), Echo(PWMIN); f303k8
+
+CANMessage canmsgTx;
+CANMessage canmsgRx;
+//CAN canPort(p30, p29); //CAN name(PinName rd, PinName td) LPC1768
+CAN canPort(PA_11, PA_12); //CAN name(PinName rd, PinName td) F303k8
+
+//プロトタイプ宣言
+//------------------send関数-------------------
+//mode Setting
+void sendOPModeT(int); //Operating Mode
+void sendOPModeV(int); //Operating Mode
+//Control Word
+void sendCtrlRS(int); //Reset
+void sendCtrlSD(int); //Shutdown
+void sendCtrlEN(int); //Switch on & Enable
+void sendCtrlQS(int); //Quick Stop
+void sendCtrlHL(int); //Halt
+//Velocity Setting
+void sendTgtVel(int,int); //Target Velocity
+//Torque Setting
+void sendTgtTrq(int,int); //Target Torque
+//Acceleration Setting
+void sendProAcc(int,int); //Plof Acceleration
+void sendProDec(int,int); //Plof Deceleration
+//------------------read関数-------------------
+void readActVel(int); //Actual Velocity
+void readActPos(int); //Actual Position
+//-------------------その他--------------------
+void printCANTX(void); //CAN送信データをPCに表示
+void printCANRX(void); //CAN受信データをPCに表示
+void CANdataRX(void); //CAN受信処理
+void SerialRX(void); //Serial受信処理
+
+int nodeall=4;
+
+int main(){
+ //Serial
+ pc.attach(SerialRX);
+ //pc.baud(115200);
+
+ //CAN
+ canPort.frequency(1000000); //Bit Rate:1MHz
+ canPort.attach(CANdataRX,CAN::RxIrq);
+ int node1 = 1; //CAN node Setting
+ int node2 = 2;
+ int node3 = 3;
+ int node4 = 4;
+
+ //モータ回転数
+ int rpm = 600;
+
+ //各モータ回転数
+ int rpm1 = rpm; //Velocity Setting[rpm]
+ int rpm2 = rpm; //Velocity Setting[rpm]
+ int rpm3 = rpm; //Velocity Setting[rpm]
+ int rpm4 = rpm; //Velocity Setting[rpm]
+
+ //エンコーダ関係
+ int ActPos = 0;
+ int Init_Pos = 0;
+
+ //超音波センサ関係パラメータ
+ int max_rpm = rpm + 200;
+ int min_rpm = rpm -200;
+ int wall_distance = 0;
+ int dist1, dist2,dist3, dist4;
+
+
+ //PID制御関係
+ //角度調整パラメータ
+ int p1, i1, d1;
+ int error_before1 = 0;
+ int error_now1 = 0;
+ int feedback_val1;
+ int integral1;
+ int pid_sum1;
+ #define DELTA_T1 0.1
+ #define target_val1 0
+ #define Kp1 3
+ #define Ki1 0
+ #define Kd1 0
+
+ /*
+ //距離調整パラメータ
+ int p2, i2, d2;
+ int error_before2 = 0;
+ int error_now2 = 0;
+ int feedback_val2;
+ int integral2;
+ int pid_sum2;
+ #define DELTA_T2 0.01
+ #define target_val2 50
+ #define Kp2 2.0
+ #define Ki2 3.0
+ #define Kd2 3.0
+ */
+
+ pc.printf("YUKA PROGRAM START\r\n");
+ wait(0.1);
+ //-------------起動時に必ず送信---------------
+ //オペレーティングモードを送信
+ sendOPModeT(node1);
+ sendOPModeT(node2);
+ sendOPModeT(node3);
+ sendOPModeT(node4);
+
+ //Shutdown,Enableコマンド送信|リセット
+ sendCtrlSD(node1);
+ sendCtrlSD(node2);
+ sendCtrlSD(node3);
+ sendCtrlSD(node4);
+
+ sendCtrlEN(node1);
+ sendCtrlEN(node2);
+ sendCtrlEN(node3);
+ sendCtrlEN(node4);
+
+ //初期加減速度
+ int Acc = 2000;
+ int Dec = 2000;
+
+ sendProAcc(1,Acc);
+ sendProAcc(2,Acc);
+ sendProAcc(3,Acc);
+ sendProAcc(4,Acc);
+
+ sendProDec(1,Dec);
+ sendProDec(2,Dec);
+ sendProDec(3,Dec);
+ sendProDec(4,Dec);
+
+ //トルク設定
+ int trq = 100; //torque Setting[mA]
+
+ sendTgtTrq(1,trq);
+ sendTgtTrq(2,trq);
+ sendTgtTrq(3,trq);
+ sendTgtTrq(4,trq);
+
+
+ //-------------------------------------------
+ /*
+ sendCtrlHL(node1);
+ sendCtrlHL(node2);
+ sendCtrlHL(node3);
+ sendCtrlHL(node4);
+
+ //-------------送信コマンドを選択--------------
+ if(Serialdata == 'a'){
+ //左移動
+ sendTgtVel(node1,rpm*(-1));
+ sendTgtVel(node2,rpm);
+ sendTgtVel(node3,rpm);
+ sendTgtVel(node4,rpm*(-1));
+ for(int i=1;i<= 4;i++){
+ sendCtrlEN(i);
+ }
+
+ Serialdata = 0;
+ fl=1;
+ wait(0.5);
+ }
+
+ else if(Serialdata == 'd'){
+ //右移動
+ sendTgtVel(node1,rpm);
+ sendTgtVel(node2,rpm*(-1));
+ sendTgtVel(node3,rpm*(-1));
+ sendTgtVel(node4,rpm);
+ for(int i=1;i<= 4;i++){
+ sendCtrlEN(i);
+ }
+ Serialdata = 0;
+ fl=1;
+ wait(0.5);
+ }
+
+ else if(Serialdata == 'w'){
+ //前移動
+ sendTgtVel(node1,rpm*(-1));
+ sendTgtVel(node2,rpm*(-1));
+ sendTgtVel(node3,rpm);
+ sendTgtVel(node4,rpm);
+ for(int i=1;i<= 4;i++){
+ sendCtrlEN(i);
+ }
+ Serialdata = 0;
+ fl=1;
+ wait(0.5);
+ }
+
+ else if(Serialdata == 's'){
+ //後移動
+ sendTgtVel(node1,rpm);
+ sendTgtVel(node2,rpm);
+ sendTgtVel(node3,rpm*(-1));
+ sendTgtVel(node4,rpm*(-1));
+ for(int i=1;i<= 4;i++){
+ sendCtrlEN(i);
+ }
+ Serialdata = 0;
+ fl=1;
+ wait(0.5);
+ }
+
+ else if(Serialdata == 'e'){
+ //右旋回
+ sendTgtVel(node1,rpm);
+ sendTgtVel(node2,rpm);
+ sendTgtVel(node3,rpm);
+ sendTgtVel(node4,rpm);
+ for(int i=1;i<= 4;i++){
+ sendCtrlEN(i);
+ }
+ Serialdata = 0;
+ fl=1;
+ wait(0.1);
+ }
+ else if(Serialdata == 'q'){
+ //左旋回
+ sendTgtVel(node1,rpm*(-1));
+ sendTgtVel(node2,rpm*(-1));
+ sendTgtVel(node3,rpm*(-1));
+ sendTgtVel(node4,rpm*(-1));
+ for(int i=1;i<= 4;i++){
+ sendCtrlEN(i);
+ }
+ Serialdata = 0;
+ fl=1;
+ wait(0.1);
+ }
+ */
+ //------------------------------------------
+
+ //人の入力待ち
+ /*
+ while(1){
+ readActPos(1);
+ ActPos=canmsgRx.data[4]+canmsgRx.data[5]*256+canmsgRx.data[6]*65536;
+ if(ActPos > 8388608){
+ ActPos -= 0x1000000;
+ printf("check\r\n");
+ }
+ printf("ActPos = %d\r\n",ActPos);
+ wait(0.1);
+ }
+ */
+
+ while(1){
+
+ ActPos = 0;
+ Init_Pos = 0;
+ readActPos(1);
+ ActPos=canmsgRx.data[4]+canmsgRx.data[5]*256+canmsgRx.data[6]*65536;
+ if(ActPos > 8388608){
+ ActPos -= 0x1000000;//16進数でのマイナス処理 16^7 = 16,777,216 = 0x1000000
+ }
+ Init_Pos = ActPos;//起動時の角度を保存
+ t.reset();
+ t.start();
+
+ while(1){
+
+ Time = t.read();
+
+ readActPos(1);
+ ActPos=canmsgRx.data[4]+canmsgRx.data[5]*256+canmsgRx.data[6]*65536;
+ if(ActPos > 8388608){
+ ActPos -= 0x1000000;//16進数でのマイナス処理 16^7 = 16,777,216 = 0x1000000
+ //printf("check\r\n");
+ }
+ printf("dsit1 %d\r\n",dist1);
+ /*--------------------------*/
+ //前方向に入力があった時
+ if(ActPos < Init_Pos - 2000){
+
+ sendProAcc(1,1000);
+ sendProAcc(2,1000);
+ sendProAcc(3,1000);
+ sendProAcc(4,1000);
+
+ sendProDec(1,700);
+ sendProDec(2,700);
+ sendProDec(3,700);
+ sendProDec(4,700);
+
+ //速度制御モード送信
+ sendOPModeV(1);
+ sendOPModeV(2);
+ sendOPModeV(3);
+ sendOPModeV(4);
+
+ while(1){
+
+ u1.start();
+ u2.start();
+ dist1 = u1.get_dist_cm();
+ dist2 = u2.get_dist_cm();
+
+ //速度を指定
+ sendTgtVel(1,rpm*(-1));
+ sendTgtVel(2,rpm*(-1));
+ sendTgtVel(3,rpm);
+ sendTgtVel(4,rpm);
+ //指令値を送信
+ for(int i=1;i<= 4;i++){
+ sendCtrlEN(i);
+ }
+
+ if(dist1 < 100 && dist1 >= 70){
+ break;
+ }
+ printf("dsit1 %d\r\n",dist1);
+ }
+
+ //速度を指定
+ sendTgtVel(1,0);
+ sendTgtVel(2,0);
+ sendTgtVel(3,0);
+ sendTgtVel(4,0);
+ //指令値を送信
+ for(int i=1;i<= 4;i++){
+ sendCtrlEN(i);
+ }
+ //実行時間
+ printf("stop!!\r\n");
+ wait(5.0);
+
+ //printf("2\r\n");
+
+ //速度を指定
+
+ while(1){
+ readActPos(1);
+ ActPos=canmsgRx.data[4]+canmsgRx.data[5]*256+canmsgRx.data[6]*65536;
+ if(ActPos > 8388608){
+ ActPos -= 0x1000000;//16進数でのマイナス処理 16^7 = 16,777,216 = 0x1000000
+ //printf("check\r\n");
+ }
+
+ if(ActPos > -10000){
+ break;
+ }
+
+ sendTgtVel(1,rpm);
+ sendTgtVel(2,rpm);
+ sendTgtVel(3,rpm*(-1));
+ sendTgtVel(4,rpm*(-1));
+ //指令値を送信
+ for(int i=1;i<= 4;i++){
+ sendCtrlEN(i);
+ }
+ //printf("3\r\n");
+ }
+
+ //ブレーキ
+ sendTgtVel(1,0);
+ sendTgtVel(2,0);
+ sendTgtVel(3,0);
+ sendTgtVel(4,0);
+ for(int i=1;i<= 4;i++){
+ sendCtrlEN(i);
+ }
+
+ wait(0.5);
+
+ sendOPModeT(1);
+ sendOPModeT(2);
+ sendOPModeT(3);
+ sendOPModeT(4);
+
+ dist1 = 0;
+
+ wait(3.0);
+ break;
+ }
+ /*--------------------------*/
+
+ /*--------------------------*/
+ //右方向に入力があった時
+ if(ActPos > Init_Pos + 2000){
+ sendProAcc(1,1000);
+ sendProAcc(2,1000);
+ sendProAcc(3,1000);
+ sendProAcc(4,1000);
+
+ sendProDec(1,1000);
+ sendProDec(2,1000);
+ sendProDec(3,1000);
+ sendProDec(4,1000);
+
+ //速度制御モード送信
+ sendOPModeV(1);
+ sendOPModeV(2);
+ sendOPModeV(3);
+ sendOPModeV(4);
+ //速度を指定
+ sendTgtVel(1,rpm);
+ sendTgtVel(2,rpm*(-1));
+ sendTgtVel(3,rpm*(-1));
+ sendTgtVel(4,rpm);
+ //指令値を送信
+ for(int i=1;i<= 4;i++){
+ sendCtrlEN(i);
+ }
+ //実行時間
+ wait(2.0);
+
+ //速度を指定
+ sendTgtVel(1,0);
+ sendTgtVel(2,0);
+ sendTgtVel(3,0);
+ sendTgtVel(4,0);
+ //指令値を送信
+ for(int i=1;i<= 4;i++){
+ sendCtrlEN(i);
+ }
+ //実行時間
+ wait(5.0);
+
+
+ //速度を指定
+ sendTgtVel(1,rpm*(-1));
+ sendTgtVel(2,rpm);
+ sendTgtVel(3,rpm);
+ sendTgtVel(4,rpm*(-1));
+ //指令値を送信
+ for(int i=1;i<= 4;i++){
+ sendCtrlEN(i);
+ }
+ //実行時間
+ wait(2.0);
+
+ //ブレーキ
+ sendTgtVel(1,0);
+ sendTgtVel(2,0);
+ sendTgtVel(3,0);
+ sendTgtVel(4,0);
+ for(int i=1;i<= 4;i++){
+ sendCtrlEN(i);
+ }
+ wait(0.5);
+
+ sendOPModeT(1);
+ sendOPModeT(2);
+ sendOPModeT(3);
+ sendOPModeT(4);
+
+ wait(4.0);
+ break;
+ }
+ /*--------------------------*/
+
+ /*--------------------------*/
+ //一定時間入力がない場合
+ if(Time > Standby_Time){
+ sendProAcc(1,5000);
+ sendProAcc(2,5000);
+ sendProAcc(3,5000);
+ sendProAcc(4,5000);
+
+ sendProDec(1,5000);
+ sendProDec(2,5000);
+ sendProDec(3,5000);
+ sendProDec(4,5000);
+
+ //速度制御モード送信
+ sendOPModeV(1);
+ sendOPModeV(2);
+ sendOPModeV(3);
+ sendOPModeV(4);
+
+ //速度を指定
+ sendTgtVel(1,rpm);
+ sendTgtVel(2,rpm);
+ sendTgtVel(3,rpm);
+ sendTgtVel(4,rpm);
+ //指令値を送信
+ for(int i=1;i<= 4;i++){
+ sendCtrlEN(i);
+ }
+ //実行時間
+ wait(1.0);
+
+ //速度を指定
+ sendTgtVel(1,rpm*(-1));
+ sendTgtVel(2,rpm*(-1));
+ sendTgtVel(3,rpm*(-1));
+ sendTgtVel(4,rpm*(-1));
+ //指令値を送信
+ for(int i=1;i<= 4;i++){
+ sendCtrlEN(i);
+ }
+ //実行時間
+ wait(1.3);
+
+ //ブレーキ
+ sendTgtVel(1,0);
+ sendTgtVel(2,0);
+ sendTgtVel(3,0);
+ sendTgtVel(4,0);
+ for(int i=1;i<= 4;i++){
+ sendCtrlEN(i);
+ }
+
+ wait(0.5);
+
+ sendOPModeT(1);
+ sendOPModeT(2);
+ sendOPModeT(3);
+ sendOPModeT(4);
+
+ wait(5.0);
+ break;
+ }
+ /*--------------------------*/
+
+ }
+ wait(0.1);
+ }
+
+ /*
+ //ジグザグ
+ else if(Serialdata == 'j'){
+ int turn_count = 0;
+ p1 = 0;
+ i1 = 0;
+ d1 = 0;
+ error_before1 = 0;
+ error_now1 = 0;
+ feedback_val1 = 0;
+ integral1 = 0;
+ pid_sum1 = 0;
+
+ rpm1 = rpm;
+ rpm2 = rpm;
+ rpm3 = rpm;
+ rpm4 = rpm;
+
+ dist1 = 30;
+ dist2 = 30;
+ dist3 = 30;
+
+ sendProAcc(1,5000);
+ sendProAcc(2,5000);
+ sendProAcc(3,5000);
+ sendProAcc(4,5000);
+
+ sendProDec(1,5000);
+ sendProDec(2,5000);
+ sendProDec(3,5000);
+ sendProDec(4,5000);
+
+ //正面壁に近づく
+ while(!(dist1 <30 && dist1 >5)){
+ printf("phase1\r\n");
+ u1.start();
+ u2.start();
+ dist1 = u1.get_dist_cm();
+ dist2 = u2.get_dist_cm();
+ pc.printf("%ld %ld %ld ID1_%ld ID2_%ld ID3_%ld ID_4%ld\r\n",dist1,dist2,dist3,rpm1,rpm2,rpm3,rpm4);
+
+ //壁との角度をPID制御
+ feedback_val1 = (dist1 - dist2);
+
+ error_before1 = error_now1;
+ error_now1 = feedback_val1 - target_val1;
+ integral1 += (error_now1 + error_before1) / 2.0 * DELTA_T1;
+
+ p1 = Kp1 * error_now1;
+ i1 = Ki1 * integral1;
+ d1 = Kd1 * (error_now1 - error_before1) / DELTA_T1;
+
+ pid_sum1 = (p1 + i1 + d1);
+
+ //モータの回転数を更新
+ rpm1 -= pid_sum1;
+ rpm2 -= pid_sum1;
+ rpm3 += pid_sum1;
+ rpm4 += pid_sum1;
+
+ sendTgtVel(node1,rpm1);
+ sendTgtVel(node2,rpm2);
+ sendTgtVel(node3,rpm3*(-1));
+ sendTgtVel(node4,rpm4*(-1));
+ for(int i=1;i<= 4;i++){
+ sendCtrlEN(i);
+ }
+
+ //回転数フィルタ
+ if(rpm1 >= max_rpm){
+ rpm1 = max_rpm;
+ sendTgtVel(node1,rpm1*(-1));
+ sendCtrlEN(1);
+ }
+
+ if(rpm2 >= max_rpm){
+ rpm2 = max_rpm;
+ sendTgtVel(node2,rpm2);
+ sendCtrlEN(2);
+ }
+
+ if(rpm3 >= max_rpm){
+ rpm3 = max_rpm;
+ sendCtrlEN(3);
+ }
+
+ if(rpm4 >= max_rpm){
+ rpm4 = max_rpm;
+ sendTgtVel(node4,rpm4*(-1));
+ sendCtrlEN(4);
+ }
+
+
+ if(rpm1 <= min_rpm){
+ rpm1 = min_rpm;
+ sendTgtVel(node1,rpm1*(-1));
+ sendCtrlEN(1);
+ }
+
+ if(rpm2 <= min_rpm){
+ rpm2 = min_rpm;
+ sendTgtVel(node2,rpm2);
+ sendCtrlEN(2);
+ }
+
+ if(rpm3 <= min_rpm){
+ rpm3 = min_rpm;
+ sendTgtVel(node3,rpm3);
+ sendCtrlEN(3);
+ }
+
+ if(rpm4 <= min_rpm){
+ rpm4 = min_rpm;
+ sendTgtVel(node4,rpm4*(-1));
+ sendCtrlEN(4);
+ }
+
+ if(Serialdata == 'h'){
+ sendCtrlHL(node1);
+ sendCtrlHL(node2);
+ sendCtrlHL(node3);
+ sendCtrlHL(node4);
+ }
+
+
+ wait(0.01);
+ }
+
+ //u1,u2が一定以上壁から離れると終了
+ while(!(turn_count == 4)){
+
+ printf("phase2\r\n");
+
+ dist3 = 30;
+
+ //右端まで移動
+ //while(dist3 > 20){
+ while(!(dist3 < 30& dist3 >10)){
+ printf("phase3\r\n");
+ u1.start();
+ u2.start();
+ u3.start();
+
+ dist1 = u3.get_dist_cm();
+ dist2 = u3.get_dist_cm();
+ dist3 = u3.get_dist_cm();
+ pc.printf("%ld %ld %ld ID1_%ld ID2_%ld ID3_%ld ID_4%ld\r\n",dist1,dist2,dist3,rpm1,rpm2,rpm3,rpm4);
+
+ //壁との角度をPID制御
+ feedback_val1 = (dist1 - dist2);
+ error_before1 = error_now1;
+ error_now1 = feedback_val1 - target_val1;
+ integral1 += (error_now1 + error_before1) / 2.0 * DELTA_T1;
+
+ p1 = Kp1 * error_now1;
+ i1 = Ki1 * integral1;
+ d1 = Kd1 * (error_now1 - error_before1) / DELTA_T1;
+
+ pid_sum1 = (p1 + i1 + d1);
+
+ //モータの回転数を更新
+ rpm1 += pid_sum1;
+ rpm2 -= pid_sum1;
+ rpm3 -= pid_sum1;
+ rpm4 += pid_sum1;
+
+ //右移動
+ sendTgtVel(node1,rpm1*(-1));
+ sendTgtVel(node2,rpm2);
+ sendTgtVel(node3,rpm3);
+ sendTgtVel(node4,rpm4*(-1));
+ for(int i=1;i<= 4;i++){
+ sendCtrlEN(i);
+ }
+ //回転数フィルタ
+ if(rpm1 >= max_rpm){
+ rpm1 = max_rpm;
+ sendTgtVel(node1,rpm1*(-1));
+ sendCtrlEN(1);
+ }
+
+ if(rpm2 >= max_rpm){
+ rpm2 = max_rpm;
+ sendTgtVel(node2,rpm2);
+ sendCtrlEN(2);
+ }
+
+ if(rpm3 >= max_rpm){
+ rpm3 = max_rpm;
+ sendCtrlEN(3);
+ }
+
+ if(rpm4 >= max_rpm){
+ rpm4 = max_rpm;
+ sendTgtVel(node4,rpm4*(-1));
+ sendCtrlEN(4);
+ }
+
+
+ if(rpm1 <= min_rpm){
+ rpm1 = min_rpm;
+ sendTgtVel(node1,rpm1*(-1));
+ sendCtrlEN(1);
+ }
+
+ if(rpm2 <= min_rpm){
+ rpm2 = min_rpm;
+ sendTgtVel(node2,rpm2);
+ sendCtrlEN(2);
+ }
+
+ if(rpm3 <= min_rpm){
+ rpm3 = min_rpm;
+ sendTgtVel(node3,rpm3);
+ sendCtrlEN(3);
+ }
+
+ if(rpm4 <= min_rpm){
+ rpm4 = min_rpm;
+ sendTgtVel(node4,rpm4*(-1));
+ sendCtrlEN(4);
+ }
+
+ if(Serialdata == 'h'){
+ sendCtrlHL(node1);
+ sendCtrlHL(node2);
+ sendCtrlHL(node3);
+ sendCtrlHL(node4);
+ }
+
+
+ wait(0.01);
+ }
+
+ //下に少し移動
+
+ printf("phase4\r\n");
+
+ sendTgtVel(node1,rpm*(-1));
+ sendTgtVel(node2,rpm*(-1));
+ sendTgtVel(node3,rpm);
+ sendTgtVel(node4,rpm);
+
+ for(int i=1;i<= 4;i++){
+ sendCtrlEN(i);
+ }
+
+ turn_count += 1;
+
+ wait(0.5);
+
+
+ //左に移動
+ while(!(dist3 < 80 && dist3 >60)){
+ printf("phase5\r\n");
+ u1.start();
+ u2.start();
+ u3.start();
+ dist1 = u1.get_dist_cm();
+ dist2 = u2.get_dist_cm();
+ dist3 = u3.get_dist_cm();
+ pc.printf("%ld %ld %ld ID1_%ld ID2_%ld ID3_%ld ID_4%ld\r\n",dist1,dist2,dist3,rpm1,rpm2,rpm3,rpm4);
+
+ //壁との角度をPID制御
+ feedback_val1 = (dist1 - dist2);
+ error_before1 = error_now1;
+ error_now1 = feedback_val1 - target_val1;
+ integral1 += (error_now1 + error_before1) / 2.0 * DELTA_T1;
+
+ p1 = Kp1 * error_now1;
+ i1 = Ki1 * integral1;
+ d1 = Kd1 * (error_now1 - error_before1) / DELTA_T1;
+
+ pid_sum1 = (p1 + i1 + d1);
+
+ //モータの回転数を更新
+ rpm1 -= pid_sum1;
+ rpm2 += pid_sum1;
+ rpm3 += pid_sum1;
+ rpm4 -= pid_sum1;
+
+ //左移動
+ sendTgtVel(node1,rpm1);
+ sendTgtVel(node2,rpm2*(-1));
+ sendTgtVel(node3,rpm3*(-1));
+ sendTgtVel(node4,rpm4);
+ for(int i=1;i<= 4;i++){
+ sendCtrlEN(i);
+ }
+ //回転数フィルタ
+ if(rpm1 >= max_rpm){
+ rpm1 = max_rpm;
+ sendTgtVel(node1,rpm1*(-1));
+ sendCtrlEN(1);
+ }
+
+ if(rpm2 >= max_rpm){
+ rpm2 = max_rpm;
+ sendTgtVel(node2,rpm2);
+ sendCtrlEN(2);
+ }
+
+ if(rpm3 >= max_rpm){
+ rpm3 = max_rpm;
+ sendCtrlEN(3);
+ }
+
+ if(rpm4 >= max_rpm){
+ rpm4 = max_rpm;
+ sendTgtVel(node4,rpm4*(-1));
+ sendCtrlEN(4);
+ }
+
+
+ if(rpm1 <= min_rpm){
+ rpm1 = min_rpm;
+ sendTgtVel(node1,rpm1*(-1));
+ sendCtrlEN(1);
+ }
+
+ if(rpm2 <= min_rpm){
+ rpm2 = min_rpm;
+ sendTgtVel(node2,rpm2);
+ sendCtrlEN(2);
+ }
+
+ if(rpm3 <= min_rpm){
+ rpm3 = min_rpm;
+ sendTgtVel(node3,rpm3);
+ sendCtrlEN(3);
+ }
+
+ if(rpm4 <= min_rpm){
+ rpm4 = min_rpm;
+ sendTgtVel(node4,rpm4*(-1));
+ sendCtrlEN(4);
+ }
+
+ if(Serialdata == 'h'){
+ sendCtrlHL(node1);
+ sendCtrlHL(node2);
+ sendCtrlHL(node3);
+ sendCtrlHL(node4);
+ }
+
+ wait(0.01);
+ }
+
+ //下に少し移動
+
+ printf("phase6\r\n");
+
+
+ sendTgtVel(node1,rpm*(-1));
+ sendTgtVel(node2,rpm*(-1));
+ sendTgtVel(node3,rpm);
+ sendTgtVel(node4,rpm);
+ for(int i=1;i<= 4;i++){
+ sendCtrlEN(i);
+ }
+
+ turn_count += 1;
+
+ wait(0.5);
+
+ }
+
+
+ if(Serialdata == 'h'){
+ sendCtrlHL(node1);
+ sendCtrlHL(node2);
+ sendCtrlHL(node3);
+ sendCtrlHL(node4);
+ break;
+ }
+
+ wait(0.1);
+ }
+
+ }
+ */
+ //-------------------------------------------
+
+}
+
+
+
+
+//0x2F-6060-00-fd-//-//-//
+void sendOPModeT(int nodeID){
+ canmsgTx.id = 0x600+nodeID;
+ canmsgTx.len = 5; //Data Length
+ canmsgTx.data[0] = 0x2F;//|0Byte:40|1Byte:2F|2Byte:2B|4Byte:23|other:22|
+ canmsgTx.data[1] = 0x60;//Index LowByte
+ canmsgTx.data[2] = 0x60;//Index HighByte
+ canmsgTx.data[3] = 0x00;//sub-Index
+ canmsgTx.data[4] = 0xFD;//data:fd = "current Mode"
+ /*
+ canmsgTx.data[5] = 0x00;//data:(user value)
+ canmsgTx.data[6] = 0x00;//data:(user value)
+ canmsgTx.data[7] = 0x00;//data:(user value)
+ */
+ printCANTX(); //CAN送信データをPCに表示
+ canPort.write(canmsgTx);//CANでデータ送信
+ wait_ms(1);
+}
+
+
+//0x2F-6060-00-03-//-//-//
+void sendOPModeV(int nodeID){
+ canmsgTx.id = 0x600+nodeID;
+ canmsgTx.len = 5; //Data Length
+ canmsgTx.data[0] = 0x2F;//|0Byte:40|1Byte:2F|2Byte:2B|4Byte:23|other:22|
+ canmsgTx.data[1] = 0x60;//Index LowByte
+ canmsgTx.data[2] = 0x60;//Index HighByte
+ canmsgTx.data[3] = 0x00;//sub-Index
+ canmsgTx.data[4] = 0x03;//data:0x03 = "Profile Velocity Mode"
+ /*
+ canmsgTx.data[5] = 0x00;//data:(user value)
+ canmsgTx.data[6] = 0x00;//data:(user value)
+ canmsgTx.data[7] = 0x00;//data:(user value)
+ */
+ printCANTX(); //CAN送信データをPCに表示
+ canPort.write(canmsgTx);//CANでデータ送信
+ wait_ms(1);
+}
+
+//0x2B-6040-00-0000-//-//
+void sendCtrlRS(int nodeID){
+ canmsgTx.id = 0x600+nodeID;
+ canmsgTx.len = 6; //Data Length
+ canmsgTx.data[0] = 0x2B;//|0Byte:40|1Byte:2F|2Byte:2B|4Byte:23|other:22|
+ canmsgTx.data[1] = 0x40;//Index LowByte
+ canmsgTx.data[2] = 0x60;//Index HighByte
+ canmsgTx.data[3] = 0x00;//sub-Index
+ canmsgTx.data[4] = 0x80;//data:0x00"80" = "Controlword(Shutdown)"
+ canmsgTx.data[5] = 0x00;//data:0x"00"80
+ /*
+ canmsgTx.data[6] = 0x00;//data:(user value)
+ canmsgTx.data[7] = 0x00;//data:(user value)
+ */
+ printCANTX(); //CAN送信データをPCに表示
+ canPort.write(canmsgTx);//CANでデータ送信
+ wait_ms(1);
+}
+
+
+//0x2B-6040-00-0006-//-//
+void sendCtrlSD(int nodeID){
+ canmsgTx.id = 0x600+nodeID;
+ canmsgTx.len = 6; //Data Length
+ canmsgTx.data[0] = 0x2B;//|0Byte:40|1Byte:2F|2Byte:2B|4Byte:23|other:22|
+ canmsgTx.data[1] = 0x40;//Index LowByte
+ canmsgTx.data[2] = 0x60;//Index HighByte
+ canmsgTx.data[3] = 0x00;//sub-Index
+ canmsgTx.data[4] = 0x06;//data:0x00"06" = "Controlword(Shutdown)"
+ canmsgTx.data[5] = 0x00;//data:0x"00"06
+ /*
+ canmsgTx.data[6] = 0x00;//data:(user value)
+ canmsgTx.data[7] = 0x00;//data:(user value)
+ */
+ printCANTX(); //CAN送信データをPCに表示
+ canPort.write(canmsgTx);//CANでデータ送信
+ wait_ms(1);
+}
+
+//0x2B-6040-00-000F-//-//
+void sendCtrlEN(int nodeID){
+ canmsgTx.id = 0x600+nodeID;
+ canmsgTx.len = 6; //Data Length
+ canmsgTx.data[0] = 0x2B;//|0Byte:40|1Byte:2F|2Byte:2B|4Byte:23|other:22|
+ canmsgTx.data[1] = 0x40;//Index LowByte
+ canmsgTx.data[2] = 0x60;//Index HighByte
+ canmsgTx.data[3] = 0x00;//sub-Index
+ canmsgTx.data[4] = 0x0F;//data:0x00"0F" = "Controlword(Enable)"
+ canmsgTx.data[5] = 0x00;//data:0x"00"0F
+ /*
+ canmsgTx.data[6] = 0x00;//data:(user value)
+ canmsgTx.data[7] = 0x00;//data:(user value)
+ */
+ //printCANTX(); //CAN送信データをPCに表示
+ canPort.write(canmsgTx);//CANでデータ送信
+ wait_ms(1);
+}
+
+//0x2B-6040-00-000B-//-//
+void sendCtrlQS(int nodeID){
+ canmsgTx.id = 0x600+nodeID;
+ canmsgTx.len = 6; //Data Length
+ canmsgTx.data[0] = 0x2B;//|0Byte:40|1Byte:2F|2Byte:2B|4Byte:23|other:22|
+ canmsgTx.data[1] = 0x40;//Index LowByte
+ canmsgTx.data[2] = 0x60;//Index HighByte
+ canmsgTx.data[3] = 0x00;//sub-Index
+ canmsgTx.data[4] = 0x0B;//data:0x00"0B" = "Quick Stop"
+ canmsgTx.data[5] = 0x00;//data:0x"00"0B
+ /*
+ canmsgTx.data[6] = 0x00;//data:(user value)
+ canmsgTx.data[7] = 0x00;//data:(user value)
+ */
+ printCANTX(); //CAN送信データをPCに表示
+ canPort.write(canmsgTx);//CANでデータ送信
+ wait_ms(1);
+}
+
+//0x2B-6040-00-010F-//-//
+void sendCtrlHL(int nodeID){
+ canmsgTx.id = 0x600+nodeID;
+ canmsgTx.len = 6; //Data Length
+ canmsgTx.data[0] = 0x2B;//|0Byte:40|1Byte:2F|2Byte:2B|4Byte:23|other:22|
+ canmsgTx.data[1] = 0x40;//Index LowByte
+ canmsgTx.data[2] = 0x60;//Index HighByte
+ canmsgTx.data[3] = 0x00;//sub-Index
+ canmsgTx.data[4] = 0x0F;//data:0x01"0F" = "Halt"
+ canmsgTx.data[5] = 0x01;//data:0x"01"0F
+ /*
+ canmsgTx.data[6] = 0x00;//data:(user value)
+ canmsgTx.data[7] = 0x00;//data:(user value)
+ */
+ printCANTX(); //CAN送信データをPCに表示
+ canPort.write(canmsgTx);//CANでデータ送信
+ wait_ms(1);
+}
+
+//0x2B-60FF-00-[user data(4Byte)]
+void sendTgtTrq(int nodeID,int trq){
+ //pc.printf("%dmA0x%08x\r\n",trq,trq); //回転数送信データの表示
+ canmsgTx.id = 0x600+nodeID;
+ canmsgTx.len = 6; //Data Length
+ canmsgTx.data[0] = 0x2B;//|0Byte:40|1Byte:2F|2Byte:2B|4Byte:23|other:22|
+ canmsgTx.data[1] = 0x30;//Index LowByte 71
+ canmsgTx.data[2] = 0x20;//Index HighByte 60
+ canmsgTx.data[3] = 0x00;//sub-Index
+ //下位から1Byteずつdataに格納
+ if(trq<0){
+ trq=0xFFFF+trq+1;
+ }
+
+ //pc.printf("iii%d\r\n",trq);
+ //canmsgTx.data[7]=((trq>>24)&0xFF);
+ //canmsgTx.data[6]=((trq>>16)&0xFF);
+
+ canmsgTx.data[5]=((trq>>8)&0xFF);
+ canmsgTx.data[4]=((trq>>0)&0xFF);
+ //printCANTX(); //CAN送信データをPCに表示
+ canPort.write(canmsgTx);//CANでデータ送信
+ wait_ms(2);
+ //send Enable
+ //pc.printf("Send Enable Command\r\n");
+ //sendCtrlEN(nodeID);
+ //wait(0.5);
+}
+
+
+
+
+//0x2B-60FF-00-[user data(4Byte)]
+void sendTgtVel(int nodeID,int rpm){
+ //pc.printf("%drpm|0x%08x\r\n",rpm,rpm); //回転数送信データの表示
+ canmsgTx.id = 0x600+nodeID;
+ canmsgTx.len = 8; //Data Length
+ canmsgTx.data[0] = 0x23;//|0Byte:40|1Byte:2F|2Byte:2B|4Byte:23|other:22|
+ canmsgTx.data[1] = 0xFF;//Index LowByte
+ canmsgTx.data[2] = 0x60;//Index HighByte
+ canmsgTx.data[3] = 0x00;//sub-Index
+ //下位から1Byteずつdataに格納
+
+ //pc.printf("%d\r\n",rpm);
+ if(rpm<0){
+ rpm=0xFFFFFFFF+rpm+1;
+ }
+ canmsgTx.data[7]=((rpm>>24)&0xFF);
+ canmsgTx.data[6]=((rpm>>16)&0xFF);
+ canmsgTx.data[5]=((rpm>>8)&0xFF);
+ canmsgTx.data[4]=((rpm>>0)&0xFF);
+
+ //printCANTX(); //CAN送信データをPCに表示
+ canPort.write(canmsgTx);//CANでデータ送信
+ wait_ms(1);
+
+}
+
+void readActVel(int nodeID){
+ //値が欲しいobjectのアドレスを送る
+ canmsgTx.id = 0x600+nodeID;
+ canmsgTx.len = 4; //Data Length
+ canmsgTx.data[0] = 0x40;//|0Byte:40|
+ canmsgTx.data[1] = 0x6C;//Index LowByte
+ canmsgTx.data[2] = 0x60;//Index HighByte
+ canmsgTx.data[3] = 0x00;//sub-Index
+ canPort.write(canmsgTx);
+ wait_ms(1);
+}
+
+void readActPos(int nodeID){
+ //値が欲しいobjectのアドレスを送る
+ canmsgTx.id = 0x600+nodeID;
+ canmsgTx.len = 4; //Data Length
+ canmsgTx.data[0] = 0x40;//|0Byte:40|
+ canmsgTx.data[1] = 0x64;//Index LowByte
+ canmsgTx.data[2] = 0x60;//Index HighByte
+ canmsgTx.data[3] = 0x00;//sub-Index
+ canPort.write(canmsgTx);
+ wait_ms(1);
+}
+
+//加速度指定
+void sendProAcc(int nodeID,int rpm){
+ if(rpm < 0){
+ rpm += 0xFFFFFFFF;
+ }
+// pc.printf("%drpm|0x%08x\r\n",rpm,rpm); //回転数送信データの表示
+ canmsgTx.id = 0x600+nodeID;
+ canmsgTx.len = 8; //Data Length
+ canmsgTx.data[0] = 0x23;//|0Byte:40|1Byte:2F|2Byte:2B|4Byte:23|other:22|
+ canmsgTx.data[1] = 0x83;//Index LowByte
+ canmsgTx.data[2] = 0x60;//Index HighByte
+ canmsgTx.data[3] = 0x00;//sub-Index
+ //下位から1Byteずつdataに格納
+ canmsgTx.data[4] = (rpm >> 0) & 0xFF;
+ canmsgTx.data[5] = (rpm >> 8) & 0xFF;
+ canmsgTx.data[6] = (rpm >> 16) & 0xFF;
+ canmsgTx.data[7] = (rpm >> 24) & 0xFF;
+// printCANTX(); //CAN送信データをPCに表示
+ canPort.write(canmsgTx);//CANでデータ送信
+ wait(0.01);
+ //send Enable
+// pc.printf("Send Enable Command\r\n");
+ sendCtrlEN(nodeID);
+ wait(0.01);
+}
+
+//減速度指定
+void sendProDec(int nodeID,int rpm){
+ if(rpm < 0){
+ rpm += 0xFFFFFFFF;
+ }
+// pc.printf("%drpm|0x%08x\r\n",rpm,rpm); //回転数送信データの表示
+ canmsgTx.id = 0x600+nodeID;
+ canmsgTx.len = 8; //Data Length
+ canmsgTx.data[0] = 0x23;//|0Byte:40|1Byte:2F|2Byte:2B|4Byte:23|other:22|
+ canmsgTx.data[1] = 0x84;//Index LowByte
+ canmsgTx.data[2] = 0x60;//Index HighByte
+ canmsgTx.data[3] = 0x00;//sub-Index
+ //下位から1Byteずつdataに格納
+ canmsgTx.data[4] = (rpm >> 0) & 0xFF;
+ canmsgTx.data[5] = (rpm >> 8) & 0xFF;
+ canmsgTx.data[6] = (rpm >> 16) & 0xFF;
+ canmsgTx.data[7] = (rpm >> 24) & 0xFF;
+// printCANTX(); //CAN送信データをPCに表示
+ canPort.write(canmsgTx);//CANでデータ送信
+ wait(0.01);
+ //send Enable
+// pc.printf("Send Enable Command\r\n");
+ sendCtrlEN(nodeID);
+ wait(0.01);
+}
+
+
+//送信データの表示
+void printCANTX(void){
+ //0x canID|Byte0|Byte1|Byte2|Byte3|Byte4|Byte5|Byte6|Byte7|
+ pc.printf("0x%3x|",canmsgTx.id);
+ for(char i=0;i < canmsgTx.len;i++){
+ pc.printf("%02x|",canmsgTx.data[i]);
+ }
+ //pc.printf("\r\n");
+}
+
+//受信データの表示
+
+void printCANRX(void){
+ //0x canID|Byte0|Byte1|Byte2|Byte3|Byte4|Byte5|Byte6|Byte7|
+ //pc.printf("0x%3x|",canmsgRx.id);
+ for(char i=0;i < canmsgRx.len;i++){
+ //pc.printf("%02x|",canmsgRx.data[i]);
+ }
+ pc.printf("\r\n");
+}
+
+void CANdataRX(void){
+ canPort.read(canmsgRx);
+ printCANRX();
+}
+
+void SerialRX(void){
+ Serialdata = pc.getc();
+ //pc.printf("%c\r\n",Serialdata);
+}