【ROS无人驾驶系列】1 软件环境基础(ROS CMake) 上
7月在线课程【全】无人驾驶系列知识入门到提高
学习笔记
01 创建ROS的工作空间
1.1 创建catkin工作空间
创建一个 catkin 工作空间:
$ mkdir -p ~/catkin_ws/src # 创建了第二层级的文件夹src,这是放ROS软件包的地方
$ cd ~/catkin_ws/src # 进入工作空间,catkin_make必须在工作空间这个路径上执行
$ catkin_init_workspace # 初始化src目录,生成的CMakeLists.txt为功能包编译配置
1.2 编译工作空间
$ cd ~/catkin_ws # 回到工作空间,catkin_make必须在工作空间下执行;
$ catkin_make # 开始编译,调用系统自动完成编译和链接过程,构建
生成目标文件
注意: catkin编译之前需要回到工作空间目录,catkin_make在其他路径下编译不会成功。
编译完成后,如果有新的目标文件产生(原来没有),那么一般紧跟着要source刷新环境,使得系统能够找到刚才编译生成的ROS可执行文件。
这个细节比较容易遗漏,致使后面出现可执行文件无法打开等错误。
1.3 设置环境变量
另外,如果你查看一下当前目录应该能看到 ‘build’ 和 ‘devel’ 这两个文件夹。在 ‘devel’ 文件夹里面你可以看到几个 setup.*sh 文件。source 这些文件中的任何一个都可以将当前工作空间设置在ROS工作环境的最顶层。接下来首先 source 一下新生成的 setup.*sh 文件:
$ source devel/setup.bash # 刷新坏境
1.4 检查环境变量
要想保证工作空间已配置正确,需确保ROS_PACKAGE_PATH环境变量包含你的工作空间目录,采用以下命令查看:
$ echo $ROS_PACKAGE_PATH
# 出现 /home/<youruser>/catkin_ws/src:/opt/ros/kinetic/share
到此你的工作环境已经搭建完成。
创建好了一个ROS的工作空间了,接下来就是在catkin_ws工作空间下的src目录下新建功能包并进行功能包程序。
02 功能包的创建
在catkin_ws/src/目录下新建功能包topic_example,并在创建时显式的指明依赖roscpp和std_msgs。打开命令行终端,输入命令:
$ cd ~/catkin_ws/src
#创建功能包topic_example时,显式的指明依赖roscpp和std_msgs,
#依赖会被默认写到功能包的CMakeLists.txt和package.xml中
$ catkin_create_pkg july_say roscpp std_msgs
03 功能包的源代码编写
功能包中需要编写两个独立可执行的节点,一个节点用来发布消息,另一个节点用来订阅消息,所以需要在新建的功能包july_say/src/目录下新建两个文件talker.cpp和listener.cpp,并将下面的代码分别填入。
3.1 编写发布器节点(july_say_node.cpp)
『节点』(Node) 是指 ROS 网络中可执行文件。接下来,我们将会创建一个发布器节点(“talker”),它将不断的在 ROS 网络中广播消息。
如何实现一个发布者
- 初始化ROS系统;
- 在 ROS 网络内广播我们将要在 july 话题上发布 std_msgs/String 类型的消息;
- 以每秒 10 次的频率在 chatter 上发布消息。
// ros/ros.h 是一个实用的头文件,它引用了 ROS 系统中大部分常用的头文件。
#include "ros/ros.h"
/*这引用了 std_msgs/String 消息, 它存放在 std_msgs package 里,是由 String.msg 文件自动生成的头文件。需要关于消息的定义,可以参考 msg 页面。
*/
#include "std_msgs/String.h"
#include <sstream>
int main(int argc, char ** argv) {
// 初始化 ROS;
// 可以指定节点名称,节点的名称必须唯一。
ros::init(argc, argv, "july_talker");
// 为这个进程的节点创建一个句柄;
/* 第一个创建的 NodeHandle 会为节点进行初始化,最后一个销毁的 NodeHandle 则会释放该节点所占用的所有资源。
*/
ros::NodeHandle n;//NodeHandle是ros提供的一些类,可以通过这个类来实例化一些publisher,即我这个节点要发布的哪些数据
//创建一个Publisher,发布名为july的topic,消息类型为std_mags::String
/*告诉 master 我们将要在 july(话题名)上发布 std_msgs/String 消息类型的消息。这样 master 就会告诉所有订阅了july_topic话题的节点,将要有数据发布。第二个参数是发布序列的大小。如果我们发布的消息的频率太高,缓冲区中的消息在大于 10 个的时候就会开始丢弃先前发布的消息。
*/
/*NodeHandle::advertise() 返回一个 ros::Publisher 对象,它有两个作用: 1) 它有一个 publish() 成员函数可以让你在topic上发布消息; 2) 如果消息类型不对,它会拒绝发布。*/
ros::Publisher july_pub = n.advertise<std_msgs::String>("july_topic", 10);//july_topic会发送std_msgs类型的数据,10代表发送的数据放到ros-master缓存里面最多10个,超过10个以前没有用的数据会被抛弃掉
//设置循环的频率以 10Hz 的频率运行。
/*
ros::Rate 对象可以允许你指定自循环的频率。它会追踪记录自上一次调用 Rate::sleep() 后时间的流逝,并休眠直到一个频率周期的时间。
*/
ros::Rate loop_rate(10);//频率,talk的速度,10HZ
int count = 0;
//创建一个主循环
while (ros::ok()) // 一旦 ros::ok() 返回 false, 所有的 ROS 调用都会失效。
{
// 初始化std_msgs::String类型的消息
std_msgs::String msg;//把数据装到std_msgs里面,然后再发布
std::stringstream ss;
ss << "hello july" << count;//把消息装进去
count++;
msg.data = ss.str();//把讲的话包装再msg里面
//向所有订阅 july 话题的节点发送消息。
july_pub.publish(msg);//最重要!!把消息发送出去
// 按照循环频率延时; 调用 ros::Rate 对象来休眠一段时间以使得发布频率为 10Hz。
loop_rate.sleep();
}
return 0;
}
03 功能包的编译配置(编译节点)
说明:
- C++代码必须通过编译生成可执行文件;
- python代码是可执行文件,不需要编译;
如何编译代码
4. 设置需要编译的代码和生成的可执行文件;
5. 设置链接库;
6. 设置依赖。
创建功能包topic_example时,显式的指明依赖roscpp和std_msgs,依赖会被默认写到功能包的
在 CMakeLists.txt 中取消这几句的注释
find_package(catkin REQUIRED COMPONENTS roscpp std_msgs)
include_directories(
# include
${catkin_INCLUDE_DIRS}
)
add_executable(${PROJECT_NAME}_node src/july_say_node.cpp)
target_link_libraries(${PROJECT_NAME}_node
${catkin_LIBRARIES}
)
取消注释就好
04 功能包的编译
$ cd ~/catkin_ws
$ catkin_make -DCATKIN_WHITELIST_PACKAGES="july_say"
$ source ~/catkin_ws/devel/setup.bash # 刷新环境
05 测试消息发布器和订阅器
5.1 启动发布器
第一步,打开一个命令行终端:
$ roscore
第二步,再打开一个命令行终端:
# 用rosrun <package_name> <node_name>启动功能包中的发布节点。
$ source ~/catkin_ws/devel/setup.bash # 激活catkin_ws工作空间(必须有,必不可少)
$ rosrun july_say july_say_node
现在还没有任何显示
检测是否成功,在cmd输入
willing@willing-virtual-machine:~$ rostopic list
/july_topic
/rosout
/rosout_agg
willing@willing-virtual-machine:~$ rosnode list
/july_talker
/rosout
willing@willing-virtual-machine:~$ rostopic echo july_topic
data: "hello july2039"
---
data: "hello july2040"
---
data: "hello july2041"
---
data: "hello july2042"
---
成功了
接下来编写listener,在cmd输入
willing@willing-virtual-machine:~$ cd catkin_ws
willing@willing-virtual-machine:~/catkin_ws$ cd src
willing@willing-virtual-machine:~/catkin_ws/src$ catkin_create_pkg july_listen std_msgs roscpp
Created file july_listen/CMakeLists.txt
Created file july_listen/package.xml
Created folder july_listen/include/july_listen
Created folder july_listen/src
Successfully created files in /home/willing/catkin_ws/src/july_listen. Please adjust the values in package.xml.
willing@willing-virtual-machine:~/catkin_ws/src$ ls
CMakeLists.txt july_listen july_say
用clion打开july_listen project
接下集