ROS学习笔记5-基于Ubuntu 16.04虚拟机编写ROS发布者节点与订阅者节点通讯
运行环境:Ubuntu 16.04 64位虚拟机ROS消息通信中使用的发布者(Publisher)和订阅者(Subscriber)可以被发送和接收所代替。在ROS中,发送端称为发布者,接收端称为订阅者。本节旨在创建一个简单的msg文件,并创建和运行发布者和订阅者节点。创建功能包以下命令是创建ros_tutorials_topic功能包的命令。这个功能包依赖于message_gen...
运行环境:Ubuntu 16.04 64位虚拟机
ROS消息通信中使用的发布者(Publisher)和订阅者(Subscriber)可以被发送和接收所代替。在ROS中,发送端称为发布者,接收端称为订阅者。本节旨在创建一个简单的msg文件,并创建和运行发布者和订阅者节点。
创建功能包
以下命令是创建ros_tutorials_topic功能包的命令。这个功能包依赖于message_generation、std_msgs和roscpp功能包,因此将这些用作依赖选项。第二行命令意味着将使用创建新的功能包时用到的message_generation表示将使用创建新消息的功能包
std_msgs(ROS标准消息功能包)和roscpp(在ROS中使用C/C ++的客户端程序库)必须在创建功能包之前安装。用户可以在创建功能包时指定这些相关的功能包设置,但也可以在创建功能包之后直接在package.xml中修改。
$ cd ~/catkin_ws/src
$ catkin_create_pkg ros_tutorials_topic message_generation std_msgs roscpp
创建功能包时,将在~/catkin_ws/src目录中创建ros_tutorials_topic功能包目录,并在该功能包目录中创建ROS功能包的默认目录和CMakeLists.txt和package.xml文件。
然后是修改package.xml文件
注意:《ROS_Robot_Programming_CN.pdf》文档7.2.2章节有错,按照里面修改的编译会报错,
报错内容如下:
《ROS_Robot_Programming_CN.pdf》文档下载地址:
https://download.csdn.net/download/gs1069405343/11029109
正确的修改如下:
<license>Apache License 2.0</license>
<buildtool_depend>catkin</buildtool_depend>
<build_depend>roscpp</build_depend>
<build_depend>std_msgs</build_depend>
<build_export_depend>roscpp</build_export_depend>
<build_export_depend>std_msgs</build_export_depend>
<exec_depend>roscpp</exec_depend>
<exec_depend>std_msgs</exec_depend>
修改构建配置文件(CMakeLists.txt)
详细的请参考ROS_Robot_Programming_CN.pdf 见第4.9节 或者学习笔记4
当前修改内如如下:
find_package(catkin REQUIRED COMPONENTS
message_generation
roscpp
std_msgs
)
add_message_files(
FILES
MsgTutorial.msg
# Message1.msg
# Message2.msg
)
generate_messages(
DEPENDENCIES
std_msgs
)
catkin_package(
# INCLUDE_DIRS include
LIBRARIES ros_tutorials_topic
# CATKIN_DEPENDS message_generation roscpp std_msgs
CATKIN_DEPENDS roscpp std_msgs
# DEPENDS system_lib
)
add_executable(topic_publisher src/topic_publisher.cpp)
add_executable(topic_subscriber src/topic_subscriber.cpp)
add_dependencies(topic_publisher ${${PROJECT_NAME}_EXPORTED_TARGETS}
${catkin_EXPORTED_TARGETS})
add_dependencies(topic_subscriber ${${PROJECT_NAME}_EXPORTED_TARGETS}
${catkin_EXPORTED_TARGETS})
target_link_libraries(topic_publisher ${catkin_LIBRARIES})
target_link_libraries(topic_subscriber ${catkin_LIBRARIES})
修改完之后,保存退出。
创建消息文件
在上述的CMakeLists.txt文中添加了如下选项。
add_message_files(FILES MsgTutorial.msg)
这意味着在构建时要包含消息MsgTutorial.msg,该消息将在此节点中被使用。现在
我们还没有创建MsgTutorial.msg,因此按以下顺序创建它:
$ roscd ros_tutorials_topic → 移动到功能包目录
$ mkdir msg → 功能包中创建新的msg消息目录
$ cd msg → 转到创建的msg目录
$ gedit MsgTutorial.msg → 创建新的MsgTutorial.msg文件并修改内容
然后写入如下内容:
time stamp
int32 data
创建发布者节点
创建源码文件
$ roscd ros_tutorials_topic/src → 移至src目录,该目录是功能包的源代码目录
$ sudo gedit topic_publisher.cpp → 新建源文件并修改内容
在文件中添加如下代码
// ROS默认头文件
#include "ros/ros.h"
// MsgTutorial消息头文件( 构建后自动生成)
#include "ros_tutorials_topic/MsgTutorial.h"
// 节点主函数
int main(int argc, char **argv)
{
// 初始化节点名称
ros::init(argc, argv, "topic_publisher");
// 声明一个节点句柄来与ROS系统进行通信
ros::NodeHandle nh;
// 声明发布者,创建一个使用ros_tutorials_topic功能包的MsgTutorial 消息文件的
// 发布者ros_tutorial_pub。话题名称是"ros_tutorial_msg",
// 消息文件发布者队列(queue)的大小设置为100
ros::Publisher ros_tutorial_pub = nh.advertise<ros_tutorials_topic::MsgTutorial>("ros_tutorial_msg", 100);
// 设定循环周期。"10"是指10Hz,是以0.1秒间隔重复
ros::Rate loop_rate(10);
// 以MsgTutorial消息文件格式声明一个 叫做msg的消息
ros_tutorials_topic::MsgTutorial msg;
// 声明要在消息中使用的变量
int count = 0;
while (ros::ok())
{
// 把当前时间传给msg的下级消息stamp
msg.stamp = ros::Time::now();
// 将变量count的值传给下级消息data
msg.data = count;
// 显示stamp.sec消息
ROS_INFO("send msg = %d", msg.stamp.sec);
// 显示stamp.nsec消息
ROS_INFO("send msg = %d", msg.stamp.nsec);
// 显示data消息
ROS_INFO("send msg = %d", msg.data);
// 发布消息。
ros_tutorial_pub.publish(msg);
// 按照上面定义的循环周期进行暂歇
loop_rate.sleep();
// 变量count增加1
++count;
}
return 0;
}
然后保存退出。
创建订阅者节点
$ roscd ros_tutorials_topic/src → 移动到src目录,该目录是功能包的源代码目录
$ sudo gedit topic_subscriber.cpp → 创建和修改新的源代码文件
代码如下:
/ ROS的默认头文件
#include "ros/ros.h"
// MsgTutorial消息头文件(构建后自动生成)
#include "ros_tutorials_topic/MsgTutorial.h"
// 这是一个消息后台函数,
// 此函数在收到一个下面设置的名为ros_tutorial_msg的话题时候被调用。
// 输入的消息是从ros_tutorials_topic功能包接收MsgTutorial消息。
void msgCallback(const ros_tutorials_topic::MsgTutorial::ConstPtr& msg)
{
ROS_INFO("recieve msg = %d", msg->stamp.sec); // 显示stamp.sec消息
ROS_INFO("recieve msg = %d", msg->stamp.nsec); // 显示stamp.nsec消息
ROS_INFO("recieve msg = %d", msg->data); // 显示data消息
}
// 节点主函数
int main(int argc, char **argv)
{
// 初始化节点名称
ros::init(argc, argv, "topic_subscriber");
// 声明用于ROS系统和通信的节点句柄
ros::NodeHandle nh;
// 声明订阅者,创建一个订阅者ros_tutorial_sub,
// 它利用ros_tutorials_topic功能包的的MsgTutorial消息文件。
// 话题名称是"ros_tutorial_msg",订阅者队列(queue)的大小设为100。
ros::Subscriber ros_tutorial_sub = nh.subscribe("ros_tutorial_msg", 100, msgCallback);
// 用于调用后台函数,等待接收消息。在接收到消息时执行后台函数。
ros::spin();
return 0;
}
然后保存退出
$ cd ~/catkin_ws → 移动到catkin目录
$ catkin_make → 执行catkin构建
运行发布者:
$ roscore
$ rosrun ros_tutorials_topic topic_publisher
运行订阅者:
$ rosrun ros_tutorials_topic topic_subscriber
下面,我们使用rostopic命令获取topic_publisher发布的话题吧。首先,我们来看一下ROS网络当前正在使用的话题列表。通过将list选项添加到rostopic命令来查看是否存在ros_tutorial_msg话题。
$ rostopic list
/ros_tutorial_msg
/rosout
/rosout_agg
接下来,让我们看看我们运行的发布者节点发布的消息。换句话说,是检查ros_tutorial_msg话题消息。您可以看到发布的消息
$ rostopic echo /ros_tutorial_msg
源码下载:
https://download.csdn.net/download/gs1069405343/11029120
更多推荐
所有评论(0)