備忘録　ラズパイ5 ROS2　⑦　Ubuntu Desktop 24.04LTSでROS2環境　C++ その3 セットアップ sub.cpp rqt_graph

 ROS2をC++で開発する3回目です。前回、publisher、今回はもう一方のTopicを受けるsubscriberを作ります。
  ```
 yoshi@yoshi:~/ros2_ws$ tree
 .
└── works
    ├── CMakeLists.txt
    ├── include
    │   └── works
    ├── package.xml
    └── src
        ├── exec_sample
        │   └── main.c
        └── pub
            └── pub.cpp
```

### 環境
- Raspberry Pi 5 8GB
- 追加ボード；NVMe Base for Raspberry Pi 5 (NVMe Base by Pimoroni)
- Crucial クルーシャル P2シリーズ 500GB 3D NAND NVMe PCIe M.2 SSD CT500P2SSD8
- 初期；RaspberryPi OS Desktop 64bit (Debian version: 12 (bookworm) Release date: March 15th 2024)
- 現在；Ubuntu Desktop 24.04LTS(64-bit)
- ROS2 HumbleではなくJazzy

　Windows10で、検索窓にcmdと入れ、コマンドプロンプトを起動します。
　sshでログインします（第１回参照）。必要ならupdateします。
```
C:\Users\yoshi>ssh yoshi.local
```

　ros2が実行できるようにします。
 
```
$ source /opt/ros/jazzy/setup.bash
$ cd ros2_ws
```
### subscribeするプログラムを作る
　ソースは、pub.cppの入っているpubディレクトリの中に記述します（失敗する）。
 
```sub.cpp
#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"
#include <stdio.h>

rclcpp::Node::SharedPtr g_node = nullptr;

void callback(const std_msgs::msg::String::SharedPtr msg)
{
  RCLCPP_INFO(g_node->get_logger(), "%s", msg->data.c_str());
}

int main(int argc, char **argv)
{
  printf("start subscribe test\n");
  
  rclcpp::init(argc, argv);
  g_node = rclcpp::Node::make_shared("my_subscriber");
  auto subscriber = g_node->create_subscription<std_msgs::msg::String>("greeting", 1, callback);

  rclcpp::spin(g_node);

  g_node = nullptr;
  rclcpp::shutdown();
  return 0;
}
```
　CMakeLists.txtに、pub.cppを追加した時のようにsub.cppの記述を追加します。
 ```
 
cmake_minimum_required(VERSION 3.8)
project(works)

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  add_compile_options(-Wall -Wextra -Wpedantic)
endif()

# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(rclcpp_components REQUIRED)
find_package(std_msgs REQUIRED)

add_executable(exec_sample
  src/exec_sample/main.c)

install(
  TARGETS exec_sample
  DESTINATION lib/${PROJECT_NAME}
)

add_executable(pub src/pub/pub.cpp)

ament_target_dependencies(pub rclcpp std_msgs)

install(
  TARGETS pub
  DESTINATION lib/${PROJECT_NAME}
)

add_executable(sub src/pub/sub.cpp)

ament_target_dependencies(sub rclcpp std_msgs)

install(
  TARGETS sub
  DESTINATION lib/${PROJECT_NAME}
)

if(BUILD_TESTING)
  find_package(ament_lint_auto REQUIRED)
  # the following line skips the linter which checks for copyrights
  # comment the line when a copyright and license is added to all source files
  set(ament_cmake_copyright_FOUND TRUE)
  # the following line skips cpplint (only works in a git repo)
  # comment the line when this package is in a git repo and when
  # a copyright and license is added to all source files
  set(ament_cmake_cpplint_FOUND TRUE)
  ament_lint_auto_find_test_dependencies()
endif()

ament_package()
```
　ビルドします。
```
yoshi@yoshi:~/ros2_ws$ colcon build
Starting >>> works
--- stderr: works
Traceback (most recent call last):
  File "/opt/ros/jazzy/share/ament_cmake_core/cmake/package_templates/templates_2_cmake.py", line 21, in <module>
    from ament_package.templates import get_environment_hook_template_path
ModuleNotFoundError: No module named 'ament_package'
CMake Error at /opt/ros/jazzy/share/ament_cmake_core/cmake/ament_cmake_package_templates-extras.cmake:41 (message):
  execute_process(/usr/bin/python3
  /opt/ros/jazzy/share/ament_cmake_core/cmake/package_templates/templates_2_cmake.py
  /home/yoshi/ros2_ws/build/works/ament_cmake_package_templates/templates.cmake)
  returned error code 1
Call Stack (most recent call first):
  /opt/ros/jazzy/share/ament_cmake_core/cmake/ament_cmake_coreConfig.cmake:41 (include)
  /opt/ros/jazzy/share/ament_cmake/cmake/ament_cmake_export_dependencies-extras.cmake:15 (find_package)
  /opt/ros/jazzy/share/ament_cmake/cmake/ament_cmakeConfig.cmake:41 (include)
  CMakeLists.txt:9 (find_package)
  ...
```
  エラーが出ました。一つのディレクトリ、ここではpubの中に複数のソースがある場合のCMakeLists.txtの書き方が正しくないのかもしれません。
  
 ```
$ source /opt/ros/jazzy/setup.bash
 ```
 
 　忘れていたようです（二日目の作業でsshを起動しなおしたから）。
  
 ```
 yoshi@yoshi:~/ros2_ws$ colcon build
Starting >>> works
--- stderr: works
/usr/bin/ld: CMakeFiles/pub.dir/src/pub/sub.cpp.o: in function `main':
sub.cpp:(.text+0x2f4): multiple definition of `main'; CMakeFiles/pub.dir/src/pub/pub.cpp.o:pub.cpp:(.text+0x88): first defined here
```
　複数のmainがあるよと言っているようです。同じディレクトリに複数のアプリを書くような書き方ではなく、分割して記述するときに使われるようです。例えば、pub.hとmain.cとpub_123.cとか。

　これらのエラー情報から、worksの下に最初に作ったsrc/exec_sample/main.c、前回作ったsrc/pub/pub.cppに加えて、新規に、src/subフォルダを作り、sub.cppを移動します。
 ```
yoshi@yoshi:~/ros2_ws$ mkdir works/src/sub
yoshi@yoshi:~/ros2_ws$ mv works/src/pub/sub.cpp works/src/sub
└── works
    ├── CMakeLists.txt
    ├── include
    │   └── works
    ├── package.xml
    └── src
        ├── exec_sample
        │   └── main.c
        ├── pub
        │   └── pub.cpp
        └── sub
            └── sub.cpp
 ```
 　CMakeLists.txtを修正します。
  ```
cmake_minimum_required(VERSION 3.8)
project(works)

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  add_compile_options(-Wall -Wextra -Wpedantic)
endif()

# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(rclcpp_components REQUIRED)
find_package(std_msgs REQUIRED)

add_executable(exec_sample src/exec_sample/main.c)

install(
  TARGETS exec_sample
  DESTINATION lib/${PROJECT_NAME}
)

add_executable(pub src/pub/pub.cpp)

ament_target_dependencies(pub rclcpp std_msgs)

install(
  TARGETS pub
  DESTINATION lib/${PROJECT_NAME}
  )

add_executable(sub src/sub/sub.cpp)

ament_target_dependencies(sub rclcpp std_msgs)

install(
  TARGETS sub
  DESTINATION lib/${PROJECT_NAME}
  )

if(BUILD_TESTING)
  find_package(ament_lint_auto REQUIRED)
  # the following line skips the linter which checks for copyrights
  # comment the line when a copyright and license is added to all source files
  set(ament_cmake_copyright_FOUND TRUE)
  # the following line skips cpplint (only works in a git repo)
  # comment the line when this package is in a git repo and when
  # a copyright and license is added to all source files
  set(ament_cmake_cpplint_FOUND TRUE)
  ament_lint_auto_find_test_dependencies()
endif()

ament_package()
```

　ビルドします。
 
 ```
 yoshi@yoshi:~/ros2_ws$ colcon build
 ```
 　エラーなく終了しました。約15秒かかっています。

　ラズパイ（画面）では、前回動かした可視化ツールrqt_graphが動いています。

　ビルドしたものを登録します。subscriberのsubを起動します。
```
yoshi@yoshi:~/ros2_ws$ source ~/ros2_ws/install/setup.bash
yoshi@yoshi:~/ros2_ws$ ros2 run works sub
```

　もう一つターミナルを立ち上げます。publisherのpubを起動します。
 ```
 ssh yoshi.local
 
 yoshi@yoshi:~/ros2_ws$ source ~/ros2_ws/install/setup.bash
 yoshi@yoshi:~/ros2_ws$ ros2 run works pub
start publish test
 ```
 最初のターミナルの様子です。
 ```
 yoshi@yoshi:~/ros2_ws$ ros2 run works sub
start subscribe test
[INFO] [1722076131.778617869] [yoshi_subscriber]: Hello, world 0
[INFO] [1722076132.778774857] [yoshi_subscriber]: Hello, world 1
[INFO] [1722076133.778717550] [yoshi_subscriber]: Hello, world 2
[INFO] [1722076134.778719985] [yoshi_subscriber]: Hello, world 3
[INFO] [1722076135.778789254] [yoshi_subscriber]: Hello, world 4
[INFO] [1722076136.778799579] [yoshi_subscriber]: Hello, world 5
[INFO] [1722076137.778784072] [yoshi_subscriber]: Hello, world 6
[INFO] [1722076138.778818511] [yoshi_subscriber]: Hello, world 7
[INFO] [1722076139.778783895] [yoshi_subscriber]: Hello, world 8
[INFO] [1722076140.778757076] [yoshi_subscriber]: Hello, world 9
[INFO] [1722076141.778729184] [yoshi_subscriber]: Hello, world 10
[INFO] [1722076142.778748571] [yoshi_subscriber]: Hello, world 11
```

 　ラズパイで動いているrqt_graphの左上にあるアイコンを押してリフレッシュします。
 
 ![Screenshot from 2024-07-27 19-35-10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/8c60f820-191d-250c-e47f-0ba65440372c.png)

 　 動作の確認ができました。

-----
（※）参考にさせていただいたサイト
  
https://zenn.dev/uchidaryo/articles/ros2-programming-5
  
https://qiita.com/srs/items/1b9b9de2ad02e689285b



-----------------
<h2>備忘録　ラズパイ5 ROS2</h2>

[①　ハードの用意とUbuntu Desktop 24.04LTS](https://qiita.com/jamjam/items/9ad621bda6ab2e1d325b)

[②　Ubuntu Desktop 24.04LTSでROS2環境　rqt_graphとturtlesim](https://qiita.com/jamjam/items/b7bed8ec9ff68426ac8d)

[③　Ubuntu Desktop 24.04LTSでROS2環境　Python その１ responder（セットアップ）](https://qiita.com/jamjam/items/d124c662813085bc69e3)

[④　Ubuntu Desktop 24.04LTSでROS2環境　Pythonその２responder（コーディングと実行；失敗）](https://qiita.com/jamjam/items/d488e2e4fa88d9882626)

[⑤　Ubuntu Desktop 24.04LTSでROS2環境　C++ その1 セットアップ main.c](https://qiita.com/jamjam/items/4bba331c08805ccda0a8)

[⑥　Ubuntu Desktop 24.04LTSでROS2環境　C++ その2 セットアップ pub.cpp rqt_graph](https://qiita.com/jamjam/items/51eeb26400517883aa59)

[⑦　Ubuntu Desktop 24.04LTSでROS2環境　C++ その3 セットアップ sub.cpp rqt_graph](https://qiita.com/jamjam/items/50f3bc352e4cd0a7959d)

[⑧　Ubuntu Desktop 24.04LTSでROS2環境　C++ その4 bme280.cpp 温度](https://qiita.com/jamjam/items/f64eaae91fefed4eac34)

[⑨ Ubuntu Desktop 24.04LTSでROS2環境　C++ その5 bme280_3.cpp 温度、湿度、気圧](https://qiita.com/jamjam/items/edb799ec88bdfba29c4c)

[⑩ Ubuntu Desktop 24.04LTSでROS2環境　C++ その6 VL53L1X.cpp 距離センサ](https://qiita.com/jamjam/items/21074d7ed830926d7ff4)

--------------

https://qiita.com/jamjam/items/692568361dde688fad16