ROSでR2の足回りを動かせれるようにしたやつです。 使えるのは今のところ、小谷(私)しかいませんが一応。

Dependencies:   mbed URF MD_MDDS30_oit_ ros_lib_melodic

Revision:
1:f6a9a3a7455d
Parent:
0:450a7208c682
--- a/main.cpp	Tue May 03 08:02:58 2022 +0000
+++ b/main.cpp	Wed May 04 15:41:36 2022 +0000
@@ -1,153 +1,126 @@
 #include "mbed.h"
-#include "CAN.h"
-#include "PS4_Controller.h"
 #include "MDDS30_oit.h"
 #include "URF.h"
-
-PS4_controller PS4(PC_12,PD_2);
-
-Serial pc(USBTX, USBRX, 115200);
+#include <ros.h>
+#include <geometry_msgs/Twist.h>
+#include <std_msgs/Float32.h>
+#include <sensor_msgs/Joy.h>
+#include <sensor_msgs/LaserScan.h>
+#include <std_msgs/String.h>
 
-URF usdRight(D6);
-URF usdLeft(D8);
+ros::NodeHandle nh;
 
-Ticker update;
+URF usdRight(D6); // 右側に取り付ける超音波センサー
+URF usdLeft(D8);  // 左側に取り付ける超音波センサー
+
+Ticker update; // よくわからないけど、「24回/秒」処理されるってことかしら。
 
 DigitalOut led(LED1);
 DigitalOut led2(PC_4);
- 
-DigitalIn btn(USER_BUTTON);
+DigitalIn btn(USER_BUTTON); // USER_BUTTONってどこだろ
 MDDS30oit MD1(PC_10, PC_11);  //left:モーター番号1(右後輪)、right:モーター番号2(左後輪)
 MDDS30oit MD2(PA_0, PA_1);  //left:モーター番号3(右前輪)、right:モーター番号4(左前輪)
 
+
+// --- 初期設定 --- //
+double speed_ang = 0.0;
+double speed_lin = 0.0;
+
+double w_r = 0.0;
+double w_l = 0.0;
+
+float duty[4]={0.0f};
+// --------------- //
+
+
+// --- ROS --- //
+std_msgs::String str_msg;
+ros::Publisher chatter("chatter", &str_msg); // マイコンからROSにデータを飛ばすことができるかを試す実験
+char hello[13] = "hello world!"; 
+// ----------- //
+
+
+// 超音波センサー
 void inter(void)
 {
     usdRight.send();
     usdLeft.send();
 }
 
-int i;
-int right = 0, left = 0;
-float duty[4]={0.0f};
 
-void Yonrin(float x,float y)       //四輪オムニのpwm値出し
-{
+// 四輪オムニのPWM値出し
+void Yonrin(float x,float y){
     duty[0] =-x/sqrtf(2)+y/sqrtf(2);
     duty[1] =-x/sqrtf(2)-y/sqrtf(2);
     duty[2] = x/sqrtf(2)-y/sqrtf(2);
     duty[3] = x/sqrtf(2)+y/sqrtf(2);
-    //pc.printf("a=%f, b=%f, c=%f, d=%f\r\n",duty[0],duty[1],duty[2],duty[3]);
         
-        MD1.left(duty[0]);
-        MD1.right(duty[1]);
-        MD2.left(duty[2]);
-        MD2.right(duty[3]);
-        wait(0.01);
+    MD1.left(duty[0]);
+    MD1.right(duty[1]);
+    MD2.left(duty[2]);
+    MD2.right(duty[3]);
+    wait(0.01);
 }
 
-void Yonrin(float x)
-{
-        //pc.printf("senkai = %f\r\n",x);
-        
-        MD1.left(x);
-        MD1.right(x);
-        MD2.left(x);
-        MD2.right(x);
-        
-        wait(0.01);
+
+// SLAMで経路計画した結果、送られてくる移動方向の入力を受け取って機体を制御する関数
+void slamControl(const geometry_msgs::Twist& msg){
+  // cmd_velを取得して制御
+
+  speed_ang = 1 - msg.angular.z; // 左右 (出力が1になると、一気に加速してしまうので1よりも小さくなってほしいために調整)
+  speed_lin = 1 - msg.linear.x; // 上下
+  w_r = -0.25f * speed_ang; // これも手動で調整した結果
+  w_l = 0.25f * speed_lin;
+  
+  Yonrin(w_l, w_r); // 上下,左右
 }
 
-void Yonrin(int mode)
-{
-    switch(mode) {
-        case 0:
-        MD1.left(0);
-        MD1.right(0);
-        MD2.left(0);
-        MD2.right(0);
+
+// PS4などのコントローラで機体を制御する関数
+void joyControl(const sensor_msgs::Joy& joy){
+    // axes[0]:Lスティック(左右), axes[1]:Lスティック(上下)
+    Yonrin(joy.axes[1] * 0.23f, joy.axes[0] * (-0.23f));
+}
+
+
+// LiDARで障害物を検知して機体を制御する関数
+void lidarControl(const sensor_msgs::LaserScan& lidar){
+    if (lidar.range_min >= 0.1f && lidar.range_max <= 0.5f){ // 0.1m以上〜0.5m以下の場所に障害物がある場合、停止。
+        while(1){
+            Yonrin(0, 0);
+            if (lidar.range_max > 0.5f){ // 障害物が0.5mよりも遠くにならないと、抜け出せないループ。
+                break;
+            }
+        }
     }
 }
 
-int main(){
-    
-    wait_ms(100);
-    
-    PS4.send_UNO(1);
+
+// --- ROS --- //
+ros::Subscriber<geometry_msgs::Twist> sub("cmd_vel", &slamControl); // SLAM データを取得したら関数が呼び出される仕組み
+ros::Subscriber<sensor_msgs::Joy> sub2("joy", &joyControl); // PS4 同上
+//ros::Subscriber<sensor_msgs::LaserScan> sub3("scan", &lidarCb); // LiDARの制御は、Bufferサイズの関係でバグって今は使えない(単に送る情報量が多すぎる)
+// ----------- //
+
 
-    while(!PS4.connect()){
-        pc.printf("1");
-        led=!led;
-        PS4.read_PAD();
-        pc.printf("2");
-        wait_ms(500);
-    }
-    led = 1;
+int main(){
+    //setup();
+    nh.initNode(); // ノードを初期化
+    nh.getHardware()->setBaud(57600);
+    nh.advertise(chatter); // マイコンからROSにデータ送信するために必要な認証?のようなもの。(道を作っている)
+    nh.subscribe(sub); // ROSからデータ取得
+    nh.subscribe(sub2); // ROSからデータ取得
+    //nh.subscribe(sub3);
     
-    update.attach(&inter, 0.06);
-
-    while(1){
+    str_msg.data = hello;
+    chatter.publish( &str_msg ); // ここで実際にROSにデータを送信している
+    
+    
+    //void loop();
+    while (1){
         int dataRight = usdRight.read(mm);
         int dataLeft = usdLeft.read(mm);
-        pc.printf("Left:%d, Right:%d\n", dataLeft, dataRight);
-        //pc.printf("right: %d, left: %d\n", dataRight, dataLeft);
-
-        //right = 0;  //機体の右側に障害物なし
-        //left = 0;   //機体の左側に障害物なし
-
-        PS4.read_PAD();
-        if(PS4.button(PS))PS4.disconnect();
-        if(PS4.connect()){
-            if(PS4.button(R1)==1){                
-                if(PS4.analog(PS_LX)<100||PS4.analog(PS_LX)>146||PS4.analog(PS_LY)<100||PS4.analog(PS_LY)>146){
-                float x_duty = ((PS4.analog(PS_LX)-128.0f)/127.0f)*0.7f;
-                float y_duty = -((PS4.analog(PS_LY)-128.0f)/127.0f)*0.7f;
-                //pc.printf("x_duty=%f y_duty=%f\r\n", x_duty, y_duty);
-                Yonrin(x_duty, y_duty);
-                /*wait(1.0);
-                Yonrin(0);*/
-                }
-                else if(PS4.analog(PS_R2)>10){
-                    float x=-((PS4.analog(PS_R2)/255.0f))*0.7f;
-                    Yonrin(x);
-                }
-                else if(PS4.analog(PS_L2)>10){
-                    float x=((PS4.analog(PS_L2)/255.0f))*0.7f;
-                    Yonrin(x);
-                }
-                else if(PS4.button(UP)==1){
-                    Yonrin(0,0.5f);
-                }
-                else if(PS4.button(DOWN)==1){
-                    Yonrin(0,-0.5f);
-                }
-                else if(PS4.button(RIGHT)==1){
-                    if (dataRight >= 400){
-                        Yonrin(-0.5f,0);
-                    }
-                    else{
-                        if (dataRight <= 400 && dataRight >= 200){
-                            Yonrin(-0.3f, 0);
-                       }
-                    }
-                }
-                else if(PS4.button(LEFT)==1){
-                    if (dataLeft >= 400){
-                        Yonrin(0.5f,0);
-                    }else{
-                        if (dataLeft <= 400 && dataLeft >= 200){
-                            Yonrin(0.3f, 0);
-                        }
-                    }
-                    
-                }
-                else Yonrin(0);
-            }
-            else Yonrin(0);
-        }
-        else Yonrin(0);
+        nh.spinOnce(); // ROSはノードごとで処理をしているため、その処理を繰り返すためのオマジナイ
+        wait_ms(10);
     }
-    /*if(PS4.button(PS)){
-        PS4.disconnect();
-    }
-    Yonrin(0);*/
 }
\ No newline at end of file