我的ROS2开发环境

2022-06-05 21:11:58 浏览数 (1)

不知道阅读本篇文章的你有没有被环境配置搞的焦头烂额过?

想要验证一个功能包,但却需要安装各种依赖。装就装吧!但是安装的依赖可能更新本机中的一些配置或软件版本,导致过去可以运行的软件这么折腾一下后就不能再运行了。

这时可能又后悔又懊恼。严重的可能要重新安装电脑系统。

本文描述了一种在Docker环境中开发和调试ROS程序的方法。旨在解决环境配置和软件依赖给我们带来的困扰。

我们使用Docker Vscode来构建开发环境。下面的操作在Ubuntu 20.04 LTS上验证过。对于其他操作系统,操作步骤应该也是一致的。

安装Docker

按照下面的命令安装Docker

代码语言:shell复制
# step 1: 安装必要的一些系统工具
sudo apt-get update
sudo apt-get -y install apt-transport-https ca-certificates curl software-properties-common

# step 2: 安装GPG证书
curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -

# Step 3: 写入软件源信息
sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"

# Step 4: 更新并安装 Docker-CE
sudo apt-get -y update
sudo apt-get -y install docker-ce

# Step 5: 查看docker是否安装成功
docker version

# Step 6: 安装x11
sudo apt-get install x11-xserver-utils 

安装Vscode和插件

vscode的安装就不多说了。

需要安装的插件是Remote Containers。可按下图操作。

在插件市场中搜索Remote Containers并安装就可以看到左侧的Docker标志和左下角的图标。

开发环境示例

  • 下载开发环境示例
代码语言:shell复制
git clone https://github.com/shoufei403/ros2_galactic_ws.git
  • 在本机打开开发环境
代码语言:shell复制
cd ros2_galactic_ws
code .
  • 导入工程代码

在文件夹中的demos.repos中维护了需要导入的工程代码。可根据需求自行修改。目前里面是放的自己收集整理的ROS2示例代码。

导入工程代码是通过运行vscodetask来进行的。task的内容维护在.vscode/tasks.json文件中。

按照上图所示,按快捷键Ctrl Shift P打开命令面板。选中Run Task将可以看到.vscode/tasks.json文件中维护的各项task

如上图,选中import from workspace file任务即可导入demos.repos文件中维护的工程代码。如果后面需要更新工程代码则可再次运行import from workspace file任务。

  • docker中重新打开环境

第一次打开时会下载docker镜像需要一段时间。后来再打开开发环境就是秒开了。

  • 安装依赖

运行install dependencies任务可以根据工程代码安装相应的依赖。但有些依赖可能还是要手动安装。如果install dependencies任务运行报错,则可以根据报错信息手动安装依赖。

  • 编译工程代码

运行build任务即可编译。你也可以设置快捷键来对应build任务。

另外,全局搜索时需要注意一下设置。如果files to exclude为空,并且后面的图标按钮被选中,则只会在打开的文件中搜索。

另外,.gitignore文件中默认是加入了src文件夹的。所以在vscode中的文件浏览器中src目录的文件是灰色显示的。并且vscode中的git工具也会忽略src目录的git信息。

src_uncommentsrc_uncomment

所以平时编辑代码的时候可以注释一下.gitignore文件中的src。然后推这个工作空间的修改时再把.gitignore文件中的src加上。

在Docker中运行GUI应用

devcontainer.json 中的 runArgs 字段中添加 --volume=/tmp/.X11-unix:/tmp/.X11-unix 表示挂载 x11 相关目录到容器中。

containerEnv 字段中添加"DISPLAY": "${localEnv:DISPLAY}"表示设定容器中的DISPLAY环境变量与本地DISPLAY为一样的值,例如:

代码语言:yaml复制
{
	"dockerFile": "Dockerfile",
	"build": {
		"args": {
			"WORKSPACE": "${containerWorkspaceFolder}"
		}
	},
	"remoteUser": "ros",
	"runArgs": [
		"--network=host",
		"--cap-add=SYS_PTRACE",
		"--security-opt=seccomp:unconfined",
		"--security-opt=apparmor:unconfined",
		"--volume=/tmp/.X11-unix:/tmp/.X11-unix",
		"--volume=/etc/localtime:/etc/localtime:ro", 
		"-e GDK_SCALE",
		"-e GCK_DPI_SCALE",
		"--privileged"
		// "--gpus" "all", // 取消注释使用 GPU 功能
	],
	"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"
	}

在主机电脑的命令行窗口中运行

代码语言:shell复制
xhost  

然后就可以在Docker中运行GUI应用了(如:Rviz2和Gazebo)。

devcontainer.json 解析

详细文档例子请见 https://aka.ms/vscode-remote/devcontainer.json ,这里我们主要来看一下常用的一些配置信息:

  • name

当前工作空间名称,会显示在左下角

  • build
  • dockerfile: 用于指定 dockerfile 文件的路径,这里是相对于 devcontainer.json 文件而言
  • context:用于指定 docker build 时的上下文路径,这里是相对于 devcontainer.json 文件而言
  • args:用于在 docker build 时传递参数
  • settings

用于设定容器中 settings.json 的默认值,比如这里设定了使用的 shell

代码语言:json复制
  	"settings": {

  		"terminal.integrated.profiles.linux": {

  			"bash": {

  				"path": "bash"

  			},

  		},

  		"terminal.integrated.defaultProfile.linux": "bash"

  	},
  • extensions

用于指定在容器中安装的插件,比如这里会自动帮我们安装 一系列插件

代码语言:json复制
  	"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"

  	]
  • portsAttributes

用于设定端口属性,比如名称,映射时的行为,也可以用 forwardPorts 简单代替

  • postCreateCommand

在容器第一次启动时执行的指令,只会执行这一次

  • remoteUser

登录到容器的用户名,默认情况下是 root 用户登录,但是有时我们不想这样,可以利用这个指定远程用户名(这个用户必须存在才行)

代码语言:json复制
  "remoteUser": "ubuntu",

此外,还有一些字段也很有用:

  • runArgs

docker run 时传递的参数,用于类似设定 –network=host` 等操作

代码语言:json复制
  	"runArgs": [

  		"--network=host",

  		"--cap-add=SYS_PTRACE",

  		"--security-opt=seccomp:unconfined",

  		"--security-opt=apparmor:unconfined",

  		"--volume=/tmp/.X11-unix:/tmp/.X11-unix"

  		// "--gpus" "all", // 取消该注释使用 GPU 功能

  	],
  • containerEnv / remoteEnv

用于设定容器中的环境变量,比如设定 http_proxy 等环境变量的值

代码语言:json复制
  	"containerEnv": { "DISPLAY": "${localEnv:DISPLAY}" },

参考:

https://www.allisonthackston.com/articles/vscode-docker-ros2.html

0 人点赞