ROS基础例程学习:节点(node)与话题(topic)
结构
例程
cd catkin_ws/src
catkin_create_pkg beginner_tutorials std_msgs roscpp rospy
cd .. //回到catkin_ws
catkin_make //会生成src,include,package.xml,CMakelists.txt
创建两个cpp文件,作为两个node。我们从代码以及运行结果来学习节点与话题及其关系。
roscd beginner_tutorials
cd src
gedit listener.cpp
gedit talker.cpp
这两个cpp文件的内容为
Listener
#include "ros/ros.h" //ros.h 包含ros程序常用的头文件。
#include "std_msgs/String.h" //ros 内置字符串数据类型。
//回调函数定义,参数类型需要与所订阅的消息类型保持一致
void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
ROS_INFO("I heard your [%s] and I love ya too, talker !", msg->data.c_str());
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "listener"); //初始化ros,并命令节点名。
ros::NodeHandle n; //初始化节点,调用ros api接口句柄。
ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback); //定义一个订阅者。
ros::spin(); //不返回函数,监听订阅者中的回调队列,并执行回调函数。
return 0; //正常运行时,不会执行到。
}
Talker
#include "ros/ros.h" //ros.h 包含ros程序常用的头文件。
#include "std_msgs/String.h" //ros 内置字符串数据类型。
#include <sstream> //c++ 流处理函数
int main(int argc, char **argv)
{
ros::init(argc, argv, "talker"); //初始化ros,并命令节点名。
ros::NodeHandle n; //初始化节点,调用ros api接口句柄。
//定义一个发布者
ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1);
ros::Rate loop_rate(10); //设置发布频率
int count = 0; //发布消息计数
while (ros::ok()){ //检测节点是否正常运行
std_msgs::String msg;
std::stringstream ss;
ss << "I love you, listener " << count;
msg.data = ss.str(); //填充要发布的消息
ROS_INFO("%s", msg.data.c_str()); //打印消息
chatter_pub.publish(msg); //发布消息
ros::spinOnce(); //处理回调函数,会返回,这里也可以不加,因为此节点没有回调函数。
loop_rate.sleep(); //与Line 11配套使用,用于控制发布频率。
++count; //消息计数。
}
return 0;
}
配置CMakelists.txt
在第155行加入
add_executable(listener src/listener.cpp)
target_link_libraries(listener ${catkin_LIBRARIES})
add_dependencies(listener ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
add_executable(talker src/talker.cpp)
target_link_libraries(talker ${catkin_LIBRARIES})
add_dependencies(talker ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
回到catkin_ws编译 catkin_make
运行
rosrun beginner_tutorials listener
rosrun beginner_tutorials talker
查看运行的节点
rosnode list
共三个节点在运行
打开rqt_graph可以发现
两个节点(node):talker & listener
一个话题(topic):chatter
rosnode info /talker
可以看到该节点发出两个topic,除了代码里的talker,还有一个rosout.
这个rosout从哪里冒出来的?
roscore其实是启动了三个进程,可以通过执行:一个是roscore,一个是rosmaster,一个是rosout,roscore作为父进程,启动后面两个进程,rosmaster即为节点管理器,rosout是log输出管理,也就是输出日志。任一运行的节点都会向rosout节点发送rosout话题。
所以说,只要运行roscore,就必然会有rosout节点以及rosout话题。
接着看:talker节点发出两个topic,没有订阅topic;与rosout和listener的连接方式为均outbound(向外),即talker发送rosout话题到rosout节点;talker发布chatter话题到listener节点。
同理看看listener节点,相信你可以举一反三
rosnode info /listener
再看看话题的具体内容
参考Reference
https://mp.weixin.qq.com/s?__biz=MzAwNTg5NzUyOA==&mid=2247483780&idx=1&sn=9a38c98853f011018fefa14772f97197&chksm=9b14edd3ac6364c5b98cdc74b62cee5332f8301d76c057c357d92b4c2e2855f1da84a6903670&scene=21#wechat_redirect
https://github.com/ahuer2435/ros_program/blob/master/catkin_ws/src/beginner_tutorials/CMakeLists.txt