[ROS] 创建并启动功能包 & 收发topic例程
ROS 版本:melodic
1. 创建工作环境 ws
(如果已经有工作环境可忽略)
mkdir -p ~/catkin_ws/src
cd ~/catkin_ws/
catkin_make
2. 在 ws 中创建 package
catkin_create_pkg 只是创建了包目录和默认的配置版本,没有做啥其他神奇的事情。
cd ~/catkin_ws/src
catkin_create_pkg testpkg roscpp std_msgs # 功能包依赖项为cpp stdmsg
cd ..
catkin_make
3. 在 package 中创建节点
3.1 创建发布节点 publisher
topic 发布语法
ros::Publisher pub = node_handle.advertise<message_type>(topic_name, queue_size);
- node_handle:
ros::NodeHandle
类的一个对象 - message_type: 模板参数,表示我们要发布的数据的类型
- topic_name: 一个字符串,话题的名称;该名称将会在
rostopic list
或者rqt_graph
中展示 - queue_size: 一个整数,表示发布者消息序列的大小,它是一个队列
如果你想发布多个话题,需要创建多个
ros::Publisher
对象。
如何控制消息发布的频率
可能很多人会想到使用简单的固定延时,如sleep、usleep,但是如果程序运行中有一些延时产生,那么频率可能就发生波动。而使用 rate::sleep()
方法,ROS 将会自动计算延时,并在等待时长中减除。
使用方法如下:
ros::Rate rate(10); // 10 means 10hz
while(1)
{
.....
rate.sleep();
.....
}
示例代码
mkdir -p ~/catkin_ws/src/testpkg/src
cd ~/catkin_ws/src/testpkg/src
vim publisher.cpp
#include "ros/ros.h"
#include "std_msgs/String.h"
#include <sstream>
int main(int argc, char **argv)
{
ros::init(argc, argv, "publisher"); //节点名称要保持唯一性
ros::NodeHandle n;
//发布一个消息类型为std_msgs/String,命名为chatter的话题
//定义消息队列大小为1000,即超过1000条消息之后,旧的消息就会丢弃
ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);
//指定发布消息的频率10Hz
ros::Rate loop_rate(10);
//通过 Rate::sleep()来处理睡眠的时间来控制对应的发布频率。
int count = 0;
while (ros::ok())
{
std_msgs::String msg;
std::stringstream ss;
ss << "hello world " << count;
msg.data = ss.str();
ROS_INFO("PubMsg >> %s", msg.data.c_str());
chatter_pub.publish(msg);
//确保消息发出去,非阻塞
ros::spinOnce();
//根据之前ros::Rate loop_rate(10)的定义来控制发布话题的频率。定义10即为每秒10次,100毫秒
loop_rate.sleep();
count++;
}
return 0;
}
3.2 创建监听节点 listerner
topic 监听语法
ros::Subscriber sub = node_handle.subscribe(topic_name, queue_size, pointer_to_callback_function);
- topic_name:同上
- queue_size:一个整数,表示接收消息的队列大小,当新消息到达时,保存到队列中,直到ROS有空闲时,从队列取出消息并执行相应的回调函数。
- pointer_to_callback_function:一个函数指针,指向消息回调函数
示例代码
~/catkin_ws/src/testpkg/src
vim listener.cpp
#include "ros/ros.h"
#include "std_msgs/String.h"
void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
ROS_INFO("SubMsg << %s", msg->data.c_str());
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "listener");
ros::NodeHandle n;
ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);
//调用此函数将不返回,直到 ros::ok()返回false。
//接收到消息不会马上被调用回调函数,而是要等到 spin 或者 spinOnce 执行才被调用。
ros::spin();
return 0;
}
4. 修改 CMakeList.txt
添加依赖库
依赖其他库可以添加到 COMPONENTS 关键字后边
find_package(catkin REQUIRED COMPONENTS
roscpp
std_msgs
message_generation
)
generate_messages(
DEPENDENCIES
std_msgs
)
catkin_package(
CATKIN_DEPENDS roscpp std_msgs message_runtime
)
声明可执行文件
涉及几个关键词
-
add_executable
:声明可执行文件的文件名 -
target_link_libraries
:告诉 Cmake 当链接此可执行文件时需要链接那些库(当然这些库需要在上边的 find_package 中添加) -
add_dependencies
include_directories(
include
${catkin_INCLUDE_DIRS}
)
add_executable(
publisher
src/publisher.cpp
)
target_link_libraries(
publisher
${catkin_LIBRARIES}
)
add_dependencies(
publisher
testpkg_generate_messages_cpp
)
add_executable(
listener
src/listener.cpp
)
target_link_libraries(
listener
${catkin_LIBRARIES}
)
add_dependencies(
listener
testpkg_generate_messages_cpp
)
5. 修改package.xml
package.xml 是包的清单文件
-
<build_depend>
:编译依赖 -
<exec_depend>
:运行依赖
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
6. 编译
cd ~/catkin_ws/
catkin_make
如果成功你将看到
#### Running command: "make cmake_check_build_system" in "/home/dev/catkin_ws/build"
####
####
#### Running command: "make -j4 -l4" in "/home/dev/catkin_ws/build"
####
[ 0%] Built target std_msgs_generate_messages_nodejs
[ 0%] Built target std_msgs_generate_messages_py
[ 0%] Built target std_msgs_generate_messages_cpp
[ 0%] Built target std_msgs_generate_messages_lisp
[ 0%] Built target testpkg_generate_messages_py
[ 0%] Built target std_msgs_generate_messages_eus
[ 0%] Built target testpkg_generate_messages_lisp
[ 0%] Built target testpkg_generate_messages_cpp
[ 20%] Built target testpkg_generate_messages_eus
[ 20%] Built target testpkg_generate_messages_nodejs
Scanning dependencies of target listener
[ 40%] Building CXX object testpkg/CMakeFiles/listener.dir/src/listener.cpp.o
[ 40%] Built target testpkg_generate_messages
[ 80%] Built target publisher
[100%] Linking CXX executable /home/dev/catkin_ws/devel/lib/testpkg/listener
[100%] Built target listener
7. 运行节点
Terminal 1
启动你的 ROS
$ roscore
Terminal 2
启动监听节点
$ source ~/catkin_ws/devel/setup.bash
$ rosrun testpkg listener
setup.bash 脚本由工作区生成,用于设置若干环境变量,使 ROS 能够找到你创建的功能包和可执行文件
Terminal 3
启动发布节点
$ source ~/catkin_ws/devel/setup.bash
$ rosrun testpkg publisher