Ros 2 topic
Jufeng Wu, 06 October 2019
ros2 跟ros1一樣都有topic,topic主要就是發布message,然後只要有註冊的node都可以聽這一個message
在這一點上ros2 跟ros1是一樣的
然而,有幾個要注意的地方:
a. 在ros2上面,topic的名稱有所限制,topic的名稱必須是大駝峰式命名法,include檔會產生底線的命名,他的namepace又是大駝峰式命名法,例如:
檔名路徑和名稱:在tm_msg/msg/RobotStatus.msg
要inlcude時: #include "tm_msgs/msg/robot_status.hpp"
include的位置會是install/tm_msgs/include
,所以可以在這一個路徑裡面找到"tm_msgs/msg/robot_status.hpp"
他的namepace會是tm_msgs::msg::RobotStatus
b. 關於subscribe,可以這一個範例
基本上改念如下
aa.初始化
bb.使用產生node
cc.設定feedback
dd.node->create_subscription
ee.rclcpp::spin(node);
這裡唯一要注意的是,create_subscription中第一個參數要和publish中的create_publisher的第一個參數一樣
c. publish的話就更簡單了,更上述幾乎一樣,但是不用設定feedback,但是要定期的去產生新的資訊
這裡可能會使用到 using namespace std::chrono_literals;
在rclcpp::WallRate loop_rate(1s);
的時候的1s就是從std::chrono_literals
而來
d.在Cmake.txt中,記得要加上
find_package(rclcpp REQUIRED)
find_package(my_msgs REQUIRED)
以及
add_executable(topic_sub_node src/topic_sub.cpp)
ament_target_dependencies(topic_sub_node
"my_msgs"
"rclcpp"
)
install(TARGETS
topic_sub_node
DESTINATION lib/${PROJECT_NAME}
)
package.xml則是要加上
<depend>rclcpp</depend>
<depend>my_msgs</depend>
e.如果有一個topic,裡面有三個變數,這時node A只設定其中一個變數,然後傳給node B,這時node B去接這三個變數,node B會crash
但是麻煩的是,node B有可能是開callback去接,這時候會有機會直接結束程式而沒有任何資訊(ex core dump)
f.(2019-11-10 新增) 有的時候會發現一開始打的訊號listener沒有聽到,原因在於連線還沒成功就開始打訊號
這時可以嘗試使用Publisher內的get_subscription_count(),看看聽到的數量是否大於0
在ros1上則是使用getNumSubscribers()
g.(2019-11-13新增) 發現同一個node,但是呼叫兩次rclcpp::spin(node)會出這一個問題:
what(): Node has already been added to an executor.
所以要避免!
topic大概就是這一些注意事項
話說,最近發現好像有越來越多人在看我的blog和程式碼了,希望以後會越來越多人閱讀