ros2 交叉编译 x86到riscv架构

本文详细描述了如何在RISC-V架构上从头开始创建docker镜像,源码编译ROS2,解决编译过程中遇到的问题,如mimick_vendor包的修改和网络依赖包的下载,最终实现交叉编译并测试ros2demo。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


前言

内容概括:
本篇文章记录了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.cmakecross/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底层代码逻辑在不同架构上具体的区别,以便更好的在不同架构平台开发功能。

在嵌入式系统中进行ROS 2交叉编译是一个相对复杂但非常有用的过程,特别是在为不同架构的嵌入式设备(如ARM架构的单板计算机)构建ROS 2节点时。ROS 2的设计在一定程度上支持了跨平台开发,但交叉编译仍需仔细配置工具链和依赖项。 ### 交叉编译的基本步骤 1. **设置交叉编译环境** 首先,需要准备一个适用于目标架构交叉编译工具链。例如,对于ARM架构,可以使用 `arm-linux-gnueabi-gcc` 或 `arm-linux-gnueabihf-gcc`。工具链的选择应基于目标设备的CPU架构和浮点运算支持情况。 2. **准备ROS 2源码** ROS 2官方推荐使用源码方式构建系统。可以从GitHub克隆ROS 2的源码仓库,并选择合适的发布版本(如Foxy、Galactic或Humble)[^1]。 ```bash git clone https://github.com/ros2/ros2.git -b <version> ``` 3. **配置CMake工具链文件** 在交叉编译过程中,CMake需要一个工具链文件来指定编译器路径、目标架构和系统类型。一个典型的工具链文件如下: ```cmake set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR arm) set(CMAKE_C_COMPILER arm-linux-gnueabi-gcc) set(CMAKE_CXX_COMPILER arm-linux-gnueabi-g++) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) ``` 4. **安装目标平台的依赖项** 交叉编译时,需要为目标平台安装ROS 2及其依赖项的开发库。这些库通常需要在目标系统的文件系统中存在,或者通过交叉编译获得。可以使用工具如 `apt-get crossbuild` 或手动编译依赖项。 5. **执行编译** 使用 `colcon` 工具进行编译,并指定工具链文件: ```bash colcon build --merge-install --cmake-args -DCMAKE_TOOLCHAIN_FILE=/path/to/toolchain.cmake ``` 6. **部署到目标设备** 编译完成后,将生成的二进制文件和相关资源复制到目标设备上,并确保其运行环境已正确配置,包括ROS 2的运行时依赖项。 ### 注意事项 - **依赖管理**:ROS 2依赖大量第三方库(如 `rclcpp`、`rclc` 等),这些库可能需要在目标平台上进行交叉编译或预安装。 - **硬件抽象层**:某些ROS 2包依赖于特定的硬件抽象层(如 `ros2_control`),这些可能需要根据目标硬件进行适配。 - **性能优化**:在嵌入式系统上运行ROS 2时,建议使用轻量级中间件(如 `rmw_cyclonedds`)以减少资源占用[^1]。 ### 示例:为ARM架构的Raspberry Pi交叉编译ROS 2 假设目标设备是Raspberry Pi 3(ARMv7架构),可以使用以下命令配置工具链: ```bash colcon build --merge-install --cmake-args -DCMAKE_TOOLCHAIN_FILE=/path/to/arm-linux-gnueabihf.cmake ``` 工具链文件内容如下: ```cmake set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR arm) set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc) set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) ``` 编译完成后,将生成的 `install` 目录复制到Raspberry Pi的文件系统中,并在设备上运行ROS 2节点。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值