DroneMind/voice_drone_assistant/docs/DEPLOYMENT_AND_OPERATIONS.md
2026-04-14 09:59:51 +08:00

13 KiB
Raw Permalink Blame History

部署与运维手册(项目总结)

本文面向 生产/外场部署:说明 voice_drone_assistant 是什么、与 云端 / ROS 伴飞桥 / PX4 如何衔接,以及 推荐启动顺序环境变量常见问题
协议细节见 llmcon.md,通用配置索引见 PROJECT_GUIDE.md,伴飞桥行为见 FLIGHT_BRIDGE_ROS1.mdflight_intent 字段见 FLIGHT_INTENT_SCHEMA_v1.md


1. 项目总结

1.1 定位

voice_drone_assistant 是板端 语音无人机助手:麦克风 → 降噪/VAD → SenseVoice STT唤醒词 → 用户一句指令 → 云端 WebSocketLLM + TTS本地 Qwen + Kokoro → 若服务端返回 flight_intent,可在本机 校验后执行TCP Socket 旧路径,或 ROS 伴飞桥 推荐路径)。

1.2 推荐数据流(方案一:云 → 语音程序 → ROS 桥)

flowchart LR
  subgraph cloud [云端]
    WS[WebSocket LLM+TTS]
  end
  subgraph board [机载 香橙派等]
    MIC[麦克风]
    MAIN[main.py TakeoffPrintRecognizer]
    ROSPUB[子进程 publish JSON]
    BRIDGE[flight_bridge ros1_node]
    MAV[MAVROS]
  end
  FCU[PX4 飞控]

  MIC --> MAIN
  MAIN <-->|WSS pcm_asr_uplink + flight_intent| WS
  MAIN -->|ROCKET_FLIGHT_INTENT_ROS_BRIDGE| ROSPUB
  ROSPUB -->|std_msgs/String /input| BRIDGE
  BRIDGE --> MAV --> FCU
  • 把 ROS 直接暴露给公网:云端只连板子的 WSS/WS;飞控由 本机 MAVROS + 伴飞桥 执行。
  • TCP Socketsystem.yamlsocket_server)是另一条试飞控通道,与云端 无关;未起 Socket 服务端时仅会重连日志,不影响 ROS 方案。

1.3 目录与核心入口(仓库根 = voice_drone_assistant/

路径 说明
main.py 语音助手入口
with_system_alsa.sh 建议包装启动,修正 Conda 与系统 ALSA
voice_drone/main_app.py 唤醒、云端/本地 LLM、TTS、flight_intent 执行策略
voice_drone/flight_bridge/ros1_node.py ROS1 订阅 /input,执行 flight_intent
voice_drone/flight_bridge/ros1_mavros_executor.py MAVROSoffboard / AUTO.LAND / RTL
voice_drone/tools/publish_flight_intent_ros_once.py 单次向 ROS 发布 JSON主程序 ROS 桥会子进程调用)
scripts/run_flight_bridge_with_mavros.sh 一键roscore可选+ MAVROS + 伴飞桥
scripts/run_flight_intent_bridge_ros1.sh 仅伴飞桥(须已有 roscore + MAVROS
voice_drone/config/system.yaml 音频、STT、TTS、云端、assistant
requirements.txt Python 依赖;rospy 来自 apt 的 ROS Noetic见文件内注释

2. 环境与依赖

2.1 硬件与系统(典型)

  • ARM64 板卡(如 RK3588、ES8388 等音频编解码器、USB/内置麦克风。
  • Ubuntu 20.04 + ROS Noetic(伴飞桥 / MAVROS 路径);同机运行语音进程与 ros1_node
  • 飞控串口(如 /dev/ttyACM0)与 MAVROS fcu_url 一致。

2.2 Python

  • Python 3.10+(与原仓库一致即可)。

  • voice_drone_assistant 根目录:

    pip install -r requirements.txt
    

2.3 ROS / MAVROS伴飞桥方案必选

sudo apt install ros-noetic-ros-base ros-noetic-mavros ros-noetic-mavros-extras
# 按官方文档执行 mavros 地理库安装(如有)
  • 语音主程序的 ROS 桥子进程会 source /opt/ros/noetic/setup.bashprepend PYTHONPATH不要在未 source ROS 的 shell 里把 PYTHONPATH 设成「只有工程根」,否则会找不到 rospy(参见 main_app_publish_flight_intent_to_ros_bridge)。

2.4 模型与权重

  • STT / TTS /可选VAD 放入 models/,或 bash scripts/bundle_for_device.sh 从原仓库打包。
  • 本地 LLMGGUF 默认路径或 ROCKET_LLM_GGUF纯云端对话时可弱化本地模型,但回退/混合模式仍需。

3. 部署拓扑

3.1 单机一体化(常见)

同一台香橙派上同时运行:

  1. roscore(若尚无 masterrun_flight_bridge_with_mavros.sh 拉起)。
  2. MAVROSpx4.launch,串口连 PX4
  3. 伴飞桥 python3 -m voice_drone.flight_bridge.ros1_node(订阅 /input)。
  4. 语音 bash with_system_alsa.sh python main.py

ROS_MASTER_URI / ROS_HOSTNAME:一键脚本内默认 http://127.0.0.1:11311127.0.0.1新开调试终端 执行 rostopic/rosservice 前须自行 source /opt/ros/noetic/setup.bash 并 export 同一 ROS_MASTER_URI(见下文「常见问题」)。

3.2 网络

  • 板子能访问 云端 WebSocketROCKET_CLOUD_WS_URL)。
  • PX4 + 遥控 + 安全开关等按外场规范配置;本文不替代安全检校清单。

4. 启动顺序(推荐)

4.1 终端 A飞控栈 + 伴飞桥

voice_drone_assistant 根目录:

cd /path/to/voice_drone_assistant
bash scripts/run_flight_bridge_with_mavros.sh /dev/ttyACM0 921600

脚本会:

  • 设置 ROS_MASTER_URIROS_HOSTNAME(未预设时默认为本机 master
  • 如无 master 则启动 roscore
  • 启动 MAVROS 并等待 /mavros/state connected
  • 前台启动伴飞桥,日志中应出现:flight_intent_bridge 就绪:订阅 /input

仅桥(已有 MAVROS 时)

source /opt/ros/noetic/setup.bash
export ROS_MASTER_URI="${ROS_MASTER_URI:-http://127.0.0.1:11311}"
export ROS_HOSTNAME="${ROS_HOSTNAME:-127.0.0.1}"
bash scripts/run_flight_intent_bridge_ros1.sh

4.2 终端 B语音助手 + 云端 + 执行飞控

cd /path/to/voice_drone_assistant

export ROCKET_CLOUD_VOICE=1
export ROCKET_CLOUD_WS_URL='ws://<云主机>:8766/v1/voice/session'
export ROCKET_CLOUD_AUTH_TOKEN='<token>'
export ROCKET_CLOUD_DEVICE_ID='drone-001'   # 可选

# 云端返回 flight_intent 时是否在机端执行
export ROCKET_CLOUD_EXECUTE_FLIGHT=1
# 走 ROS 伴飞桥(与 Socket/offboard 序列互斥,勿双开重复执行)
export ROCKET_FLIGHT_INTENT_ROS_BRIDGE=1
# 可选ROCKET_FLIGHT_BRIDGE_TOPIC=/input  ROCKET_FLIGHT_BRIDGE_WAIT_SUB=2

# 默认关闭本地「起飞演示」口令直起 offboard需要时再设为 1
# export ROCKET_LOCAL_KEYWORD_TAKEOFF=1

bash with_system_alsa.sh python main.py

成功时日志类似:[飞控-ROS桥] 已发布至 /input;伴飞桥端出现 执行 flight_intentsteps=...

4.3 配置写进 YAML可选

  • 云端:system.yamlcloud_voiceenabledserver_urlauth_token 等)。
  • 本地口令起飞:assistant.local_keyword_takeoff_enabled(默认 false);环境变量 ROCKET_LOCAL_KEYWORD_TAKEOFF 非空时优先生效

5. 环境变量速查(飞控与云端)

变量 含义
ROCKET_CLOUD_VOICE 1:对话走云端 WebSocket
ROCKET_CLOUD_WS_URL 云端会话地址
ROCKET_CLOUD_AUTH_TOKEN WS 鉴权
ROCKET_CLOUD_DEVICE_ID 设备 ID可选
ROCKET_CLOUD_EXECUTE_FLIGHT 1:云端 flight_intent 在机端执行
ROCKET_FLIGHT_INTENT_ROS_BRIDGE 1:执行方式为 发布到 ROS /input,不跑机内 Socket+offboard 序列
ROCKET_FLIGHT_BRIDGE_TOPIC 默认 /input
ROCKET_FLIGHT_BRIDGE_SETUP 子进程内 source ROS 的命令,默认 source /opt/ros/noetic/setup.bash
ROCKET_FLIGHT_BRIDGE_WAIT_SUB 发布前等待订阅者的秒数,默认 20 即尽可能快发
ROCKET_LOCAL_KEYWORD_TAKEOFF 非空时:1/true/yes 开启 keywords.yaml takeoff → 本地 offboard
ROCKET_CLOUD_PX4_CONTEXT_FILE 覆盖 cloud_voice.px4_context_file,合并进 session.start

更多调试变量见 voice_drone/main_app.py 文件头注释PROJECT_GUIDE.md 第 5 节。


6. 联调与自测

6.1 仅测 ROS 链(无语音)

终端已 source /opt/ros/noetic/setup.bash 且与 master 一致:

rostopic pub -1 /input std_msgs/String \
  "data: '{\"is_flight_intent\":true,\"version\":1,\"actions\":[{\"type\":\"land\",\"args\":{}}],\"summary\":\"测\"}'"

注意:std_msgs/String 在命令行里只能写 data: '...json...',不能把 JSON 放在消息顶层。

6.2 确认话题与 master

source /opt/ros/noetic/setup.bash
export ROS_MASTER_URI=http://127.0.0.1:11311
rosnode list
rostopic info /input
rosservice list | grep set_mode

Unable to communicate with master!:当前 shell 未连上正在运行的 roscore(或未 export 正确 ROS_MASTER_URI)。


7. 常见问题(摘录)

现象 可能原因 处理
ModuleNotFoundError: rospy 子进程未继承 ROS 的 PYTHONPATH 已修复为 PYTHONPATH=<根>:$PYTHONPATH;确保 ROCKET_FLIGHT_BRIDGE_SETUP 能 source Noetic
语音端「已发布」但桥无日志 曾用相对 input,与全局 /input 不一致 伴飞桥默认已改为订阅 /input;重启桥
set_mode unavailable / land 失败 OFFBOARD 断流、MAVROS 异常等 伴飞桥降落逻辑已带持续 setpoint + 重连 proxy仍失败则查 rosservice/mavros/state、链路
takeoff 超时 未进 OFFBOARD、未解锁、定位未就绪 查地面站、/mavros/state、适当增大 ~takeoff_timeout_secROS 私有参数)
ALSA underrun 播放与采集竞争 板端常见;可调缓冲区/设备或 recognizer.ack_pause_mic_for_playback

8. 安全与运维建议

  • 外场前在 SITL 或系留 环境验证完整 flight_intent 序列。
  • 云端 token、WS URL 勿提交到公开仓库;用环境变量或本机 overlay 配置注入。
  • 升级伴飞桥或 MAVROS 后清日志重试一遍 /input 手发 JSON。

9. 迁移到另一台香橙派:是否只拷贝 voice_drone_assistant 即可?

结论:目录是「代码 + 配置」的核心载体,但仅靠「整文件夹 scp 过去」通常不够新板必须再装系统级依赖、模型与可选ROS并按现场改配置。

9.1 拷贝目录本身会带上什么

已包含 说明
全部 Python 源码、voice_drone/config/*.yaml 默认配置 可直接改 YAML / 环境变量适配新环境
scripts/with_system_alsa.shdocs/ 启动与说明在包内

9.2 新板必须单独准备(不随目录自动存在)

说明
Ubuntu + 音频/ALSA 与当前开发板同代或自行适配;录音设备索引可能变化,需重选或设 ROCKET_INPUT_DEVICE_INDEX
pip install -r requirements.txt 每台新 Python 环境执行一次(或整体迁移同一 conda 目录)
models/ STT/TTS/VAD 体积大,务必在本机先 bash scripts/bundle_for_device.sh /path/to/rocket_drone_audio 或手工拷入,见 models/README.txt
cache/ GGUF 纯云端可不强依赖;若需本地 Qwen 回退,拷贝或设 ROCKET_LLM_GGUF
ROS Noetic + MAVROS apt 安装;伴飞桥方案 必选rospy 不要指望只靠 pip
云端连通 新板 IP/防火墙能访问 ROCKET_CLOUD_WS_URLtoken 用环境变量注入
dialout 等权限 访问 /dev/ttyACM0 的用户加入 dialout,否则 MAVROS 无串口
system.yaml 现场差异 socket_server IP、可选 tts.output_device、若麦索引固定可写 audio.input_device_index

9.3 推荐迁移流程(简表)

  1. 在旧机或 CIbundle 模型 → 打包整个 voice_drone_assistant(含 models/,按需含 cache/)。
  2. 新香橙派:解压到任意路径,安装 requirements.txtROS+MAVROS、系统音频工具。
  3. with_system_alsa.sh python main.py 试麦与 STT再按本文 §4 双终端起 桥 + 语音
  4. 首次外场前做一次 rostopic pub /input 手发 JSON§6)。

9.4 常见误区

  • 只拉 Git、不拷 models/STT/TTS 启动即失败。
  • 新板 Noetic 未装却开 ROCKET_FLIGHT_INTENT_ROS_BRIDGE:发布子进程仍可能报错。
  • 假设麦克风设备号一定相同Orange Pi 刷机或换内核后常变,以首次启动日志为准。

10. 文档索引

文档 用途
README.md 仓库简介、模型、bundle
PROJECT_GUIDE.md 配置项与日常用法索引
本文 部署拓扑、启动顺序、环境变量、联调、§9 迁移清单
FLIGHT_BRIDGE_ROS1.md 伴飞桥参数、PX4 行为、rostopic pub 注意
FLIGHT_INTENT_SCHEMA_v1.md JSON 协议
llmcon.md 云端协议
CLOUD_VOICE_FLIGHT_CONFIRM_v1.md 飞控口头二次确认(闲聊不变、确认/取消/超时)云端与机端字段约定

文档版本与仓库同步;若行为与代码不一致,以当前 main_app.pyflight_bridge/*.py 为准。