既存のROSパッケージをROS2で使用するためのコンバーティングに関する備忘録。
ROSパッケージの準備
ROSのチュートリアルのパッケージを利用する。
まずcatkin形式のパッケージを作る。
以下のコマンドを実行する。
cd ~/catkin_ws/src
catkin_create_pkg beginner_tutorials std_msgs rospy roscpp
次にtalkerノードとlistenerノードのソースを格納する。
~/catkin_ws/src/beginner_tutorials/src配下に以下のlistener.cppとtalker.cppのファイルを作成し、以下のものを張り付ける。
# include "ros/ros.h"
# include "std_msgs/String.h"
void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
ROS_INFO("I heard: [%s]", msg->data.c_str());
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "listener");
ros::NodeHandle n;
ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);
ros::spin();
return 0;
}
# include <sstream>
# include "ros/ros.h"
# include "std_msgs/String.h"
int main(int argc, char **argv)
{
ros::init(argc, argv, "talker");
ros::NodeHandle n;
ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);
ros::Rate loop_rate(10);
int count = 0;
std_msgs::String msg;
while (ros::ok())
{
std::stringstream ss;
ss << "hello world " << count++;
msg.data = ss.str();
ROS_INFO("%s", msg.data.c_str());
chatter_pub.publish(msg);
ros::spinOnce();
loop_rate.sleep();
}
return 0;
}
次に~/catkin_ws/src/beginner_tutorials/package.xmlを編集する。
以下のものを張り付ける。
<package>
<name>beginner_tutorials</name>
<version>0.0.0</version>
<description>talker</description>
<maintainer email="you@yourdomain.tld">Your Name</maintainer>
<license>Apache 2.0</license>
<buildtool_depend>catkin</buildtool_depend>
<build_depend>roscpp</build_depend>
<build_depend>std_msgs</build_depend>
<run_depend>roscpp</run_depend>
<run_depend>std_msgs</run_depend>
</package>
最後に~/catkin_ws/src/beginner_tutorials/CMakeLists.txtを編集する。
以下のものを張り付ける。
cmake_minimum_required(VERSION 2.8.3)
project(beginner_tutorials)
## Find catkin and any catkin packages
find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs genmsg)
## Declare a catkin package
catkin_package()
## Build talker and listener
include_directories(include ${catkin_INCLUDE_DIRS})
add_executable(talker src/talker.cpp)
target_link_libraries(talker ${catkin_LIBRARIES})
add_executable(listener src/listener.cpp)
target_link_libraries(listener ${catkin_LIBRARIES})
ROSパッケージの動作確認
パッケージが正しく動作するかを確かめる。
以下のコマンドを実行しパッケージをビルドする。
cd ~/catkin_make
catkin_make
次に3つのターミナルを起動してそれぞれ以下のコマンドを実行する。以下が正常に動いているものである.
roscore
rosrun beginner_tutorials talker
[ INFO] [1618961980.031075257]: hello world 0
[ INFO] [1618961980.131142666]: hello world 1
[ INFO] [1618961980.231113532]: hello world 2
[ INFO] [1618961980.331107085]: hello world 3
[ INFO] [1618961980.431122565]: hello world 4
[ INFO] [1618961980.531117988]: hello world 5
rosrun beginner_tutorials listener
[ INFO] [1618961980.332236166]: I heard: [hello world 0]
[ INFO] [1618961980.432181902]: I heard: [hello world 1]
[ INFO] [1618961980.532188363]: I heard: [hello world 2]
[ INFO] [1618961980.632173786]: I heard: [hello world 3]
[ INFO] [1618961980.732066074]: I heard: [hello world 4]
[ INFO] [1618961980.832214154]: I heard: [hello world 5]
ROS2への移植
ROS2用のワークスペースに先ほど作成したROSパッケージ(beginner_tutorials)をコピーする。
talkerノードの移植作業
修正する点を列挙する。
# | ROS | ROS2 | 備考 |
---|---|---|---|
1 | #include "ros/ros.h" | #include "rclcpp/rclcpp.hpp" | ROS2用C++用クライアントライブラリに変更 |
2 | #include "std_msgs/String.h" | #include "std_msgs/msg/string.hpp" | std_msgs/String型のメッセージのヘッダをインクルード |
3 | ros::init(argc, argv, "talker"); ros::NodeHandle n; |
rclcpp::init(argc, argv); auto node = rclcpp::Node::make_shared("talker"); |
ノードの初期化の書式を変更 |
4 | ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000); | auto chatter_pub = node->create_publisher<std_msgs::msg::String>("chatter",rmw_qos_profile_default); | パブリッシャの書式を変更 |
5 | ros::Rate loop_rate(10); | rclcpp::Rate loop_rate(10); | rosからrclcppに変更 |
6 | std_msgs::String msg; | auto msg = std::make_shared<std_msgs::msg::String>(); | std_msgs/String型でmsgという名前の変数を登録する際の書式を変更 |
7 | while (ros::ok()) | while (rclcpp::ok()) | rosからrclcppに変更 |
8 | msg.data = ss.str(); | msg->data = ss.str(); | アローに変更 |
9 | chatter_pub.publish(msg); | chatter_pub->publish(msg); | アローに変更 |
10 | ROS_INFO("%s", msg.data.c_str()); | RCLCPP_INFO(node->get_logger(),"%s", msg->data.c_str()); | ROS_INFOをRCLCPP_INFOの書式に変更 |
11 | ros::spinOnce(); | rclcpp::spin_some(node); | スピンの書式の変更 |
以下が上記の点を修正したコードである。
# include <sstream>
# include "rclcpp/rclcpp.hpp"
# include "std_msgs/msg/string.hpp"
int main(int argc, char **argv)
{
rclcpp::init(argc, argv);
auto node = rclcpp::Node::make_shared("talker");
auto chatter_pub = node->create_publisher<std_msgs::msg::String>("chatter", rmw_qos_profile_default);
rclcpp::Rate loop_rate(10);
int count = 0;
auto msg = std::make_shared<std_msgs::msg::String>();
while (rclcpp::ok())
{
std::stringstream ss;
ss << "hello world " << count++;
msg->data = ss.str();
RCLCPP_INFO(node->get_logger(),"%s", msg->data.c_str());
chatter_pub->publish(msg);
rclcpp::spin_some(node);
loop_rate.sleep();
}
return 0;
}
listenerノードの移植作業
修正する点を列挙する。
# | ROS | ROS2 | 備考 |
---|---|---|---|
1 | #include "ros/ros.h" | #include "rclcpp/rclcpp.hpp" | ROS2用C++用クライアントライブラリに変更 |
2 | #include "std_msgs/String.h" | #include "std_msgs/msg/string.hpp" | std_msgs/String型のメッセージのヘッダをインクルード |
3 | 記述なし | std::shared_ptr<rclcpp::Node> node; | nodeをグローバル変数に登録 |
4 | void chatterCallback(const std_msgs::msg::String::ConstPtr msg) | void chatterCallback(const std_msgs::msg::String::SharedPtr msg) | ConstPtrからSharedPtrに変更 |
5 | ROS_INFO("%s", msg.data.c_str()); | RCLCPP_INFO(node->get_logger(),"%s", msg->data.c_str()); | ROS_INFOをRCLCPP_INFOの書式に変更 |
6 | ros::init(argc, argv, "listener"); ros::NodeHandle n; |
rclcpp::init(argc, argv); node = std::make_shared<rclcpp::Node>("listener"); |
ノードの初期化の書式を変更 |
7 | ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback); | auto chatter_sub = node->create_subscription("chatter", rclcpp::QoS(10),chatterCallback); | サブスクライバの書式を変更 |
8 | ros::spin(node); | rclcpp::spin(node); | rosからrclcppに変更 |
以下が上記の点を修正したコードである。
# include "rclcpp/rclcpp.hpp"
# include "std_msgs/msg/string.hpp"
std::shared_ptr<rclcpp::Node> node;
void chatterCallback(const std_msgs::msg::String::SharedPtr msg)
{
RCLCPP_INFO(node->get_logger(),"%s", msg->data.c_str());
}
int main(int argc, char **argv)
{
rclcpp::init(argc, argv);
node = std::make_shared<rclcpp::Node>("listener");
auto chatter_sub = node->create_subscription<std_msgs::msg::String>(
"chatter",
rclcpp::QoS(10),
chatterCallback
);
rclcpp::spin(node);
return 0;
}
package.xmlの移植作業
修正する点を列挙する。
# | ROS | ROS2 | 備考 |
---|---|---|---|
1 | <package> | <package format="2"> | マニュフェストのバージョンを2に変更 |
2 | <buildtool_depend>catkin</buildtool_depend> | <buildtool_depend>ament_cmake</buildtool_depend> | catkinではなくamentを使用 |
3 | <build_depend>roscpp</build_depend> | <build_depend>rclcpp</build_depend> <build_depend>rmw_implementation</build_depend> |
ビルドの依存関係を修正 |
4 | <run_depend>roscpp</run_depend> <run_depend>std_msgs</run_depend> |
<exec_depend>rclcpp</exec_depend> <exec_depend>rmw_implementation</exec_depend> <exec_depend>std_msgs</exec_depend> |
実行の依存関係を修正 |
5 | 記述なし | <export> <build_type>ament_cmake</build_type> </export> |
ビルドタイプ宣言を追加 |
以下が上記の点を修正したコードである。
<package format="2">
<name>beginner_tutorials</name>
<version>0.0.0</version>
<description>talker</description>
<maintainer email="you@yourdomain.tld">Your Name</maintainer>
<license>Apache 2.0</license>
<buildtool_depend>ament_cmake</buildtool_depend>
<build_depend>rclcpp</build_depend>
<build_depend>rmw_implementation</build_depend>
<build_depend>std_msgs</build_depend>
<exec_depend>rclcpp</exec_depend>
<exec_depend>rmw_implementation</exec_depend>
<exec_depend>std_msgs</exec_depend>
<export>
<build_type>ament_cmake</build_type>
</export>
</package>
CMakeLists.txtの移植作業
修正する点を列挙する。
# | ROS | ROS2 | 備考 |
---|---|---|---|
1 | cmake_minimum_required(VERSION 2.8.3) | cmake_minimum_required(VERSION 3.5) | Cmakeのバージョンの変更 |
2 | 記述なし | set(CMAKE_CXX_STANDARD 14) | C++14に設定 |
3 | find_package(catkin REQUIRED COMPONENTS roscpp std_msgs) | find_package(ament_cmake REQUIRED) find_package(rclcpp REQUIRED) find_package(rmw_implementation REQUIRED) find_package(std_msgs REQUIRED) |
ament_cmakeから個別にパッケージを探し出す |
4 | catkin_package() | ament_package() | パッケージの登録の宣言をcatkinからamentに変更し、末尾に記述する |
5 | include_directories(include ${catkin_INCLUDE_DIRS}) | include_directories(${rclcpp_INCLUDE_DIRS} | 依存パッケージのパスを指定(1) |
6 | ${rmw_implementation_INCLUDE_DIRS} | 依存パッケージのパスを指定(2) | |
7 | ${std_msgs_INCLUDE_DIRS}) | 依存パッケージのパスを指定(3) | |
8 | target_link_libraries(talker ${catkin_LIBRARIES}) | target_link_libraries(talker | パッケージライブラリを追加(1) |
9 | ${rclcpp_LIBRARIES} | パッケージライブラリを追加(2) | |
10 | ${rmw_implementation_LIBRARIES} | パッケージライブラリを追加(3) | |
11 | ${std_msgs_LIBRARIES}) | パッケージライブラリを追加(4) | |
12 | 記述なし | install(TARGETS talker DESTINATION lib/${PROJECT_NAME}) | 実行ファイルの保存先を追記 |
13 | target_link_libraries(listener ${catkin_LIBRARIES}) | target_link_libraries(listener | パッケージライブラリを追加(1) |
14 | ${rclcpp_LIBRARIES} | パッケージライブラリを追加(2) | |
15 | ${rmw_implementation_LIBRARIES} | パッケージライブラリを追加(3) | |
16 | ${std_msgs_LIBRARIES}) | パッケージライブラリを追加(4) | |
17 | 記述なし | install(TARGETS listener DESTINATION lib/${PROJECT_NAME}) | 実行ファイルの保存先を追記 |
以下が上記の点を修正したコードである。
cmake_minimum_required(VERSION 3.5)
project(beginner_tutorials)
set(CMAKE_CXX_STANDARD 14)
## Find ament and any ament_package packages
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(rmw_implementation REQUIRED)
find_package(std_msgs REQUIRED)
## Build talker and listener
include_directories(${rclcpp_INCLUDE_DIRS}
${rmw_implementation_INCLUDE_DIRS}
${std_msgs_INCLUDE_DIRS})
add_executable(talker src/talker.cpp)
target_link_libraries(talker
${rclcpp_LIBRARIES}
${rmw_implementation_LIBRARIES}
${std_msgs_LIBRARIES})
install(TARGETS talker DESTINATION lib/${PROJECT_NAME})
add_executable(listener src/listener.cpp)
target_link_libraries(listener
${rclcpp_LIBRARIES}
${rmw_implementation_LIBRARIES}
${std_msgs_LIBRARIES})
install(TARGETS listener DESTINATION lib/${PROJECT_NAME})
## Declare a ament package
ament_package()
ROS2パッケージの動作確認
パッケージが正しく動作するかを確かめる。
以下のコマンドを実行しパッケージをビルドする。
cd ~/ros2-dashing
colcon build
次に2つのターミナルを起動してそれぞれ以下のコマンドを実行する。以下が正常に動いているものである.
source ~/ros2-dashing/install/setup.bash
ros2 run beginner_tutorials talker
[INFO] [talker]: hello world 0
[INFO] [talker]: hello world 1
[INFO] [talker]: hello world 2
[INFO] [talker]: hello world 3
[INFO] [talker]: hello world 4
[INFO] [talker]: hello world 5
source ~/ros2-dashing/install/setup.bash
ros2 run beginner_tutorials listener
[INFO] [listener]: hello world 0
[INFO] [listener]: hello world 1
[INFO] [listener]: hello world 2
[INFO] [listener]: hello world 3
[INFO] [listener]: hello world 4
[INFO] [listener]: hello world 5