# 宇树 G1 机载计算单元 PC2 Docker 部署 ROS2 Nav2 指南

> 原文链接：https://robotics.hellobike.com/wiki/g1-onboard-nav2-docker
> 频道：wiki | 更新日期：2026-10-10 | 标签：G1, Docker, Jetson, PC2, Nav2, 容器化部署, arm64
> 核心摘要：详细介绍在宇树 G1 机载 Jetson Orin 计算单元（Ubuntu 20.04）上通过 Docker sidecar 容器部署 ROS2 Humble Nav2 的架构、构建流程与运行维护。

# 宇树 G1 机载计算单元 PC2 Docker 部署 ROS2 Nav2 指南

> 本文为宇树 G1 EDU 真机实操记录，固件/SDK 版本以文中标注为准。

## 1. 架构速览与环境约束

宇树 G1 机载的高性能计算单元（PC2，硬件平台为 aarch64 架构的 NVIDIA Jetson Orin NX）出厂宿主系统为 Ubuntu 20.04（预装 ROS2 Foxy）。

由于现代 Nav2 导航栈在 ROS2 Humble 版本具备更完善的规划器生态（如 SmacPlanner2D、Collision Monitor 等），为避免破坏宿主机预装的依赖环境，工程上采用 **Docker Sidecar** 容器方案在 PC2 上运行 ROS2 Humble Nav2：

```text
控制台界面 ──HTTP──> 机载宿主服务 (systemd 托管，运行于宿主机 Python 环境)
                           │
                           │ stdin/stdout JSONL 通信管道
                           ▼
                     Nav2 Docker Sidecar (ROS2 Humble, --network host)
                           │
                           │ cmd_vel / TF / costmap（ROS_DOMAIN_ID=42）
                           ▼
                     底层运动适配器 ──DDS──> 机器人底盘 (ROBOT_DDS_DOMAIN=0)
```

关键部署原则：
- **宿主机解耦**：不在 Ubuntu 20.04 宿主机上源码硬编 Humble，所有 Nav2 组件均封装于容器内。
- **主机网络共享**：Nav2 容器采用 `--network host` 运行，与宿主服务进行同机轻量 IPC，不额外映射或暴露公网网络端口。
- **DDS 域隔离**：容器内部 ROS2 通信锁定 `ROS_DOMAIN_ID=42`，底盘通信与传感器点云锁定 `ROBOT_DDS_DOMAIN=0`。

## 2. Docker 镜像加速与依赖准备

PC2 机载网络通常无法稳定访问外部镜像仓库。需在 PC2 宿主机上配置可用的镜像加速器，并使用官方基础镜像 `ros:humble-ros-base-jammy`。

配置 Docker 守护进程镜像源：

```bash
sudo python3 - <<'PY'
import json
from pathlib import Path

path = Path("/etc/docker/daemon.json")
payload = json.loads(path.read_text()) if path.exists() else {}
mirrors = payload.setdefault("registry-mirrors", [])
mirror = "https://docker.m.daocloud.io"
if mirror not in mirrors:
    mirrors.insert(0, mirror)
path.write_text(json.dumps(payload, indent=2) + "\n")
PY

sudo systemctl restart docker
docker pull ros:humble-ros-base-jammy
```

**注意事项**：避免使用已被限制公共访问或不提供代理服务的镜像组织路径。

## 3. 容器构建与依赖编译要点

在 PC2（aarch64 架构）构建 Docker 镜像时，需处理以下平台特有依赖：

1. **软件源适配**：由于基础镜像基于 Ubuntu 22.04（Jammy）arm64，apt 源需指向支持 aarch64 的 `ports` 镜像源（如清华大学开源镜像站的 `ubuntu-ports`）以及 ROS2 专用源。
2. **CycloneDDS 0.10.2 源码编译**：
   - PyPI 仓库未提供适配 Linux aarch64 的 CycloneDDS 0.10.2 pre-built wheel；
   - 必须在容器构建阶段拉取固定提交版本的 CycloneDDS C 库源码，先执行 CMake 编译安装动态链接库，随后构建匹配的 Python 模块并安装，确保 `from cyclonedds.domain import DomainParticipant` 导入成功。
3. **用户组权限**：运行宿主服务的系统账号需加入 `docker` 用户组，具备访问 `/var/run/docker.sock` 的权限：

```bash
sudo usermod -aG docker <service-user>
```

## 4. 生产配置与环境变量注入

Nav2 部署成功后，机载配置环境文件中会注入如下核心环境变量：

```bash
# 导航侧边栏运行环境
EDGE_NAV2_RUNTIME=docker
EDGE_NAV2_DOCKER_IMAGE=robot-nav2-sidecar:latest
EDGE_NAV_BACKEND=nav2
EDGE_NAV2_ACCEPTANCE_MODE=0

# 通信域隔离
ROBOT_DDS_DOMAIN=0
EDGE_ROS_DOMAIN_ID=42
```

## 5. 部署验证与排障

### 5.1 零运动状态检查

在机器人在场静止、未下发运动指令时进行环境与容器检查：

```bash
# 检查镜像是否存在
docker images | grep nav2-sidecar

# 检查宿主服务运行状态
systemctl is-active robot-edge.service

# 检查健康检测端点
curl -sS http://127.0.0.1:8002/health
```

### 5.2 常见故障与处理措施

| 异常现象 | 根因分析 | 解决措施 |
|---|---|---|
| `docker pull` 基础镜像超时 | 加速镜像源未生效或网络阻断 | 检查 `/etc/docker/daemon.json` 并重启 Docker，确认镜像拉取成功 |
| 容器启动报缺少 Docker 权限 | 宿主机运行账号未加入 `docker` 组 | 执行 `sudo usermod -aG docker <user>` 并重启相关服务 |
| aarch64 下 CycloneDDS 导入失败 | 缺少原生 C 库链接或架构不匹配 | 在构建阶段以 `--network host` 从固定源码分支完成 C 库本地编译 |
| 点云或地图文件挂载报权限错误 | 宿主机地图路径未挂载至容器白名单 | 确保地图资产与运行目录在 Docker 启动参数的共享挂载卷内 |

## 原始参考来源 (Sources)

- [Navigation2](https://github.com/ros-navigation/navigation2)
- [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds)