介绍 在 Windows 系统上使用 WSL2 + VS Code + ROS + Docker 进行项目开发。
WSL2 + VS Code是此前一直使用的开发方式,只要使用VS Code的WSL插件,就可以在WSL2中进行开发,而不用在Windows系统中安装编译器和调试器。在一般的C++项目开发中,运行调试项目可以通过设置.vscode/launch.jso
n,.vscode/tasks.json
,.vscode/c_cpp_properties.json
等文件来实现。但是在开发ROS项目时,需要在VSC中安装ROS插件,这样才能在VSC中运行ROS项目。并且使用ROS插件提供的设置来运行ROS项目。这个插件有一些bug,有时会出现一些奇怪的问题。另外,在运行ros_motion_planning
项目时,在ubuntu-18.04
下始终无法编译通过,而在ubuntu-20.04
下运行还需要设置很多东西,恰巧该项目提供了dockerfile
,因此使用 WSL2 + VS Code + ROS + Docker 进行项目开发。这里对于遇到的问题及解决方案进行记录。有一些具有很多教程的步骤,在这里不再赘述。比如安装WSL2,安装VS Code,安装ROS,Windows下安装docker并使用WSL2作为后端引擎等。
docker的基本命令 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 docker ps -a docker images docker rm -f <container_id> docker rmi <image_id> docker exec -it <container_id> /bin/bash exit docker build -t <image_name> . docker run -it --name <container_name> <image_name> /bin/bash docker image prune docker volume prune docker builder prune docker system prune docker system df
项目docker镜像构建 ros_motion_planning的项目结构如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 $ cd ros_motion_planning $ tree -d -L 3 . ├── assets ├── data ├── docker │ └── noetic ├── docs ├── package │ ├── osqp │ │ ├── configure │ │ ├── docs │ │ ├── examples │ │ ├── include │ │ ├── lin_sys │ │ ├── site │ │ ├── src │ │ └── tests │ └── osqp-eigen │ ├── cmake │ ├── docs │ ├── example │ ├── include │ ├── src │ └── tests ├── scripts └── src ├── core │ ├── curve_generation │ ├── global_planner │ ├── local_planner │ ├── trajectory_optimization │ └── utils ├── sim_env │ ├── config │ ├── launch │ ├── maps │ ├── meshes │ ├── models │ ├── rviz │ ├── scripts │ ├── urdf │ └── worlds ├── third_party │ ├── dynamic_rviz_config │ ├── dynamic_xml_config │ ├── gazebo_plugins │ ├── map_plugins │ └── rviz_plugins └── user_config
项目提供的dockerfile如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 FROM osrf/ros:noetic-desktop-fullWORKDIR /project RUN apt-get update \ && apt-get -y --no-install-recommends install \ git \ gcc \ vim \ psmisc \ libxml2-dev \ libxslt-dev \ python3 \ python3-pip \ python-is-python3\ ros-noetic-amcl \ ros-noetic-base-local-planner \ ros-noetic-map-server \ ros-noetic-move-base \ ros-noetic-navfn RUN pip3 install setuptools && pip3 install catkin-tools RUN echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc COPY . /project RUN /bin/bash -c '. /opt/ros/noetic/setup.bash; catkin_make'
在执行软件更新及安装时,由于网络问题,可能会更新较慢或者失败,可以在dockerfile中添加中科大的源,如下:
1 RUN sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
具体来说:
sed
是一个流编辑器,常用于文本替换操作。
-i
选项指示 sed
直接修改文件内容,而不是输出到标准输出。
‘s/archive.ubuntu.com/mirrors.ustc.edu.cn/g’ 是一个替换命令,其中: s
是替换命令。archive.ubuntu.com
是要被替换的原始字符串。mirrors.ustc.edu.cn
是要替换成的新字符串。g
表示在整个文件中进行全局替换,而不仅仅是替换第一次出现的地方。
总结来说,以上命令可将 /etc/apt/sources.list
文件中所有出现的 archive.ubuntu.com
都替换为 mirrors.ustc.edu.cn
。
增加了中科大源后,构建镜像时,速度会快很多,镜像构建的命令如下:
1 2 cd docker/noeticdocker build -t ros-motion-planning:noetic --no-cache -f ./Dockerfile ../../
构建在进行到最后一步的catkin_make
时,出现以下错误:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 9.440 CMake Error at core/local_planner/mpc_planner/CMakeLists.txt:19 (find_package): 9.440 By not providing "FindOsqpEigen.cmake" in CMAKE_MODULE_PATH this project 9.440 has asked CMake to find a package configuration file provided by 9.440 "OsqpEigen" , but CMake did not find one. 9.440 9.440 Could not find a package configuration file provided by "OsqpEigen" with 9.440 any of the following names: 9.440 9.440 OsqpEigenConfig.cmake 9.440 osqpeigen-config.cmake 9.440 9.440 Add the installation prefix of "OsqpEigen" to CMAKE_PREFIX_PATH or set 9.440 "OsqpEigen_DIR" to a directory containing one of the above files. If 9.440 "OsqpEigen" provides a separate development package or SDK, be sure it has 9.440 been installed. 9.440 9.440 9.448 -- Configuring incomplete, errors occurred!
显然是由于缺少OsqpEigen
库导致的错误,查看项目的README.md
文件,可看到以下关于OSQP
和OsqpEigen
安装的部分:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 git clone -b release-0.6.3 --recursive https://github.com/oxfordcontrol/osqp cd osqp && mkdir build && cd buildcmake .. -DBUILD_SHARED_LIBS=ON make -j6 sudo make install sudo cp /usr/local/include/osqp/* /usr/local/include git clone https://github.com/robotology/osqp-eigen.git cd osqp-eigen && mkdir build && cd buildcmake .. make sudo make install
所以可以参考以上内容,在构建时增加OSQP
和OsqpEigen
的安装,首先新建一个package
目录用于存放OSQP
和OsqpEigen
的源文件,然后在scripts
目录下新建一个install_osqp.sh
文件,内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #!/bin/bash set -ecd /project/package/osqpmkdir build && cd buildcmake .. -DBUILD_SHARED_LIBS=ON make -j$(nproc ) make install cd /project/package/osqprm -rf buildcd /project/package/osqp-eigenmkdir build && cd buildcmake .. make -j$(nproc ) make install cd /project/package/osqp-eigenrm -rf build
在dockerfile
中增加以下内容:
1 2 RUN /project/scripts/install_osqp.sh
出现以下错误:
1 2 3 4 5 => ERROR [ 9/10] RUN /project/scripts/install_osqp.sh 0.5s ------ > [ 9/10] RUN /project/scripts/install_osqp.sh: 0.471 /project/scripts/install_osqp.sh: line 5: cd : /project/package/osqp: No such file or directory ------
仔细排查后,发现这是由于项目的.dockerignore
文件导致的,.dockerignore 文件用于排除不需要复制到 Docker 镜像中的文件和目录, 该项目的.dockerignore
文件如下:
1 2 3 4 5 6 7 8 9 10 11 12 * !assets !docker !docs !package !scripts !src !Doxyfile !LICENSE !README.md !.clang-format
其中*
表示排除所有文件和目录,!
表示不排除,所以需要在.dockerignore
文件中添加!package
,然后重新构建镜像,此时出现以下错误:
1 2 3 4 5 6 7 8 9 10 11 12 13 27.27 Scanning dependencies of target mpc_planner 27.30 [89%] Building CXX object core/local_planner/mpc_planner/CMakeFiles/mpc_planner.dir/src/mpc_planner.cpp.o 27.52 In file included from /usr/local/include/OsqpEigen/Compat.hpp:12, 27.52 from /usr/local/include/OsqpEigen/Constants.hpp:11, 27.52 from /usr/local/include/OsqpEigen/OsqpEigen.h:10, 27.52 from /project/src/core/local_planner/mpc_planner/src/mpc_planner.cpp:19: 27.52 /usr/local/include/osqp.h:9:11: fatal error: types.h: No such file or directory 27.52 9 | 27.52 | ^~~~~~~~~ 27.52 compilation terminated. 27.52 make[2]: *** [core/local_planner/mpc_planner/CMakeFiles/mpc_planner.dir/build.make:63: core/local_planner/mpc_planner/CMakeFiles/mpc_planner.dir/src/mpc_planner.cpp.o] Error 1 27.52 make[1]: *** [CMakeFiles/Makefile2:8368: core/local_planner/mpc_planner/CMakeFiles/mpc_planner.dir/all] Error 2 27.52 make[1]: *** Waiting for unfinished jobs ....
尝试将OSQP
和OsqpEigen
的源文件复制到/usr/local/include
目录下,但是似乎没有作用,因此放弃了这种方式,而是直接在dockerfile
中将OSQP
的include路径添加到了环境变量中,此后构建成功,完整的修改后的dockerfile
如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 FROM osrf/ros:noetic-desktop-fullWORKDIR /project RUN sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list RUN apt-get update \ && apt-get -y --no-install-recommends install \ git \ gcc \ vim \ psmisc \ libxml2-dev \ libxslt-dev \ python3 \ python3-pip \ python-is-python3\ ros-noetic-amcl \ ros-noetic-base-local-planner \ ros-noetic-map-server \ ros-noetic-move-base \ ros-noetic-navfn RUN pip3 install setuptools && pip3 install catkin-tools RUN echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc COPY . /project RUN /project/scripts/install_osqp.sh ENV CPLUS_INCLUDE_PATH="${CPLUS_INCLUDE_PATH}:/project/package/osqp/include" RUN /bin/bash -c '. /opt/ros/noetic/setup.bash; catkin_make;'
ROS 项目调试 项目构建成功后,可使用以下命令运行容器:
1 docker run -it --env ="DISPLAY" --env ="QT_X11_NO_MITSHM=1" --volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" --name=ros-motion-planning-noetic ros-motion-planning:noetic /bin/bash
利用vscode的插件Remote Development
、Docker
、ROS
、Remote Explorer
等插件,可以在vscode中直接连接到docker容器中,然后在vscode中打开项目文件夹,即可在vscode中进行ros项目开发调试。出于个人习惯,使用clang提供代码补全,可参见这个博客 进行设置。
创建.vscode
文件夹,然后在其中创建launch.json
、tasks.json
、c_cpp_properties.json
等文件。
c_cpp_properties.json
文件如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 { "configurations" : [ { "name" : "Linux" , "includePath" : [ "${workspaceFolder}/**" , "/usr/include/**" , "/usr/local/include/**" ] , "defines" : [ ] , "compilerPath" : "/usr/bin/clang" , "cStandard" : "c11" , "cppStandard" : "c++17" , "intelliSenseMode" : "clang-x64" , "compileCommands" : "${workspaceFolder}/build/compile_commands.json" , "configurationProvider" : "ms-vscode.cmake-tools" } ] , "version" : 4 }
tasks.json
文件如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 { "version" : "2.0.0" , "tasks" : [ { "label" : "build_debug" , "type" : "shell" , "command" : "bash" , "args" : [ "-c" , "cd build_debug && cmake -DCMAKE_BUILD_TYPE=DEBUG .. && make -j4" ] , "group" : "build" , "presentation" : { "echo" : true , "reveal" : "always" , "focus" : false , "panel" : "shared" } } ] }
launch.json
文件内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 { "version" : "0.2.0" , "configurations" : [ { "name" : "ROS: launch" , "type" : "ros" , "request" : "launch" , "target" : "/project/src/sim_env/launch/main.launch" , "preLaunchTask" : "make_debug" , } ] }
点击运行,出现以下错误:
1 2 Error from roslaunch: xacro: in-order processing became default in ROs Melodic. You can drop the option.
按下ctrl+shift+f
搜索--inorder
,将其删除,再次运行,可以解决此问题,但是又出现了以下错误:
1 2 3 Unable to start debugging.Launch options string provided by the project system is invalid.Unable to determine path to debugger.Please specify the "MIDebuggerPath" option.
根据ROS插件的一个GitHub Issue ,这是由于ROS插件基于gdb
进行调试,而此镜像没有安装gdb
,使用apt-get install gdb
安装gdb
,再次运行,可以解决此问题,此时出现以下错误提示:
1 ROS launch can not load launch file that includes gazebo (program path 'PATH' is missing or invalid
根据issue-474 以及插件的官方说明,插件无法调试gazebo
,因此需要在launch.json
文件中将gazebo
相关的launch
文件注释掉,再次运行,可以正常启动ros
项目。 根据插件中的说明,修改launch.json
屏蔽gazebo
等插件,内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 { "version" : "0.2.0" , "configurations" : [ { "name" : "ROS: launch" , "type" : "ros" , "request" : "launch" , "target" : "/project/src/sim_env/launch/main.launch" , "launch" : [ "rviz" , "gz" , "gzserver" , "gzclient" ] , "preLaunchTask" : "make_debug" , } ] }
在配置完全部环境之后,可以将配置好的环境重新打包成镜像,以便下次使用,具体的步骤如下:
1 2 3 4 5 6 docker ps -a docker commit <container_id> ros-motion-planning:vscode-ros-dev docker save -o ros-motion-planning-vscode-ros-dev.tar ros-motion-planning:vscode-ros-dev