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

Dependencies:   mbed URF MD_MDDS30_oit_ ros_lib_melodic

Committer:
yakifrog
Date:
Wed May 04 15:52:12 2022 +0000
Revision:
2:87caac24d995
Parent:
1:f6a9a3a7455d
ROSROSOROOAAAA;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
akihiron 0:450a7208c682 1 #include "mbed.h"
akihiron 0:450a7208c682 2 #include "MDDS30_oit.h"
akihiron 0:450a7208c682 3 #include "URF.h"
yakifrog 1:f6a9a3a7455d 4 #include <ros.h>
yakifrog 1:f6a9a3a7455d 5 #include <geometry_msgs/Twist.h>
yakifrog 1:f6a9a3a7455d 6 #include <std_msgs/Float32.h>
yakifrog 1:f6a9a3a7455d 7 #include <sensor_msgs/Joy.h>
yakifrog 1:f6a9a3a7455d 8 #include <sensor_msgs/LaserScan.h>
yakifrog 1:f6a9a3a7455d 9 #include <std_msgs/String.h>
akihiron 0:450a7208c682 10
yakifrog 1:f6a9a3a7455d 11 ros::NodeHandle nh;
akihiron 0:450a7208c682 12
yakifrog 1:f6a9a3a7455d 13 URF usdRight(D6); // 右側に取り付ける超音波センサー
yakifrog 1:f6a9a3a7455d 14 URF usdLeft(D8); // 左側に取り付ける超音波センサー
yakifrog 1:f6a9a3a7455d 15
yakifrog 1:f6a9a3a7455d 16 Ticker update; // よくわからないけど、「24回/秒」処理されるってことかしら。
akihiron 0:450a7208c682 17
akihiron 0:450a7208c682 18 DigitalOut led(LED1);
akihiron 0:450a7208c682 19 DigitalOut led2(PC_4);
yakifrog 1:f6a9a3a7455d 20 DigitalIn btn(USER_BUTTON); // USER_BUTTONってどこだろ
akihiron 0:450a7208c682 21 MDDS30oit MD1(PC_10, PC_11); //left:モーター番号1(右後輪)、right:モーター番号2(左後輪)
akihiron 0:450a7208c682 22 MDDS30oit MD2(PA_0, PA_1); //left:モーター番号3(右前輪)、right:モーター番号4(左前輪)
akihiron 0:450a7208c682 23
yakifrog 1:f6a9a3a7455d 24
yakifrog 1:f6a9a3a7455d 25 // --- 初期設定 --- //
yakifrog 1:f6a9a3a7455d 26 double speed_ang = 0.0;
yakifrog 1:f6a9a3a7455d 27 double speed_lin = 0.0;
yakifrog 1:f6a9a3a7455d 28
yakifrog 1:f6a9a3a7455d 29 double w_r = 0.0;
yakifrog 1:f6a9a3a7455d 30 double w_l = 0.0;
yakifrog 1:f6a9a3a7455d 31
yakifrog 1:f6a9a3a7455d 32 float duty[4]={0.0f};
yakifrog 1:f6a9a3a7455d 33 // --------------- //
yakifrog 1:f6a9a3a7455d 34
yakifrog 1:f6a9a3a7455d 35
yakifrog 1:f6a9a3a7455d 36 // --- ROS --- //
yakifrog 1:f6a9a3a7455d 37 std_msgs::String str_msg;
yakifrog 1:f6a9a3a7455d 38 ros::Publisher chatter("chatter", &str_msg); // マイコンからROSにデータを飛ばすことができるかを試す実験
yakifrog 1:f6a9a3a7455d 39 char hello[13] = "hello world!";
yakifrog 1:f6a9a3a7455d 40 // ----------- //
yakifrog 1:f6a9a3a7455d 41
yakifrog 1:f6a9a3a7455d 42
yakifrog 1:f6a9a3a7455d 43 // 超音波センサー
akihiron 0:450a7208c682 44 void inter(void)
akihiron 0:450a7208c682 45 {
akihiron 0:450a7208c682 46 usdRight.send();
akihiron 0:450a7208c682 47 usdLeft.send();
akihiron 0:450a7208c682 48 }
akihiron 0:450a7208c682 49
akihiron 0:450a7208c682 50
yakifrog 1:f6a9a3a7455d 51 // 四輪オムニのPWM値出し
yakifrog 1:f6a9a3a7455d 52 void Yonrin(float x,float y){
akihiron 0:450a7208c682 53 duty[0] =-x/sqrtf(2)+y/sqrtf(2);
akihiron 0:450a7208c682 54 duty[1] =-x/sqrtf(2)-y/sqrtf(2);
akihiron 0:450a7208c682 55 duty[2] = x/sqrtf(2)-y/sqrtf(2);
akihiron 0:450a7208c682 56 duty[3] = x/sqrtf(2)+y/sqrtf(2);
akihiron 0:450a7208c682 57
yakifrog 1:f6a9a3a7455d 58 MD1.left(duty[0]);
yakifrog 1:f6a9a3a7455d 59 MD1.right(duty[1]);
yakifrog 1:f6a9a3a7455d 60 MD2.left(duty[2]);
yakifrog 1:f6a9a3a7455d 61 MD2.right(duty[3]);
yakifrog 1:f6a9a3a7455d 62 wait(0.01);
akihiron 0:450a7208c682 63 }
akihiron 0:450a7208c682 64
yakifrog 1:f6a9a3a7455d 65
yakifrog 1:f6a9a3a7455d 66 // SLAMで経路計画した結果、送られてくる移動方向の入力を受け取って機体を制御する関数
yakifrog 1:f6a9a3a7455d 67 void slamControl(const geometry_msgs::Twist& msg){
yakifrog 1:f6a9a3a7455d 68 // cmd_velを取得して制御
yakifrog 1:f6a9a3a7455d 69
yakifrog 1:f6a9a3a7455d 70 speed_ang = 1 - msg.angular.z; // 左右 (出力が1になると、一気に加速してしまうので1よりも小さくなってほしいために調整)
yakifrog 1:f6a9a3a7455d 71 speed_lin = 1 - msg.linear.x; // 上下
yakifrog 1:f6a9a3a7455d 72 w_r = -0.25f * speed_ang; // これも手動で調整した結果
yakifrog 1:f6a9a3a7455d 73 w_l = 0.25f * speed_lin;
yakifrog 1:f6a9a3a7455d 74
yakifrog 1:f6a9a3a7455d 75 Yonrin(w_l, w_r); // 上下,左右
akihiron 0:450a7208c682 76 }
akihiron 0:450a7208c682 77
yakifrog 1:f6a9a3a7455d 78
yakifrog 1:f6a9a3a7455d 79 // PS4などのコントローラで機体を制御する関数
yakifrog 1:f6a9a3a7455d 80 void joyControl(const sensor_msgs::Joy& joy){
yakifrog 1:f6a9a3a7455d 81 // axes[0]:Lスティック(左右), axes[1]:Lスティック(上下)
yakifrog 1:f6a9a3a7455d 82 Yonrin(joy.axes[1] * 0.23f, joy.axes[0] * (-0.23f));
yakifrog 1:f6a9a3a7455d 83 }
yakifrog 1:f6a9a3a7455d 84
yakifrog 1:f6a9a3a7455d 85
yakifrog 1:f6a9a3a7455d 86 // LiDARで障害物を検知して機体を制御する関数
yakifrog 1:f6a9a3a7455d 87 void lidarControl(const sensor_msgs::LaserScan& lidar){
yakifrog 1:f6a9a3a7455d 88 if (lidar.range_min >= 0.1f && lidar.range_max <= 0.5f){ // 0.1m以上〜0.5m以下の場所に障害物がある場合、停止。
yakifrog 1:f6a9a3a7455d 89 while(1){
yakifrog 1:f6a9a3a7455d 90 Yonrin(0, 0);
yakifrog 1:f6a9a3a7455d 91 if (lidar.range_max > 0.5f){ // 障害物が0.5mよりも遠くにならないと、抜け出せないループ。
yakifrog 1:f6a9a3a7455d 92 break;
yakifrog 1:f6a9a3a7455d 93 }
yakifrog 1:f6a9a3a7455d 94 }
akihiron 0:450a7208c682 95 }
akihiron 0:450a7208c682 96 }
akihiron 0:450a7208c682 97
yakifrog 1:f6a9a3a7455d 98
yakifrog 1:f6a9a3a7455d 99 // --- ROS --- //
yakifrog 1:f6a9a3a7455d 100 ros::Subscriber<geometry_msgs::Twist> sub("cmd_vel", &slamControl); // SLAM データを取得したら関数が呼び出される仕組み
yakifrog 1:f6a9a3a7455d 101 ros::Subscriber<sensor_msgs::Joy> sub2("joy", &joyControl); // PS4 同上
yakifrog 1:f6a9a3a7455d 102 //ros::Subscriber<sensor_msgs::LaserScan> sub3("scan", &lidarCb); // LiDARの制御は、Bufferサイズの関係でバグって今は使えない(単に送る情報量が多すぎる)
yakifrog 1:f6a9a3a7455d 103 // ----------- //
yakifrog 1:f6a9a3a7455d 104
akihiron 0:450a7208c682 105
yakifrog 1:f6a9a3a7455d 106 int main(){
yakifrog 1:f6a9a3a7455d 107 //setup();
yakifrog 1:f6a9a3a7455d 108 nh.initNode(); // ノードを初期化
yakifrog 1:f6a9a3a7455d 109 nh.getHardware()->setBaud(57600);
yakifrog 1:f6a9a3a7455d 110 nh.advertise(chatter); // マイコンからROSにデータ送信するために必要な認証?のようなもの。(道を作っている)
yakifrog 1:f6a9a3a7455d 111 nh.subscribe(sub); // ROSからデータ取得
yakifrog 1:f6a9a3a7455d 112 nh.subscribe(sub2); // ROSからデータ取得
yakifrog 1:f6a9a3a7455d 113 //nh.subscribe(sub3);
akihiron 0:450a7208c682 114
yakifrog 1:f6a9a3a7455d 115 str_msg.data = hello;
yakifrog 1:f6a9a3a7455d 116 chatter.publish( &str_msg ); // ここで実際にROSにデータを送信している
yakifrog 1:f6a9a3a7455d 117
yakifrog 1:f6a9a3a7455d 118
yakifrog 1:f6a9a3a7455d 119 //void loop();
yakifrog 1:f6a9a3a7455d 120 while (1){
akihiron 0:450a7208c682 121 int dataRight = usdRight.read(mm);
akihiron 0:450a7208c682 122 int dataLeft = usdLeft.read(mm);
yakifrog 1:f6a9a3a7455d 123 nh.spinOnce(); // ROSはノードごとで処理をしているため、その処理を繰り返すためのオマジナイ
yakifrog 1:f6a9a3a7455d 124 wait_ms(10);
akihiron 0:450a7208c682 125 }
akihiron 0:450a7208c682 126 }