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

89 lines
4.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Flight Intent 伴飞桥ROS 1 + MAVROS
本目录代码与语音助手 **`main.py` 独立进程**:在 **MAVROS 已连接 PX4** 的前提下,订阅一条 JSON**`FLIGHT_INTENT_SCHEMA_v1.md`** 顺序执行。
## 依赖
- Ubuntu / 设备上已装 **ROS Noetic**`mavros`(与 `scripts/run_px4_offboard_one_terminal.sh` 一致)
- Python 能 import`rospy``std_msgs``geometry_msgs``mavros_msgs`
- 本仓库根目录 **`voice_drone_assistant`** 需在 `PYTHONPATH`(启动脚本已设置)
## 启动
**推荐(不会单独敲 roslaunch 时用)**:一键拉起 roscore若尚无→ MAVROS → 伴飞桥:
```bash
cd voice_drone_assistant
bash scripts/run_flight_bridge_with_mavros.sh
bash scripts/run_flight_bridge_with_mavros.sh /dev/ttyACM0 921600
```
**已有 MAVROS 时**只启桥:
```bash
cd voice_drone_assistant
bash scripts/run_flight_intent_bridge_ros1.sh
```
默认节点名(含 anonymous 后缀):`/flight_intent_mavros_bridge_<...>`,默认订阅 **全局 `/input`**`std_msgs/String`,内容为 JSON。私有参数 `~input_topic` 可改(例如专用名时填入完整话题)。桥启动日志会打印实际订阅名。
## JSON 格式
- **完整** `flight_intent`(与云端相同顶层字段),或
- **最小**`{"actions":[...], "summary":"任意非空"}`(节点内会补 `is_flight_intent/version`
校验失败会打 `rospy.logerr`,不执行。
## 行为映射(首版)
| `type` | 行为(简述) |
|--------|----------------|
| `takeoff` | Offboard 位姿:当前点预热 setpoint → `OFFBOARD` + arm → `z0 + Δz`Δz 来自 `relative_altitude_m` 或参数 `~default_takeoff_relative_m`,与 `px4_ctrl_offboard_demo` 同号约定) |
| `hover` / `hold` | 当前位姿 hold 约 1s持续发 setpoint |
| `wait` | `rospy.Duration`Offboard 时顺带维持当前点 setpoint |
| `goto` | `local_ned` / `body_ned` 增量 → 目标 NED 点,到位容差见 `~goto_position_tolerance` |
| `land` | `AUTO.LAND` |
| `return_home` | `AUTO.RTL` |
**注意**:真机前请 SITL 验证;不同 PX4/机型的 `custom_mode` 字符串若不一致需在 `ros1_mavros_executor.py` 中调整。
## 参数(私有命名空间)
| 参数 | 默认 | 含义 |
|------|------|------|
| `~input_topic` | `/input` | 订阅话题(建议绝对路径;勿再用相对名 `input`,否则与 `/input` 对不上) |
| `~default_takeoff_relative_m` | `0.5` | `takeoff``relative_altitude_m` 时 |
| `~takeoff_timeout_sec` | `15` | |
| `~goto_position_tolerance` | `0.15` | m |
| `~goto_timeout_sec` | `60` | |
| `~land_timeout_sec` | `45` | land/rtl 等待 disarm 超时 |
| `~offboard_pre_stream_count` | `80` | 与 demo 类似 |
## 与语音程序的关系
- **`main.py`**:仍可用 Socket / 本地 offboard **演示脚本**(产品过渡期)。
- **桥**:适合作为 **长期** MAVROS 执行端;后续可把语音侧改为 **向本节点 `input` 发布 JSON**`rospy``roslibpy` 等),而不再直接起 bash demo。
## 与语音侧联调:`rostopic pub`(注意 `data:`
`std_msgs/String` 的 YAML 只有字段 **`data`**JSON 必须写在 **`data: '...'`** 里;不能把 JSON 直接当消息顶层(否则会 `ERROR: No field name [is_flight_intent]` / `Args are: [data]`)。
终端 A已跑 `run_flight_bridge_with_mavros.sh`(或 MAVROS + 桥)。
终端 B
```bash
source /opt/ros/noetic/setup.bash
# 订阅名以桥日志为准,常见为全局 /input
rostopic pub -1 /input std_msgs/String \
"data: '{\"is_flight_intent\":true,\"version\":1,\"actions\":[{\"type\":\"land\",\"args\":{}}],\"summary\":\"联调降落\"}'"
```
**悬停 2 秒再降**(须已在空中时再试):
```bash
rostopic pub -1 /input std_msgs/String \
"data: '{\"is_flight_intent\":true,\"version\":1,\"actions\":[{\"type\":\"hover\",\"args\":{}},{\"type\":\"wait\",\"args\":{\"seconds\":2}},{\"type\":\"land\",\"args\":{}}],\"summary\":\"测\"}'"
```
在语音进程内集成时,建议 **不要在 asyncio 里直接调 rospy**,用 **独立桥进程 + topic****UNIX socket 转发到桥**