ROS/C++ 入门(Introduction to ROS/C++)

原文: https://syrotek.felk.cvut.cz/course/ROS_CPP_INTROnode

当我看到这一个教程的时候很兴奋,由于这里面的东西很实在,干货比较多。这个系列的教程有基于stage的仿真,有实物对照仍是不错的。全部的翻译不必定彻底遵守原文,掺杂有翻译者的我的经验和理解python

主要内容:

1. ROS的入门介绍

2. 基于激光雷达的避障

3. 沿墙运动

4. PID控制器

5. 里程计的矫正

6. 固定路径跟随

一、ROS 入门介绍

ROS (Robot Operating System)

ROS是一个编写机器人软件很灵活的框架,它包含了工具集、库和协议(conventions),这些包经过交叉不一样的机器人平台,能够简化机器人的开发。
ROS支持多中操做系统,可是官方支持的是ubuntu,每个版本ubuntu对应一个ROS版本,ROS indigo 版本对应的是ubuntu 14.04,kinetic对应ubuntu 16.04,本教程采用的是ros kinetic版本。
在ros下运行的能够理解为图节点,经过ROS的通讯框架这些线程被松散耦合到一块儿。编写ROS时候采用ROS的客户端库,ROS容许用不一样程序编写的节点进行通信。节点既能够经过topic进行subscribe/publish,也能够服务(service)的方式进行通信。ROS只有一个MASTER节点,它提供的是名称检索服务,帮助节点之间创建通信。roscore的启动命令:
roscore
节点启动命令;
rosrun <package_name> <executable_name> <parameters>
若是有多个节点要启动能够编写launch文件,经过roslaunch命令启动。web

建立包(packages)

编写ROS程序时候须要首先建立一个package1,首先跳转到路径catkin_ws/src下面。执行下面的指令,
catkin_create_pkg <package_name> [dep1] ... [depN]
将package_name替换为本身的package名字,dep1 。。。 depN为依赖包,本教程中经常使用依赖项为:roscpp、std_msgs。编写C++时候依赖包要包含roscpp,python程序须要rospy,用其余语言编写ROS程序不推荐,由于支持的不是特别好。
添加依赖roscpp后,生成的包里面会在目录下面生成两个新文件(package.xml, CMakeLists.txt)和两个新目录(src/, include/),你能够在package.xml填写这个package的相关信息(做者,版本,名字、描述、、、) 。头文件通常放在include目录下面,源文件放在src目录下面。ubuntu

准备 CMakeLists.txt

能够设置变量来包含全部必要的源文件:
set (SRCS1 ${SRCS1} src/file_1.cpp)
set (SRCS1 ${SRCS1} src/file_2.cpp)
包含catkin文件路径:
include_directories(include ${catkin_INCLUDE_DIRS})
建立可执行文件和catkin库:
add_executable(executable_name ${SRCS1}) ## executable_name 节点的名字
target_link_libraries(executable_name ${catkin_LIBRARIES})框架

编译程序

跳转到catkin_ws目录下面,执行下面的指令:
catkin_makesvg

ROS and C++

若是是用C++编写的ROS程序,必须添加roscpp依赖,ros.h里面有经常使用的ros代码
#include "ros/ros.h"
ros程序正常运行必须得初始化
ros::init(argc, argv, "name_of_the_node");
初始化完成后须要一个Nodehandle进行ros的资源管理、通讯
ros::NodeHandle n;函数

Messages 和 topics

如上面提到的分立的节点之间是经过topic进行通信的。每个节点既能够publish 消息到topic上面,也能够经过subscribe的方式得到topic上的信息。ROS里面包含了不少种类的messages,也能够本身建立。基本的消息类型包含在std_msgs包里面。大多数的消息里面会包含:std_msgs::Header。你能够看到这个message的详尽内容以下操做:
rosmsg show Header
输出结果:
uint32 seq
time stamp
string frame_id

Header里面包含了三个变量,seq序列号,保证发送的多个消息能够正确的排列,stamp是epoch格式的时间戳。frame_id为坐标系名字,header的名字能够经过std_msgs::Header类在C++中访问。
为了可以发布消息,必须建立一个publisher对象:
ros::Publisher pub = n.advertise<std_msgs::Header>("topic_name", 1000);
1000为缓冲区的大小,经过pub函数进行发送消息:
pub.publish(message);
定于一个主题的时候须要建立一个callback函数,接收和处理订阅的topic的消息。
void callback(const std_msgs::Header::ConstPtr& msg);
建立一个subscriber,在消息publish到topic上时候会调用这个callback函数。
ros::Subscriber sub = n.subscribe("topic_name", 1000, callback);
也能够把callback函数写做类里面:
ros::Subscriber sub = n.subscribe("topic_name", 1000, &SomeClass::callback, instanceOfThatClass);
最后调用spin,开始subscribe消息:
ros::spin();工具

ROS经常使用调试图形化工具

rqtui

这里写图片描述

rviz操作系统

这里写图片描述

机器人stage 仿真

下载仿真机器和环境:(右键另存为)
eci-arena.world
运行指令启动仿真环境:
rosrun stage_ros stageros <path_to_the_world_file>/eci-arena.world

这里写图片描述