Docker環境でROS2プログラム開発
前回作成したROS2開発環境のDockerイメージを使ってROS2プログラムを作っていきます。
以下のような流れです。
- パッケージの作成
- ソースの記述
- CMakeLists.txtの編集
- package.xmlの編集
- ビルド
- 動作確認
コンテナの起動
以下のようにして/etc/group
と/etc/passwd
をマウントし,Dockerコンテナのシェルを一般ユーザーで起動するようにするとソースの記述やCMakeLists.txtを編集するときにsudoを使う手間がなくなります。
以降の手順ではros2 pkg createによってディレクトリやファイルが自動生成されるので,空のディレクトリ内で以下を実行します。
$ docker run --rm -it -v `pwd`:/home -v /etc/group:/etc/group:ro -v /etc/passwd:/etc/passwd:ro -u $(id -u $USER):$(id -g $USER) ros2:dashing
コンテナ起動後に以下を実行します。
$ source /opt/ros2/dashing/setup.bash
パッケージの作成
パッケージはsrcディレクトリ内に作成する必要があります。まずはsrcディレクトリを作成し,その中でros2 pkg create
コマンドを実行します。
ビルド時にはここで作成したsrcディレクトリの一つ上(ここでは/home)でcolcon build
コマンドを実行する必要があります。
$ cd /home $ mkdir src $ cd src $ ros2 pkg create --build-type ament_cmake sample --dependencies rclcpp
sample/src内にsample.cppを作成
上のようなros2 pkg create
コマンドを実行するとsampleディレクトリが作成され,その中にsrcディレクトリが作成されます。
以下のようなsample.cppをsrcディレクトリ内に作成します。
#include <memory> #include <chrono> #include "rclcpp/rclcpp.hpp" using namespace std::chrono_literals; class SampleClass : public rclcpp::Node { public: SampleClass() : Node("sample_node") { timer_ = create_wall_timer(1s, std::bind(&SampleClass::timer_callback, this)); } private: void timer_callback() { RCLCPP_INFO(this->get_logger(), "Hello World"); } rclcpp::TimerBase::SharedPtr timer_; }; int main(int argc, char *argv[]) { rclcpp::init(argc, argv); rclcpp::spin(std::make_shared<SampleClass>()); rclcpp::shutdown(); return 0; }
CMakeLists.txtの編集
CMakeLists.txtを以下のように編集します。
Dockerコンテナを立ち上げたディレクトリ内にあるファイルを適当なエディタで編集すればDockerコンテナ内にも反映されます(当たり前ですが)
cmake_minimum_required(VERSION 3.5) project(sample) # Default to C99 if(NOT CMAKE_C_STANDARD) set(CMAKE_C_STANDARD 99) endif() # Default to C++14 if(NOT CMAKE_CXX_STANDARD) set(CMAKE_CXX_STANDARD 14) endif() 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) add_executable(sample_package src/sample.cpp) ament_target_dependencies(sample_package rclcpp) install(TARGETS sample_package DESTINATION lib/${PROJECT_NAME} ) if(BUILD_TESTING) find_package(ament_lint_auto REQUIRED) # the following line skips the linter which checks for copyrights # uncomment the line when a copyright and license is not present in all source files #set(ament_cmake_copyright_FOUND TRUE) # the following line skips cpplint (only works in a git repo) # uncomment the line when this package is not in a git repo #set(ament_cmake_cpplint_FOUND TRUE) ament_lint_auto_find_test_dependencies() endif() ament_package()
package.xmlの編集
package.xmlを以下のように編集します。
<?xml version="1.0"?> <?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?> <package format="3"> <name>sample</name> <version>0.0.0</version> <description>TODO: Package description</description> <maintainer email="root@todo.todo">root</maintainer> <license>TODO: License declaration</license> <buildtool_depend>ament_cmake</buildtool_depend> <test_depend>ament_lint_auto</test_depend> <test_depend>ament_lint_common</test_depend> <build_depend>rclcpp</build_depend> <exec_depend>rclcpp</exec_depend> <export> <build_type>ament_cmake</build_type> </export> </package>
ビルド
ros2 pkg create
コマンドを実行したディレクトリの一つ上(ここでは/home)に移動し,colcon build
を実行します。
$ cd /home $ colcon build
動作確認
ビルドに成功したら以下のコマンドを実行し,動作確認を行います。
$ source install/setup.bash $ ros2 run sample sample_package
ここでsample
はros2 pkg create
コマンド実行時に与えたパッケージ名,sample_package
はCMakeLists.txtで指定したexecutable名です。
これらを変えれば好きな名前にできます。
上記のコマンドを実行すると以下のように1秒毎に文字列が表示されます。
[INFO] [sample_node]: Hello World [INFO] [sample_node]: Hello World [INFO] [sample_node]: Hello World [INFO] [sample_node]: Hello World
開発環境コンテナでROS2プログラムを作成することができました。
VSCodeの拡張機能か何かを使ってラクしたいですね〜