はじめに
初めて記事を書きます。オガネソンです。ただいま情報通信工学科のB3です。C++をプログラミングしたいけど、何を目標にしていいか分からないそこのあなた!ROS2のプログラミングを通してC++を練習しましょう!
想定されるレベルは次の通りです。
- C++は入門書である程度んだけど特に作りたいものも無いという方
- ROS2をC++でプログラミングしてみたい方
また、使用するPCは以下の水準以上のものをおすすめします。
使用OS | Ubuntu 22.04 LTS |
---|---|
ROS distribution | ROS2 humble |
CPU性能 | 11th Gen Intel® Core™ i7-1165G7 |
ROS2とは?
ROS2を説明するにはここのページは余白が狭すぎる...と言いたいところですが、簡単にROS2について説明したいと思います。
ROS2とは、ROS(Robot Operating System)の進化版である、ロボット開発に必要なライブラリ群、ツール群、通信規格などを含んだオープンソースミドルウェアです。ROSには経路計画や地図生成のアプリケーションが用意されていて、ロボット開発にはなくてはならない存在です。
出典:(https://www.fsi.co.jp/ros/)
そのROSには問題点が多くあり、例えば、ROSは主に研究開発用に作られており、一般に使用されることは難しいところがありました。また、ROSを使用できるプラットホームがUbuntuのみで、一般的に売られているパソコンにはWindows OSか、Mac OSが搭載されているので、OSを複数入れなければならず、参入する障壁が高いです。
しかし、ROS2では、そのようなROSの不便な点が数多く解消されているので、一般の人や企業でも導入しやすくなりました。対応OSもWisndowsやMacにも対応しましたし、通信方式や基盤になっているシステムが大幅に変わりました。
出典:(https://www.slideshare.net/takasehideki/fpgaros-240272923)
このように使いやすくなったROS2を使ってロボットのプログラミングをやってみようという訳ですが、ROS2のセットアップは最初はかなり大変です。
Ubuntuをインストール
今まで散々Ubuntu以外でも使えるよと言ってきたのになんでと思われるかもしれませんが、Ubuntu OSでセットアップするのがプログラミングをする上で一番簡単に終わるのです。インストールにはこちらのサイトが分かりやすいです。
ROS2 humbleを当記事では扱うので、それに合うバージョンはUbuntu 22.04 LTSとなっています。20.04以前のUbuntuではROS2 humbleはインストールできないのでご注意ください。
ROS2をインストール
UbuntuをインストールしたらいよいよROS2のインストールです。ディストリビューション(バージョン)はhumbleが2027年までサポートしているので、おすすめです。サイトはこちらがとても分かりやすいです。
以下のコマンドを1行ずつコピーしてターミナルで実行しましょう。
$ sudo apt update && sudo apt install curl software-properties-common python3-rosdep
$ sudo add-apt-repository universe
$ 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 -y
$ sudo apt install ros-humble-desktop
$ echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc
$ source ~/.bashrc
$ sudo rosdep init && rosdep update
以上を実行したらROS2 humbleがインストールされます。インストールされたか確認するには、ターミナルを開いて
$ ros2 run demo_nodes_cpp talker
もうひとつ新たなターミナルを開き、そこに以下のコマンドを実行します。
$ ros2 run demo_nodes_py listener
お互いに通信ができていればインストールは完了となります。
C++の基礎知識
いよいよプログラミングに入ります。ROS2のプログラミングをするのに最低限必要なC++の知識を上げておきます。
- 基本的なプログラミング(条件分岐、繰り返し、変数の型など)
- オブジェクト指向(クラス、インスタンス、コンストラクタetc...)
- ポインター(アロー演算子とドット演算子の使い分け、スマートポインタなど)
これらの知識が身についていればすぐにでもROS2のプログラミングを始めましょう!
上に挙げたC++の例が十分身についていなくても、ポインターとクラスの継承の仕方、コンストラクタの意味などが分かっていれば十分です。
ROS2のパッケージを作る
ROS2のプログラミングを始める前に、プログラムを保管しておくフォルダを作って置かなければなりません。そのフォルダをROSの用語ではパッケージといいます。パッケージは用途に合わせて幾つも作ることができ、そのパッケージをまとめるフォルダをワークスペースといいます。これからそのパッケージとワークスペースを一緒に作りましょう。
1.ワークスペースを作る
ここではワークスペース名はcolcon_ws
とします。srcディレクトリを作っておくと自動でパッケージを作ってくれるので、以下のようにコマンドを実行します。
$ mkdir -p ~/colcon_ws/src
2.パッケージを作る
パッケージはsrcディレクトリで作ります。ここではC++で開発をしたいので、ビルドシステムをament_cmake
にします。以下のようにしてください。
$ cd ~/colcon_ws/src
$ ros2 pkg create --build-type ament-cmake <パッケージ名>
3.パッケージのビルド
ビルドシステムはament_cmake
ですが、ROS2でのパッケージのビルド方法はcolcon build
です。
$ cd ~/colcon_ws && colcon build
後ほどC++のプログラムのビルドを行いますが、そちらとは意味合いが異なり、パッケージのビルドになります。まあ深いことは気にしないで大丈夫です。
以下のようになれば成功です。
出典:(https://zenn.dev/uchidaryo/articles/ros2-programming-2)
ROS2のプログラム
ここからはようやくROS2のプログラムを書いていきます。基本的なプログラムしか記事の都合上ご紹介することができませんが、そちらは今後の記事をお待ちください。
Happy world!とターミナル上に表示させるプログラム
これからソースコードを書いていくわけですが、書けるようになるためにはソースコードの流れ(フロー)をしっかり理解した上で自分で手を動かして書くことが大事です。
#include"rclcpp/rclcpp.hpp"
////happy worldと画面に表示するノード
class HappyNode : public rclcpp::Node{ //rclcppからNodeクラスを継承
public :
HappyNode() : Node("happy_node"){ //スーパークラスのNodeコンストラクタ呼び出し。ノードの定義をする。
RCLCPP_INFO(this->get_logger(),"Happy world!"); //ターミナルに表示したい文字を出力できる
}
};
int main(int argc, char **argv){
rclcpp::init(argc,argv); ////ROS2通信を初期化
auto node = std::make_shared<HappyNode>(); //ノードを生成
rclcpp::shutdown(); //ROS2通信をシャットダウン
return 0;
}
長ったらしいプログラムに見えますが、構造は単純です。クラスでROSのノードを定義して、メイン関数内で実行しているだけです。
このプログラムのポイントを一つずつ解説していきます。
1行目 インポート ROS2ではrclという基礎部分の上にC++やpythonでコーディングするのでrclcppをインポートしてきます。
4行目 クラスを作成 先程インポートしてきたrclcppライブラリからNodeクラスを継承しています。
5行目 ノードを定義 クラスのコンストラクタを呼び出してインスタンス化された時にノードが定義されるようになっています。
6行目 ログを表示 RCLCPP_INFO()
メソッドでログとして文章を表示することができます。引数の方でget_logger()
メソッドを置いておく必要があります。
11行目〜 メイン文で、プログラムがここから順に実行される。
12行目 ROS2の通信を初期化
13行目 クラスをインスタンス化してノードを生成 先程の5行目のコンストラクタが呼び出されることでノードが定義されます。
14行目 ROS2通信をシャットダウン
このような流れでROS2のプログラムを書きます。
演習1 このソースコードの流れを理解したら、なるべく何も見ないでもう一度同じようなプログラムを作ってみてください。
プログラムを実行する
C++で書いたプログラムは事前にコンパイル(機械語に翻訳)しておかなければなりません。コンパイルするにはCMakelists.txtをちょっと書かなくてはいけません。
CMakelists.txt
コンパイルするときの手順書のようなものです。以下のように書きます。
cmake_minimum_required(VERSION 3.8)
project(ros_practice)
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(std_msgs REQUIRED)
add_executable(happy_node src/happy_node.cpp)
ament_target_dependencies(happy_node rclcpp)
install(TARGETS
happy_node
DESTINATION lib/${PROJECT_NAME})
ament_package()
実際はパッケージを作る時に大半は出来上がっていて、新しく書くべきは
add_executable(happy_node src/happy_node.cpp)
ament_target_dependencies(happy_node rclcpp)
これとinstall(TARGETS
の下にhappy_node
を
install(TARGETS
happy_node
DESTINATION lib/${PROJECT_NAME})
と書きましょう。
書いたら保存してターミナルに戻って
$ cd ~/colcon_ws && colcon build --symlink-install
と打ち込みましょう。--symlink-install
は便利なオプションらしいです。成功したら
$ ros2 run ros_practice happy_node
を実行すれば、
[INFO] [1698247301.829961920] [happy_node]: hello world!
と表示されるはずです。
さいごに
お疲れ様でした!
これでROS2のノードをC++で書くことができました。次はパブリッシャーとサブスクライバーを書いてみましょう。