一. 工作空间

1.1 工作空间的概念

workspace:存放工程文件的文件夹

1.2 创建工作空间

# 创建文件夹
mkdir -p ~/wheeltec/src
# 进入文件夹
cd ~/wheeltec/src
# 初始化工作空间
catkin_init_workspace

1.3 编译工作空间

# 返回上一级路径
cd ..
# 编译工作空间
catkin_make

# 编译单独功能包
catkin_make -DCATKIN_WHITELIST_PACKAGES="package_name"
# 自定义编译线程
catkin_make -j -1

如果编译单独的功能包之后,再使用catkin_make 的时候,仍默认编辑上一种单独的功能包。当我们想去编译整个功能包时,需要将packge_name 设定为空。

1.4 设置环境变量

  • 添加局部的环境变量,如果roslauch指令在另外一个终端执行会失效。
# 添加环境变量
source devel/setup.bash
# 查看ROS的环境变量
echo $ROS_PACKAGE_PATH
# 然后再运行
roslauch xxx.launch

  • 添加全局的环境变量
# 编辑 .bashrc文件
cd ~
nano .bashrc

source ..../devel/setup.bash
source .bashrc

二. 功能包

2.1 功能包的概念

2.2 功能包的内容

  • include: .h文件
  • src :.cpp文件
  • launch: launch文件,启动
  • urdf :.urdf文件,rviz工具中三维模型的一个描述性文件
  • config: 参数文件,yaml,srv,msg,action
  • scripts: 可执行脚本文件(Python)
  • CMakeLists.txt :定义编译的规则
  • package.xml : 定义package的属性

2.3 创建功能包

# 创建功能包
catkin_create_pkg <package_name> [depend1] [depend2] [depend3]
# 实例
catkin_create_pkg new_package std_msgs rospy roscpp

三. CMakeLists.txt

3.1 CMakeLists.txt文件的作用

定义编译规则的文件

cmakelists的wiki网址

3.2 最常用的cmakelists宏

  • cmake_minimum_required() CMake版本
  • project() 项目名称
  • find_package() 添加依赖
  • catkin_package() 编译生成信息导出
  • add_executable() 生成可执行文件
  • target_link_libraries()可执行文件链接到库

3.3 其他的cmakelists宏

  • add_message_files() 添加话题消息类型文件
  • add_service_files() 添加服务消息类型文件
  • add_action_files() 添加行为消息类型文件
  • generate_messages() 生成消息文件
  • include_directories() 添加头文件路径
  • install() 安装规则
  • add_dependencies() 添加依赖项
  • add_library() 生成自定义的库

四. package.xml

4.1 package.xml文件的作用

功能包的描述信息

4.2 必要的package.xml标签

<package format="2"> 根标签
...
</package>

<name> 包名
<license> 开源许可
<maintainer> 维护者
<description> 描述
<version> 版本号

五. Launch文件和参数服务器

5.1 Launch标签总览

Launch文件:可实现多节点启动和参数配置的xml文件

<launch> ... </launch> : 根标签
<node> :启动节点
<include> :嵌套,包含其他launch文件,其他XML文件
<remap> :重命名
<param> :全局参数
<rosparam> :加载参数
<group> :节点分组
<arg> :局部参数
<machine> :远程标签
<env> :环境变量
<test> :测试节点

  • 节点
# 模板
rosrun <package_name> <executable|python>
<node pkg="package_name" type="executable|python" name="node_name" />
# 示例
<node pkg="turn_on_wheeltec_robot" type="wheeltec_robot_node" name="wheeltec_robot">

5.2 参数服务器

rosparam list : 列出参数服务器中的参数
rosparam get : 获取参数
rosparam set : 设置参数
rosparam delete : 删除参数
rosparam load : 从文件中加载参数到参数服务器
rosparam dump : 将参数服务器的参数写入文件



六. ROS话题

  • 一种一对多、异步的通信机制
    一对多:一个话题可以有多个订阅者
    异步:发布者只管发布话题而不在意有多少个订阅者。

6.1 topic 命令行指令

rostopic echo :打印话题信息
rostopic hz :话题频率
rostopic info :话题信息
rostopic list :列举话题
rostopic pub :往话题输入信息
rostopic bw :话题带宽
rostopic find :从数据类型寻找话题
rostopic type :查看话题的数据类型




6.2 发布话题

发布流程
①创建一个发布者
②创建消息数据
③消息赋值
④将消息发布出去

ros::Publisher pub = nh.advertise<std_msgs::String>("topic_name", queue size);
std_msgs::String str;
str.data = "hello world";
pub.publish(str);

6.3 订阅话题


①创建一个订阅者 Subscriber
②创建一个回调函数

void callback(const std_msgs::StringConstPtr& str)
{
...
}.
..
ros::Subscriber sub = nh.subscribe("my_topic", queue size, callback);

6.4 自定义消息类型数据

  • 官方定义好的消息数据类型:
    查看所有的消息数据类型:rosmsg list
    显示消息类型的内容rosmsg show
    查看某个话题的消息数据类型:rostopic type /topic_name | rosmsg show
  • 自定义消息类型的步骤
    ①自定义msg文件
    在功能包下,新建一个msg的文件夹,并在该文件夹下新建一个test.msg的文件。 并在该文件中编辑消息数据类型。
    ②添加编译规则
# CMakeLists.txt
find_package (catkin REQUIRED COMPONENTS roscpp std_msgs message_generation)
add_message_files( FILES Message1.msg )
generate_messages( DEPENDENCIES std_msgs )
catkin_package( ... CATKIN_DEPENDS message_runtime ... )

find_package中添加message_generationstd_msgsroscpp

catkin_package中添加message_runtime


catkin_package前面加入add_message_filesgenerate_messages

package.xml 中添加如下依赖:

package.xml:
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>

③添加描述规则
CMakeLists.txt中添加如下内容:


wheeltec_robot.cpp文件中添加#include "功能包名/test.h"

#include "turn_on_wheeltec_robot/test.h"

然后添加发布者

test_publisher =n.advertise<turn_on_wheeltec_robot::test>("test_topic",10);

以及发布函数

Publish_Test();

wheeltec_robot.h文件中添加发布者

ros::Publisher test_publisher;

以及发布函数

void Publish_Test();


然后重新编译功能包。

七. 把ROS和STM32联系起来

7.1 两种控制器的功能

  • ROS主控
    例如jason nano等
    ①雷达信息采集
    ②摄像头信息采集
    ③路径规划

  • STM32控制器
    ①里程计信息采集(odom,电机的转速)
    ②陀螺仪信息采集(imu,xyz三轴角速度和加速度)
    ③电机控制(控制运动底盘的运动)

  • 通信内容

  • 硬件连接

7.2 软件设置

  • 软件设置
    ①更改CP2102芯片的serial
    wheeltec_udev.sh
    ②创建设备别名
    CP21xx Customization Utility .exe

  • wheeltec_robot.cpp文件

八. ROS传感器的介绍

8.1 激光雷达

  • 实现的功能
    ①建图
    ②导航
    ③避障
    ④跟随

  • 开启雷达
    roslaunch rplidar_ros rplidar.launch

  • 订阅雷达话题

/scan   sensor_msgs/LaserScan
Header header
float32 angle_min
float32 angle_max
float32 angle_increment
float32 time_increment
float32 scan_time
float32 range_min
float32 range_max
float32[] ranges
float32[] intensities

8.2 摄像头

  • 实现的功能
    ①视觉巡线
    ②物体识别
    ③3D建图
    ④颜色跟踪

  • 开启摄像头
    roslaunch usb_cam usb_cam-test.launch
    roslaunch astra_camera astra.launch
    roslaunch astra_camera astra_pro.launch

  • 订阅摄像头话题

sensor_msgs/Image
Header header
uint32 height
uint32 width
string encoding
uint8 is_bigendian
uint32 step
uint8[] data

sensor_msgs/CompressedImage
Header header
string format
uint8[] data

九. RVIZ配置方法

  • 首先打开终端,通过ssh命令连接到机器人上

  • 运行导航的.launch文件

  • 然后在虚拟机的终端重新打开一个窗口,运行rviz

  • 点击add,添加一个机器人模型
    有两种添加方式,一种是通过话题添加,一种是通过设备添加。在这里我们选择通过设备添加。

  • 添加TF坐标

  • 添加一个全局地图和一个局部地图

  • 添加雷达信息

  • 添加全局路径和局部路径信息。

rqt可视化工具集

名称 功能
Node Graph 查看ros话题和节点通信的结构
TF Tree 查看tf坐标关系链接
Plot 图形化查看话题数据
Dynamic Reconfigure 实时调参
Image View 查看图片
Bag 记录/复现 ROS进程
  • Node Graph
    指令: rqt_graph

  • TF Tree
    指令:rosrun rqt_tf_tree rqt_tf_tree

  • Plot
    指令:rqt_plot

  • Dynamic Reconfigure
    指令:rosrun rqt_reconfigure rqt_reconfigure
    注意:需要对应程序中,参数读取是以指针的形式才可以实时调参

  • Image View
    指令:rqt_image_view

  • Bag

# 记录所有话题
rosbag record -a 
# 播放一次
rosbag play <name.bag> 
# 倍速播放
rosbag play -r num <name.bag> 
# 只播放某个话题
rosbag play <name.bag> --topic /topic_name 

十一、TF坐标关系变换

TF用于两个坐标系之间的转换,包括平移和旋转。

  • TF树
    运行指令:rosrun rqt_tf_tree rqt_tf_tree打开tf树。

  • TF的frame_id
    上图中椭圆中的名字就是tf的frame_id

  • TF的broadcaster
    两个坐标之间的关系需要broadcast广播。broadcast其实相当于rosnode, 可以用rosnode list 查看。

  • TF的基坐标
    所有TF坐标的根坐标。每个tf坐标都会索引到一个父坐标,直到索引到一个基坐标。

  • TF的消息数据类型

  • TF静态坐标变换

  • TF广播器和监听器
    TF广播器

static tf2_ros::TransformBroadcaster br;
geometry_msgs::TransformStamped transformStamped;
... 
transformStamped.xxx=xxx;
... 
br.sendTransform( transformStamped );

TF监听器

tf2_ros::Buffer tfBuffer;
tf2_ros::TransformListener tfListener(tfBuffer);
geometry_msgs::TransformStamped transformStamped;
transformStamped = tfBuffer.lookupTransform("target","source",time);