C++で作ったROS 1のパッケージをROS 2に移植するときのつまづきポイント ―その1(2があるかどうかは不明)
Tue Apr 23 15:35:13 JST 2024 (modified: Tue Apr 23 23:12:25 JST 2024)
views: 2671, keywords:ROS 2
https://github.com/ryuichiueda/value_iteration を https://github.com/ryuichiueda/value_iteration2 に移植中です。前回に引き続き、困った点についてメモ。
CMakeLists.txt どうやって書くの?
上田研の有志のみなさんがROS 2に移植したemcl2(emcl2_ros2: https://github.com/CIT-Autonomous-Robot-Lab/emcl2_ros2 ) のCMakeLists.txt が参考になりました。無茶振りして知見だけもらって申し訳ないですありがとうございます。 転載してコメントいれさせてもらいます。これ見てたらメシ代請求してください。
cmake_minimum_required(VERSION 3.8)
project(emcl2)
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 17) #この前後3行はいらないかも
endif()
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-O3 -Wall -Wextra -Wpedantic) #Clangかg++に渡すオプション
endif()
find_package(ament_cmake_auto REQUIRED) #ament_cmake_autoというパッケージを
#使うとpackage.xmlに書いたパッケージを
ament_auto_find_build_dependencies() #探してくれるっぽい
ament_auto_add_executable(emcl2_node
#.cppファイルをここに並べる
src/Mcl.cpp
src/ExpResetMcl2.cpp
(中略)
src/emcl2_node.cpp
)
if(BUILD_TESTING) #あとはたぶんデフォルト
(以下略)
ヘッダファイルを探す命令も書いていませんが、 include/<パッケージ名>/
に入れておけば探してくれる模様です。
emcl2_ros2パッケージについてはpackage.xml
やディレクトリ構成も参考になると思います。
YAMLに制限
次のような、型の違うデータの並びの読み込みには対応していないとのこと。
vi_node:
action_list:
- name: forward #文字列
onestep_forward_m: 0.3 #浮動小数点(ここでエラーが出る)
onestep_rotation_deg: 0.0
・・・
↓ここらへんにこの問題への言及があります。
違う型のものをyamlに並べられないのね・・・https://t.co/SGNWTZ1Gfo
— 上田隆一 (@ryuichiueda) April 22, 2024
たぶん、YAMLのデータを流用したければ、すべて文字列型で読み込んで変換すればいいんじゃないっすかね?(投げやり)
ちなみにYAMLファイル自体はconfig
ディレクトリを作って次のように書くとよいみたいです。
vi_node:
ros__parameters: #この項目が必要になる(なんでアンダースコア2個なん??)
global_thread_num: 2
local_thread_num: 1
online: true
# action_list: #以下、ROS 1時代の残骸(よみこめねえ)
# - name: "forward"
# onestep_forward_m: 0.3
# onestep_rotation_deg: 0.0
実行時、YAMLファイルは次のように指定します。
ros2 run value_iteration2 vi_node --ros-args --params-file ./config/params.yaml $
C++側でのパラメータの読み込み方もいろいろ変わってます。 ROS 2のコードをのせときます。
/* ROS 2 */
"global_thread_num", 1); //パラメータを宣言しないとアカンらしい(1はデフォルト値)
declare_parameter(int thread_num = get_parameter("global_thread_num").as_int(); //読み込み
パブリッシャ、サブスクライバの型
こんなふうに変わるみたいです。なげーよ。 ROS 2のほうのSubscription
をSubscriber
にして10分くらい死んでました。 Rustみたいにuse(using)を多用しないといけないのかもしれません。
/* ROS 1 */
pub_cmd_vel_; //パブリッシャ
ros::Publisher sub_laser_scan_; //サブスクライバ
ros::Subscriber /* ROS 2 */
pub_cmd_vel_; //パブリッシャ
rclcpp::Publisher<geometry_msgs::msg::Twist>::SharedPtr sub_laser_scan_; //サブスクライバ rclcpp::Subscription<sensor_msgs::msg::LaserScan>::SharedPtr
ConstSharedPtr
ConstPtr
がdeprecatedだと叱られました。 次のようにConstSharedPtr
を使えとのことです。 ・・・なげーよ。
/* ROS 1 */
void scanReceived(const sensor_msgs::LaserScan::ConstPtr &msg);
/* ROS 2 */
void scanReceived(const sensor_msgs::msg::LaserScan::ConstSharedPtr msg);
事情はここらへん にちょろっとだけ書いてあります。
std_msgsのヘッダファイル
std_msgs/UInt32MultiArray.h
はstd_msgs/msg/uint32_multi_array.hpp
になるんだろうなーと思ったけどビルドが通らず、 そこそこ時間を消耗しました。u
のうしろにもアンダースコアがいりました。 死にました。ここらへん が参考になります。 ていうかおじさんが学生のころはhppという拡張子を見たことがなったんですが、 いつごろみんな使い始めたんでしょう?
/* ROS 1 */
#include "std_msgs/UInt32MultiArray.h"
#include "std_msgs/Float32MultiArray.h"
/* ROS 2 */
#include <std_msgs/msg/u_int32_multi_array.hpp>
#include <std_msgs/msg/float32_multi_array.hpp>
おわりに
また作業進めていて気づいたら書きます。最後に一言。
なげーよ