零之前言
節點之間是通過一個ROS話題來互相通信的。A節點在一個話題上發佈按鍵輸入消息,而B節點則訂閱該話題以接收該消息。
根據ROS Wiki上的描述,我們很輕鬆可以知道,消息與話題的關係,通信機制是話題,而消息只是話題的數據結構。
ROS在命令行中可以通過命令查看話題及其使用的消息,也有可視化查看話題的工具,詳細的使用方法,可以查看ROS wiki上的理解ROS話題
根據我們創建消息,你會發現,它更像是C語言中的結構體。
一.創建一個消息
我們新創建一個功能包:
catkin_create_pkg top roscpp std_msgs message_generation message_runtime
再看看ROS Wiki上的原話:
接下來,還有關鍵的一步:我們要確保msg文件被轉換成爲C++,Python和其他語言的源代碼:
查看package.xml, 確保它包含一下兩條語句:
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
如果沒有,添加進去。 注意,在構建的時候,我們只需要"message_generation"。然而,在運行的時候,我們只需要"message_runtime"。
哦,我的老天,在創建包的時候,它已經爲我們創建好了。
然後就是創建我們的消息:
然後我們修改CMakeList.txt
,確保以下命令我們是修改了的:
find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs message_generation)
catkin_package(
...
CATKIN_DEPENDS message_runtime ...
...)
取消註釋並修改:
add_message_files(
FILES
Name.msg
)
generate_messages(
DEPENDENCIES
std_msgs
)
確保find_package裏只有message_generation, 而沒有message_runtime,否則會報錯。
編譯後我們查看一下,成功:
二.編寫一組發送接收節點
先不說代碼具體是啥意思,後面會一起講解
1.發送節點
在top/src裏編寫寫入puber.cpp
:
#include "ros/ros.h"
#include "top/Name.h"
#include "sstream"
int main(int argc, char **argv)
{
std::stringstream ss;
top::Name msg;
ros::init(argc, argv, "publisher");
ros::NodeHandle h;
ros::Publisher puber = h.advertise<top::Name>("Name_Info", 10);
ros::Rate loop_rate(1);
ss << "A B";
while (ros::ok())
{
ss >> msg.first_name;
ss >> msg.last_name;
ROS_INFO("I Send [%s %s]", msg.first_name.c_str(), msg.last_name.c_str());
puber.publish(msg);
loop_rate.sleep();
}
return 0;
}
2.接收節點
寫入suber.cpp
#include "ros/ros.h"
#include "top/Name.h"
void infoCallback(const top::Name::ConstPtr& msg)
{
ROS_INFO("Name Changed [%s %s]", msg->last_name.c_str(), msg->first_name.c_str());
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "suber");
ros::NodeHandle n;
ros::Subscriber sub = n.subscribe("Name_Info", 1000, infoCallback);
ros::spin();
return 0;
}
3.修改CMakeList.txt
除了創建消息的時候,我們修改了CMakeList中關於話題使用的消息的配置,現在是節點配置,加入:
add_executable(puber src/puber.cpp)
target_link_libraries(puber ${catkin_LIBRARIES})
add_executable(suber src/suber.cpp)
target_link_libraries(suber ${catkin_LIBRARIES})
4.編譯運行
roscore
rosrun top puber
rosrun top suber
rqt_graph
Nice!搞定!