ROS2 に関する書籍を入手したので、今回は、ROS2 について調べていきたいと思います。
ROS1 は、少しやっていたのですが、ROS2 は初めてです。
それでは、やっていきます。
参考文献
環境構築については、こちらを参考にしました。Python よりも C++ の解説が多かったです。ROS2 について、しっかりと詳しく解説されていた印象です。
こちらは、逆に、Python が多く、ROS2 について、基本的なことは解説されていますが、応用的なところとして、AI と関連付けての説明に重点が置かれていた印象です。
はじめに
ROS の公式ページです。ただ、インストール手順や、その他の情報は、ROS の各ディストリビューションごとのページに書かれているので、使用するディストリビューションに応じた公式のドキュメントを参照する必要があります。このページで紹介されているディストリビューションは、Ubuntu と同じように 5年間の長期サポートをしている、最新の Jazzy Jalisco(以下、Jazzy)と、最初に長期サポートを行った Humble Hawksbill(以下、Humble)でした。現状、長期サポートしているのは、この 2つのディストリビューションのようです。
今回は、Humble を使っていこうと思います。Humble が対応している Ubuntu のバージョンは、22.04 のみであり、現在、私の PC の Virtual Box に入ってる Ubuntu が 22.04 だからです。ちなみに、Jazzy の方は、Ubuntu のバージョンは、24.04 のみ対応しています。ちなみに、書籍(改訂新版 ROS 2ではじめよう 次世代ロボットプログラミング〜ロボットアプリケーション開発のための基礎から実践まで)では、Jazzy のインストール方法が解説されています。
Humble のドキュメントは以下です。
それでは、やっていきます。
概要
ROS2とは
ROS(Robot Operating System)とは、ソフトウェア開発者のロボットアプリケーションの開発を支援するライブラリとツールです。ROS は、OS というだけあって、デバイスドライバ、ライブラリ、メッセージ通信、パッケージ管理などを提供しています。
有名な機能では、ナビゲーションパッケージとして、地図を作成する SLAM(Simultaneous Localization and Mapping)というアルゴリズムがあります。また、ロボットの動作計画(ロボットの関節構造とアクチュエータの制御)として、MoveIt というパッケージが提供されています。
ROS1とROS2の違い
ROS1 では、ROSマスターというものが存在して、ROSマスターがメッセージ通信を仲介していました。よって、ROSマスターに問題が発生すると、その影響は大きいです。一方、ROS2 では、ROSマスターの考え方はなくなり、分散化されたシステムになっています。
また、ROS1 のコアの部分は、C++ で実装されていました。非力なマイコンでは動かせない状況でした。ROS2 のコアは C言語で実装されており、組み込み環境でも ROS を動作させることが可能になりました。
通信についても、ROS1 は TCP通信を採用していましたが、ROS2 では、UDP通信をベースとしたプロトコルを採用しており、リアルタイム制御についても進化しています。また、ROS2 では、通信部分を、Publisher/Subscriber通信のミドルウェアの仕様である、DDS(Data Distribution Service)に任せています。
ROS2の基本
ROS2 は複数のノードが、通信により、メッセージやデータをやりとりします。ROS2 における通信方法として、トピック通信、サービス通信、アクション通信、パラメータ通信の 4つがあります。
トピック通信
トピック通信は、一方向で、非同期通信です。書籍では、トピック通信のイメージとして、テレビ放送をあげてました。
テレビ局に相当するパブリッシャ(Publisher)、視聴者に相当するサブスクライバ(Subscriber)、番組のチャンネルに相当するのがトピック(Topic)、配信するデータをメッセージ(Message)と呼びます。
トピック通信は、カメラや LiDAR など、常にセンサデータを送信し続ける用途に使われます。
サービス通信
サービス通信は、双方向、同期通信です。書籍では、サービス通信のイメージとして、Google検索をあげていました。
ユーザがブラウザ上で、検索キーワードを送信する(クライアント)と、そのデータがネット上の検索エンジンで処理(サーバ)されて、結果がブラウザに送信されます。これが双方向通信であり、依頼に対して、すぐに応答を返すので、同期通信というわけです。
サービス通信は、サーバの処理に時間があまりかからない、カメラや LiDAR などのセンサの動作モードの切り替えなどの用途に使われます。
アクション通信
アクション通信は、双方向、非同期通信です。アクション通信は、長時間かかる複雑なタスクを処理するために作られたそうです。アクション通信は、サービス通信より高機能な通信で、サービス通信とトピック通信の両方を使っています。
書籍では、ロボットに商品を配達してもらうような場合に使われると説明されていました。
アクション通信は、ゴールサービス、リザルトサービス、フィードバックトピックで構成されています。ゴール地点をアクションサーバに送り、ゴールに到着したら、リザルトサービスでアクションクライアントに結果を返します。アクションサーバは、途中経過をアクションクライアントに、常に送り続けます。
パラメータ通信
パラメータ通信は、双方向で、書籍には明記されてませんでしたが、同期と非同期の両方の通信がありそうです(?)。
パラメータ通信は、ノードの設定値を取得したり、設定するための通信です。
ROS2のインストール
書籍(改訂新版 ROS 2ではじめよう 次世代ロボットプログラミング〜ロボットアプリケーション開発のための基礎から実践まで)を参考にしつつ、具体的なインストール手順は、以下の公式の手順に沿ってやっていきます。
ロケールの設定
OS の文字コードを UTF-8 に設定しておく必要があるようです。ただし、Ubuntu が日本語バージョンなので、公式手順とは異なりますが、ja_JP.UTF-8 に設定します。ここは書籍に従います。
$ locale LANG=ja_JP.UTF-8 LANGUAGE= LC_CTYPE="ja_JP.UTF-8" LC_NUMERIC="ja_JP.UTF-8" LC_TIME="ja_JP.UTF-8" LC_COLLATE="ja_JP.UTF-8" LC_MONETARY="ja_JP.UTF-8" LC_MESSAGES="ja_JP.UTF-8" LC_PAPER="ja_JP.UTF-8" LC_NAME="ja_JP.UTF-8" LC_ADDRESS="ja_JP.UTF-8" LC_TELEPHONE="ja_JP.UTF-8" LC_MEASUREMENT="ja_JP.UTF-8" LC_IDENTIFICATION="ja_JP.UTF-8" LC_ALL= $ sudo apt update && sudo apt install locales $ sudo locale-gen ja_JP ja_JP.UTF-8 $ sudo update-locale LC_ALL=ja_JP.UTF-8 LANG=ja_JP.UTF-8 export LANG=ja_JP.UTF-8
Ubuntu Universeリポジトリの有効化
Ubuntu の apt の参照先に Universe を追加します。
$ sudo apt install software-properties-common $ sudo add-apt-repository universe
aptの参照先にROSを追加
ここは、書籍に従います。upgrade は書籍にないですが、最近やってない気がするので、やっときます。
$ sudo apt update && sudo apt install curl -y $ sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg $ echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/ os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null $ sudo apt update $ sudo apt upgrade
ROS2をインストール
ROS2 Humble をインストールします。ros-dev-tools は、公式サイトではオプションとありましたが、書籍でインストールを推奨してたので、入れておきます。python-argcomplete は、argparse で定義したオプションをタブ補完できるもので、必須ではありませんが、書籍でインストールしていたので、入れておきます。
$ sudo apt install ros-humble-desktop $ sudo apt install ros-dev-tools $ sudo apt install python3-argcomplete
無事、インストールできました。
rosdepの初期化と情報更新
こちらは公式サイトのインストール手順にはないですが、書籍で実施してるので、やっておきます。
$ sudo rosdep init $ rosdep update
動作確認
以下の公式のチュートリアルを参照しながら、簡単な動作について確認していきます。
まずは、正しくインストールが出来ているかを確認します。
環境設定
ROS2 の環境変数を読み込むために、以下を実行します。ROS2 を動かすときは必ず必要です。.bashrc に記載しておくことで、常に実行されるようにできます。
追加された環境変数を確認します。/opt/ros/humble 以下にインストールされたようです。
$ source /opt/ros/humble/setup.bash $ printenv | grep -i ROS ROS_VERSION=2 ROS_PYTHON_VERSION=3 AMENT_PREFIX_PATH=/opt/ros/humble PYTHONPATH=/opt/ros/humble/lib/python3.10/site-packages:/opt/ros/humble/local/lib/python3.10/dist-packages LD_LIBRARY_PATH=/opt/ros/humble/opt/rviz_ogre_vendor/lib:/opt/ros/humble/lib/x86_64-linux-gnu:/opt/ros/humble/lib ROS_LOCALHOST_ONLY=0 PATH=/opt/ros/humble/bin:/home/daisuke/.local/bin:/home/daisuke/.nvm/versions/node/v20.13.1/bin:/home/daisuke/Downloads/xpack-arm-none-eabi-gcc-13.2.1-1.1/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin ROS_DISTRO=humble
デモノードを動かす(Python)
既に用意されているデモ用のノード(Python)を動かしてみます。
talker を起動した後、別のターミナルで、listener を起動します。
まず、動かしたいパッケージがインストールされているかを確認します。
$ ros2 pkg executables | grep demo*
(途中、割愛)
demo_nodes_cpp listener
(途中、割愛)
demo_nodes_cpp talker
(途中、割愛)
demo_nodes_py listener
(途中、割愛)
demo_nodes_py talker
(途中、割愛)
Python からやっていきます。
$ ros2 run demo_nodes_py talker [INFO] [1748776570.847112674] [talker]: Publishing: "Hello World: 0" [INFO] [1748776571.753634599] [talker]: Publishing: "Hello World: 1" [INFO] [1748776572.758624312] [talker]: Publishing: "Hello World: 2" [INFO] [1748776573.758645907] [talker]: Publishing: "Hello World: 3" [INFO] [1748776574.756477993] [talker]: Publishing: "Hello World: 4" [INFO] [1748776575.756870348] [talker]: Publishing: "Hello World: 5" [INFO] [1748776576.763700357] [talker]: Publishing: "Hello World: 6" [INFO] [1748776577.760917182] [talker]: Publishing: "Hello World: 7" [INFO] [1748776578.757337733] [talker]: Publishing: "Hello World: 8"
別のターミナルで、listener を動かします。
$ ros2 run demo_nodes_py listener [INFO] [1748776575.867168344] [listener]: I heard: [Hello World: 5] [INFO] [1748776576.781237312] [listener]: I heard: [Hello World: 6] [INFO] [1748776577.768407392] [listener]: I heard: [Hello World: 7]
node、topic、service、action を見ます。
$ ros2 node list /listener /talker $ ros2 topic list /chatter /parameter_events /rosout $ ros2 service list /listener/describe_parameters /listener/get_parameter_types /listener/get_parameters /listener/list_parameters /listener/set_parameters /listener/set_parameters_atomically /talker/describe_parameters /talker/get_parameter_types /talker/get_parameters /talker/list_parameters /talker/set_parameters /talker/set_parameters_atomically $ ros2 action list
正しく実行できました。
デモノードを動かす(C++)
次は、C++ で動かします。
$ ros2 run demo_nodes_cpp talker [INFO] [1748699575.803237924] [talker]: Publishing: 'Hello World: 1' [INFO] [1748699576.801127719] [talker]: Publishing: 'Hello World: 2' [INFO] [1748699577.811796671] [talker]: Publishing: 'Hello World: 3' [INFO] [1748699578.815786936] [talker]: Publishing: 'Hello World: 4' [INFO] [1748699579.806280020] [talker]: Publishing: 'Hello World: 5' [INFO] [1748699580.805941157] [talker]: Publishing: 'Hello World: 6' ^C[INFO] [1748699581.240502038] [rclcpp]: signal_handler(signum=2)
別のターミナルで、listener を動かします。
$ ros2 run demo_nodes_cpp listener [INFO] [1748699577.814761453] [listener]: I heard: [Hello World: 3] [INFO] [1748699578.818457329] [listener]: I heard: [Hello World: 4] [INFO] [1748699579.807641563] [listener]: I heard: [Hello World: 5] ^C[INFO] [1748699580.324195907] [rclcpp]: signal_handler(signum=2)
正しく実行できました。
turtlesimを動かす
亀が動くプログラムも実行してみたいと思います。
1つ目の端末で以下を実行します。
$ ros2 pkg executables | grep turtle* turtlesim draw_square turtlesim mimic turtlesim turtle_teleop_key turtlesim turtlesim_node $ ros2 run turtlesim turtlesim_node Warning: Ignoring XDG_SESSION_TYPE=wayland on Gnome. Use QT_QPA_PLATFORM=wayland to run on Wayland anyway. [INFO] [1748700106.956484687] [turtlesim]: Starting turtlesim with node name /turtlesim [INFO] [1748700107.028340430] [turtlesim]: Spawning turtle [turtle1] at x=[5.544445], y=[5.544445], theta=[0.000000]
別の端末で以下を実行します。
$ ros2 run turtlesim turtle_teleop_key Reading from keyboard --------------------------- Use arrow keys to move the turtle. Use G|B|V|C|D|E|R|T keys to rotate to absolute orientations. 'F' to cancel a rotation. 'Q' to quit.
以下のように、キーボードの矢印キーで、亀を動かすことが出来ます。

node、topic、service、action を見ます。
$ ros2 node list /teleop_turtle /turtlesim $ ros2 topic list /parameter_events /rosout /turtle1/cmd_vel /turtle1/color_sensor /turtle1/pose $ ros2 service list /clear /kill /reset /spawn /teleop_turtle/describe_parameters /teleop_turtle/get_parameter_types /teleop_turtle/get_parameters /teleop_turtle/list_parameters /teleop_turtle/set_parameters /teleop_turtle/set_parameters_atomically /turtle1/set_pen /turtle1/teleport_absolute /turtle1/teleport_relative /turtlesim/describe_parameters /turtlesim/get_parameter_types /turtlesim/get_parameters /turtlesim/list_parameters /turtlesim/set_parameters /turtlesim/set_parameters_atomically $ ros2 action list /turtle1/rotate_absolute
今回は以上になります。
おわりに
今回は、ROS2 を始めてみました。以前、ROS1 をやったことがありますが、ここまでは表面的なことしかやってないので、あまり違いを感じません。次回はもう少し中に入っていきたいと思います。
最後になりましたが、エンジニアグループのランキングに参加中です。
気楽にポチッとよろしくお願いいたします🙇
今回は以上です!
最後までお読みいただき、ありがとうございました。