10天零基础玩转ROS小车

ROS搭建基于Linux版本: Ubuntu 18.04 LTS
首先需要安装虚拟机和Linux操作系统,安装过程参考百度

目录:

  • 一、ROS基础
    • ROS常用关键词
    • 文件系统的概念
  • 二、环境搭建
    • 快速安装
    • 分步安装
  • 三、ROS初体验
    • ROS串口通信
    • 主机topic通信
  • 四、ROS分布式通信规范
    • 节点通信原理
      • 话题发布
      • 话题订阅
  • 五、ROS描述文件
  • 六、启动小车底盘节点
  • 七、激光雷达构建地图
  • 八、SLAM自主导航
  • 九、机器视觉巡线避障
  • 十、深度机器视觉构建三维点云

一、ROS基础

ROS核心教程官方链接 http://wiki.ros.org/ROS/Tutorials

ROS常用的关键词

1: message: 即消息.机器人需要传感器,传感器采集到的信息,即这儿的message. 假如我们的GPS采集到机器人位置消息,温度计采集到的温度等. 任何数据都能作为message.

2: topic: 假设我们有两个传感器,GPS和温度计.在ROS中我们得给采集到的消息取个名字用来区分不同的message,这就是topic了. 至于怎么取名字,后面的程序可见.

3: node: 节点. ROS中,通常来讲你写的c++或者python程序主函数所在的程序称为一个节点(并不准确,暂时这么理解).

4: package: 一个ROS package包含了你要完成的一个项目的所有文件.

5: workSpace: ROSworkspace,即ROS的工作空间.你当然需要ROS来完成很多不同的项目.你的ROS工作空间是用来存放很多不同package的.

6: publish, subscribe: ROS很大的一个作用就是传递message.为什么要传递消息呢? 打个比方你写了一个程序,用来获得GPS的讯息,写了另外一个程序,用来处理GPS的信息.这时你就是需要把采集到的信息传输到处理用的程序中.信息的传输在ROS中称为publish. 信息的订阅在ROS中称为subscribe.
好了,有了这几个概念,我们就可以开始撸第一个ROS程序了.(可能大佬们觉得还有好多没讲呢,没关系我们慢慢来.)

快速了解文件系统概念

Packages:
软件包,是ROS应用程序代码的组织单元,每个软件包都可以包含程序库、可执行文件、脚本或者其它手动创建的东西。

Manifest (package.xml):
清单,是对于’软件包’相关信息的描述,用于定义软件包相关元信息之间的依赖关系,这些信息包括版本、维护者和许可协议等。

Launch (file.launch):
launch文件顾名思义就是启动文件,launch文件是描述一组节点及其话题重映射和参数的XML文件。launch允许同时启动多个节点

二、环境搭建

树莓派系统安装
Ubuntu mate 下载链接

这里使用ubuntu mate 18.04 raspberry版本,考虑到官方镜像Linux是基于Debian9发行的,使用ubuntu mate可以减少很多兼容性带来的麻烦

使用镜像烧录工具将系统拷入SD卡中,启动树莓派

这里分享了两种安装方式:
1- 快速安装:快速配置所有ROS系统以及所需软件
2- 分步安装:理解安装所需要的软件包和熟悉常用的Linux操作

快速安装:

创建工作区

cd ~/ 
mkdir catkin_ws/
cd catkin_ws

ROS安装器下载

在下载链接中选择保存->下载,然后吧下载好的.sh文件保存到刚创建好的catkin_ws文件夹下,在终端输入

chmod +x ros_install.sh
./ros_install.sh

此时开始进行安装程序,等待安装完成后就可以进入下一个环节

分步安装:

安装ROS主要步骤:

1.切换软件源
sudo sh -c 'echo "deb https://mirror.tuna.tsinghua.edu.cn/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
2.配置秘钥
sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654
3.更新本地软件列表
sudo apt update
4.安装ROS
sudo apt install ros-melodic-ros-base
5. 安装完成后初始化ros
sudo rosdep init
rosdep update
6. 添加环境变量
echo "source /opt/ros/melodic/setup.bash" >> ~/.bashrc
source ~/.bashrc

三、ROS初体验

本章目标: 体验ROS通信原理以及测试ROS配置是否完善

ROS串口通信

为什么要用串口通信:
ROS运行在树莓派或其他嵌入式系统平台上,而机器人控制器大部分由底层的单片机或控制器组成的,多数控制算法的PID、滤波器、传感器姿态角都是重复的矩阵迭代运算,占用CPU和内存。这个时候为了降低系统资源使用,就会使用串口来与底层的驱动器通信。这样ROS就可以去处理其他的工作。

通过ros与arduino串口通信:

Arduino端配置

在linux上安装ArduinoIDE (网上很多教程,这里不多赘述).
安装rosserial库: 工具->管理库->搜索rosserial->安装.
打开Helloworld例程: 文件->示例->RosserialAdruinoLibary->HelloWorld:

烧录到Arduino中,选择波特率为115200. 完成后测试ROS通信–>

1.打开串口权限
sudo chmod 777 /dev/ttyACM0   //这里我的串口号是ttyACM0
2.开启ros主节点
roscore
3.开启ros串口节点
rosrun rosserial_python serial_node.py /dev/ttyACM0
4.订阅节点消息
rostopic echo /chatter

这里终端在不停地打印:

---
data: "hello world!"
---
data: "hello world!"
---
data: "hello world!"
---
data: "hello world!"

到这里就说明串口通信已经成功了,下面开始自己尝试构建ROS通信的node和topic:

ROS主机topic通信:

1.创建workspace

ROS通信模式主要是分布式结构,通过节点的话题通信来传递消息和指令,首先需要创建一个Workspace来放置自己的package,便于管理和维护。

mkdir -p ~/catkin_ws/src
cd ~/catkin_ws/
catkin_make

执行完成后,在catkin_ws目录下会生成3个文件夹/build、/devel、/src
这里一个工作空间就已经创建完了,后续的package都会存放在这个目录下面

2. 创建一个ROS package

使用命令: catkin_create_pkg 创建一个包

catkin_create_pkg topic_test std_msgs rospy roscpp

topic_test 就是我们需要创建的包名
std_msgs rospy roscpp 是包所需的依赖包,类似于C语言的#include “xxxxx.h”

3. 创建话题发布者(Publisher)和订阅者(Subscriber)

进入到我们新创建的包中,创建src源文件目录

roscd topic_test

roscd: ROS工具之一,在编译通过后,就可以通过roscd快速进入包所在目录

这时你的终端的目录应该会跳转至:

~/catkin_ws/src/topic_test/:

我们创建一个发布者pub_test.cpp文件,并写入测试代码

touch pub_test.cpp
gedit pub_test.cpp

将下面代码放到pub_test.cpp文件中

#include "ros/ros.h"
#include "std_msgs/String.h"

#include 

int main(int argc, char **argv)
{
  ros::init(argc, argv, "talker");
  ros::NodeHandle n;
  ros::Publisher chatter_pub = n.advertise("chatter", 1000);
  ros::Rate loop_rate(10);
  
  int 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());
    chatter_pub.publish(msg);
    ros::spinOnce();
    loop_rate.sleep();
    ++count;
  }
  return 0;
}

同样, 创建一个订阅者, 将代码拷贝到.cpp文件中.

touch sub_test.cpp
gedit sub_test.cpp

将下面代码放到sub_test.cpp文件中

#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::NodeHandle n;
  ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);
  ros::spin();
  return 0;
}

关闭已经打开的编辑框,您在上一教程中使用过catkin_create_pkg,该教程为您创建了package.xml和CMakeLists.txt文件.
现在只需将以下几行添加到CMakeLists.txt的底部

add_executable(talker src/pub_test.cpp)
target_link_libraries(talker ${catkin_LIBRARIES})
add_dependencies(talker topic_test)

add_executable(listener src/sub_test.cpp)
target_link_libraries(listener ${catkin_LIBRARIES})
add_dependencies(listener topic_test)

进入catkin_ws目录, 重新编译生成

cd ~/catkin_ws
catkin_make

四、ROS分布式通信规范

ROS中的通信方式有四种,主题、服务、参数服务器、动作库。每个通信方式都有自己的特点

节点通信原理

ROS所有节点间通信都是以话题、订阅的方式,当发布话题者创建一个话题时,订阅者可以通过订阅这个话题来接收消息

一、话题发布:

经过上一章的试验,我们大概对ROS通信有了一定的概念,接下来我们分析一下在Arduino中,ROS是如何发布话题的:
在Arduino中选择文件-示例-Rosserial Arduino Library -> Helloworld

//Rosserial Arduino Library -> Helloworld

#include 
#include 

ros::NodeHandle  nh;

std_msgs::String str_msg;
ros::Publisher chatter("chatter", &str_msg);

char hello[13] = "hello world!";

void setup()
{
  nh.initNode();
  nh.advertise(chatter);
}

void loop()
{
  str_msg.data = hello;
  chatter.publish( &str_msg );
  nh.spinOnce();
  delay(1000);
}
  1. 包含ROS头文件,主要是一些ROS用到的库和消息类型
#include 
#include  
  1. 创建一个节点句柄对象,在spinOnce()中处理消息发布、订阅等
ros::NodeHandle  nh;
  1. 示例创建了一个chatter话题对象,引用publish可以发布话题。
std_msgs::String str_msg;
ros::Publisher chatter("chatter", &str_msg);
  1. 初始化ROS节点句柄,将创建的chatter话题注册到通信句柄中
nh.initNode();
nh.advertise(chatter);
  1. 通过chatter对象的publish实例将str_msg加入消息队列,通过spinOnce()将消息队列内的消息推送给串口
chatter.publish( &str_msg );
nh.spinOnce();
二、话题订阅:

在Arduino中选择文件-示例-Rosserial Arduino Library -> Blink

// Rosserial Arduino Library -> Blink

#include 
#include 

ros::NodeHandle  nh;

void messageCb( const std_msgs::Empty& toggle_msg){
  digitalWrite(13, HIGH-digitalRead(13));   // blink the led
}

ros::Subscriber sub("toggle_led", &messageCb );

void setup()
{ 
  pinMode(13, OUTPUT);
  nh.initNode();
  nh.subscribe(sub);
}

void loop()
{  
  nh.spinOnce();
  delay(1);
}
  1. 包含ROS头文件,主要是一些ROS用到的库和消息类型
#include 
#include 
void messageCb( const std_msgs::Empty& toggle_msg)
{
    digitalWrite(13, HIGH-digitalRead(13));   // blink the led
}
ros::Subscriber sub("toggle_led", message);

示例创建了一个toggle_led订阅对象,当接收到来自toggle_led话题发布的消息时,调用message函数。

ros::Subscriber sub("toggle_led", &messageCb );

五、ROS描述文件

六、启动小车底盘节点

七、激光雷达构建地图

八、SLAM自主导航

九、机器视觉巡线避障

十、深度机器视觉构建三维点云

你可能感兴趣的:(ROS,树莓派,Ubuntu)