ROS1 授業備忘録 【追記中】



# 環境

- MacBookPro14-2021(M1Pro-16GB)
- Ubuntu18.04.6 LTS Server-Arm64(Parallels Desktop)
- Kubuntus-Desktop
- ROS1: melodic

手順はホームディレクトリとカレントディレクトリ併用で記載しています。

https://26gram.com/directory-meaning

# 手順


```bash:Ubuntu18.04.6 LTSへのROS1(melodic)のセットアップ手順
# ROSリポジトリ追加
sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
sudo apt -y install curl
curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | sudo apt-key add -

# apt update
sudo apt -y update
sudo apt -y upgrade

# ROS1 melodic インストール
sudo apt -y install ros-melodic-desktop-full python3-rosdep

sudo rosdep init
rosdep update

# ターミナル起動時に読み込まれるように設定
echo "source  /opt/ros/melodic/setup.bash" >> ~/.bashrc
source ~/.bashrc

# catkinの設定
mkdir -p ~/ros1_ws/src
cd ~/ros1_ws
catkin_make
echo "source ~/ros1_ws/devel/setup.bash" >> ~/.bashrc
source ~/.bashrc
```


# catkinチュートリアルのビルド?

```bash:catkinチュートリアルの作成とビルド手順
cd ~/ros1_ws/src/
# std_msgs, roscpp, という依存パッケージを一緒に指定
catkin_create_pkg beginner_tutorials std_msgs roscpp

# beginner_tutorials ディレクトリが作成されたか確認し移動
ls
cd ~/ros1_ws/src/beginner_tutorials/src/

# プログラムとCMakeListsにビルド手順を記述
vim talker.cpp
vim listener.cpp
# vim ~/ros1_ws/src/beginner_tutorials/src/talker.cpp
# vim ~/ros1_ws/src/beginner_tutorials/src/listener.cpp

# 一段上のディレクトリにある`CMakeLists.txt`へ追記する
vim ../CMakeLists.txt
# vim ~/ros1_ws/src/beginner_tutorials/CMakeLists.txt

# ビルド
cd ~/ros1_ws/
catkin_make
```

# ソースコード
```c++:talker.cpp
//ROSの最も基本的な命令を含むヘッダファイル 
#include "ros/ros.h"
//ROSが持つ標準メッセージのうち、String(文字列)を扱うヘッダファイル 
#include "std_msgs/String.h"
//StringStreamという文字列を処理するためのC++標準ヘッダファイル 
#include <sstream>

int main(int argc, char **argv){
  //ROSを初期化すると共にノード名称をtalkerに設定
  //ノード名称は実行中のシステムの中で一意(ユニーク)でないといけない
  ros::init(argc, argv, "talker");
  //ノードハンドル... プログラムの中でこのノード自体を意味する変数(のようなもの)を宣言
  ros::NodeHandle n;

  //このノードがPublisher (発行者)としてString タイプのメッセージを公開することを 
  //マスター (roscore)に伝える。 
  //第二引数の1000は公開キュー(バッファ)の大きさ
  ros::Publisher chatter_pub = n.advertise <std_msgs::String>("chatter", 1000);

  //遅延を発生させるためのRateオブジェクトを生成 
  //10秒?間の遅延を行う <-本当か??
  ros::Rate loop_rate(10);

  //カウンタ変数の宣言・初期化
  int count = 0;

  //ros::ok()がTrueの間(つまりノードが正常動作している間)処理を永久に繰り返す 
  //Ctrl+Cが押されたりすると、ros::ok)がFalseになるのでループを脱出する。
  while(ros::ok()){

    //送信メッセージを格納するStringクラス
    std_msgs::String msg;
    //文字列処理を行うStringstreamクラス
    std::stringstream ss;

    //hello worldとcount変数の内容を合わせてssに流し込む
    ss << "hello world" << count;
    //ssの内容を文字列化して送信メッセージデータとして格納↓
    msg.data = ss.str();

    //送信内容を画面に表示(ROS_INFOはprintfの代わりになるマクロ) 
    ROS_INFO("%s", msg.data.c_str());

    //メッセージを送信
    chatter_pub.publish(msg);
    
    //応答を待ち受ける(このプログラムではあまり意味はない)↓ 
    ros::spinOnce();
    //指定時間(10秒)待機↓  <-本当か??
    loop_rate.sleep();
    //カウンタ変数をカウントアップ
    ++count;
  } 
  return 0;
}

```


```c++:listener.cpp
//ROSの最も基本的な命令を含むヘッダファイル
#include "ros/ros.h"
//ROSが持つ標準メッセージのうち、String(文字列)を扱うヘッダファイル
#include "std_msgs/String.h"

void chatterCallback(const std_msgs::String::ConstPtr& msg){
  //受信内容を画面に表示 
  //(ROS_INFOはprintfの代わりになるマクロ)↓
  ROS_INFO("I have: [%s]", msg->data.c_str());
}

int main(int argc, char **argv){
  //ROSを初期化すると共にノード名称をlistenerに設定
  //ノード名称は実行中のシステムの中で一意(ユニーク)でないといけない
  ros::init(argc, argv, "listener");
  //ノードハンドル... プログラムの中でこのノード自体を意味する変数(のようなもの)を宣言
  ros::NodeHandle n;

  //このノードがSubscriber (購読者)として働くことをマスター (roscore)に伝える。 
  //第二引数の1000は公開キュー(バッファ)の大きさ。 
  //第三引数のchatterCallbackはメッセージ受信時に動作するコールバック関数↓ 
  ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);
  
  //メッセージの受信待ちループを開始して、応答を待ち受ける
  ros::spin();
  return 0;
}

```

```vim:CMakeLists.txt
# 元ファイルの一番下に追記する

add_executable(talker src/talker.cpp)
target_link_libraries(talker ${catkin_LIBRARIES})

add_executable(listener src/listener.cpp)
target_link_libraries(listener ${catkin_LIBRARIES})

```


# TALKER/LISTENER を動かしてみる

ホームディレクトリで実行しても動くようです。
詳しくは調べてません。

- ROSCORE を実行する(1 つ目のターミナル)
以下のコマンドを入力して roscore を実行する
これを先に起動しないと動かないので注意
```bash:1 つ目のターミナル
roscore
```
実行後はターミナルを最小化しておいて OK

- LISTENER を実行する(2 つ目のターミナル)
2 つ目のターミナルを起動する。
以下のコマンドを入力して listener を実行する
```bash:2 つ目のターミナル
rosrun beginner_tutorials listener
```

- TALKER を実行する(3 つ目のターミナル)
3 つ目のターミナルを起動する。
以下のコマンドを入力して talker を実行する
```bash:3 つ目のターミナル
rosrun beginner_tutorials talker
```

|--|ホームディレクトリにて実行|
|--|--|
|![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363815/6d73dcd3-833c-5f85-a226-e6dcc8a15105.png)|![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363815/418abb4d-5203-351d-00e5-0f1cedb34848.png)|