# D1_Backend **Repository Path**: lookc4/D1_Backend ## Basic Information - **Project Name**: D1_Backend - **Description**: D1_BackendD1_BackendD1_BackendD1_BackendD1_Backend - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-27 - **Last Updated**: 2026-07-29 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # D1_Backend 手机控制后端部署 ![Jetson](https://img.shields.io/badge/Jetson-Orin%20Nano-76B900?logo=nvidia&logoColor=white) ![Ubuntu](https://img.shields.io/badge/Ubuntu-22.04-E95420?logo=ubuntu&logoColor=white) ![ROS 2](https://img.shields.io/badge/ROS%202-Humble-22314E?logo=ros&logoColor=white) ![systemd](https://img.shields.io/badge/systemd-navbot--phone-7F7F7F?logo=linux&logoColor=white) ![D1](https://img.shields.io/badge/D1-external%20runtime-0078D4) [English version](README.md) > 本文说明如何在已经独立部署好 `D1_rl_sar` 的 Jetson 上构建、安装和运行 `D1_Backend` 手机控制后端。 `D1_Backend` 负责手机侧 HTTP/WebSocket、ROS 话题、`/cmd_vel` 超时保护和 D1 虚拟手柄控制。它通过 systemd 适配器调用已有的 D1 IMU 与 `rl_real_d1`,但不安装、配置或修复 D1 的 CAN、驱动、策略模型和工作区。 ## 目录 - [1. 适用范围与验证状态](#1-适用范围与验证状态) - [2. 系统架构与职责边界](#2-系统架构与职责边界) - [3. 仓库来源与 Git 管理](#3-仓库来源与-git-管理) - [4. 环境、依赖与目录](#4-环境依赖与目录) - [5. 源码检查与构建](#5-源码检查与构建) - [6. GUI 配置与系统安装](#6-gui-配置与系统安装) - [7. systemd 启动、停止与运行机制](#7-systemd-启动停止与运行机制) - [8. 现场验收与卸载](#8-现场验收与卸载) - [9. 最短启动清单](#9-最短启动清单) - [10. 常见问题](#10-常见问题) ## 1. 适用范围与验证状态 ### 1.1 适用范围 | 项目 | 要求 | |---|---| | 开发板 | Jetson Orin Nano 系列,Linux aarch64 | | 系统 | Ubuntu 22.04 | | ROS | ROS 2 Humble | | 运行用户 | 默认 `navbot` | | 后端仓库 | `/home/navbot/project/D1_Backend` | | D1 工作区 | 默认 `/home/navbot/project/D1_rl_sar/rl_sar` | | IMU | `/dev/ttyACM0`,921600 baud | | 虚拟手柄 | `/dev/uhid` → `/dev/input/navbot_d1_js` | | 后端端口 | TCP 8081 | | 相机端口 | TCP 8080,可选 | ### 1.2 当前验证状态 | 状态 | 内容 | |---|---| | 已验证 | `verify-phone-stack.sh` 的 Shell、禁用内容和 systemd 静态检查通过 | | 已验证 | 从空 `backend/build` 和空 `install` 全新构建成功 | | 已验证 | 生成 `ros_gui_backend`、`navbot_cmd_vel_guard`、`d1_hid_bridge` | | 已验证 | 加载 ROS 与 D1 环境后,三个程序的 `ldd` 无 `not found` | | 已验证 | 对现有 D1 工作区执行安装脚本 `--check-only` 通过 | | 已验证 | 在 `192.168.1.3` 重新安装,`BACKEND_ROOT=/home/navbot/project/D1_Backend`,无旧后端路径残留 | | 已验证 | 对 active 的 `can1/can2` 隔离运行 `preflight + can-ready`,Backend、IMU、RL 均保持停止 | | 已验证 | Git 只跟踪源码和部署模板,构建产物与运行数据被忽略 | | 尚未现场验证 | 在新机器上把 `navbot-phone-*` units 安装到系统 | | 尚未现场验证 | 启动 `navbot-phone.target` 并控制真实 D1 | | 尚未现场验证 | 手机 HTTP/WebSocket、模式切换和速度控制的完整实机链路 | | 尚未现场验证 | USB 相机与 8080 视频服务的现场链路 | 注意:文档中的安装、启动和实机验收步骤必须在机器人安全吊起、急停方式可用且 D1 硬件链路已经由 D1 部署流程确认后执行。 ## 2. 系统架构与职责边界 ### 2.1 手机控制链路 ```text 手机 │ HTTP / WebSocket ▼ ros_gui_backend :8081 ├─ 发布 /cmd_vel ├─ 发送 D1 站立、趴下等模式命令 └─ 连接 D1 虚拟手柄桥 │ ▼ navbot_cmd_vel_guard ├─ 订阅 /cmd_vel ├─ 作为 /cmd_vel 发布者注入超时安全零速度 └─ timeout=300 ms,zero period=100 ms │ ▼ 已独立部署的 D1_rl_sar ├─ dm_imu_node └─ rl_real_d1 ``` ### 2.2 `D1_Backend` 负责的内容 - `ros_gui_backend`,监听 TCP 8081。 - `/cmd_vel` 超时保护节点 `navbot_cmd_vel_guard`。 - D1 UHID 虚拟手柄桥 `d1_hid_bridge`。 - 一次手机控制会话内使用的 D1 IMU 与 RL 启动适配器。 - 对外部管理的 `can1`、`can2` CAN FD 接口执行有超时、只读的就绪等待。 - 可选 `usb_cam` 与 `web_video_server`,监听 TCP 8080。 - 启动前 preflight、RL 依赖等待、最终 ready 检查和失败清理。 ### 2.3 `D1_Backend` 明确不负责的内容 - 不克隆、编译或安装 `D1_rl_sar`。 - 不复制 D1 策略配置或 ONNX 模型。 - 不安装、检查、加载或卸载 `gs_usb.ko`。 - 不检查、配置、拉起或关闭 CAN 接口。 - 不安装或启停 D1 自己的 CAN systemd units。 - 只等待外部 CAN units 和链路状态,不执行修复。 - D1 因 CAN、驱动或策略问题失败时,通过 `navbot-phone-can-ready.service` 或 `navbot-phone-rl.service` 暴露错误,D1_Backend 不尝试修复。 ### 2.4 手机模式 D1 参数 手机 target 直接运行现有 D1 工作区中的 `rl_real_d1`,保留以下参数: ```text dog_usb_enable=false keyboard_enable=false sys_joystick_device=/dev/input/navbot_d1_js navigation_mode_default=true ``` 它不会改为调用实体手柄/LoRa 模式的 `rl-sar-main.service`。 ## 3. 仓库来源与 Git 管理 ### 3.1 来源记录 | 项目 | 内容 | |---|---| | 来源主机 | `192.168.1.3` | | 当前仓库目录 | `/home/navbot/project/D1_Backend` | | Gitee 仓库 | `https://gitee.com/lookc4/D1_Backend.git` | | 源码整理日期 | `2026-07-27` | | 整理目标 | 可由 Git 管理的手机控制后端源码 | | 外部 D1 运行时 | `/home/navbot/project/D1_rl_sar/rl_sar` | ### 3.2 获取仓库 仓库配置远端地址后,在新机器上执行: ```bash mkdir -p ~/project git clone https://gitee.com/lookc4/D1_Backend.git ~/project/D1_Backend cd ~/project/D1_Backend ``` 本地目录名与 Gitee 仓库名保持一致。已有克隆需要先更新 `origin`、移动工作树, 然后重新执行安装脚本: ```bash git remote set-url origin https://gitee.com/lookc4/D1_Backend.git cd ~/project mv ros_backend D1_Backend ``` ### 3.3 跟踪与忽略规则 Git 跟踪: - `backend/src`、`backend/cmake`、协议文件和构建脚本。 - `deploy/systemd`、`deploy/libexec`、udev、modules-load 与配置示例。 - 顶层构建、安装、验证、卸载脚本和双语 README。 - `backend/src/app/install` 中属于源码的安装模板。 Git 不跟踪: ```text backend/build/ install/ backups/ deployments/ .runtime-backup/ third_party/ *.log *.pid *.orig *.bak *.zip *.zip.sha256 ``` 检查忽略结果: ```bash git status --short --ignored git check-ignore -v backend/build install ``` 真实 GUI 配置和密码不能加入 Git。 ## 4. 环境、依赖与目录 ### 4.1 D1 前置条件 开始构建 D1_Backend 前,D1 必须已经独立部署完成,至少存在: ```text /home/navbot/project/D1_rl_sar/rl_sar/install/setup.bash /home/navbot/project/D1_rl_sar/rl_sar/install/lib/rl_sar/rl_real_d1 /home/navbot/project/D1_rl_sar/rl_sar/policy/d1/robot_lab/policy_onnx.onnx ``` 加载工作区后必须能找到: ```bash source /opt/ros/humble/setup.bash source /home/navbot/project/D1_rl_sar/rl_sar/install/setup.bash ros2 pkg prefix rl_sar ros2 pkg prefix dm_imu ``` ### 4.2 构建和运行依赖 安装 `deploy/packages/apt-build.txt` 对应的软件包: ```bash sudo apt update sudo apt install -y \ build-essential \ cmake \ pkg-config \ protobuf-compiler \ libprotobuf-dev \ libboost-filesystem-dev \ libboost-program-options-dev \ libsdl2-dev \ libsdl2-image-dev \ libc-ares-dev \ libssl-dev \ libopencv-core-dev \ libopencv-imgcodecs-dev \ curl \ iproute2 \ kmod \ udev \ zip ``` 构建过程通过 CMake FetchContent 下载固定版本: | 依赖 | 版本 | |---|---| | Drogon | `v1.9.11` | | fmt | `10.2.1` | | yaml-cpp | `0.8.0` | 根目录旧 `third_party/` 不参与构建。 ### 4.3 设备、用户组与端口 主链路要求: ```bash ls -l /dev/ttyACM0 ls -l /dev/uhid id navbot ``` 安装器会创建 `navbot-hid` 组,并把运行用户加入: ```text navbot-hid input dialout video ``` 用户组发生变化后应退出当前登录会话并重新登录。 端口要求: - 8081 必须空闲。 - 存在 `/dev/video0` 并准备启动相机时,8080 必须空闲。 检查端口: ```bash ss -ltnp | grep -E ':(8080|8081)\b' || true ``` ## 5. 源码检查与构建 ### 5.1 静态检查 以普通用户执行: ```bash cd ~/project/D1_Backend ./scripts/verify-phone-stack.sh ``` 该脚本检查: - 所有受管理 Shell 脚本的语法。 - 手机部署层没有 CAN 或 `gs_usb` 管理命令。 - 配置示例没有非空 SSH 密码。 - 手机专用 systemd units 可以通过 `systemd-analyze verify`。 期望最后看到: ```text Phone stack source verification passed. ``` 主机上其它 systemd unit 的兼容性警告不代表手机 units 验证失败,应以脚本退出码和最后一行结果为准。 ### 5.2 全新构建 不要使用 root 构建: ```bash cd ~/project/D1_Backend ./scripts/build-phone-backend.sh ``` 输出目录: ```text backend/build/phone-release/ install/ ``` 期望生成: ```text install/bin/ros_gui_backend install/bin/navbot_cmd_vel_guard install/bin/d1_hid_bridge ``` 检查: ```bash test -x install/bin/ros_gui_backend test -x install/bin/navbot_cmd_vel_guard test -x install/bin/d1_hid_bridge ``` ### 5.3 动态库检查 ROS 程序依赖 ROS 环境。不要在未 source ROS 的普通 Shell 中根据裸 `ldd` 判断 ROS 库缺失。 正确检查方式: ```bash cd ~/project/D1_Backend source /opt/ros/humble/setup.bash source ~/project/D1_rl_sar/rl_sar/install/setup.bash export LD_LIBRARY_PATH="$PWD/install/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" for binary in \ install/bin/ros_gui_backend \ install/bin/navbot_cmd_vel_guard \ install/bin/d1_hid_bridge; do echo "===== $binary =====" ldd "$binary" | grep 'not found' || true done ``` 没有 `not found` 输出即为正常。 ### 5.4 D1 只读安装检查 构建完成后先执行: ```bash cd ~/project/D1_Backend sudo ./scripts/install-phone-stack.sh \ --backend-root /home/navbot/project/D1_Backend \ --d1-root /home/navbot/project/D1_rl_sar/rl_sar \ --user navbot \ --check-only ``` `--check-only` 只验证 D1_Backend 构建产物、D1 路径和 ROS 包,不写系统目录、不检查 CAN。 期望看到: ```text Phone stack check passed. BACKEND_ROOT=/home/navbot/project/D1_Backend D1_ROOT=/home/navbot/project/D1_rl_sar/rl_sar NAVBOT_USER=navbot ``` ## 6. GUI 配置与系统安装 ### 6.1 配置文件 仓库只包含: ```text deploy/config/gui_app_settings.example.json ``` 其中以下字段必须保持为空: ```json { "SSHHost": "", "SSHUsername": "", "SSHPassword": "" } ``` 正式运行配置: ```text /etc/navbot/gui_app_settings.json owner: root group: navbot mode: 0640 ``` 运行路径配置: ```text /etc/default/navbot-phone ``` 它记录 `BACKEND_ROOT`、`D1_ROOT`、`ROS_SETUP`、`GUI_CONFIG`、`NAVBOT_USER` 和相机配置路径。 ### 6.2 默认安装 只安装系统集成,不启动机器人: ```bash cd ~/project/D1_Backend sudo ./scripts/install-phone-stack.sh \ --backend-root /home/navbot/project/D1_Backend \ --d1-root /home/navbot/project/D1_rl_sar/rl_sar \ --user navbot ``` 默认行为: - 安装 `navbot-phone-*` systemd units。 - 安装 `/usr/local/libexec/navbot-phone` 辅助脚本。 - 安装 RL 启动前最长 30 秒、只读的 CAN 就绪门控。 - 安装 HID udev 与 `uhid/joydev` modules-load 配置。 - 生成 `/etc/default/navbot-phone`。 - 目标 GUI 配置不存在时安装空字段示例。 - 执行 udev reload、systemd daemon-reload 和 unit verify。 - 不 enable、不启动 `navbot-phone.target`。 - 不修改 D1、CAN 或驱动。 ### 6.3 使用已有 GUI 配置 首次安装时指定配置: ```bash sudo ./scripts/install-phone-stack.sh \ --backend-root /home/navbot/project/D1_Backend \ --d1-root /home/navbot/project/D1_rl_sar/rl_sar \ --user navbot \ --config /path/to/gui_app_settings.json ``` 目标配置已经存在时默认保留。只有明确需要覆盖时使用: ```bash sudo ./scripts/install-phone-stack.sh \ --backend-root /home/navbot/project/D1_Backend \ --d1-root /home/navbot/project/D1_rl_sar/rl_sar \ --user navbot \ --config /path/to/gui_app_settings.json \ --force-config ``` ### 6.4 安装后立即启动 仅在现场安全条件已经确认后使用: ```bash sudo ./scripts/install-phone-stack.sh \ --backend-root /home/navbot/project/D1_Backend \ --d1-root /home/navbot/project/D1_rl_sar/rl_sar \ --user navbot \ --start ``` 新用户组权限通常需要重新登录才能在当前会话中生效,因此首次部署更推荐先安装、重新登录,再手工启动。 ### 6.4 配置 Nano 开机热点 Nano 使用 NetworkManager 管理无线网卡。仓库提供独立脚本,把支持 AP 模式的 Wi-Fi 配置为固定手机接入点: ```text SSID: navbot 密码: 无(开放热点) Nano 地址: 192.168.50.1/24 手机后端地址: 192.168.50.1:8081 频段: 2.4 GHz,信道 6 ``` 先执行只读检查,再安装热点配置: ```bash cd ~/project/D1_Backend ./scripts/manage-navbot-hotspot.sh check sudo ./scripts/manage-navbot-hotspot.sh install ``` `install` 会幂等创建或更新 `navbot-hotspot`,设置为开机优先自动连接,但不会立即 切换无线网卡或重启系统,因此当前 Wi-Fi SSH 不会在安装中途断开。重启后 Nano 开始广播 `navbot`: ```bash sudo reboot ``` 手机连接无密码的 `navbot` 后,在手机应用中填写 `192.168.50.1` 和端口 `8081`, 完整地址为 `http://192.168.50.1:8081`。部分手机会提示该 Wi-Fi 无互联网,需要选择 “仍然连接”。Nano 当前只有一块 Wi-Fi;热点启用后不能同时连接原来的 `ChinaNet-NavBot-5G`,旧的 `192.168.1.3` 地址和 SSH 会话会失效。如果 Nano 另有 有线上行,NetworkManager shared 模式可以将其转发给热点客户端。 热点与机器人控制栈相互独立,不会启动 `navbot-phone.target`。只有在机器人安全吊起、 急停可用且 CAN 已就绪后,才单独启动控制栈: ```bash sudo systemctl start navbot-phone.target ``` 检查热点、客户端、8081 和 phone target 状态: ```bash ./scripts/manage-navbot-hotspot.sh status ``` 需要立即切热点时执行以下命令;通过当前 Wi-Fi 操作时 SSH 会正常断开: ```bash sudo ./scripts/manage-navbot-hotspot.sh start ``` 切回客户已经保存的 Wi-Fi: ```bash sudo ./scripts/manage-navbot-hotspot.sh stop --connect '客户的 Wi-Fi 配置名' ``` 可以用 `nmcli connection show` 查看配置名。不指定 `--connect` 时只停止热点并列出 保存的连接;下次重启仍会优先启动 `navbot`。如果无线配置错误导致无法远程连接, 应通过 Nano 本地控制台或有线网络执行恢复命令。 上述 `stop --connect` 只切换当前运行会话。`navbot-hotspot` 默认保持 `autoconnect=yes` 和优先级 `100`,因此下次重启仍会优先启动热点。如果希望后续 重启也保持连接客户 Wi-Fi,先关闭热点自启动,再切换连接: ```bash sudo nmcli connection modify 'navbot-hotspot' connection.autoconnect no sudo nmcli connection modify '客户的 Wi-Fi 配置名' connection.autoconnect yes sudo ./scripts/manage-navbot-hotspot.sh stop --connect '客户的 Wi-Fi 配置名' ``` 以后需要恢复开机热点时,可以重新启用 profile: ```bash sudo nmcli connection modify 'navbot-hotspot' \ connection.autoconnect yes \ connection.autoconnect-priority 100 ``` 也可以重新执行安装命令,它会恢复完整的热点配置但不会立即切换当前 Wi-Fi: ```bash sudo ./scripts/manage-navbot-hotspot.sh install ``` 恢复后可在下次重启自动进入热点,或使用 `start` 立即切换。 只删除本项目创建的热点配置: ```bash sudo ./scripts/manage-navbot-hotspot.sh remove ``` 该命令不会删除客户 Wi-Fi。开放热点没有链路密码,8081 后端也没有网络认证;无线 覆盖范围内的任何设备都可能访问机器人控制接口,只能在受控现场使用。 ## 7. systemd 启动、停止与运行机制 ### 7.1 手机 target 组成 `navbot-phone.target` 强依赖: | Unit | 作用 | |---|---| | `navbot-phone-preflight.service` | 启动前检查 D1_Backend、D1、设备、冲突进程和端口 | | `navbot-phone-can-ready.service` | 最长等待 30 秒,确认外部 `gs_usb`、`can1`、`can2` 就绪,但不配置它们 | | `navbot-phone-hid-bridge.service` | 创建 UHID 虚拟手柄 | | `navbot-phone-backend.service` | 运行手机 HTTP/WebSocket 后端 | | `navbot-phone-cmd-vel-guard.service` | `/cmd_vel` 超时安全零速度 | | `navbot-phone-imu.service` | 调用 D1 的 `dm_imu_node` | | `navbot-phone-rl.service` | 以手机导航参数调用 D1 的 `rl_real_d1` | | `navbot-phone-ready.service` | 检查 API、HID、节点、IMU 和 `/cmd_vel` 图关系 | 可选: | Unit | 作用 | |---|---| | `navbot-phone-camera.service` | `/dev/video0`、`usb_cam`、`web_video_server :8080` | ### 7.2 启动 首次实机启动前必须吊起机器人,并准备好急停方式: ```bash sudo systemctl start navbot-phone.target ``` 查看状态: ```bash systemctl --no-pager --full status navbot-phone.target systemctl --no-pager --full status \ navbot-phone-preflight.service \ navbot-phone-can-ready.service \ navbot-phone-hid-bridge.service \ navbot-phone-backend.service \ navbot-phone-cmd-vel-guard.service \ navbot-phone-imu.service \ navbot-phone-rl.service \ navbot-phone-ready.service ``` 实时日志: ```bash journalctl -u 'navbot-phone-*' -f ``` ### 7.3 开启或关闭开机自启动 安装器默认不会 enable `navbot-phone.target`。启用开机自启动并立即启动: ```bash sudo systemctl enable --now navbot-phone.target ``` 只启用开机自启动,但不启动当前会话: ```bash sudo systemctl enable navbot-phone.target ``` 确认自启动和当前运行状态: ```bash systemctl is-enabled navbot-phone.target systemctl --no-pager --full status navbot-phone.target ``` 重启机器后,查看本次开机日志: ```bash journalctl -b -u 'navbot-phone-*' --no-pager ``` 取消开机自启动,并停止当前手机控制会话: ```bash sudo systemctl disable --now navbot-phone.target ``` 如果希望当前会话继续运行、只是不再随下次开机自动启动,则使用不带 `--now` 的 `sudo systemctl disable navbot-phone.target`。 开机时 `/dev/ttyACM0`、`/dev/uhid`、USB CAN 适配器和可选的 `/dev/video0` 可能异步出现。仍由独立部署的 D1 开机机制加载 `gs_usb`, 并配置 `can1` 和 `can2`。允许 RL 启动前, `navbot-phone-can-ready.service` 最长等待 30 秒,确认: - `d1-gs-usb.service` 已 active。 - `d1-canfd@can1.service`、`d1-canfd@can2.service` 已 active。 - 两个接口均为 `UP`、CAN FD(`mtu 72`),且状态为 `ERROR-ACTIVE`。 该门控只读,不启动、停止、配置或恢复外部 CAN 栈。等待超时会在 `rl_real_d1` 启动前让 phone target 失败。 ### 7.4 CAN 与 RL 依赖等待 CAN 门控通过后,RL 适配器还会等待: - HID Bridge、Guard、IMU 服务 active。 - `/run/navbot-d1/d1-hid.sock` 存在。 - `/dev/input/navbot_d1_js` 存在。 - `/imu/data` 能收到一帧。 - `/navbot_cmd_vel_guard` 已发现。 CAN 未能就绪时检查: ```bash systemctl --no-pager --full status navbot-phone-can-ready.service systemctl --no-pager --full status \ d1-gs-usb.service \ d1-canfd@can1.service \ d1-canfd@can2.service ip -details link show can1 ip -details link show can2 ``` `navbot-phone-rl.service` 使用: ```text Restart=no KillSignal=SIGINT TimeoutStartSec=45 TimeoutStopSec=15 ``` RL 正常或异常退出后不会被自动重新拉起,target 会随之退出。 ### 7.5 停止 ```bash sudo systemctl stop navbot-phone.target ``` 停止顺序优先结束 RL,然后结束相机、后端、IMU、Guard 和 HID Bridge。 停止时不会: - 关闭任何 CAN 接口。 - 停止 D1 的 CAN services。 - 卸载 `gs_usb`。 - 删除 D1 工作区或策略。 ## 8. 现场验收与卸载 ### 8.1 后端 API ```bash curl -fsS http://127.0.0.1:8081/api/settings ``` 返回 JSON 即表示后端 API 正常。 ### 8.2 HID ```bash test -S /run/navbot-d1/d1-hid.sock ls -l /dev/input/navbot_d1_js ``` ### 8.3 ROS 节点 ```bash source /opt/ros/humble/setup.bash source ~/project/D1_rl_sar/rl_sar/install/setup.bash ros2 node list ``` 必须看到: ```text /ros_gui_app_backend /navbot_cmd_vel_guard /dm_imu_node /rl_real_d1 ``` ### 8.4 IMU ```bash timeout 5 ros2 topic echo /imu/data --once ``` 收到一帧 `sensor_msgs/msg/Imu` 即为正常。 ### 8.5 `/cmd_vel` 图关系 ```bash ros2 topic info /cmd_vel -v ``` 确认: - Backend 是发布者。 - Guard 同时是订阅者和发布者。 - RL 是订阅者。 ### 8.6 可选相机 没有 `/dev/video0` 时不影响主链路: ```bash systemctl is-active navbot-phone-camera.service || true ls -l /dev/video0 2>/dev/null || true ``` 存在相机时检查: ```bash ros2 topic list | grep -x /image_raw curl -I http://127.0.0.1:8080/ ``` ### 8.7 卸载 ```bash cd ~/project/D1_Backend sudo ./scripts/uninstall-phone-stack.sh ``` 卸载器删除 D1_Backend 安装的 units、libexec、HID udev/modules-load 和 `/etc/default/navbot-phone`,但默认保留: ```text /etc/navbot/gui_app_settings.json ``` 它不会删除 D1、模型、CAN 配置或驱动。 ## 9. 最短启动清单 前提:D1 已独立部署,机器人已吊起,急停可用。 1. 进入仓库并检查源码: ```bash cd ~/project/D1_Backend ./scripts/verify-phone-stack.sh ``` 2. 构建: ```bash ./scripts/build-phone-backend.sh ``` 3. 只读检查: ```bash sudo ./scripts/install-phone-stack.sh \ --backend-root /home/navbot/project/D1_Backend \ --d1-root /home/navbot/project/D1_rl_sar/rl_sar \ --user navbot \ --check-only ``` 4. 安装: ```bash sudo ./scripts/install-phone-stack.sh \ --backend-root /home/navbot/project/D1_Backend \ --d1-root /home/navbot/project/D1_rl_sar/rl_sar \ --user navbot ``` 5. 重新登录,确认用户组后选择启动方式: ```bash id # 仅启动当前会话: sudo systemctl start navbot-phone.target # 或启用开机自启动并立即启动: sudo systemctl enable --now navbot-phone.target ``` 6. 检查 API 与 ready: ```bash curl -fsS http://127.0.0.1:8081/api/settings systemctl --no-pager status navbot-phone-can-ready.service systemctl --no-pager status navbot-phone-ready.service ``` 7. 停止当前会话,或同时取消开机自启动: ```bash sudo systemctl stop navbot-phone.target # 如果还要取消开机自启动,改用: sudo systemctl disable --now navbot-phone.target ``` ## 10. 常见问题 ### D1 路径不存在或找不到 ROS 包 检查: ```bash ls -l ~/project/D1_rl_sar/rl_sar/install/setup.bash source /opt/ros/humble/setup.bash source ~/project/D1_rl_sar/rl_sar/install/setup.bash ros2 pkg prefix rl_sar ros2 pkg prefix dm_imu ``` D1_Backend 不负责构建 D1。先按 D1 仓库自己的流程完成部署,再重新执行 `--check-only`。 ### `/dev/ttyACM0` 不存在或权限不足 ```bash ls -l /dev/ttyACM* id journalctl -u navbot-phone-imu.service -b --no-pager ``` 确认 IMU 已连接、端口正确,运行用户属于 `dialout`。 ### `/dev/uhid` 或虚拟手柄不存在 ```bash ls -l /dev/uhid ls -l /dev/input/navbot_d1_js systemctl --no-pager status navbot-phone-hid-bridge.service journalctl -u navbot-phone-hid-bridge.service -b --no-pager ``` 确认 `uhid`、`joydev` 已加载,运行用户属于 `navbot-hid` 和 `input`。 ### 8080 或 8081 被占用 ```bash ss -ltnp | grep -E ':(8080|8081)\b' ``` 停止冲突进程后重新启动 target。不要同时运行旧后端和新手机 target。 ### preflight 报冲突进程 检查: ```bash pgrep -af 'ros_gui_backend|navbot_cmd_vel_guard|d1_hid_bridge|dm_imu_node|rl_real_d1|usb_cam_node_exe|web_video_server' ``` 确认这些进程不属于仍在使用的控制会话,再通过其原有 systemd unit 或前台终端正常停止。 ### Ready 检查失败 ```bash systemctl --no-pager --full status navbot-phone-ready.service journalctl -u navbot-phone-ready.service -b --no-pager journalctl -u 'navbot-phone-*' -b --no-pager ``` 按日志依次检查 API、HID、ROS 节点、IMU 和 `/cmd_vel` 图关系。 ### 裸 `ldd` 报 ROS 动态库 `not found` 先加载运行环境: ```bash cd ~/project/D1_Backend source /opt/ros/humble/setup.bash source ~/project/D1_rl_sar/rl_sar/install/setup.bash export LD_LIBRARY_PATH="$PWD/install/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" ldd install/bin/ros_gui_backend | grep 'not found' || true ``` systemd 启动脚本也会加载这些环境。 ### 相机失败 相机是可选组件。没有 `/dev/video0` 时主链路仍应 ready。 存在设备但服务失败时检查: ```bash ls -l /dev/video0 id systemctl --no-pager status navbot-phone-camera.service journalctl -u navbot-phone-camera.service -b --no-pager ``` 确认用户属于 `video`,并确认 8080 未占用。 ### RL 报 CAN、驱动或策略错误 ```bash systemctl --no-pager --full status navbot-phone-rl.service journalctl -u navbot-phone-rl.service -b --no-pager ``` 此类错误属于独立 D1 部署范围。D1_Backend 只等待链路级就绪,不配置或 修复 CAN、驱动和策略,必须回到 D1 仓库与硬件部署流程处理。 ### Git 意外加入 build 或 install 检查: ```bash git status --short --ignored git check-ignore -v backend/build install git ls-files backend/build install ``` 如果生成目录已经被加入索引,但希望保留本地文件: ```bash git rm -r --cached backend/build install git status --short ```