写作目的:记录ROS编码最重要的部分,争取做到28原则,用7篇以内的文章讲清楚最常用的20%的内容。
明确ROS使用原则:将功能模块化,分解为一个个功能节点,相互联系
0. 安装ROS
安装ROS最重要的难点是rosdep update的问题,解决方法:先把文件下载到本地,修改相关代码中地址,然后就可以了。其他什么修改hosts、连接手机热点都是治标不治本。
1. 最常用内容:创建功能包
mkdir -p ~/catkin_ws/src
cd ~/catkin_ws/src
catkin_init_workspace #创建工作空间
cd ~/catkin_ws
catkin_make
catkin_make install #编译工作空间
source devel/setup.bash # 设置环境变量
echo $ROS_PACKAGE_PATH # 检查环境变量
################# 创建功能包 ########################
cd ~/catkin_ws/src
# catkin_create_pkg <package_name>[depend1][depend2] [depend3]
# 创建test_pkg这个功能包,相关依赖是std_msgs rospy roscpp
# 如果之后需要添加依赖,可以在CMakeLists.txt 和 package.xml中添加
catkin_create_pkg test_pkg std_msgs rospy roscpp
################ 添加代码文件 #########################
cd ~/catkin_ws
catkin_make
source ~/catkin_ws/devel/setup.bash
2. 功能包中编译代码
假设已经创建了test_pkg功能包,并编写一个简单的cpp。
#include<ros/ros.h>
int main(int argc,char **argv){
ros::init(argc,argv,"hello_ros");
ros::NodeHandle nh;
ROS_INFO_STREAM("hello,ROS!");
}
修改CMakeLists.txt
TODO
修改package.xml
上文创建功能包的时候忘记添加什么依赖,就添加什么依赖。参考package.xml 中已有依赖包的写法,来添加依赖。如下:
<buildtool_depend>catkin</buildtool_depend>
<build_depend>roscpp</build_depend>
<build_depend>std_msgs</build_depend>
<!-- <build_depend>sensor_msgs</build_depend> -->
<build_export_depend>roscpp</build_export_depend>
<build_export_depend>std_msgs</build_export_depend>
<!-- <build_export_depend>sensor_msgs</build_export_depend> -->
<exec_depend>roscpp</exec_depend>
<exec_depend>std_msgs</exec_depend>
3. 发布节点cpp
伪代码:
- 初始化ROS节点
- 向ROS Master 注册节点信息,包括发布的话题名和话题中的消息类型
- 创建消息数据
- 按照一定的频率循环发布消息
#include "ros/ros.h"
#include "geometry_msgs/Twist.h" //消息类型
int main(int argc, char **argv)
{
ros::init(argc,argv,"velocity_publisher"); // 初始化节点
ros::NodeHandle n; // 实例化节点
ros::Publisher
turtle_vel_pub = n.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel",10);
// 消息类型为 geometry_msgs::Twist, 话题为 "/turtle1/cmd_vel", 消息队列为10
ros::Rate loop_rate(10); // 指定发布消息的频率,一秒钟10次,配合Rate::sleep()
int count = 0;
while (ros::ok())
{
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;
}
4. 接收节点cpp
伪代码:
- 初始化ROS节点
- 订阅需要的话题
- 循环等待话题消息,接收到消息后进入回调函数
- 在回调函数中完成消息处理
#include "ros/ros.h"
#include "std_msgs/String.h"
//话题回调函数
void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
ROS_INFO("node_b is receiving [%s]", msg->data.c_str());
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "node_b");
//初始化ROS,节点命名为node_b,节点名必须唯一。
ros::NodeHandle n; //节点句柄实例化
ros::Subscriber
sub = n.subscribe("str_message", 1000, chatterCallback);
//向话题“str_message”订阅,一旦发布节点(node_a)在该话题上发布消息,本节点就会调用chatterCallbck函数。
ros::spin(); //程序进入循环,直到ros::ok()返回false,进程结束。
return 0;
}
5. 运行功能包中的功能
roscore # 运行roscore
cd ~/catkin_ws
source devel/setup.bash
rosrun 功能包 功能