赞
踩
最近工作涉及到自动驾驶的,需要学习ROS,学习中总结了一些知识点,分享给大家。
机器人操作系统ROS,是一种分布式处理框架(又名Nodes),ROS常用C++和python编程语言开发;(这里项目开发采用C++ 11版本)。ROS的点对点设计以及服务和节点管理器等机制,可以分散由计算机视觉和语音识别等功能带来的实时计算压力,能够适应多机器人遇到的挑战。ROS免费并且开源。
目录
执行ROS程序方法1、方法2: 使用roslaunch来运行程序
1、node: 节点. 节点就是一些直行运算任务的进程。节点之间是通过传送消息进行通讯的;ROS中,通常来讲我们写的c++程序主函数所在的程序称为一个节点;
2、message: 消息.机器人需要传感器,传感器采集到的信息,即这儿的message.(如:位置消息,温度、湿度等);消息以一种发布/订阅的方式传递;
3、topic: 话题.node交换Messages的命名总线异步通讯机制,传输消息;
4、package: 包 是组织ROS代码的最基本单位,每一个Package都可以包括库文件,可执行文件,脚本及其它的一些文件。
5、workSpace: 工作空间 用来存放很多不同package的。
6、roslaunch: 启动文件,其目的是一次性启动多个节点s。
7、Master: 节点管理器,ROS名称服务,帮助节点找到彼此。
8、publish : 发布器,把相关的信息发送到topic
9、subscribe: 订阅器,订阅相应的topic,接收话题的信息
ROS分为两层,底层是操作系统层,上层则是广大用户编写提供的各种功能不同的软件包,比如定位导航,行动规划等等。
所以ROS实际上可以看成是一个中间层,提供和重新封装了底层硬件调用的API,这些重新封装的API称为客户端库,运用这些库可是实现硬件调用,以此实现各种不同的功能,如使用激光雷达扫描生成周围环境的2D地图……
ROS框架基于集中式拓扑图结构,它的进程(即节点,ROS以节点形式进行通信,以此实现功能)是分布式的,进程分布在各个功能不同的功能包里面。
1、流程
2、Ros发布信息 例子:
- /**
- *本程序演示了通过ROS系统简单发送消息。
- */
- #include "ros/ros.h" //要使用ROS,得包含这个头文件
- #include "std_msgs/String.h" //导入 String类型的头文件
- #include <sstream> //c++自带的头文件 实现输入输出流等
-
- int main(int argc, char **argv)
-
- {
-
- ros::init(argc, argv, "talker"); //ros初始化,talker就是node(节点)的名字
- ros::NodeHandle n; //为这个进程的节点创建一个句柄。
- ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);
- //定义要publish(发布)信息的对象
- ros::Rate loop_rate(10); //发布的信息的快慢 速度为10Hz
- int count = 0;
- while (ros::ok())
- {
- std_msgs::String msg;
- std::stringstream ss;
- ss << "hello world " << count;
- msg.data = ss.str();
- ROS_INFO("%s", msg.data.c_str()); //可以理解为ROS里的printf()
- chatter_pub.publish(msg); //用来发布信息(msg中的内容)
- ros::spinOnce(); //这个函数是用于接收器,是检测一次
- loop_rate.sleep();
- ++count;
-
- }
-
- return 0;
-
- }
3、程序重点降解:
ros::NodeHandle n;
ros:: Publisher chatter_pub = n.advertise < std_msgs::String>("chatter", 1000);
1) 它有一个 publish() 成员函数可以让你在topic上发布消息;
2) 如果消息类型不对,它会拒绝发布。
4、为什么需要缓冲呢?
这发布和接收之间并不是瞬间进行的,发布消息和接收到消息之间的时间差。缓冲区接收最新的信息放到信息序列的最后。即缓冲区的信息的数据结构是queue。第一条来的信息在序列满了的情况下会被第一个丢弃。
在 ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);
1000这个数字的意思是要缓冲的信息数量
1、流程
Ros订阅信息 例子:
- /**
- * 本程序演示了通过ROS系统简单接收消息。
- */
- #include "ros/ros.h"
- #include "std_msgs/String.h"
-
- void chatterCallback(const std_msgs::String::ConstPtr& msg)
- //是一个回调函数,当接收到 chatter 话题的时候就会被调用。{
- ROS_INFO("I heard: [%s]", msg->data.c_str());//msg->data就是一个std::string类型的量
- }
-
-
-
- int main(int argc, char **argv)
- {
- ros::init(argc, argv, "listener");//节点的名字换成了listener
- ros::NodeHandle n;
- ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);
- //定义接收器,topic话题:chatter,第三个参数chatterCallback称为回调函数
- ros::spin(); //会使程序在循环中,一直检测有没有接收到新的消息
- return 0;
- }
-
3、注意点
1、流程
2、编译例子:
来到编写好程序的包目录中
cd ~/catkin_ws/src/pub_sub_test/
编辑CMakeLists文件
gedit CMakeLists.txt
在后面添加如下内容:
- add_executable(pub_string src/pub_string.cpp)
-
- target_link_libraries(pub_string ${catkin_LIBRARIES})
第一行表示我们要编译add_executable表示我们要添加一个可执行文件,
pub_string是这个可执行文件的名字
src/pub_string.cpp指定要编译的源文件的位置.
第二行target_link_libraries表示我们要将可执行文件链接到一个库,我们要使用ROS当然是要链接到ROS的库了,
pub_string指定要链接可执行文件的名字,后面是指定要链接的库的名字.
来到工作空间中,执行catkin_make命令
- cd ~/catkin_ws/
-
- catkin_make
-
方法1:
打开第一个terminal,执行roscore命令(打开rosmaster 服务器)
roscore
roscore是为了让各种节点之间能够沟通用的
打开第二个terminal,进入工作空间,执行source devel/setup.bash 命令,
- cd ~/catkin_ws/
-
- source devel/setup.bash
-
使用rosrun 命令运行程序(例如:执行pub_string.cpp):
rosrun pub_sub_test pub_string
第一个参数:程序pub_string.cpp所在的包(package)的名字
第二个参数:运行程序的名称
特点:
可以便捷开启多个节点,自动开启rosmaster服务
区别:
流程:
详细说明:
格式: <
- launch>
- <node name="pub_string" pkg = "pub_sub_test" type = "pub_string" output = "screen">
- </node>
- <node name="pub_int8" pkg = "pub_sub_test" type = "pub_int8" output = "screen">
- </node>
- </launch>
roslaunch使用的是xml语言,launch文件的内容是跑一个node简单的形式
<launch>,<\launch>表示launch文件的开始和结束
<node ....>表示接下来输入node相关的内容,比如说首先输入的是node的名字,这个东西一般和type后面输入的内容一样,
type需要被赋值为节点对应的可执行文件的名字,
name则是节点的名字.具体区别是你在CMakeLists.txt文件里编译文件的命令
output = "screen" :设置通过print()输出的信息,打印到命令窗口中,默认时关闭的
通过roslaunch,执行节点程序
格式:
关键字:roslaunch
第一个参数: xx.launch 所在的包的名称
第二个参数: 要执行的.launch 的文件
简介
录制所有发布出来的话题,此时默认将话题保存在一个以当时时间戳命名的文件夹中:
$ rosbag record –a
录制指定话题:
$ rosbag record /topic1 /topic12
基本功能:
$ rosbag play <your bagfile name>
等待一定时间之后发布bag文件中的内容
$ rosbag play <your bagfile name> -d <delay time>
按一定频率回放,-r选项用来设定消息发布速率,如下面命令则表示以3倍原始速率发布话题
$ rosbag play -r 3 <your bagfile name>
回放指定话题:
$ rosbag play <your bagfile name> --topics <topics>
rosbag info filename.bag
这些信息包括 topic 的名称、类型和 message 数量。
2) 接下来回放数据包中的 topic。
首先在turtle_teleop_key 所在的终端窗口中按Ctrl+C退出该键盘控制节点。保留turtlesim节点继续运行。在终端中bag文件所在目录下运行以下命令:
rosbag play <bagfile>
就能够回放出 bag 中包含的 topic 内容了。
rosbag play -r 2 <bagfile>
这时的轨迹相当于以两倍的速度通过按键发布控制命令时产生的轨迹。 -r 后面的数字对应播放速率。
rosbag play -l <bagfile> # -l == --loop
rosbag play <bagfile> --topic /topic1
在上述播放命令执行期间,空格键可以暂停播放。
简介:
ROS中创建软件包所依赖的文件为CMakeList.txt,catkin_make会根据你写的CMakeList.txt来配置编译软件包。
格式:
所需CMake版本 cmake_minimum_required(VERSION 2.8.3)
软件包名称 project()
查找构建此包所需的包 find_package()
消息 / 服务 / 动作生成器 add_message_files(),add_service_files(),add_action_files
消息 / 服务 / 动作生成 generate_messages()
指定包构建的消息导出 catkin_package()
要建立的库 / 可执行文件 add_library() / add_executable() / target_link_libraries())
例如:
其中:add_executable(read_param src/show_param.cpp)和target_link_libraries(read_param ${catkin_LIBRARIES}) 是新添加的,指定可执行文件
详细解释:
1.所需CMake版本
catkin_make的底层是使用cmake进行编译的,这里指定cmake的版本(最低版本)
2.软件包名称
project(package_name)
在使用catkin_create_pkg创建包时,后面跟的参数(包名)就是此处的package_name
在CMakeList.txt后面的部分可以使用 ${PROJECT_NAME} 来使用此参数
3. 查找此包创建时所需要的其它包(依赖包)
可以将所依赖的包写成下面的形式:
find_package(catkin REQUIRED)
find_package(roscpp REQUIRED)
find_package(rospy REQUIRED)
find_package(std_msgs REQUIRED)
其中catkin是创建每个包所必须的依赖项,创建包时所依赖的其它项又可以将其组成catkin的组件,所以上面可以总写为:
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
)
上面中的roscpp、rospy、std_msgs 是运行程序所需要的依赖包;
roscpp: 用C++ 语言进行ros开发要用到的包
rospy: 用python 语言进行ros开发要用到的包
std_msgs: 基本的数据类型int 、string、float、double等的依赖包
4.add_message_files()
像message service 和action的定义需要在catkin_package()之前
## Generate messages in the 'msg' folder
# add_message_files(
# FILES
# Message1.msg
# Message2.msg
# )
比如:
add_message_files(
FILES Num1.msg Num2.msg
)
5.catkin_package()
用来向编译系统指明catkin-specific的信息,格式如下:
catkin_package(
INCLUDE_DIRS include # 此项打开之后该软件包的include文件可以被其它包所引用
LIBRARIES ${PROJECT_NAME} #同理
CATKIN_DEPENDS roscpp nodelet
DEPENDS eigen opencv)
6.包含文件目录
include_directories(include ${catkin_INCLUDE_DIRS})
其中include是指包含本软件包下的头文件, ${catkin_INCLUDE_DIRS}是指ROS下其它包的头文件,include需要写在${catkin_INCLUDE_DIRS}前面。
7.生成可执行文件
#其中talker为将要生成的二进制文件,在ros所有的包中必须是独一无二不能重复的,src/talker.cpp为需要编译的源文件
add_executable(talker src/talker.cpp)
target_link_libraries(talker ${catkin_LIBRARIES})
生成的可执行文件会存放在./devel/lib/*pack_name*/下:
解决思路:
1.在错误原因中,找到错误代码端,分析,确定缺失的包
2.在程序所在包下,添加依赖包
添加依赖包,详细说明:
思路:
例如:
- find_package(catkin REQUIRED COMPONENTS
- roscpp
- rospy
- std_msgs
- )
括号中的内容正好一一对应我们创建包时添加的依赖项,在后面添加geometry_msgs,变成下面的样子,保存退出。
- find_package(catkin REQUIRED COMPONENTS
-
- roscpp
-
- rospy
-
- std_msgs
-
- geometry_msgs
-
- )
-
- <build_depend>roscpp</build_depend>
-
- <build_depend>rospy</build_depend>
-
- <build_depend>std_msgs</build_depend>
-
- <build_export_depend>roscpp</build_export_depend>
-
- <build_export_depend>rospy</build_export_depend>
-
- <build_export_depend>std_msgs</build_export_depend>
-
- <exec_depend>roscpp</exec_depend>
-
- <exec_depend>rospy</exec_depend>
-
- <exec_depend>std_msgs</exec_depend>
发现std_msgs, rospy, roscpp,每个出现了三次,所以只我们需要按照这个文档里相同的语法让geometry_msgs出现三次就行了。更改之后该文件同样位置变成下面的内容:
- <build_depend>roscpp</build_depend>
-
- <build_depend>rospy</build_depend>
-
- <build_depend>std_msgs</build_depend>
-
- <build_depend>geometry_msgs</build_depend>
-
- <build_export_depend>roscpp</build_export_depend>
-
- <build_export_depend>rospy</build_export_depend>
-
- <build_export_depend>std_msgs</build_export_depend>
-
- <build_export_depend>geometry_msgs</build_export_depend>
-
- <exec_depend>roscpp</exec_depend>
-
- <exec_depend>rospy</exec_depend>
-
- <exec_depend>std_msgs</exec_depend>
-
- <exec_depend>geometry_msgs</exec_depend>
-
- <exec_depend>geometry_msgs</exec_depend>
-
保存退出。这时候再用catkin_make编译,就成功了。改变上面两个文档的内容就相当于我们在创建包时添加了依赖项geometry_msgs。
Could not find a package configuration file provided by
"gazebo_ros_control" with any of the following names:
gazebo_ros_controlConfig.cmake
gazebo_ros_control-config.cmake
分析
提示缺少“gazebo_ros_control”功能包,
解决方案:
sudo apt-get install ros-kinetic-gazebo-ros-control
Could not find a package configuration file provided by "move_base_msgs"
with any of the following names:
move_base_msgsConfig.cmake
move_base_msgs-config.cmake
分析
提示缺少“gazebo_ros_control”功能包
解决方案:
sudo apt-get install ros-kinetic-move-base-msgs
alsa/asoundlib.h: No such file or directory
分析
缺少一个库,libasound2-dev
解决方案:
sudo apt-get install libasound2-dev
希望对你有帮助。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。