机器人操作系统ROS 编程开发 | 您所在的位置:网站首页 › c语音编程是什么语言 › 机器人操作系统ROS 编程开发 |
最近工作涉及到自动驾驶的,需要学习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常用的概念 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分为两层,底层是操作系统层,上层则是广大用户编写提供的各种功能不同的软件包,比如定位导航,行动规划等等。 所以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 //c++自带的头文件 实现输入输出流等 int main(int argc, char **argv) { ros::init(argc, argv, "talker"); //ros初始化,talker就是node(节点)的名字 ros::NodeHandle n; //为这个进程的节点创建一个句柄。 ros::Publisher chatter_pub = n.advertise("chatter", 1000); //定义要publish(发布)信息的对象 ros::Rate loop_rate(10); //发布的信息的快慢 速度为10Hz int count = 0; while (ros::ok()) { std_msgs::String msg; std::stringstream ss; ss 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、注意点 如果ROS遇到了相同的节点名字那么他会停止掉旧节点的名字然后使用新节点的那个程序(这时候旧的节点如果 有ros::ok(),那么他会就变得不OK了 = = 。这是ros::ok()返回false的第三种情况)注意node的名字得独一无二,但是topic的名字得和你想接收的信息的topic一样!chatterCallback称为回调函数,接收器每一次接收到消息,就会调用名字为它的函数;一般命名为...Callback这样一看就知道这是ROS使用得回调函数std_msgs::String对象msg,类包含数据成员data,调用方式为msg.data。如果类的指针叫msg,那么调用该成员的方式是msg->dataROS 编译程序 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 服务器) roscoreroscore是为了让各种节点之间能够沟通用的
打开第二个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也会关闭
流程: 来到程序所在包的文件夹目录下,新建一个名字叫launch 的文件夹在launch中建立的一个文件,名字可以随意,后缀必须是launch.编译程序编辑launch文件通过roslaunch,执行节点程序详细说明: 编辑launch文件格式: roslaunch使用的是xml语言,launch文件的内容是跑一个node简单的形式 ,表示launch文件的开始和结束 表示接下来输入node相关的内容,比如说首先输入的是node的名字,这个东西一般和type后面输入的内容一样, type需要被赋值为节点对应的可执行文件的名字, name则是节点的名字.具体区别是你在CMakeLists.txt文件里编译文件的命令 output = "screen" :设置通过print()输出的信息,打印到命令窗口中,默认时关闭的
通过roslaunch,执行节点程序 格式: 关键字:roslaunch 第一个参数: xx.launch 所在的包的名称 第二个参数: 要执行的.launch 的文件 ROS发布和接收图 rosbag 简介 rosbag 指命令行中数据包相关命令;rosbag 主要用于记录、回放、分析 rostopic 中的数据。它可以将指定 rostopic 中的数据记录到 .bag 后缀的数据包中,便于对其中的数据进行离线分析和处理。对于 subscribe 某个 topic 的节点来说,它无法区分这个 topic 中的数据到底是实时获取的数据还是从 rosbag 中回放的数据。这就有助于我们基于离线数据快速重现曾经的实际场景,进行可重复、低成本的分析和调试。rosbag 的命令 rosbag录制: 录制所有发布出来的话题,此时默认将话题保存在一个以当时时间戳命名的文件夹中: $ rosbag record –a
录制指定话题: $ rosbag record /topic1 /topic12 rosbag回放: 基本功能: $ rosbag play
等待一定时间之后发布bag文件中的内容 $ rosbag play -d 按一定频率回放,-r选项用来设定消息发布速率,如下面命令则表示以3倍原始速率发布话题 $ rosbag play -r 3
回放指定话题: $ rosbag play --topics
rosbag检查和回放 rosbag info指令可以显示数据包中的信息: rosbag info filename.bag 这些信息包括 topic 的名称、类型和 message 数量。
2) 接下来回放数据包中的 topic。 首先在turtle_teleop_key 所在的终端窗口中按Ctrl+C退出该键盘控制节点。保留turtlesim节点继续运行。在终端中bag文件所在目录下运行以下命令: rosbag play 就能够回放出 bag 中包含的 topic 内容了。 如果想改变消息的发布速率,可以用下面的命令 rosbag play -r 2 这时的轨迹相当于以两倍的速度通过按键发布控制命令时产生的轨迹。 -r 后面的数字对应播放速率。 如果希望 rosbag 循环播放,可以用命令 rosbag play -l # -l == --loop 如果只播放感兴趣的 topic ,则用命令 rosbag play --topic /topic1 在上述播放命令执行期间,空格键可以暂停播放。 CMakeLists 简介: 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.在程序所在包下,添加依赖包
添加依赖包,详细说明: 思路: 一个是包目录下的的CMakeLists.txt,添加依赖包然后在位于同一位置的package.xml中,添加添加依赖包
例如: 打开的CMakeLists.txt,发现就在最前面几行,有下面的内容。 find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs )括号中的内容正好一一对应我们创建包时添加的依赖项,在后面添加geometry_msgs,变成下面的样子,保存退出。 find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs geometry_msgs )打开位于同一目录下的package.xml roscpp rospy std_msgs roscpp rospy std_msgs roscpp rospy std_msgs
发现std_msgs, rospy, roscpp,每个出现了三次,所以只我们需要按照这个文档里相同的语法让geometry_msgs出现三次就行了。更改之后该文件同样位置变成下面的内容: roscpp rospy std_msgs geometry_msgs roscpp rospy std_msgs geometry_msgs roscpp rospy std_msgs geometry_msgs geometry_msgs
保存退出。这时候再用catkin_make编译,就成功了。改变上面两个文档的内容就相当于我们在创建包时添加了依赖项geometry_msgs。
catkin_make编译错误 问题: 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 2018-2019 实验室设备网 版权所有 |