一 ROS基础教程

ROS教程

这是小弟的学习笔记,有错求请拍,多指教,谢谢

一 ROS基础知识

ROS文件系统介绍

1.功能包集stack

ROS软件包集合,像Navigation Stack,属于导航软件包集合,包含了与导航有关的软件包,例如地图软件包,路径规划软件包,TF坐标软件包,move_base移动控制软件包等,一整个stack下载后可以任意使用其中的软件包,每个软件包都实现其中一个或者好几个小功能,多个软件包组成集合实现一个完整的大的功能

http://wiki.ros.org/navigation

2.软件包package

ROS程序的单元,每个软件包都包含程序库,可执行文件,脚本。图中列出的learning_joy软件包,包含编译配置文件CMakeLists.txt,include头文件库,launch启动脚本文件夹,package.xml软件包概况描述文件,src程序源码库
figure1

软件包文件详解:

1)编译配置文件CMakeLists.txt, 使用cmake编译时要写的
2)include头文件库,如果只是使用ROS中附带有的头文件,include这个文件夹可能会是空的,但是系统会自动创建,当以后需要用到自己的头文件或者添加别人的头文件时,把头文件添加到该文件夹里便可正确使用
3)launch启动脚本文件夹,里边包含了后缀名为launch的启动脚本,功能是一次性启动多个节点,至于什么是节点,以后会详细讲

figure2

4)清单文件package.xml,包含软件包的相关信息的描述,包括版本号,开发者信息,各软件包之间的依赖关系
5)src程序源码库,存放编写的cpp或者python源码文件

ROS基本框架

1.节点node

节点是ROS机器人系统里任何操作的单元,可以理解为每一个节点可以实现一个小功能,一个机器人工程就是由多个节点组成的,节点与节点之间可以相互通信,相互协调完成工作,比如人手臂的运动,运动指令从大脑发出,经过肩膀,手肘,手腕,最后再到手指,触感的信息则是反过来传递,每个关节理解成一个节点,它们之间可能是相互传递消息,也可能是一个发送消息,一个接收消息;通常,我们在编程的时候就是编写一个个节点

2.话题topic

话题是ROS里的一个通信方法,topic里包含了消息的名称,类型,内容,节点可以发布或者订阅某个或某几个话题,以此达到传递的目的;话题有两个重要的性质:a.话题的发布频率;b.话题的消息类型

3.发布者和订阅者publisher & subscriber

ROS里的节点node可能是发布者或者是订阅者,甚至两者都兼备,发布者就是发布topic的节点,订阅者就是订阅topic的节点,发布者以一定的消息类型格式在ROS服务器上发布消息,订阅者则根据话题名称在服务器上订阅消息,消息类型在ROSwiki上有详细定义
http://wiki.ros.org/std_msgs

还有一些常用软件包内需要的消息类型,如:

common_msgs 查看各类消息类型
geometry_msgs 运动几何学相关的消息类型,包括速度,加速度等
sensor_msgs 传感器相关的消息类型,包括激光雷达,点云,IMU惯性测量单元,JoySticks遥控手柄,图像等

4.理解ROS的通信流程

  1. master 节点,管理所有的节点,每个节点都需要先向 master 节点注册, master 节点会让发布者和订阅
    者进行匹配;所以每次启动ROS时,都需要先打开master节点
    kevin@kevin-Laptop:~$ roscore
  2. 发布者和订阅者之间通过话题来通信时,信息不通过 master
  3. 发布者发布一个话题,订阅者进行订阅
  4. 流程:
    1 )订阅者发送建立链接请求
    2 )发布者进行反馈,确认链接
    3 )订阅者请求 topic 的数据
    4 )发布者发送 topic 数据

创建和编译 ROS 软件包

1.创建软件包

1)创建工作空间

在编写任何ROS程序之前,都应该先建立一个工作空间workspace,因为使用catkin环境,所以一般网上很多教程都会将工作空间命名为catkin_ws,但其实可以任意命名,工作空间就是一个在~/home目录下的文件夹。工作空间下是存放软件包的,所以一般而言,工作空间不需要创建太多,除非某个工程特别庞大,才需要为它独立创建工作空间

创建工作空间目录:~$ mkdir -p catkin_ws/src

这里写图片描述

查看文件夹目录:tree catkin_ws/

编译软件包命令:~/catkin_ws$ catkin_make

即使没有源码文件,工作空间也是可以通过编译的,编译命令要在工作空间文件夹目录下执行,系统会自动生成build文件夹和devel文件夹,devel文件夹内的文件与引导路径有关系,没有source配置正确的环境变量路径,即使catkin_make编译通过,ROS也无法正确识别通过编译的节点

在工作空间目录下执行source命令:~/catkin_ws$ source devel/setup.bash

但这个命令只能在该终端内source到正确的环境变量,每次新打开一个终端,仍需要再次配置,可以修改整个环境:
$ gedit ~/.bashrc
把编辑文本拉到最后,添加:
source ~/catkin_ws/devel/setup.bash
就是添加工作空间下的/devel/setup.bash文件的路径,让终端每次打开时,都会自动执行source命令
配置完成后,按ctrl+alt+T打开终端,如果配置不正确,终端会提示找不到路径
这里写图片描述

2)创建软件包

软件包一般在工作空间的src文件夹下创建,否在ROS可能无法定位你的软件包,命名要避免与ROS的操作指令重复,不能以数字或者符号开头,并且不允许大写字母
创建软件包命令:
格式: catkin_create_pkg pkg_name pkg_depends
例子: catkin_create_pkg testing_pkg roscpp rospy std_msgs

  1. pkg_name是对软件包的命名;
  2. pkg_depends是软件包的依赖关系,如roscpp,rospy,std_msgs;软件包的依赖关系类似依赖某个源代码或者头文件
  3. 依赖关系分为一级依赖和间接依赖,一级依赖是我们在创建软件包过程中添加的依赖项,间接依赖是各依赖项之间的关系,
    $ rospack depends1 pkg_name 查看一级依赖关系
    $ rospack depends pkg_name 查看所有的依赖关系
3)删除软件包

软件包删除命令:$ rm -rf 文件夹名称
再重新编译

2.编写测试代码步骤

1)先进入软件包目录下的src文件夹 $ cd catkin_ws/src/testing_pkg/src/
2)打开编辑器编写cpp或者python源码

$ gedit talker.cpp $ gedit listener.cpp
如果没有gedit编辑器,系统会提示安装gedit $ sudo apt-get install gedit

3)修改编译配置文件
4)返回工作空间目录,编译代码 $ catkin_make

3.编写发布者代码

1)简单的发布者代码,发布者代码基本都是这个框架
#include "ros/ros.h"//ROS程序必备的头文件
#include "std_msgs/String.h"//传递的消息类型
#include "sstream"

int main(int argc, char **argv)//写ROS程序需要加argc,argv,因为init需要传这两个参数
{
  ros::init(argc, argv, "talker");//初始化ros,向master注册一个叫“talker”的节点

  ros::NodeHandle n;//初始化一个句柄,就是将ROS实例化

  ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);
  //发布者注册一个叫“chatter”的话题,<消息类型>,1000是消息队列大小
  //消息队列相当于缓存消息,如果处理速度不够快的话消息会被保存在队列中

  ros::Rate loop_rate(10);//执行循环的速率,可以理解为发布消息的频率,单位是Hz

  int count = 0;
  while (ros::ok())//ros::ok()函数用来判断master节点是否正常
  {
    std_msgs::String msg;//声明变量

    std::stringstream ss;
    ss << "hello world " << count;
    msg.data = ss.str();

    ROS_INFO("%s", msg.data.c_str());//ROS_INFO()可以在终端打印数据

    chatter_pub.publish(msg);//发布该消息

    ros::spinOnce();//动作执行一次
    //ros::spin()是循环执行,在没有while的时候使用

    loop_rate.sleep();//相当于delay函数,因为程序可能不需要0.1s,就是10Hz的频率就可以发送完成,所以sleep()函数可以让程序暂停一会,让消息的发送频率符合10Hz
  }
  return 0;
}

wiki.ros.org/PublisherSubscriber

4.编写订阅者代码

1)简单的订阅者代码
#include "ros/ros.h"
#include "std_msgs/String.h"//要和订阅的消息类型所匹配

void chatterCallback(const std_msgs::String::ConstPtr& msg)//回调函数
{
  ROS_INFO("I heard: [%s]", msg->data.c_str());
}

int main(int argc, char **argv)
{
  ros::init(argc, argv, "listener");//初始化ros,向master注册一个叫“listener”的节点

  ros::NodeHandle n;

  ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);
  //订阅者向master注册自己需要订阅的话题"chatter",消息队列大小是1000,chatterCallback是回调函数
  //回调函数的意义是,当订阅者从自己所订阅的话题上接收到消息,回调函数自动执行

  ros::spin();//因为不在while循环体中,所以它要不断执行,而不是用spinOnce(),只执行一次

  return 0;
}

wiki.ros.org/PublisherSubscriber

5.修改CMakeLists.txt文件

  1. ctrl+F找到关键字 ## Declare a C++ executable
  2. 去掉#注释项add_executable(${PROJECT_NAME}_node src/test_pkg_node.cpp),将test_pkg_node.cpp修改成自己所要编译的cpp文件,如果有多个cpp文件需要编译(一个软件包内可能存在多个节点),则多添加add_executable语句
  3. 找到关键字target_link_libraries,将注释去掉,如果有特别需要添加的依赖库,可以在这里添加,一般的编译过程不需要,因为ROS里已经揉合了很多第三方库,例如OpenCV
  4. 每一个软件包都要配置自己的CMakeLists.txt文件

6.运行节点

1)先运行master节点 $ roscore
2)运行节点

格式:$ rosrun your_pkg_name your_node_name
例子:$ rosrun testing_pkg talker rosrun testing_pkg listener

3)如果不记得节点名或者软件包名称,可以按Tab键补全,但一定要记得先source正确的环境变量

7.编写launch文件(可选)

1)launch文件是xml格式的脚本,我们把需要启动的节点信息写进去,launch脚本会自动帮我们运行需要的节点,而不需要手动逐个开启
2)launch脚本开启节点的顺序是不确定的,这也是ROS节点编写的一个理念,尽可能让节点之间的耦合性降低,节点尽可能地独立完成某项工作
3)进入软件包文件夹目录 $ cd catkin_ws/src/testing_pkg/
4)创建launch文件夹 $ mkdir -p launch
5)进入launch文件夹 $ cd launch
6)新建launch文件 $ gedit testing_pkg.launch
7)编写launch文件
语法格式
每个 xml 文件都包含根元素,根元素由 launch 标签来定义
<launch>// 开始标签
<node pkg=”package_name” type=”executable_name” name=”node_name” output=“screen”/>
//type填写的是与CMakeLists.txt中add_executable修改的test_pkg_node.cpp名称一致
...
</launch>// 结束标签,结束标签都多一个 /
简单的launch文件
<launch>
<node pkg="testing_pkg" type="talker" name="talker" output="screen"/>
<node pkg="testing_pkg" type="listener" name="listener" output="screen"/>
</launch>
8)注意
  1. launch 文件中,启动节点的时候给 node 重新指定了名称,会覆盖掉在源码文件中通过 ros::init 赋予节点的名称,所以在使用launch启动时要留意被修改的节点名
  2. 如果 output 没有定义到 screen ,节点的输出信息会在 log 日志文件下保存,查看方式:
    $ ~/.ros/log/run_id/node_name-number-stour.log

拓展:jason来自星星的博客教程

8.通过launch文件启动节点

1)

格式:$ roslaunch pkg_name launch_name
例子:$ roslaunch testing_pkg testing_pkg.launch

ROS基础工具

1.rqt_graph

1)通过直观的图谱来查看当前正在运行的节点之间的关系
2)$ rosrun rqt_graph rqt_graph

这里写图片描述

3)graph图谱会列出节点,话题等信息

2.rqt_robot_steering

1)rqt_robot_steering是与机器人运动控制的密切相关的ROS工具,它相当于一个节点,可以发布/cmd_vel类型的消息,/cmd_vel类消息包括了机器人直线运动和转向运动的控制指令,通过滑动条可以十分方便地控制机器人运动
2)$ rosrun rqt_robot_steering rqt_robot_steering

这里写图片描述

Twist&/cmd_vel

3.rviz

1)rviz是一款2D&3D的数据可视化软件,提供了丰富的ROS接口,可以建立机器人运动模型,激光雷达地图等,并且进行仿真验证
2)rosrun rviz rviz

4.rqt_logger_level

1)ROS的一个log日志查看器,用于检查每个节点的日志信息,比如说什么时候哪个节点作出了更改,都会记录在log日志下
2)$ rosrun rqt_logger_level rqt_logger_level

这里写图片描述

3)log消息等级划分,从Debug到Fatal越来越严重

5.rqt_console

1)用来查看节点输出信息,因为有很多消息并未通过ROS_INFO()函数在终端显示出来,可以通过console查看是否有正确输出
2)rosrun rqt_console rqt_console

这里写图片描述

6.ROS文件系统工具

1)rospack 获取软件包相关信息,类似一个 find 的命令,只需要知道软件包的名称即可
  1. rospack help 查看 rospack 相关功能的命令
  2. rospack list 列出当前系统中安装了的软件包名称和路径信息
  3. rospack list-names 只查看软件包名称
  4. rospack list-names | wc -l 统计有多少个软件包,| 是一个符号,表示上一个命令的结果是下一个命令的输入
  5. rospack find [package_name] 查询软件包的路径信息
2)roscd 软件包名
直接切换工作目录到某个软件包中
3)rosls 软件包名
直接罗列该软件包的目录结构
4)rosed 软件包 可编辑文件名
直接编辑某个软件包的可编辑文件
5)roscp 软件包名 需要复制的文件名
直接把某个软件包下的文件复制到当前的命令行目录下

猜你喜欢

转载自blog.csdn.net/kevin_chan04/article/details/78467237