零、工作空间
//创建工作空间
mkdir catkin_ws
cd catkin_ws/
mkdir src
cd src/
catkin_init_workspace //将文件夹变成ros工作空间,属性变化
//编译工作空间
cd~/catkin_ws/ //回到根目录
catkin_make //产生工作空间
catkin_make install //生成install文件夹
//设置环境变量
source devel/setup.bash
//检查环境变量
echo $ROS_PACKAGE_PATH
0.1 src:代码空间
放功能包源码
0.2 build:编译空间
开发中间的二进制文件
0.3 devel:开发空间
开发过程中的可执行文件和一些库文件
0.4 install:安装空间
最终编译生成的可执行文件
一、文件系统
1.1元功能包
组织用于同一目的的功能包
1.2功能包
ROS软件中的基本单元,包含节点源码、配置文件等,同一个工作空间不允许存在同名功能包。
//创建功能包
cd ~/catkin_ws/src //功能包放在src文件下
catkin_create_pkg 文件名_依赖的文件名或库1_依赖的文件名或库2
常用的依赖库有roscpp rospy std_msgs geometry_msgs
创建后会生成一些文件夹,其中src文件用于储存代码文件,include用于放置头文件。
//编译功能包
cd ~/catkin_ws //回到根目录编译
catkin_make
source ~/catkin_ws/devel/setup.bash //设置工作空间环境变量
package.xml文件内容:
1 文件、内容信息和功能包维护者信息
2 开源许可
3 功能包依赖信息<bulid_depend>、<exec_depend>可以在此处更改拓展依赖的库
CMakeLists.txt文件内容:
描述功能包的编译规则
添加库时需要有相应的修改,可以见最后的链接文章
1.3功能包清单
记录功能包基本信息
二 、节点(Node)——执行单元
独立运行的可执行文件
不同节点可用不同的编程语言,可分布式运行在不同的主机
在系统中名称需唯一
三、节点管理器(ROS Master)——控制中心
为节点提供命名与注册服务(节点是待婚男女,管理器就是婚介所)
跟踪记录通讯、辅助节点互相查找
提供参数服务器
四、通信方式
4.1话题通信Topic
使用publish——subscribe模型,单向、异步传输,同一个话题的订阅者或发布者不唯一。
4.1.1消息Message
话题中的数据,以.msg文件定义,编译过程中生成对应的代码。
发布和接受的数据类型一定要相同,查看.msg文件以确定。
4.1.2 Publisher的编程实现
主要步骤:
0 创建一个功能包
本示例使用了topic方法在ros中实现了两个节点(msg_pub——msg_sub)的单向信息交流
使用自定义消息类型话题(msg文档)储存了
uint8 id
uint8 weight
uint8 height
char name
四个信息
msg_pub作为publisher以5HZ的频率发布为/person_message的话题
msg_sub作为subscriber订阅/person_message话题
话题内容包括person_msg.msg内的四个信息
功能包的依赖有roscpp rospy std_msgs geometry_msgs
环境配置详见CMakeLists.txt
需要在package.xml中添加
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
的依赖路径
1 初始化ros节点
2 创建一个publisher,包括话题名和消息类型
3 创建消息数据
4 发布消息
代码文件放在功能包的src文件中
//代码将发布发布名为/person_message的话题,数据类型由person_msg.msg定义
#include <ros/ros.h>
#include "std_message/person_msg.h"//包名/变量文件
int main(int argc, char **argv)
{
ros::init(argc, argv, "msg_pub"); //初始化
ros::NodeHandle nh; //节点句柄初始化
ros::Publisher pb = nh.advertise<std_message::person_msg>("/person_message", 5); //发布名为/person_message的话题,队列长度5
ros::Rate loop_rate(5); //设置发布频率为5hz
while (ros::ok()) //判定ros是否准备就绪
{
std_message::person_msg person; //实例化person对象
person.name = "zhou"; //成员变量赋值
person.id = 666;
person.height = 178;
person.weight = 75;
pb.publish(person);//发布person
ROS_INFO("Publish students' informations name:%s id:%d height:%d weight:%d", person.name.c_str(), person.id, person.height, person.weight);//打印信息
// 按照循环频率延时
loop_rate.sleep();
}
return 0;
}
节点句柄
用于管理ROS相关API的一些资源,如发布者、api调用都是用节点句柄来调用的。
队列长度
发布者发布信息时,底层没办法及时反应发布频率,先把发布的数据放进队列,再从队列发布。若队列数据与发送数据不匹配,会先发送时间戳最新的数据。
5 配置CMakeLists.txt
#找到库
find_package(catkin REQUIRED COMPONENTS
geometry_msgs
roscpp
rospy
std_msgs
#turtlesim
message_generation
)
#加入自定义变量文件
add_message_files(
FILES
person_msg.msg
)
generate_messages(
DEPENDENCIES
std_msgs
)
include_directories(include ${catkin_INCLUDE_DIRS})#设置头文件的相对路径
add_executable(msg_pub src/msg_pub.cpp)#设置需要编译的代码和生成的可执行文件
target_link_libraries(msg_pub ${catkin_LIBRARIES})#设置连接库
add_dependencies(msg_pub ${PROJECT_NAME}_generate_messages_cpp)#添加依赖的路径
add_executable(msg_sub src/msg_sub.cpp)
target_link_libraries(msg_sub ${catkin_LIBRARIES})
add_dependencies(msg_sub ${PROJECT_NAME}_generate_messages_cpp)
复制以上代码到 CMakeLists.txt中,基本就是以上三个部分需要修改,如自己再添加相关msg定义文件,也是修改以上代码。
6 配置package.xml
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
例如
7 编译
cd ~/catkin_ws //回到根目录
catkin_make //编译
source devel/setup.bash //配置环境变量
rosrun turtlesim turtlesim_node
rosrun learning_topic velocity_publisher
4.1.3 Subscriber的编程实现
与publisher类似,src文件中的代码如下
//该代码定义了/person_message节点发出的消息,数据类型为person_msg.msg文件定义
#include <ros/ros.h>
#include "std_message/person_msg.h"//包名/变量文件
//创建回调函数
void msg_Callback(const std_message::person_msg::ConstPtr& msg)//包名::变量名::接收信息
{
ROS_INFO("Subcribe students' informations: name:%s id:%d height:%d weight:%d", msg->name.c_str(), msg->id, msg->height, msg->weight); //提示消息
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "msg_sub"); //ros初始化
ros::NodeHandle nh; //节点句柄初始化
ros::Subscriber pb = nh.subscribe("/person_message", 5, msg_Callback); //订阅"/person_message"话题
// 循环等待回调函数
ros::spin();
return 0;
}
在回调函数中进行接受消息的处理,要保证回调函数处理时间较短,否则容易卡住。
1 配置CMakeLists.txt代码如下
#找到库
find_package(catkin REQUIRED COMPONENTS
geometry_msgs
roscpp
rospy
std_msgs
#turtlesim
message_generation
)
#加入自定义变量文件
add_message_files(
FILES
person_msg.msg
)
generate_messages(
DEPENDENCIES
std_msgs
)
include_directories(include ${catkin_INCLUDE_DIRS})#设置头文件的相对路径
add_executable(msg_pub src/msg_pub.cpp)#设置需要编译的代码和生成的可执行文件
target_link_libraries(msg_pub ${catkin_LIBRARIES})#设置连接库
add_dependencies(msg_pub ${PROJECT_NAME}_generate_messages_cpp)#添加依赖的路径
add_executable(msg_sub src/msg_sub.cpp)
target_link_libraries(msg_sub ${catkin_LIBRARIES})
add_dependencies(msg_sub ${PROJECT_NAME}_generate_messages_cpp)
2 配置package.xml
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
接着使用rosrun 文件名 运行文件
有关自定义话题消息的更多实现方法,详见文章ROS系列教程二:自定义消息类型话题的发布及订阅_ros小车怎么发布接收话题-CSDN博客