最近工作涉及到自动驾驶的,需要学习ROS,学习中总结了一些知识点,分享给大家。

ROS基本介绍

机器人操作系统ROS,是一种分布式处理框架(又名Nodes),ROS常用C++和python编程语言开发;(这里项目开发采用C++ 11版本)。ROS的点对点设计以及服务和节点管理器等机制,可以分散由计算机视觉和语音识别等功能带来的实时计算压力,能够适应多机器人遇到的挑战。ROS免费并且开源。

目录

ROS基本介绍

ROS常用的概念

ROS的结构是怎样的?

ROS发布消息-- publish

ROS订阅消息—subscribe

ROS 编译程序

执行ROS程序方法1、方法2: 使用roslaunch来运行程序

ROS发布和接收图

rosbag

rosbag 的命令

rosbag录制

rosbag回放

rosbag检查和回放

CMakeLists

问题与解决方案总结

缺失依赖库

catkin_make编译错误


ROS常用的概念

1node: 节点. 节点就是一些直行运算任务的进程。节点之间是通过传送消息进行通讯的;ROS中,通常来讲我们写的c++程序主函数所在的程序称为一个节点;

2message: 消息.机器人需要传感器,传感器采集到的信息,即这儿的message.(如:位置消息,温度、湿度等);消息以一种发布/订阅的方式传递;

3topic: 话题.node交换Messages的命名总线异步通讯机制,传输消息;

4package:  是组织ROS代码的最基本单位,每一个Package都可以包括库文件,可执行文件,脚本及其它的一些文件。

5workSpace工作空间 用来存放很多不同package的。

6roslaunch: 启动文件,其目的是一次性启动多个节点s。

7Master节点管理器,ROS名称服务,帮助节点找到彼此。

8publish发布器,把相关的信息发送到topic

9、subscribe: 订阅器,订阅相应的topic,接收话题的信息

ROS的结构是怎样的?

ROS分为两层,底层是操作系统层,上层则是广大用户编写提供的各种功能不同的软件包,比如定位导航,行动规划等等。

所以ROS实际上可以看成是一个中间层,提供和重新封装了底层硬件调用的API,这些重新封装的API称为客户端库,运用这些库可是实现硬件调用,以此实现各种不同的功能,如使用激光雷达扫描生成周围环境的2D地图……

ROS框架基于集中式拓扑图结构,它的进程(即节点,ROS以节点形式进行通信,以此实现功能)是分布式的,进程分布在各个功能不同的功能包里面。

ROS发布消息-- publish

1、流程

  • 初始化 ROS 系统
  • 在 ROS 网络内广播中,我们将要在 chatter 话题上,发布 std_msgs/String 类型的消息
  • 以每秒 10 次的频率(可以设置修改)在 chatter 上发布消息

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);                 //发布的信息的快慢 速度为10Hzint 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;

  • 第一个创建的 NodeHandle 会为节点进行初始化,最后一个销毁的 NodeHandle 则会释放该节点所占用的所有资源

ros:: Publisher chatter_pub = n.advertise < std_msgs::String>("chatter", 1000);

  • n.advertise 通过NodeHandle的对象n告诉ROS系统我要创建一个可以发布信息的对象
  • < std_msgs::String>告诉ROS我要发布的是标准信息中的String类型,chatter 通讯时的topic(主题)
  • 1000这个数字的意思是要缓冲的信息数量
  • advertise返回一个 ros::Publisher 对象,它有两个作用:

     1) 它有一个 publish() 成员函数可以让你在topic上发布消息;

      2) 如果消息类型不对,它会拒绝发布。

4、为什么需要缓冲呢?

这发布和接收之间并不是瞬间进行的,发布消息和接收到消息之间的时间差。缓冲区接收最新的信息放到信息序列的最后。即缓冲区的信息的数据结构是queue。第一条来的信息在序列满了的情况下会被第一个丢弃。

ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);

1000这个数字的意思是要缓冲的信息数量

ROS订阅消息subscribe

1、流程

  • 初始化ROS系统
  • 订阅 chatter 话题
  • 进入自循环,等待消息的到达
  • 当消息到达,调用 chatterCallback() 函数

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. 如果ROS遇到了相同的节点名字那么他会停止掉旧节点的名字然后使用新节点的那个程序(这时候旧的节点如果 有ros::ok(),那么他会就变得不OK了 = = 。这是ros::ok()返回false的第三种情况)
  2. 注意node的名字得独一无二,但是topic的名字得和你想接收的信息的topic一样!
  3. chatterCallback称为回调函数,接收器每一次接收到消息,就会调用名字为它的函数;一般命名为...Callback这样一看就知道这是ROS使用得回调函数
  4. std_msgs::String对象msg,类包含数据成员data,调用方式为msg.data。如果类的指针叫msg,那么调用该成员的方式是msg->data

ROS 编译程序

1、流程

  • 编辑CMakeLists文件(指定要编译的文件)
  • 再使用catkin_make编译

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

执行ROS程序方法1:

方法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)的名字

第二个参数:运行程序的名称

方法2: 使用roslaunch来运行程序

特点:

可以便捷开启多个节点,自动开启rosmaster服务

区别:

  • 方法一在使用rosrun之前,我们一定得需要启动rosmaster,即开启一个窗口输入roscore,来开启rosmaster 服务器;
  • 运行roslaunch文件后rosmaster会自动启动.当然你关闭了roslaucn之后rosmaster也会关闭

流程:

  1. 来到程序所在包的文件夹目录下,新建一个名字叫launch 的文件夹
  2. 在launch中建立的一个文件,名字可以随意,后缀必须是launch
  3. 编译程序
  4. 编辑launch文件
  5. 通过roslaunch,执行节点程序

详细说明:

  1. 编辑launch文件

格式: <

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 的文件

ROS发布和接收图

rosbag

简介

  1. rosbag 指命令行中数据包相关命令;
  2. rosbag 主要用于记录、回放、分析 rostopic 中的数据。它可以将指定 rostopic 中的数据记录到 .bag 后缀的数据包中,便于对其中的数据进行离线分析和处理。
  3. 对于 subscribe 某个 topic 的节点来说,它无法区分这个 topic 中的数据到底是实时获取的数据还是从 rosbag 中回放的数据。这就有助于我们基于离线数据快速重现曾经的实际场景,进行可重复、低成本的分析和调试。

rosbag 的命令   

rosbag录制:

录制所有发布出来的话题,此时默认将话题保存在一个以当时时间戳命名的文件夹中:

$ rosbag record –a

录制指定话题:

$ rosbag record /topic1 /topic12

rosbag回放:

基本功能:

$ 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检查和回放

  1. rosbag info指令可以显示数据包中的信息:

rosbag  info filename.bag

这些信息包括 topic 的名称、类型和 message 数量。

2) 接下来回放数据包中的 topic。
首先在turtle_teleop_key 所在的终端窗口中按Ctrl+C退出该键盘控制节点。保留turtlesim节点继续运行。在终端中bag文件所在目录下运行以下命令:

rosbag play <bagfile>

就能够回放出 bag 中包含的 topic 内容了。

  1. 如果想改变消息的发布速率,可以用下面的命令

rosbag play -r 2 <bagfile>

这时的轨迹相当于以两倍的速度通过按键发布控制命令时产生的轨迹。 -r 后面的数字对应播放速率。

  1. 如果希望 rosbag 循环播放,可以用命令

rosbag play -l  <bagfile>  # -l == --loop

  1. 如果只播放感兴趣的 topic ,则用命令

rosbag play <bagfile> --topic /topic1

在上述播放命令执行期间,空格键可以暂停播放。

CMakeLists

简介:

ROS中创建软件包所依赖的文件CMakeList.txtcatkin_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

)

上面中的roscpprospystd_msgs 是运行程序所需要的依赖包

roscpp: 用C++ 语言进行ros开发要用到的包

rospy: 用python 语言进行ros开发要用到的包

std_msgs: 基本的数据类型int stringfloat、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.在程序所在包下,添加依赖包

添加依赖包,详细说明:

思路:

  1. 一个是包目录下的的CMakeLists.txt,添加依赖包
  2. 然后在位于同一位置的package.xml中,添加添加依赖包

例如:

  1. 打开的CMakeLists.txt,发现就在最前面几行,有下面的内容。
find_package(catkin REQUIRED COMPONENTSroscpprospystd_msgs
)

括号中的内容正好一一对应我们创建包时添加的依赖项,在后面添加geometry_msgs,变成下面的样子,保存退出。

find_package(catkin REQUIRED COMPONENTSroscpprospystd_msgsgeometry_msgs)
  1. 打开位于同一目录下的package.xml
 <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。

catkin_make编译错误

  1. 问题:

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

  1. 问题:

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

  1. 问题:

alsa/asoundlib.h: No such file or directory

分析

缺少一个库,libasound2-dev

解决方案:

sudo apt-get install libasound2-dev

希望对你有帮助。

机器人操作系统ROS 编程开发--详细总结相关推荐

  1. python机器人编程教程入门_机器人操作系统(ROS)入门必备:机器人编程一学就会

    本书是针对机器人操作系统(ROS)初学者的入门教程,从基础的如何安装ROS,到ROS的框架介绍和C/C++.Python编程基础概念介绍,直至完整搭建一个机器人项目,每一个部分都有详细的操作过程和相应 ...

  2. 机器人操作系统ROS(4)话题编程

    此节的前提是已经创建好工作空间,请参考 工作空间 一.话题通讯模型 二.话题编程实现 1. 实现发布者(Talker) a.在~/catkin_ws/src/learning_communicaton ...

  3. 机器人操作系统ROS(5)服务编程

    在catkin\_ws工作空间下的功能包learning\_communication下继续实现通信编程,请参考上节-话题编程 一.服务通讯模型 二.服务编程实现 注:实现加法listener发布两个 ...

  4. 机器人操作系统ROS(6)动作编程

    注:在 catkin\_ws 工作空间下的功能包earning\_communication 下继续实现通信编程,参考上节-服务编程 一.动作通讯模型 二.动作编程实现 1. 自定义动作文件actio ...

  5. 关于机器人操作系统(ROS)学习前须知二三

    ROS基础资料 1.什么是ROS? ROS(机器人操作系统,Robot Operating System),是专为机器人软体开发所设计出来的一套电脑作业系统架构.它是一个开源的元级操作系统(后操作系统 ...

  6. 机器人操作系统ROS(1)

    ROS总体设计 ROS五个特点 点对点设计 一个使用ROS的系统包括一系列进程,这些进程存在于多个不同的主机并且在运行过程中通过端对端的拓扑结构进行联系,如图2所示.虽然基于中心服务器的那些软件框架也 ...

  7. 《机器人操作系统ROS原理与应用》——1.3 智能机器人的分类

    本节书摘来自华章出版社<机器人操作系统ROS原理与应用>一 书中的第1章,第1.3节,作者:周兴社 杨刚 王岚,更多章节内容可以访问云栖社区"华章计算机"公众号查看. ...

  8. 计算机操作系统(OS)安装机器人操作系统(ROS)实现物联网功能

    博客中大量介绍了将Ubuntu等Linux系统借助机器人操作系统ROS实现机器人控制设计开发和物联网功能案例,并可基于OpenAI等实现人工智能相关训练. 这篇博文围绕windows系统展开,之前也写 ...

  9. 一文读懂自动驾驶中的机器人操作系统ROS

    一.什么是机器人操作系统ROS 1.ROS(Robot Operating System)是一个操作系统 ROS是对机器人的硬件进行了封装,不同的机器人.不同的传感器,在ROS里可以用相同的方式表示( ...

最新文章

  1. Windows RT复活!Windows 10 Cloud首波截图曝光
  2. python 错误代码_PYTHON错误代码及解决办法
  3. c语言不同指令意识,C语言必须理清的概念1
  4. 计算机专业特殊人才上大学,上海交通大学计算机科学与工程系(CSE)
  5. ajax-form表单快速传递参数
  6. linux实用小功能
  7. 数据结构-----平衡二叉树
  8. hdu3790最短路径问题 (用优先队列实现的)
  9. 电源大师课笔记 2.3
  10. 按键精灵执行cmd命令_如何用cmd运行按键精灵脚本
  11. 2应用层 - P2P应用
  12. Android Permission is only granted to system apps问题
  13. CWebBrowser 中处理回车相应的问题
  14. (转)来自一位作业辅导老师的经验分享
  15. 获取员工其当前的薪水比其manager当前薪水还高的相关信息
  16. python若干整数的最大值_python脚本3_输入若干个整数打印出最大值
  17. eclipse IDE
  18. 在kali使用DDos-Attack 进行DDos攻击
  19. android 自由浏览器下载地址,改善手机上网体验 云集浏览器Android 2.3.1版发布
  20. linux之sudo apt-get install **** 是到哪里下载软件以及下载到哪里去了

热门文章

  1. GA-LSTM的国内外研究现状
  2. 公交线路管理 数据结构课程设计
  3. NoSQL数据库的基础知识
  4. 2022长三角产业区块链生态图谱 附下载
  5. MATLAB符号运算(七)
  6. 嵌入式 IIC(I2C)协议
  7. 一些Pixel手机的使用技巧
  8. 浅议极大似然估计(MLE)背后的思想原理
  9. 大学英语四级电子照片修改过程。
  10. BLOB与CLOB的区别