文章目录

前言一、创建 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底层在不共架构上具体的区别,以便更好的在不同架构平台开发功能。

参考文章

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: