文章目录
前言一、创建 riscv_ubuntu 镜像下载ros2官方提供的 dockerfiles 和 示例examples创建docker镜像
二、源码编译ros2拉取ros2源码将ros2源码目录挂载到docker对ros2源码进行编译完成编译测试ros2 demo
三、交叉编译将官方示例examples放到挂载目录下安装所需包和依赖修改交叉编译工具链generic_linux.cmake交叉编译完成交叉编译测试交叉编译ros2 demo
总结
前言
内容概括: 本篇文章记录了ros2 交叉编译(从x86_ubuntu到 riscv_ubuntu)过程,以及问题解决。 整体思路:创建riscv_ubuntu docker镜像——源码编译ros2——交叉编译 因为ros2没有提供riscv预编译版本,所以不能像arm架构那样在创建docker就直接安装好ros2,需要先创建docker再用源码编译,相对来说实现过程复杂一些。
一、创建 riscv_ubuntu 镜像
下载ros2官方提供的 dockerfiles 和 示例examples
mkdir -p ~/cc_ws/ros2_ws/src
cd ~/cc_ws/
git clone https://github.com/ros-tooling/cross_compile.git -b 0.0.1 .
创建docker镜像
在执行创建docker镜像命令前需要先对Dockerfile_ubuntu_arm进行修改(在cross_compile/sysroot下),避免混淆可以先把文件名改为Dockerfile_ubuntu_riscv 拉取的docker 镜像是riscv64/ubuntu:jammy,docker hub镜像地址:riscv64/ubuntu
ARG ARM_ARCH=arm64v8
FROM ${ARM_ARCH}/ubuntu:bionic
修改为:
ARG ARM_ARCH=riscv64
FROM ${ARM_ARCH}/ubuntu:jammy
rosdep改为rosdepc:
--------------------------
RUN apt install -y \
python3-colcon-common-extensions \
python3-pip \
python3-rosdep
修改为:
RUN apt install -y \
python3-colcon-common-extensions \
python3-pip
--------------------------
RUN python3 -m pip install -U \
argcomplete \
flake8 \
flake8-blind-except \
flake8-builtins \
flake8-class-newline \
flake8-comprehensions \
flake8-deprecated \
flake8-docstrings \
flake8-import-order \
flake8-quotes \
pytest-repeat \
pytest-rerunfailures
修改为:
RUN python3 -m pip install -U \
rosdepc \
argcomplete \
flake8 \
flake8-blind-except \
flake8-builtins \
flake8-class-newline \
flake8-comprehensions \
flake8-deprecated \
flake8-docstrings \
flake8-import-order \
flake8-quotes \
pytest-repeat \
pytest-rerunfailures
--------------------------
RUN rosdep init
RUN rosdep update
RUN rosdep install --from-paths src \
--ignore-src \
--rosdistro crystal -y \
--skip-keys "console_bridge \
fastcdr \
fastrtps \
libopensplice67 \
libopensplice69 \
rti-connext-dds-5.3.1 \
urdfdom_headers"
修改为:
RUN rosdepc init
RUN rosdepc update
RUN rosdepc install --from-paths src \
--ignore-src \
--rosdistro crystal -y \
--skip-keys "console_bridge \
fastcdr \
fastrtps \
libopensplice67 \
libopensplice69 \
rti-connext-dds-5.3.1 \
urdfdom_headers"
执行创建docker命令:
cd ~/cc_ws/
# qemu 用于使用docker在目标文件系统上安装ROS 2依赖项
mkdir qemu-user-static
cp /usr/bin/qemu-*-static qemu-user-static
docker build -t riscv_ros2:latest -f cross_compile/sysroot/Dockerfile_ubuntu_arm .
docker run --name riscv_sysroot riscv_ros2:latest
执行docker run时会提示因为架构不同所以无法直接进入docker,没有影响,docker镜像能正常挂载使用。
二、源码编译ros2
拉取ros2源码
cd ~/cc_ws/ros2_ws
wget https://raw.githubusercontent.com/ros2/ros2/humble/ros2.repos
vcs-import src < ros2.repos
如果终端提示无法连接网址,则可以在浏览器打开手动保存网页到本地
将ros2源码目录挂载到docker
docker run -it --rm -v /home/sun/cc_ws/ros2_ws:/data --name riscv_sys e5279bcbe77
成功执行后就相当于进入docker镜像中执行后续操作,其中 /home/sun/cc_ws/ros2_ws 是本地包含src的目录, /data是docker镜像中挂载目录,riscv_sys是docker容器名称(sudo docker container查看),e5279bcbe77是docker镜像id(sudo docker images查看)
对ros2源码进行编译
# 挂载后在docker中进行操作
cd /data
ls # 查看是否有src文件夹
colcon build --symlink-install # 源码编译
在riscv64架构上通过源码编译ros2时会遇到一些问题:
问题一:mimick_vendor功能包不支持riscv64架构
解决方法:在src中通过查找方法找到mimick_vendor功能包(一定要查找,因为直接进文件夹没有显示),对CMakelists进行修改,将对应两行内容修改为如下
set(mimick_version "90d02296025f38da2e33c67b02b7fa0c7c7d460c")
GIT_REPOSITORY https://github.com/ziyao233/Mimick.git
问题二:部分功能包编译时需要在网址下载但报错无法连接
解决方法:手动打开连接并下载,放到挂载的目录下,修改对应功能包的cmakelists 中的 URL 将网络地址修改该为本地文件 绝对路径(注意一定是 docker 镜像中的绝对路径,而不是本地绝对路径)
问题三:riscv64_ubuntu缺少很多需要的依赖,需要一边编译一边报错再安装,ros2还有一些包比如rviz(ros 可视化)需要python绑定器等问题,若无法解决且不需要相关功能,则可以根据情况删除对应功能包
apt install libeigen3-dev
apt-get install libacl1-dev
apt-get install libx11-dev libxaw7-dev
apt-get install libldap2-dev
apt-get install libssl-dev
apt-get install libeigen3-dev
pip install lark-parser
apt-get install qtbase5-dev
apt-get install libfreetype-dev
apt install -y ninja-build
apt install python3-numpy
apt install libopencv-dev
apt install libbullet-dev
apt-get install libfreetype-dev
完成编译
ros2 完成源码有三百多个功能包,完整编译需要足够的磁盘空间,源码编译完成后就可以在对应目录下source 测试ros2 demo
测试ros2 demo
# 挂载后在docker中进行操作
cd /data
source install/local_setup.bash
ros2 run demo_nodes_cpp talker
ros2 run demo_nodes_py listener
注意:以挂载的方式使用docker,编译生成的文件内容是在本地,但是如果源码编译ros2则编译产生的build/install中的文件链接/索引路径都是相对于docker系统的绝对路径,所以想要使用riscv_ubuntu架构ros2只能每次都把cc_ws/ros2_ws挂载到/data下
三、交叉编译
前提:已将/cc_ws/ros2_ws挂载到docker /data下
将官方示例examples放到挂载目录下
cd ~/cc_ws
mkdir -p ~/cc_ws/ros2_ws/cross/src
sudo cp -r cross_compile/ ~/cc_ws/ros2_ws/cross/src
安装所需包和依赖
# 在docker中执行
apt install libssl-dev
pip install netifaces
apt-get install gcc-riscv64-linux-gnu
riscv64-linux-gnu-gcc --version
apt-get install g++-riscv64-linux-gnu
riscv64-linux-gnu-g++ --version
修改交叉编译工具链generic_linux.cmake
generic_linux.cmake在cross/cross_compile/cmake-toolchains目录下:
# 显式设置交叉编译器 riscv_ubuntu系统自带
set(CMAKE_C_COMPILER /usr/bin/riscv64-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER /usr/bin/riscv64-linux-gnu-g++)
-----------------------------------------------------
if("$ENV{TARGET_ARCH}" STREQUAL "" OR
#"$ENV{CROSS_COMPILE}" STREQUAL "" OR
"$ENV{SYSROOT}" STREQUAL "" OR
"$ENV{ROS2_INSTALL_PATH}" STREQUAL "" OR
"$ENV{PYTHON_SOABI}" STREQUAL "")
message(FATAL_ERROR "Target environment variables not defined")
endif()
修改为
if("$ENV{TARGET_ARCH}" STREQUAL "" OR
#"$ENV{CROSS_COMPILE}" STREQUAL "" OR
"$ENV{SYSROOT}" STREQUAL "" OR
"$ENV{ROS2_INSTALL_PATH}" STREQUAL ""
#"$ENV{PYTHON_SOABI}" STREQUAL ""
)
message(FATAL_ERROR "Target environment variables not defined")
endif()
交叉编译
# # 挂载后在docker中进行操作
cd /data
source install/local_setup.bash
export TARGET_ARCH=riscv64
export SYSROOT=/
export ROS2_INSTALL_PATH=/data/install/
cd cross
# 交叉编译指令
colcon build --merge-install \
--cmake-force-configure \
--cmake-args \
-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \
-DCMAKE_TOOLCHAIN_FILE="/data/cross/src/cross_compile/cmake-toolchains/generic_linux.cmake" \
完成交叉编译
交叉编译本质上是将x86架构下的代码文件编译成riscv架构下ros2可直接运行的可执行文件,编译后的生成文件在本地可以看到,但是不能运行,必须得在riscv架构硬件上或者docker 镜像中运行。
测试交叉编译ros2 demo
cd /data/cross
source install/local_setup.bash
ros2 run demo_nodes_cpp listener &
ros2 run demo_nodes_py talker
总结
因为ros2没有提供riscv架构预编译版本,所以整个实现交叉编译的过程比arm架构复杂一些,但整体思路和实现方法没有太多区别,后续还要看一下ros2底层在不共架构上具体的区别,以便更好的在不同架构平台开发功能。
参考文章
发表评论