机器人操作系统ROS—树莓派Pi4B+激光雷达SLAM建图环境搭建(Ubuntu20.04.3 + ROS Noetic)

之前学习ros,nvidia jetson nano板子装的ubuntu18.04系统比较正常,但是pi4b的板子装的raspberry系统会出现各种依赖问题。最近想充分利用下几块Pi4B的板子,反复试了pi4安装官方/非官方的ubuntu18.04.5+ROS Melodic版本,最终都会卡在map-server或rviz等依赖上。最终用Pi4B + Ubuntu20.04.3 + ROS Noetic + RpLidar安装测试成功,记录一下安装过程。

一、Ubuntu镜像烧制

准备好PI4B板子、SD卡、USB读卡器、显示器、无限键鼠,外加一台烧制用的电脑,这里我用的一个ubuntu的开发本。

1.准备烧制软件

a.安装Raspberry Pi Imager

安装树莓派官方的烧制软件Raspberry Pi Imager,我用的本身是linux,可以直接命令安装:

sudo snap install rpi-imager

其他操作系统可以自行下载对应版本:

app安装完是树莓派的icon,找到后启动:

2.烧制镜像

a.选择镜像

点击“CHOOSE OS”,选择“Other general-purpose OS” —“Ubuntu”—“Ubuntu Server 20.04.3”,选中arm64的版本(会自动下载对应镜像文件,不用自己单独下载):

b.选择SD卡

点击“CHOOSE STOGAGE”,选择要烧制的SD卡后,点击“WRITE”即可。

*注意:这里下载并烧制的速度很慢,感觉至少1-2个小时左右,实在熬不动了睡了,第二天早上起来看烧制完毕了…

3.系统初始化

a.初始化密码

sd卡插入pi4,接上键鼠、显示器,启动系统,初始用户名和密码都是ubuntu,第一次登录会强制修改密码。

你也可以创建一个自己习惯的用户:

# 添加work用户
sudo adduser work
# 添加权限
sudo vim /etc/sudoers
  work ALL=(ALL) ALL
#sudo usermod -aG sudo,adm,dialout,cdrom,floppy,audio,dip,video,plugdev,lxd,netdev work
# 查看权限
id work
# 切换用户
su work

b.安装桌面

因为安装的是server版,为了方便操作,我们还需要安装桌面:

# 更新
sudo apt update
sudo apt upgrade
# 安装桌面
sudo apt install -y ubuntu-desktop

4.远程管理

a.远程桌面

设置里配置wiki之后,从官网下载安装nomachine arm64版本,之后就可以脱离显示器和键鼠,通过路由器查看ip后直接ssh或nomachine操作即可。

b.异地组网

推荐使用teamviewer免费版(非商业用途),当然你还可以安装ZeroTier(自测稳定性没有teamviewer好),登录并创建私有网络,在板子里join后,你就可以在非局域网直接链接到板子:

# linux下一键安装
curl -s https://install.zerotier.com | sudo bash
# 加入自己创建的私有网络
zerotier-cli join a09acf02339e3f97 

c.科学上网

设置“network”自动网络代理,配置.pac文件地址,以避免后边某些包无法下载。

 

二、安装ROS Noetic

1.安装ros noetic

因为melodic仅支持18.04,ROS1里只有noetic支持ubuntu20.04,所以我们这里安装noetic版本:

# 配置ros源(ustc的源最好最快)
#sudo sh -c 'echo "deb [arch=$(dpkg --print-architecture)] http://packages.ros.org/ros/ubuntu $(lsb_release -cs) main" > /etc/apt/sources.list.d/ros-latest.list'
sudo sh -c '. /etc/lsb-release && echo "deb [arch=$(dpkg --print-architecture)] http://mirrors.ustc.edu.cn/ros/ubuntu/ $DISTRIB_CODENAME main" > /etc/apt/sources.list.d/ros-latest.list'
# 添加公钥
sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654
# 或  curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | sudo apt-key add -
# 安装ros桌面版
sudo apt update
sudo apt install ros-noetic-desktop   #桌面完整版-desktop-full;桌面版-desktop;基础版-ros-base
# 安装slam包
sudo apt install ros-noetic-slam-gmapping  ros-noetic-map-server


# 设置环境
echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc
source ~/.bashrc

# 安装编译依赖
sudo apt install python3-rosdep python3-rosinstall python3-rosinstall-generator python3-wstool build-essential 
# 初始化 rosdep
sudo apt install python3-rosdep
sudo vim /etc/hosts
    185.199.110.133  raw.githubusercontent.com
sudo rosdep init
rosdep update

2.安装编译环境并测试激光雷达

# 准备编译目录
mkdir -p ~/catkin_ws/src
cd catkin_ws/src/
# 克隆RPLIDAR ROS代码库(记得添加板子的ssh key到github)
git clone git@github.com:robopeak/rplidar_ros.git
# 编译
cd ~/catkin_ws
catkin_make

# source
echo "source /home/ubuntu/catkin_ws/devel/setup.bash" >> ~/.bashrc
source ~/.bashrc
echo $ROS_PACKAGE_PATH

# 启动激光雷达节点
roscore
rosrun rplidar_ros rplidarNode

# 查看激光雷达数据
rostopic list
rostopic echo /scan

# 可视化点云数据
roslaunch rplidar_ros view_rplidar.launch
# 如果在PC上查看点云,须去掉rplidarNode的启动
roscd rplidar_ros/launch/
cp view_rplidar.launch view_rplidar_robot.launch # 修改robot文件,把rplidar.launch注释掉,以免PC本地启动rplidar节节点

# 查看topic
rostopic list
# 查看节点关系
rqt_graph

开启rviz后,相比于单独启动rplidarNode,会多出几个topic:

  • /initialpose:初始位姿
  • /move_base_simple/goal:全局路径规划目标位置
  • /scan:rplidar发布的激光雷达扫描数据
  • /tf、/tf_static:用于激光雷达坐标系、基坐标系、里程计坐标系之间的相互变换

可以看到rplidarNode发出/scan雷达数据topic:

3.测试slam建图

参考:机器人操作系统ROS—使用激光雷达RpLidar A1进行SLAM定位建图 #四、使用激光雷达进行SLAM定位建图

# 定位与地图管理工具
sudo apt install ros-noetic-fake-localization ros-noetic-map-server 
# hector 不需要里程计数据,只根据激光信息即可构建地图
sudo apt install ros-noetic-hector-slam ros-noetic-hector-slam-launch 
# gmapping 需要IMU+里程计+激光信息构建地图
sudo apt install ros-noetic-gmapping ros-noetic-slam-gmapping
# karto
sudo apt install ros-noetic-open-karto ros-noetic-slam-karto

# 克隆slam+导航代码库
cd catkin_ws/src/
git clone git@github.com:yanjingang/robot_navigation.git
# 编译
cd ~/catkin_ws
catkin_make

# SLAM建图测试
roslaunch robot_navigation robot_slam_laser.launch
# PC端可视化
roslaunch robot_navigation slam_rviz.launch

# 查看topic
rostopic list
# 查看节点关系
rqt_graph

# 保存地图
roscd robot_navigation/maps/
rosrun map_server map_saver -f map

开启slam建图后,相比于view_rplidar,会多出几个topic:

  • /initialpose:初始位姿
  • /map/map_metadata:hector发布的地图栅格数据、地图数据Meta
  • /move_base_simple/goal:全局路径规划目标位置
  • /poseupdate/slam_out_pose:hector发布的当前机器人位姿估计(高斯估计、无协方差两种)
  • /scan:rplidar发布的激光雷达扫描数据
  • /syscommand:hector订阅的系统命令(例如reset等)
  • /tf、/tf_static:用于激光雷达坐标系、基坐标系、里程计坐标系之间的相互变换

可以看到SLAM节点hector_height_mapping监听和发布的topic情况:

三、pi ros与arduino底盘的导航控制

1.测试导航

首先我们需要先通过测试导航包来搞清楚“定位-规划-控制”相关的topic及发送和监听关系:

# 导航功能包 (包含move_base导航+amcl定位+teb规划+键盘控制发送vel_cmd)
sudo apt install ros-noetic-navigation  ros-noetic-teb-local-planner ros-noetic-teleop-twist-keyboard

# pi上启动TEB planner,用于无地图场景导航并建图
roslaunch robot_navigation robot_slam_laser.launch planner:=teb
# pc端启动rviz查看建图数据和“2D Nav Goal”控制机器人移动
roslaunch robot_navigation slam_rviz.launch
# pc键盘控制
rosrun teleop_twist_keyboard teleop_twist_keyboard.py
# 查看topic(hector—slam负责建图,move_base负责路径规划,amcl负责定位)
rostopic list
    /cmd_vel         # move_base发布给底盘的移动速度命令
    /initialpose     # amcl定位初始位姿,可通过rviz控制栏的"2D Pose Estimate"按钮测试修正此值
    /map             # hector-slam发布的地图栅格数据,amcl/move_base都会订阅用于定位和路径规划
    /map_metadata    # hector-slam发布的地图数据Meta
    /move_base/current_goal 
    /move_base/goal  # move_base监听的规划目标,可通过rviz的“2D Nav Goal”按钮测试发送
    /move_base_simple/goal   # 同上,但是非action接口,无法追踪目标状态
    /poseupdate      # hector-slam发布的当前机器人位姿估计(具有高斯估计的不确定性)
    /rosout
    /rosout_agg
    /scan            # rplidar发布的激光雷达数据
    /slam_cloud
    /slam_out_pose   # hector-slam发布的当前机器人位姿估计(没有协方差)
    /syscommand      # hector-slam订阅的系统命令,例如reset
    /tf              # 用于激光雷达坐标系、基坐标系、里程计坐标系之间的相互变换
    /tf_static      
# 查看节点关系
rqt_graph

# 点击rviz控制栏里的"2D Pose Estimate"修正初始位姿按钮,同时监听初始位姿topic,可以看到修正初始位姿数据
rostopic echo /initialpose
    header: 
      seq: 0
      stamp: 
        secs: 1637590180
        nsecs: 619881730
      frame_id: "map"
    pose: 
      pose: 
        position: 
          x: 0.898611545563
          y: -0.214766919613
          z: 0.0
        orientation: 
          x: 0.0
          y: 0.0
          z: 0.364361599826
          w: 0.931257550075
      covariance: [0.25, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.25, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.06853892326654787]
    ---
# 点击rviz控制栏里的"2D Nav Goal"设定导航目标按钮,同时监听对应topic,可以看到修正初始位姿数据
rostopic echo /move_base/goal
    header: 
      seq: 2
      stamp: 
        secs: 1637592510
        nsecs: 186612710
      frame_id: ''
    goal_id: 
      stamp: 
        secs: 0
        nsecs:         0
      id: ''
    goal: 
      target_pose: 
        header: 
          seq: 2
          stamp: 
            secs: 1637592510
            nsecs: 182121126
          frame_id: "map"
        pose: 
          position: 
            x: 0.610744893551
            y: 0.824579000473
            z: 0.0
          orientation: 
            x: 0.0
            y: 0.0
            z: 0.564671369508
            w: 0.825315845272
    ---

截止到这里,我们基本弄明白了“slam-定位-规划-控制-底盘”之间的topic关系,也进行了模拟的导航测试,但是目前我们的ros跟底盘之间还并没有建立连接和联动(ros未拿到底盘的里程计数据,也没有把move指令发送给底盘),所以我们下一步需要打通pi ros与arduino 底盘的连接,并使move_base与arduino联动起来。

2.控制机构

a.打通pi ros与arduino的基本通讯能力

机器人操作系统ROS—Arduino执行机构

b.测试base_control底盘通信

# 添加base_control
vim launch/robot_lidar.launch
  <!-- base control -->
  <include file="$(find robot_navigation)/launch/base_control.launch" />

# 绑定底盘端口
 vim launch/base_control.launch
<launch>
    ...
    <!-- serial param -->
    <arg name="port" default="/dev/ttyACM0" />
    <arg name="baudrate" default="57600" />
    ...
</launch>

# 编写双向通信测试代码
vim script/base_control.py
#代码详见 https://github.com/yanjingang/robot_navigation

# 单独验证sub/pub
rosrun rosserial_python serial_node.py _port:=/dev/ttyACM0
python script/base_control.py

# 合并验证建图
roslaunch robot_navigation base_control.launch
roslaunch robot_navigation robot_slam_laser.launch planner:=teb
roslaunch robot_navigation slam_rviz.launch   #pc

# 使用地图导航测试
roslaunch robot_navigation robot_navigation.launch
roslaunch robot_navigation navigation_rviz.launch  #pc

# 查看base_control发送的轮速数据
rostopic list
rostopic echo /odom

# 测试"2D Nav Goal",查看base_control收到的指令数据
rostopic echo /cmd_vel
    linear: 
      x: 0.0
      y: 0.0
      z: 0.0
    angular: 
      x: 0.0
      y: 0.0
      z: 0.0
    ---
robot_navigation.launch下能看到base_control.py里收到的/cmd_vel
    [INFO] [1638249681.414300]: get cmd data:linear: 
      x: 0.10077160733559222
      y: 0.0
      z: 0.0
    angular: 
      x: 0.0
      y: 0.0
      z: -0.19502660300177715

c.完善base_control底盘指令执行逻辑

这里我们用arduino底盘通过rosserial直接监听/cmd_vel并通过pid模拟信号控制电机转动的方式实现。

stydy/iot/arduino/pid/pid.ino

robot_navigation/arduino/chassis/chassis.ino

*注:也可直接在base_control.py里直接转换成serial裸串口的指令发给底盘执行,这种方式对底盘板子的算力要求会更低些。

d.完善base_control的里程计计算上报逻辑

arduino板子算力有限,监听cmd_vel就有点跑不动了,里程计的计算放在pi上吧。

 

四、总结

安装过程中全程连接手机4G热点,除了raw.githubusercontent.com安装相对顺畅,所以如果大家因为各种网络问题,注意三种解决方法:

1.科学上网避免有些域名不能访问

2.手机4/5G热点网速更快(全部下来2-3G的流量)

3.域名如果怎么搞都不行,就在其他机器ping出IP地址,直接把IP配置到/etc/hosts中,跳过DNS过程

 

yan 21.10.17

 

参考:

How to install Ubuntu Desktop on Raspberry Pi 4

Ubuntu Server LTS 20.04 安装桌面

ROS Noetic installation instructions

清华大学开源软件镜像站-ubuntu arm

Getting Started With ROS Melodic on Raspberry Pi 4 Model B

Ubuntu 18.04 LTS (Bionic Beaver)

ROS小车启动功能包编写

move_base代码学习一

ROS与Arduino学习(八)电机控制(基于rosserial_arduino)

发表评论

邮箱地址不会被公开。