松灵学院 | 在松灵 LIMO 上使用 Docker 进行 ROS2 开发

2023-05-16

截至目前,Jetson Nano 平台官方仍不提供 Ubuntu 20.04 固件,所以使用 Jetson Nano 平台开发 ROS2 存在巨大的困难,但是好在 Docker 提供的容器技术,让我们能非常方便的虚拟出一个 Ubuntu 20.04 环境进行 ROS2 开发并通过云端快速分享自己的开发环境,本文我将以松灵 LIMO 为例向大家演示如何使用 Docker 进行 ROS2 开发以及这种开发模式的优越性。

此外,在 ROS 开发过程中(尤其是在多人团队协同中)你一定遇到过这样的问题:需要快速(在不同架构机器上)部署相同开发环境、别人电脑上可以编译但到了自己这里就会报错、无法复现别人的 Bug、经常会出现缺少支持库或者支持库冲突的情况,尤其是一台电脑上需要做多种任务的情况(比如 深度学习、QT 开发、ROS1、ROS2)则会更糟糕…… 这个时候我们就有必要使用 Docker 进行开发

本文分为两部分,1-6节讲解 使用 Docker+VSCode 开发方式,7 节将带领大家在 LIMO 平台进行实战

无论您之前使用什么样的方式进行开发,笔者在这里都推荐您尝试 Docker + VSCode,虽然这可能需要两三个下午的时间进行学习,但请相信这一切都是值得的!

如果您不会使用 docker 或者没有尝试过类似的操作,请您先阅读 《Docker 配合 VSC 开发最佳实践》(https://anthonysun256.github.io/docker-with-vsc_best-practice/)

1. 镜像选取

Docker 官方镜像服务器上有很多的 ROS 开发镜像,这里我们可以有如下选择(这几个镜像也是笔者常用的):

• ROS 官方镜像:https://hub.docker.com/_/ros 

内含所有 ROS 发行版的基础开发镜像,而且支持多种架构,非常适合在多种架构的机器上进行部署。

• althack 的开发镜像 https://hub.docker.com/u/althack

althack 提供了 VSCode 的开发工作环境模板:https://github.com/athackst/vscode_ros2_workspace

虽然模板是 ROS2 但是只要简单修改 Dockerfile 中引用的镜像名称即可改成 ROS1 环境

Dockerfile 源码:https://github.com/athackst/dockerfiles

这个镜像优点是提供了 ROS-desktop-full 的开发环境,省去了自行安装的麻烦,非常适合学习使用。缺点是只支持 PC,如果其他环境需要自己使用 Dockerfile 编译。

2. 开发环境搭建

我们新建的工作空间目录格式如下:

.
├── .devcontainer # docker 配置文件
│   ├── devcontainer.json
│   └── Dockerfile
└── src # ROS 源码目录

 VSCode 会自动读取 .devcontainer 中的配置文件。对于我个人学习而言我一直使用的是 https://hub.docker.com/u/althack 的镜像和配置,下面的配置文件也是改变于此,各位读者可以根据自己的需要进行修改:

Dockerfile

# 改编自 https://github.com/athackst/vscode_ros2_workspace
# 我使用的 ROS 学习镜像,根据您的喜好可以自行更改
FROM althack/ros:melodic-gazebo as gazebo 

# ** [可选] 取消注释安装其他组件 **
#
# ENV DEBIAN_FRONTEND=noninteractive
# RUN apt-get update \
#    && apt-get -y install --no-install-recommends <your-package-list-here> \
#    #
#    # Clean up
#    && apt-get autoremove -y \
#    && apt-get clean -y \
#    && rm -rf /var/lib/apt/lists/*
# ENV DEBIAN_FRONTEND=dialog

# 为 ros 用户配置自动 source
ARG WORKSPACE
RUN echo "if [ -f ${WORKSPACE}/install/setup.bash ]; then source ${WORKSPACE}/install/setup.bash; fi" >> /home/ros/.bashrc

 如果需要 GPU 支持(需要安装nvidia-docker [https://anthonysun256.github.io/docker_with_nvidia/ ] )(Jetson 平台不要用这个指导!!请使用 Jetpack 套件固件自带的 nvidia-docker2 或者直接进行安装 sudo install nvidia-docker2 (使用 l4t2 的源))则在上述脚本之后追加如下指令:

RUN apt-get update \
    && apt-get install -y -qq --no-install-recommends \
    libglvnd0 \
    libgl1 \
    libglx0 \
    libegl1 \
    libxext6 \
    libx11-6 \
    && apt-get autoremove -y \
    && apt-get clean -y \
    && rm -rf /var/lib/apt/lists/*
ENV DEBIAN_FRONTEND=dialog

# Nvidia 运行时变量.
ENV NVIDIA_VISIBLE_DEVICES all
ENV NVIDIA_DRIVER_CAPABILITIES graphics,utility,compute

ENV QT_X11_NO_MITSHM=1

 devcontainer.json

// 改编自 https://github.com/athackst/vscode_ros2_workspace
// See https://aka.ms/vscode-remote/devcontainer.json for format details.
{
    "dockerFile": "Dockerfile",
    "build": {
        "args": {
            "WORKSPACE": "${containerWorkspaceFolder}"
        }
    },
    "remoteUser": "ros",
    "runArgs": [
        "--network=host",
        "--cap-add=SYS_PTRACE",
        "--cap-add=SYS_RAWIO",
        "--privileged=true",
        "--security-opt=seccomp:unconfined",
        "--security-opt=apparmor:unconfined",
        "--volume=/tmp/.X11-unix:/tmp/.X11-unix",
        // "--gpus" "all", // 取消该注释使用 GPU 功能
        "--device=/dev/bus/usb:/dev/bus/usb", // 挂载外部硬件,比如摄像头,根据需要修改路径
    ],
    "containerEnv": {
        "DISPLAY": "${localEnv:DISPLAY}"
    },
    // Set *default* container specific settings.json values on container create.
    "settings": {
        "terminal.integrated.profiles.linux": {
            "bash": {
                "path": "bash"
            },
        },
        "terminal.integrated.defaultProfile.linux": "bash"
    },
    // 推荐安装的插件
    "extensions": [
        "dotjoshjohnson.xml",
        "zachflower.uncrustify",
        "ms-azuretools.vscode-docker",
        "ms-iot.vscode-ros",
        "ms-python.python",
        "ms-vscode.cpptools",
        "redhat.vscode-yaml",
        "smilerobotics.urdf",
        "streetsidesoftware.code-spell-checker",
        "twxs.cmake",
        "yzhang.markdown-all-in-one"
    ]
}

3.启动开发环境

我们使用 VSCode 打开文件夹,并且 Reopen in docker 即可(不要自己只使用 Dockerfile 进行构建,因为在 devcontainer.json 中我们还挂载了一些目录,添加了一些参数)

根据网络状况不同初次启动这里可能需要等待 VSCode 安装一些组件,请耐心等待,下次启动即可极速启动

部分挂载的设备可能需要 root 权限才能访问,这一点需要注意

5.查看图形界面

在我们的主机中,打开一个终端,运行 xhost +

之后在我们 VSCode 中的命令行中随便打开一个图形界面,比如 rqt,可以看到 rqt 直接显示在了我们的屏幕上

对于 Rviz 和 Gazebo,如果您的电脑上没有显卡、未正确安装闭源显卡驱动或者没有正确开启 nvidia-docker 显卡功能那界面会很卡,这和用不用 Docker 没有关系

5.插件简介

笔者的 devcontainer.json 中会为大家安装一些实用插件,这部分我们简略了解一下

• ROS——这个插件可以帮助我们快速更新 VSCode 中有关 ROS include 的路径,而且提供了图形界面查看 ROS 话题、服务等

按下 shift+ctrl+p 呼出快捷命令栏,输入 ros,可以看到自动更新选项

这个可说的不多,能够帮助我们快速编写相应的文件,为其提供智能补全

• yaml xml xacro 语法助手

6.修复本地包 include / import 错误

默认情况下 ROS 插件可能不会包含我们本地路径的包,这并不会导致编译错误,但是会导致我们无法使用智能提示。

msg 类型的包需先编译生成对应的 c++或者python头文件(在 devel 或者 install 中寻找对应

目录)

这时候我们需要手动添加路径到 c_cpp_properties.json(注意每条路径后需要有个逗号:

 提示:我们可以直接在左侧资源管理器中右键文件夹在弹出的菜单中复制文件夹的绝对路径

python 同理:

至此我们就能愉快的进行开发了,而且您还能保存自己的开发环境、推送到云端或者整理成压缩包进行分享,让团队中的所有人都能在几分钟之内拥有一致的开发环境,最重要的是还不会搞坏电脑本身的环境!

7. 远程开发实战

本节我们将运用上面所讲的知识,在松灵 LIMO 上使用 docker 进行开发!

首先运行 docker 环境( docker 在默认系统中已经安装,这里我们不使用图形界面,不需要开启显卡支持)

$ mkdir limo_foxy_dev && cd limo_foxy_dev
$ docker run --network=host  --cap-add=SYS_PTRACE --cap-add=SYS_RAWIO --security-opt=seccomp:unconfined --security-opt=apparmor:unconfined --volume=/tmp/.X11-unix:/tmp/.X11-unix --runtime=nvidia --device /dev/ttyTHS1:/dev/ttyTHS1 --device /dev/ttyUSB0:/dev/ydlidar --device /dev/bus/usb/:/dev/bus/usb -v $(pwd)/:workspace --name limo-foxy-dev  -w /workspace -id ros:foxy
$ docker exec -it limo-foxy-dev /bin/bash

这里我们挂载了底盘通信接口、激光雷达、USB 设备到我们的容器之中,以及将本地的 limo_foxy_dev 文件夹挂载到了容器中的 /workspace 之中并开启了一些相应的权限。

之后等待 docker 启动(第一次需要拉取远程镜像,速度稍慢,再次启动无需等待)进入之后可以看到如下界面:

接下来我们换源,提升下载速度:

# 更换系统源
$ sed -i "s/ports.ubuntu.com/mirrors.ustc.edu.cn/g" /etc/apt/sources.list
# 更换 ros2 源
$ sed -i "s/packages.ros.org/repo.huaweicloud.com/g" /etc/apt/sources.list.d/ros2-latest.list
$ apt update

设置一下自动 source

$ echo "source /opt/ros/foxy/setup.bash" >> /etc/bash.bashrc

安装 rosdepc 提升 rosdep 下载速度(注意这俩不是一个东西,多了个 c):

$ apt install -y python3-pip
$ pip install rosdepc
$ rosdepc init && rosdepc update

安装远程开发必备组件:

$ apt install openssh-server systemctl udev swig # 分别为 远程连接组件 服务控制组件 驱动控制组件 雷达驱动组件
$ service  ssh start
$ echo -e "Port 10022\nPermitRootLogin yes\nPermitEmptyPasswords yes" >> /etc/ssh/sshd_config.d/dev.conf
$ service ssh restart

 重要!:容器重启后 ssh 会无法连接,请重新在容器中运行 service ssh start

设定密码:

$ passwd # 之后输入新的密码(在这个过程中不会显示文字,输入完成按回车即可)

之后我们离开镜像,保证我们的小车和电脑在同一个局域网中,在本地电脑中打开 VSCode 使用 Remote ssh 插件连接镜像:

任选一个文件进行编辑:

Host 名称自定义,HostName 是 limo 在局域网中的 ip,Port 是 ssh-server 连接的端口,用户是 root

保存退出。

如果大家不想使用 root 登陆请注意自定义用户组的权限,不然可能无法访问硬件(如雷达等)

重新打开 Connect to Host 选项,选择我们刚刚保存的条目进行连接:

之后会弹出一个新的窗口,在那里输入我们之前设定的密码:

之后打开我们挂载的 workspace 文件夹,这里会再次要求我们输入密码:

选择信任:

这里我在远程安装了如下插件方便我的开发:

之后打开命令行(快捷键 Shift+Ctrl+~)下载 ydlidar 的驱动并编译安装(当前目录 /workspace

$ git clone https://ghproxy.com/https://github.com/YDLIDAR/YDLidar-SDK.git # 使用了ghproxy.com 加速
$ mkdir -p YDLidar-SDK/build
$ cd YDLidar-SDK/build
$ cmake ..
$ make
$ make install # 安装 C/C++ 支持
$ cd ..
$ pip install . # 安装 py 支持
$ cd .. && rm -r YDLidar-SDK # 删除 SDK 源码防止影响之后构建

请注意命令中 . 与 .. 的区别不要敲错了

下载 LIMO 的 ROS2 镜像(当前目录 /workspace):

$ git clone --recursive https://ghproxy.com/https://github.com/agilexrobotics/limo_ros2.git src # 使用了ghproxy.com 加速

修改 /workspace/src/ydlidar_ros2/src/ydlidar_ros2_driver_node.cpp 中源码参数:

# 61 行
int optval = 115200;
# 76 行
optval = 3;
# 108 行
b_optvalue = true;
# 134 行
f_optvalue = 12.f;
# 143 行
f_optvalue = 8.f;

安装必要的支持库并编译(当前目录/workspace):

$ rosdepc install --from-paths src --ignore-src -r -y
$ colcon build --symlink-install # 使用符号链接节省空间,如果要删除源码,则使用 --merge-install

会发现有一些标准错误输出,是正常的,不需要管。

之后 source 安装并启动雷达节点

$ source install/setup.bash
$ ros2 launch limo_bringup limo_start.launch.py

然后在我们本地的电脑上打开我们本地的开发环境(也是在 Docker 中,根据上文所讲,使用的是 https://github.com/athackst/vscode_ros2_workspace 的模板)

在本地开发环境的终端中启动 rviz:

$ rviz2

然后订阅雷达节点,按照图示进行配置

即可看到 LIMO 远程发来的雷达信息:

至此,我们便掌握了机器人远程开发的基础操作!熟悉这种方法可以极大的提升我们工作效率,降低机器人开发复杂度。并且您也可以将刚才的开发环境提交到 Docker 的服务器之上或者输出成压缩包供他人使用,让我们能够快速大批量的部署完全相同的开发环境!

最后,感谢您的阅读!如果您喜欢本文请点赞分享,如有任何疑问请联系松灵机器人。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

松灵学院 | 在松灵 LIMO 上使用 Docker 进行 ROS2 开发 的相关文章

随机推荐

  • linux安装anaconda3

    wget https repo anaconda com archive Anaconda3 2020 11 Linux x86 64 sh sh Anaconda3 2020 11 Linux x86 64 sh xff08 一路回车和y
  • linux安装zookeeper单点

    需要有jdk环境 安装java yum list java 1 8 yum install java 1 8 0 openjdk y 下载地址 http zookeeper apache org wget tar zvxf zookeepe
  • CAN总线网络的传输模式

    CAN总线网络的传输模式根据触发条件的不同 xff0c 在车身CAN网络中可分为事件型 周期性及混合型三种传输模式 xff1b 1 事件型传输模式 xff1a 随着类型或数据的转变及时发送的消息 此类型消息的好处是极少占用总线资源 xff0
  • matlab中m文件的命名规则

    matlab的m文件的命名规则 xff1a 1 文件名命名要用英文字符 xff0c 首字符不能是数字或下划线 xff1b 2 文件名不能与matlab的内部函数名相同 m文件名的命名尽量不要是简单的英文单词 xff0c 最好是由大小写英文
  • 2014去哪儿校招笔试

    共 3 43 2 43 2 个题 开发 前3 个必做 xff0c 其他选做 测试或web 开发 前 2 个必做 43 另外 2 个必做 1 字符串split 43 翻转 2 实现 访问历史记录 xff0c insert next pre 3
  • MicroStrategy笔试

    1 coding判定二叉树是否是有序二叉树 2 一个有序数组A xff08 buffer 足够大 xff09 xff0c 和一个有序数组 B xff0c 设计算法 xff0c merge 两个数组后有序 xff0c 不使用任何额外的内存空间
  • 欢迎使用CSDN-markdown编辑器

    能力培养 与team leader讨论 xff0c 大抵将能力培养分成三类 业务能力 解决具体反馈的问题 xff1b 总结通用的解决方案 xff1b 从根本上改善根本问题技术能力 设计架构的能力 xff0c 注重性能的改善泛化能力 明确问题
  • 一些5G整理

    鲁棒性 设计 相对于终端成本 xff0c 网络掉线的损失是行业客户是不可接受的 xff0c 所以行业终端鲁棒性设计很重要 这里的鲁棒性是指排除了前述的散热 环境可靠性等自身设计后面对其他突发未知情况的还能可靠应用的能力 业内对于鲁棒性的设计
  • ES设置多个自定义分词器,每个分词器使用不同的词库

    ES中如何设置自定义分词器并且每个分词器使用自己定义的词库 xff1f 1 首先在ansj cfg yml中配置 然后在ansj library properties文件中添加词典放置路径 ansj library properties和l
  • 开发原则

    1 提供完整的数据 xff0c 不需要调用者进行额外的处理 2 测试 xff0c 保证比较对象要都是真实正确的 3 以业务需求为驱动 xff0c 兼顾系统架构升级
  • Windows下多台电脑共享剪切板的方法

    转自于 http www microsoft com china MSDN library WebServices WebServices WebServices mspx mfr 61 true
  • Cisco Packet Tracer模拟器使用

    第一篇 熟悉界面 一 设备的选择与连接 在界面的左下角一块区域 xff0c 这里有许多种类的硬件设备 xff0c 从左至右 xff0c 从上到下依次为路由器 交换机 集线器 无线设备 设备之间的连线 xff08 Connections xf
  • 各种路由器接口与连接方法

    转自于 http bbs pcsoft com cn thread 138952 1 4 html 路由器所在的网络位置比较复杂 xff0c 既可是内部子网边缘 xff0c 也可位于内 外部网络边缘 同时为了实现强大的适用性 xff0c 它
  • line vty 0 4 什么意思

    转自于 http hi baidu com rxlly blog item 9072bc397ae18bde7c1e71f6 html line vty 0 4是不是指启用5个telnet会话的意思 xff1f 那line vty 0 0是
  • matlab实现牛顿迭代法求解非线性方程组

    http hi baidu com aillieo blog item 0800e2a10ac9a59647106493 html 已知非线性方程组如下 3 x1 cos x2 x3 1 2 61 0 x1 2 81 x2 43 0 1 2
  • 区别 chown和chmod的用法

    本人总是习惯使用chmod xff0c 而把chown混淆 chown就是修改 第一列内容的 xff0c chmod是修改 第3 4列内容的 chown用法 用来更改某个目录或文件的用户名和用户组的 chown 用户名 组名 文件路径 xf
  • Linux中安装新的包时错误提示

    错误1 E Could not open lock file var lib dpkg lock open 13 Permission denied E Unable to lock the administration directory
  • django框架简介

    主要内容 1 Django框架发展 2 Django架构 MTV模式 3 开发流程 4 开发实例 Poll python下各种框架 一个完整的Web应用框架包括下面功能的支持 服务发布 URL分发 模板支持 数据库处理 Python框架一般
  • 用VirtualBox打开VMware创建的虚拟机的方法

    方法一 xff1a 用VMware7 0以上版本 xff0c 自带的 ovftool exe 工具将 vmx 文件转化成 ovf 文件 命令格式 xff1a ovftool vmx文件完整路径 要存放ovf 文件的路径 注意 xff1a 源
  • 松灵学院 | 在松灵 LIMO 上使用 Docker 进行 ROS2 开发

    截至目前 xff0c Jetson Nano 平台官方仍不提供 Ubuntu 20 04 固件 xff0c 所以使用 Jetson Nano 平台开发 ROS2 存在巨大的困难 xff0c 但是好在 Docker 提供的容器技术 xff0c