在上一个博客已经搭建好旭日 X3 派的远程开发环境和 esp32 的开发环境。那么如何建立旭日 X3 派与 esp32 之间的通信呢?


这里就要引出 micro-ROS, Micro-ROS是一个轻量级的ROS2(Robot Operating System 2)实现,旨在为嵌入式系统和物联网设备提供ROS2功能。ROS2是一款用于机器人和智能系统开发的开源操作系统,但是它的大小和复杂性往往使得它难以运行在资源受限的嵌入式平台上。


Micro-ROS 在嵌入式平台上提供了 ROS2的功能,包括节点、话题、服务、参数服务器和行为等。它使用了一种特殊的通信协议,称为 DDS(Data Distribution Service),该协议在嵌入式设备上具有高效性和可扩展性。DDS 通信就是大家常见的推送-订阅消息通信机制。Micro-ROS 的主要优点是,它具有高度的可定制性和可配置性,使得开发人员能够选择要使用的 ROS2功能,并根据需要将其集成到嵌入式系统中。

micro-ROS

micro-ROS 架构




Micro-ROS 还使用了一个称为“Micro-XRCE-DDS”的通信协议,它可以使得极度资源受限环境下能够与 ROS2节点进行交互。这使得开发人员能够在嵌入式设备上运行 ROS2节点,并与其他 ROS2节点通信,同时保持高效性和可扩展性。


那么接下来就让我们开始搭建 micro-ROS 的环境,从上面架构图可以看到,我们旭日 X3 派上的 ROS2 是运行了一个 agent,由 ROS2 Agent 与 Micro XRCE-DDS Client 进行通信。ROS2 agent 的作用就是 micro-ROS 节点的代理,通过这个代理处理 micro-ROS 端节点的推送-订阅请求。

ROS 2 Agent

所以我们首先要做的就是搭建出 ROS2 Agent,ROS2 Agent 是 ROS2 的一个软件包,我们可以直接在我们的 TROS 环境下下载搭建,也可以使用官方为我们的提供的 docker 镜像运行。两种方法各有利弊,当然我比较喜欢 docker 环境进行安装。那么首先就是要在旭日 X3 派中配置 docker 环境。


在安装 docker 前我们需要对 TogetheROS.Bot 进行配置,安装相关的工具链。

TogetheROS.Bot

首先升级系统镜像以及源信息 sudo apt update sudo apt upgrade


更改 github 的域名解析,避免后续出现的在地址无法访问的错误
echo "185.199.108.133 raw.githubusercontent.com" > /etc/hosts


添加 ROS apt 源

sudo apt update && sudo apt install curl gnupg2 lsb-release
sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key  -o /usr/share/keyrings/ros-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(source /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null



更新 apt 仓库
sudo apt update


安装 ROS2-foxy
apt install ros-foxy-desktop


建立软连接

cd /opt/tros
## 使用/opt/tros目录下的create_soft_link.py创建ROS package至tros.b的软连接
sudo python3 create_soft_link.py --foxy /opt/ros/foxy/ --tros /opt/tros/



添加环境变量

echo "source /opt/tros/local_setup.bash" > ~/.bashrc
source ~/.bashrc

docker 环境安装

安装基本软件
sudo apt-get install curl wget apt-transport-https ca-certificates software-properties-common


添加 docker 密钥
curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add -


添加 apt 源,这里和密钥一样,都是使用的中国科学技术大学的源
sudo add-apt-repository "deb [arch=arm64] https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu $(lsb_release -cs) stable"


更新 apt 索引并下载 docker
apt update && apt install docker-ce


查看一下 docker 的状态
systemctl status docker


接下来给 docker 更换一下镜像源,不然在国内进行访问速度太慢
创建文件 /etc/docker/daemon.json

vim /etc/docker/daemon.json



添加一下内容

{
    "registry-mirrors":[
        "https://docker.mirrors.ustc.edu.cn/",
        "https://hub-mirror.c.163.com/",
        "https://registry.docker-cn.com"
    ]
}



重启 docker 和 daemon

systemctl daemon-reload
systemctl restart docker

使用 micro-ROS agent 镜像

micro-ROS agent 支持多种协议,能够支持 UDP、TCP、CAN 等多种协议下运行,具体指令如下

# UDPv4 micro-ROS Agent
docker run -it --rm -v /dev:/dev -v /dev/shm:/dev/shm --privileged --net=host microros/micro-ros-agent:$ROS_DISTRO udp4 --port 8888 -v6

# Serial micro-ROS Agent
docker run -it --rm -v /dev:/dev -v /dev/shm:/dev/shm --privileged --net=host microros/micro-ros-agent:$ROS_DISTRO serial --dev [YOUR BOARD PORT] -v6

# TCPv4 micro-ROS Agent
docker run -it --rm -v /dev:/dev -v /dev/shm:/dev/shm --privileged --net=host microros/micro-ros-agent:$ROS_DISTRO tcp4 --port 8888 -v6

# CAN-FD micro-ROS Agent
docker run -it --rm -v /dev:/dev -v /dev/shm:/dev/shm --privileged --net=host microros/micro-ros-agent:$ROS_DISTRO canfd --dev [YOUR CAN INTERFACE] -v6



tcp 和 udp 协议也支持使用 IPv6。但是对于支持的传输协议,只能使用串口和 udp4版本,但是用户可以开发和使用代理来测试自己的 tcp4和 canfd 自定义传输。

micro-ROS

下载环境

在 esp-32 使用 micro-ROS 非常的方便,只需要在我们搭建的 platformio 库中加入依赖即可。


如果按照项目简介中所说,在 platformio.ini 文件中添加

lib_deps =
    https://github.com/micro-ROS/micro_ros_platformio



之后保存文件,就会自动加载项目依赖库,但是如果你的本机没有安装相关编译工具的话最后会报出一些错误,导致我们无法使用这个库。


所以我们对 lib 库的地址进行更改,更换成国内的已经编译好的库文件

lib_deps =
    https://gitee.com/ohhuo/micro_ros_platformio.git



之后保存文件,项目会下载该库文件到你所创建的项目的 .pio/libdeps/ 中去,之后便可以使用 micro-ROS 提供的 C API 来编写实现在微控制器上的 ROS 功能。

测试是否能够通信

首先在旭日 X3 派中运行 docker 容器,使用 udp4 进行通信。
docker run -it --rm -v /dev:/dev -v /dev/shm:/dev/shm --privileged --net=host microros/micro-ros-agent:$ROS_DISTRO udp4 --port 8888 -v6


之后将测试代码下载到 esp32 开发板上,观察是否两者之间是否成功连接,测试代码如下

#include <Arduino.h>
#include <micro_ros_platformio.h>
#include <WiFi.h>
#include <rcl/rcl.h>
#include <rclc/rclc.h>
#include <rclc/executor.h>

rclc_executor_t executor;
rclc_support_t support;
rcl_allocator_t allocator;
rcl_node_t node;

void setup()
{
    pinMode(2, OUTPUT);
    digitalWrite(2, HIGH);
    Serial.begin(115200);
    IPAddress agent_ip(192,168,1,110); // 填入旭日X3派的IP地址,用逗号分隔
    // 填入自己WIFI的名称和密码
    set_microros_wifi_transports("SSID", "PASSWD", agent_ip, 8888);
    delay(2000);
    allocator = rcl_get_default_allocator();
    rclc_support_init(&support, 0, NULL, &allocator);
    rclc_node_init_default(&node, "microros_wifi", "", &support);
    rclc_executor_init(&executor, &support.context, 1, &allocator);
}

void loop()
{
    delay(100);
    rclc_executor_spin_some(&executor, RCL_MS_TO_NS(100));
}



观察容器的运行日志,如下则是已经成功连接

此时再使用 ros2 node list 命令查看,可以看到新增的 /Test_Node 节点。