WSL+Docker创建ros2容器的过程,参考ROS2(1)安装(WSL+Docker)

1. 工作目录映射到Docker容器

在前面的文章中,我们通过一个自定义的Dockerfile文件创建了1-dockerfile-img镜像,可以通过下面步骤,映射主机的工作目录到该容器中。
首先在主机中创建ros2_ws目录:

mkdir ~/ros2_ws

然后拉取代码,这里参考《ROS2(3)入门篇 - 使用客户端库》

cd ~/ros2_ws
git clone https://github.com/ros2/examples src/examples -b humble

然后创建容器:

docker run   -e DISPLAY=$DISPLAY \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-v ~/ros2_ws:/home/自己用户名/ros2_ws \
--name my_humble \
--net=host \
-it 1-dockerfile-img

具体参数解释:

-e DISPLAY=$DISPLAY 和 -v /tmp/.X11-unix:/tmp/.X11-unix: 为了容器中显示使用
-v ~/ros2_ws:/home/自己用户名/ros2_ws : 这就是要映射的工作目录,会把整个ros2_ws目录及子目录映射到容器中,注意需要使用自己的用户名,前面文章的dockerfile中已经修改默认的容器用户了
--name my_humble : 容器名称
--net=host : ROS2依赖DDS通信,共享网络可简化节点发现(避免手动配置网络)。
-it 1-dockerfile-img : 镜像

进入容器后,ls一下看看是否有ros2_ws目录了。

2. vscode配置

win端的vscode安装如下插件:

C/C++
Wsl
Dev Containers
ROS # 提供 ROS 特定语法支持,如.msg/.srv文件解析

2.1 连接WSL

ctrl+shift+p,输入WSL: Connect to WSL,连接成功后左下角会显示连接的WSL:
在这里插入图片描述

2.2 连接容器

确保容器Status为Up状态。
连接WSL成功后,Ctrl+Shift+P 打开命令面板,输入并选择 Dev Containers: Attach to Running Container…,连接指定的容器。此时连接容器成功,vscode上下文切换到容器中了。

2.3 打开容器中挂载的目录

直接打开文件夹选择ros工作目录打开,我的是ros2_ws,vscode文件浏览器显示:
在这里插入图片描述
此时可以修改代码了。

2.4 编译与调试的配置

主要是配置tasks.json和launch.json文件,前者负责编译,后者负责执行调试。

注意,我遇到了vscode中编辑容器文件无权限的问题,主要是dockerfile中编写的UID和GID和自己用户名对应的不一致导致的。通过id 用户名可以查看自己的ID

首先在ros2_ws创建.vscode目录,并添加两个文件:

mkdir .vscode 
cd .vscode 
touch tasks.json
touch launch.json

tasks.json:

{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "colcon build",
      "type": "shell",
      "command": "bash",  // 核心命令:使用bash执行
      "args": [
        "-c",  // 表示后续字符串为要执行的命令
        // 拼接完整命令:加载环境 + 编译 + 参数
        "source /opt/ros/humble/setup.bash && colcon build --symlink-install --event-handlers console_cohesion+ --cmake-args -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_EXPORT_COMPILE_COMMANDS=ON"
      ],
      "options": {
        "cwd": "${workspaceFolder}"  // 容器内的工作空间路径
      },
      "group": {
        "kind": "build",
        "isDefault": true
      },
      "problemMatcher": [],
      "detail": "ROS 2 colcon build in container"
    }
  ]
}

注意这里command字段用的是bash,因为要执行source /opt/ros/humble/setup.bash,否则找不到colcon指令。

colcon build 
--symlink-install 
--event-handlers console_cohesion+  //console_cohesion+ 是一个增强的控制台输出处理器,将同一包的日志合并,避免不同包日志交叉混乱。
--cmake-args -DCMAKE_BUILD_TYPE=RelWithDebInfo //编译时启用优化(类似 Release 模式)。同时保留调试符号(debug info),方便调试。
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON 生成compile_commands.json是 C++ 语言服务器用于解析代码依赖的关键文件,由 CMake 生成,方便代码提示使用。

编写完后,Ctrl+Shift+P,输入Tasks:Run task,选择colcon build,即可进行单独的编译操作了。
因为我不需要编译所有ros2的例程,所以我在不想管的目录下新建了COLCON_IGNORE文件夹。但是编译还是很慢。

launch.json

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "ROS2 C++ Debug (Container)",
      "type": "cppdbg",
      "request": "launch",
      // 容器内可执行文件路径(注意:install目录在容器内的工作空间下)
      "program": "${workspaceFolder}/install/${input:packageName}/lib/${input:packageName}/${input:executableName}",
      "args": [],  // 节点运行参数(如需要)
      "stopAtEntry": true,
      "cwd": "${workspaceFolder}",
      "environment": [
        // 加载ROS 2和工作空间的库路径
        {
          "name": "LD_LIBRARY_PATH",
          "value": "/opt/ros/humble/lib:${workspaceFolder}/install/lib:${LD_LIBRARY_PATH}"
        }
      ],
      "externalConsole": false,
      "MIMode": "gdb",
      "setupCommands": [
        {
          "description": "Enable pretty-printing for gdb",
          "text": "-enable-pretty-printing",
          "ignoreFailures": true
        }
      ],
      "preLaunchTask": "colcon build",  // 调试前自动编译
      "miDebuggerPath": "/usr/bin/gdb",  // 容器内gdb路径
      "logging": {
        "moduleLoad": false,
        "trace": true
      }
    }
  ],
  "inputs": [
    {
      "id": "packageName",
      "type": "pickString",
      "description": "请选择ROS2包名",
      "options": [  // 可选的包名列表(根据你的实际包名修改)
        "examples_rclcpp_minimal_publisher"
      ],
      "default": "examples_rclcpp_minimal_publisher"
    },
    {
      "id": "executableName",
      "type": "pickString",
      "description": "请选择ROS2节点",
      "options": [  // 可选的包名列表(根据你的实际包名修改)
        "publisher_member_function",
        "publisher_lambda"
      ],
      "default": "publisher_member_function"
    }
  ]
}

当你想改想要调试的包时,只需要改inputs标签的options就可以了,调试的时候让你选。
在这里插入图片描述

2.5 代码提示

在 VS Code 中,按 Ctrl+Shift+P 执行 C/C++: Edit Configurations (JSON),生成 .vscode/c_cpp_properties.json

{
  "configurations": [
    {
      "name": "ROS2 Container",
      "includePath": [
        "${workspaceFolder}/**",
        "/opt/ros/humble/include/**",  // ROS 2系统头文件路径
        "${workspaceFolder}/install/**/include/**"  // 工作空间内包的头文件
      ],
      "defines": [],
      "compilerPath": "/usr/bin/g++",  // 容器内的g++路径
      "cStandard": "c17",
      "cppStandard": "c++17",  // ROS 2默认C++标准
      "intelliSenseMode": "linux-gcc-x64",
      // 关联compile_commands.json(自动解析依赖)
      "compileCommands": "${workspaceFolder}/build/compile_commands.json"
    }
  ],
  "version": 4
}
Logo

「智能机器人开发者大赛」官方平台,致力于为开发者和参赛选手提供赛事技术指导、行业标准解读及团队实战案例解析;聚焦智能机器人开发全栈技术闭环,助力开发者攻克技术瓶颈,促进软硬件集成、场景应用及商业化落地的深度研讨。 加入智能机器人开发者社区iRobot Developer,与全球极客并肩突破技术边界,定义机器人开发的未来范式!

更多推荐