ros的节点之间的通信靠话题消息或者服务,每个节点可能是发布者节点、订阅者节点、客户端节点、服务端节点。
话题是节点之间传输数据的管道,传送的数据叫做消息。
工作空间:存放工程开发相关的文件与文件夹
src:代码空间
build:编译空间
devel:开发空间
install:包安装空间
1 . 在主目录创建工作空间文件夹
mkdir XX
XX 为工作空间文件名
2 . 在工作空间文件夹中创建 src
cd XX
mkdir src
3 . 将src设置为ros的工作空间文件夹
cd src
catkin_init_workspace
这里生成了一个CMakeLists.txt,有了该文件后说明该路径就是我们的工作空间了
4 . 编译
cd ..
返回工作空间的根目录
catkin_make
会产生build和devel文件
首次编译可能会报错,试试:
catkin_make -DPYTHON_EXECUTABLE=/usr/bin/python3
5 . 产生install文件
catkin_make insatll
6 . 在src文件夹中创建功能包
cd src
catkin_create_pkg learning_topic rospy roscpp std_msgs turtlesim
learning_topic 为功能包名字(不允许相同名称的功能包),名称后面则为包的依赖,创建完成后功能包会生成以下文件
include 可以放置的头文件,src 放置代码文件
catkin_make
8 . 设置工作空间的环境变量
source devel/setup.bash
查看环境变量
echo $ROS_PACKAGE_PATH
9 . 在功能包的src中添加代码文件
touch topiccpp.cpp
/*
发布turtle1/cmd_vel话题,消息类型为geometry_msgs::Twist
*/
#include
#include
int main(int argc, char **argv)
{
// ROS节点初始化,节点名字不能重复
// 节点-->话题-->发布的消息类型-->发布给谁
ros::init(argc, argv, "velocity_publisher");
// 创建节点句柄,管理节点资源
ros::NodeHandle n;
// 创建一个publisher,发布到名为/turtle1/cmd_vel的topic,消息类型为geometry_msgs::Twist,
// 队列长度10,速度太快就等待发布队列
ros::Publisher turtle_vel_pub = n.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel", 10);
// 设置循环的频率
ros::Rate loop_rate(10);
int count = 0;
while(ros::ok())
{
// 初始化geomery_msgs::Twist类型的消息
geometry_msgs::Twist vel_msg;
vel_msg.linear.x = 0.5;
vel_msg.angular.z = 0.2;
// 发布消息
turtle_vel_pub.publish(vel_msg);
ROS_INFO("Publish turtle velocity command[%0.2f m/s, %0.2f rad/s]",
vel_msg.linear.x, vel_msg.angular.z);
// 按照循环频率延时
loop_rate.sleep();
}
return 0;
}
10 . 在Cmakelists中配置编译规则
add_executable(velocity_publisher src/topiccpp.cpp)
将文件 src/topiccpp.cpp 编译为可执行文件 velocity_publisher
target_link_libraries(velocity_publisher ${catkin_LIBRARIES})
将可执行文件 velocity_publisher 链接到ROS库
catkin_make
第1种方法:将工程添加到环境变量
source devel/setup.bash
第2种方法:在home主目录文件夹下,按 ctrl + h 显示隐藏文件,然后打开文件 .bashrc
然后在文件末尾添加路径:
source /home/lplp/autocar_ws/devel/setup.bash
12 . 新开终端启动 ROS Master(控制中心)
roscore
新开终端运行海龟仿真节点
rosrun turtlesim turtlesim_mode
turtlesim 为功能包的名字,turtlesim_mode 为功能包中节点的名字
新开终端运行键盘输入节点
rosrun turtlesim turtle_teleop_key
第1种:新开终端运行:可以查看节点信息
rqt_graph
rosnode list
rosnode info /turtlesim
publications:发布的话题
subscriptions:订阅的话题
services:服务
② 查看话题信息
rostopic list
③ 给话题发布消息:
-r 后为发布数据的频率(指令发布次数)
/turtle1/cmd_vel 为话题名称
geometry_msgs/Twist 为话题发布消息的数据类型
"linear:… 为具体的数据
rostopic pub -r 10 /turtle1/cmd_vel geometry_msgs/Twist "linear:
x: 0.0
y: 0.0
z: 0.0
angular:
x: 0.0
y: 0.0
z: 0.0"
④ 查看发布消息的结构:
rosmsg show geometry_msgs/Twist
rosservice list
rosservice call /spawn "x: 0.0
y: 0.0
theta: 0.0
name: ''"
⑥ 记录节点产生的数据(默认保存到桌面):
rosbag record -a -O cmd_record
-a 为保存所有节点数据
-O 为保存压缩包格式
cmd_record 为压缩包名称
播放保存的数据:
rosbag play cmd_record.bag
13 . 订阅话题消息,创建 .cpp 文件:
**
该例程将订阅/turtle1/pose话题,消息类型turtlesim::pose
**/
#include
#include "turtlesim/Pose.h"
// 接收到订阅的消息后,会进入消息回调函数
void poseCallback(const turtlesim::Pose::ConstPtr& msg)
{
// 将接收到的消息打印出来
// 最好保证回调函数的数据处理时间不会太长
ROS_INFO("Turtle pose: x:%0.6f, y:%0.6f", msg->x, msg->y);
}
int main(int argc, char **argv)
{
// 初始化ROS节点
ros::init(argc, argv, "pose_subscriber");
// 创建节点句柄
ros::NodeHandle n;
// 创建一个Subscriber,订阅名为/turtle1/pose的话题,注册回调函数poseCallback
// 一旦接收到了消息,则立马跳转到回调函数 poseCallback
ros::Subscriber pose_sub = n.subscribe("/turtle1/pose", 10, poseCallback);
// 循环等待回调函数
ros::spin();
return 0;
}
参考资料:https://www.bilibili.com/video/BV1zt411G7Vn?p=9&vd_source=a85b1d28d237161903d04396c133cacc