# 智途投送 - 物流保障系统 使用说明

## 一、系统简介

智途投送是一套面向军事后勤保障场景的无人机物资投送管理系统（电脑端），支持：

- **任务调度** — 接收前方部队物资需求，分配无人机执行投送任务
- **无人机监控** — 实时监控无人机飞行状态、位置、电量等信息
- **士兵位置追踪** — 接收并显示前方士兵的实时位置
- **危险区域标记** — 标记无人机被摧毁等危险区域，供后续任务规避

系统通过 **rosbridge + MAVROS** 直接连接实机飞控（PX4），实现航线规划、自动起飞、巡航投送、返航降落等全流程控制。

---

## 二、环境要求

| 项目 | 要求 |
|------|------|
| 操作系统 | Windows 10/11 |
| Python | 3.8+ |
| 浏览器 | Chrome / Edge（推荐 Chromium 内核） |
| 网络 | 电脑需连接无人机的 WiFi 数传网络 |
| 无人机 | PX4 飞控 + 机载电脑运行 ROS + MAVROS + rosbridge_server |

---

## 三、启动系统

### 3.1 启动 Flask 服务器

打开终端，进入项目目录：

```bash
cd 电脑端/server
python app.py
```

启动成功后会显示：

```
==================================================
  智途投送 - 物流保障系统
  http://localhost:5000
  实机 rosbridge: ws://192.168.1.14:9090
==================================================
 * Running on http://127.0.0.1:5000
Press CTRL+C to quit
```

### 3.2 打开浏览器

在浏览器中访问 **http://localhost:5000** 即可进入系统。

### 3.3 安装 Python 依赖（如未安装）

```bash
pip install flask
```

---

## 四、功能模块详解

### 4.1 任务调度（首页）

#### 页面概览

进入系统后默认显示「任务调度」页面，包含：

- **统计卡片** — 顶部展示待处理需求数、飞行中任务数、已完成数、可用无人机数
- **待处理需求列表** — 左侧卡片，显示所有待调度物资需求
- **飞行中任务列表** — 右侧卡片，显示正在执行的任务

#### 调度任务操作

1. 在「待处理需求」列表中 **点击** 一条需求
2. 弹出调度窗口，显示任务详情：
   - 任务编号、请求士兵、物资类型、物资清单、紧急程度
   - **起点坐标**（默认为补给基地，可手动修改）
   - **终点坐标**（默认为士兵位置，可手动修改）
   - 无人机分配
3. 点击 **「确认调度」** 开始执行任务，或点击 **「拒绝」** 取消该需求
4. 调度成功后系统自动跳转到「无人机监控」页面

#### 紧急程度说明

| 标签 | 颜色 | 含义 |
|------|------|------|
| 紧急 | 红色 | 最高优先级，需立即处理 |
| 高 | 黄色 | 高优先级 |
| 一般 | 蓝色 | 普通优先级 |

---

### 4.2 无人机监控

点击左侧导航栏的 **「无人机监控」** 进入监控页面。

#### 4.2.1 连接无人机

1. 在右侧面板「连接设置」卡片中，确认 rosbridge 地址：
   - 默认地址：`ws://192.168.1.14:9090`
   - 根据实际机载电脑 IP 修改（需连接无人机 WiFi 数传网络）
2. 点击 **「连接」** 按钮
3. 连接成功后：
   - 按钮变为 **「已连接」** 并置灰
   - 左侧导航底部连接指示灯变绿
   - 操作日志显示「无人机已连接」
   - 状态栏显示电量、速度、高度、GPS 等实时数据

> **注意**：连接前请确保：
> - 电脑已连接无人机的 WiFi 数传网络
> - 机载电脑上 rosbridge_server 已启动
> - MAVROS 节点已正常运行

#### 4.2.2 地图操作

- **缩放** — 鼠标滚轮或地图右下角 +/- 按钮
- **平移** — 鼠标拖拽
- **添加航点** — 点击地图任意位置（可在调度前手动规划航线）
- **图层切换** — 地图右上角可切换显示「士兵位置」和「危险区域」图层

地图上的元素：
- **蓝色三角** — 无人机当前位置及航向
- **蓝色虚线** — 计划航线
- **红色实线** — 飞行轨迹（实时记录）
- **绿色圆点** — 士兵位置（带名字标签）
- **红色虚线圆圈** — 危险区域

#### 4.2.3 无人机信息面板

连接成功后，「无人机信息」卡片显示：

| 数据项 | 说明 |
|--------|------|
| 纬度/经度 | 当前 GPS 坐标 |
| 航向 | 飞行方向（0-360°） |
| 距目标 | 当前航点进度（如 航点 1/2） |
| 信号 | GPS 信号状态 |
| 预计到达 | 当前航段进度 |

#### 4.2.4 控制面板

| 按钮 | 功能 | 启用条件 |
|------|------|----------|
| 暂停任务 | 无人机悬停等待 | 已连接 + 任务执行中 |
| 继续任务 | 恢复巡航 | 已连接 + 任务暂停中 |
| 紧急返航 | 返回起飞点并降落 | 已连接 |
| 标记无人机被摧毁 | 在当前位置标记危险区域 | 无人机已连接 |

#### 4.2.5 操作日志

底部「操作日志」卡片记录所有系统事件，包括连接状态、任务进度、错误信息等。日志按颜色区分：

| 颜色 | 类型 |
|------|------|
| 绿色 | 成功消息 |
| 红色 | 错误消息 |
| 黄色 | 警告消息 |
| 灰色 | 一般信息 |

点击 **「清除」** 按钮可清空日志。

---

### 4.3 士兵位置追踪

系统自动每 5 秒轮询后端 API，获取前方士兵的最新位置并显示在：

- **地图** — 绿色圆点 + 士兵姓名标签
- **右侧面板「在线士兵」列表** — 显示士兵姓名和坐标

点击列表中的士兵，地图会自动平移到该士兵位置。

> **数据来源**：士兵位置由 APP 端通过 REST API 上报（见下方 API 说明）。如需测试，可通过 curl 命令模拟上报。

---

### 4.4 危险区域标记

#### 标记无人机被摧毁

1. 在无人机已连接且获取到 GPS 位置后
2. 点击控制面板的 **「标记无人机被摧毁」** 按钮
3. 系统自动在无人机最后位置标记半径 50m 的红色危险区域
4. 无人机状态变为「已摧毁」

#### 查看危险区域

- **地图** — 红色虚线圆圈 + 警告图标
- **右侧面板「危险区域」列表** — 显示描述和坐标

点击地图上的危险区域圆圈可查看详细信息。

---

## 五、REST API 接口说明

系统提供以下 REST API，供 APP 端（移动设备）或外部系统调用。

### 5.1 士兵位置上报

**请求**

```
POST /api/soldier/location
Content-Type: application/json

{
    "id": "soldier_001",
    "name": "张三",
    "lat": 30.001,
    "lng": 120.001
}
```

| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| id | string | 是 | 士兵唯一标识 |
| name | string | 否 | 士兵姓名（默认使用 id） |
| lat | float | 否 | 纬度 |
| lng | float | 否 | 经度 |

**响应**

```json
{"ok": true}
```

### 5.2 获取所有士兵位置

```
GET /api/soldiers
```

**响应**

```json
{
    "soldiers": [
        {
            "id": "soldier_001",
            "name": "张三",
            "lat": 30.001,
            "lng": 120.001,
            "updated_at": "2026-05-11 14:30:00"
        }
    ]
}
```

### 5.3 添加危险区域

**请求**

```
POST /api/danger-zones
Content-Type: application/json

{
    "lat": 30.005,
    "lng": 120.003,
    "radius": 50,
    "description": "无人机被摧毁"
}
```

| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| lat | float | 否 | 纬度 |
| lng | float | 否 | 经度 |
| radius | float | 否 | 半径（米），默认 50 |
| description | string | 否 | 描述，默认「危险区域」 |

**响应**

```json
{"ok": true, "id": 1}
```

### 5.4 获取所有危险区域

```
GET /api/danger-zones
```

**响应**

```json
{
    "danger_zones": [
        {
            "id": 1,
            "lat": 30.005,
            "lng": 120.003,
            "radius": 50,
            "description": "无人机被摧毁",
            "created_at": "2026-05-11 14:35:00"
        }
    ]
}
```

---

## 六、测试 API（使用 curl）

在系统运行状态下，可通过以下命令测试 API 功能：

### 模拟士兵位置上报

```bash
curl -X POST http://localhost:5000/api/soldier/location -H "Content-Type: application/json" -d "{\"id\":\"s1\",\"name\":\"test\",\"lat\":30.001,\"lng\":120.001}"
```

### 查询士兵列表

```bash
curl http://localhost:5000/api/soldiers
```

### 模拟添加危险区域

```bash
curl -X POST http://localhost:5000/api/danger-zones -H "Content-Type: application/json" -d "{\"lat\":30.005,\"lng\":120.003,\"radius\":50,\"description\":\"crash\"}"
```

### 查询危险区域

```bash
curl http://localhost:5000/api/danger-zones
```

---

## 七、无人机连接配置

### 7.1 系统架构

```
浏览器 (roslibjs) ──WebSocket──► rosbridge_server ──ROS话题──► MAVROS ──MAVLink──► PX4 飞控
```

### 7.2 机载电脑端准备

在无人机机载电脑（如树莓派/NVIDIA Jetson）上运行：

```bash
# 1. 启动 MAVROS（连接飞控）
roslaunch mavros px4.launch fcu_url:=/dev/ttyUSB0:921600

# 2. 启动 rosbridge_server（提供 WebSocket 接口）
roslaunch rosbridge_server rosbridge_websocket.launch

# 默认端口为 9090，即 ws://机载电脑IP:9090
```

### 7.3 网络配置

1. 机载电脑和地面电脑需在同一局域网（通常通过无人机 WiFi 数传连接）
2. 机载电脑 IP 示例：`192.168.1.14`
3. 在浏览器「连接设置」中输入 `ws://192.168.1.14:9090`

### 7.4 MAVROS 话题说明

| 话题 | 方向 | 说明 |
|------|------|------|
| /uav1/mavros/state | 订阅 | 飞控状态（模式、解锁） |
| /uav1/mavros/global_position/raw/fix | 订阅 | GPS 全球坐标 |
| /uav1/mavros/local_position/pose | 订阅 | 本地位置（ENU坐标+航向） |
| /uav1/mavros/battery | 订阅 | 电池电量 |
| /uav1/mavros/setpoint_position/local | 发布 | 位置控制设定值 |
| /uav1/mavros/set_mode | 服务 | 飞行模式切换 |
| /uav1/mavros/cmd/arming | 服务 | 解锁/上锁电机 |

> 系统会自动检测 MAVROS 命名空间（`/uav1` 或无命名空间），如检测不到 `/uav1` 会自动尝试无命名空间连接。

---

## 八、任务执行流程

```
1. 前方士兵通过 APP 提交物资需求
       ↓
2. 电脑端「任务调度」页面收到需求
       ↓
3. 操作员点击需求 → 设置航线 → 确认调度
       ↓
4. 系统上传航线至飞控 → 切换 OFFBOARD 模式 → 解锁电机 → 自动起飞
       ↓
5. 无人机沿航线巡航至投送位置
       ↓
6. 到达目标后任务完成 → 可操作返航或继续下一任务
```

### 飞行控制时序

1. **上传航线** — 将起点/终点坐标转换为 ENU 坐标系发送给飞控
2. **发送位置设定值** — 以 10Hz 频率持续发送目标位置（OFFBOARD 模式要求 ≥2Hz）
3. **切换 OFFBOARD 模式** — 最多重试 3 次
4. **解锁电机** — 最多重试 3 次
5. **起飞检测** — 检测高度是否达到目标高度，超时 15 秒后强制开始巡航
6. **巡航导航** — 逐航点飞行，每航点超时 30 秒
7. **任务完成** — 所有航点到达后悬停，可手动操作返航

---

## 九、常见问题

### Q: 连接无人机失败？

- 检查电脑是否已连接无人机的 WiFi 数传网络
- 确认机载电脑上 rosbridge_server 和 MAVROS 已启动
- 尝试在浏览器中访问 `http://机载电脑IP:9090`，应返回 rosbridge 页面
- 检查防火墙是否阻止了 WebSocket 连接

### Q: 连接成功但无遥测数据？

- 确认 MAVROS 话题命名空间正确（系统默认 `/uav1`，会自动尝试无命名空间）
- 检查飞控是否已正常启动（查看操作日志中是否显示飞控模式）
- 确认 GPS 已定位（未定位时坐标显示为默认值）

### Q: 任务调度后无人机不动？

- 确认无人机已连接且 GPS 已定位
- 检查飞控是否通过安全检查（传感器校准、GPS 定位等）
- 确认 OFFBOARD 模式切换成功（查看操作日志）
- 检查电机是否解锁成功

### Q: 士兵列表为空？

- 士兵位置由 APP 端通过 API 上报，需 APP 端运行并上报数据
- 可通过 curl 命令手动测试（见第六节）
- 前端每 5 秒自动轮询，上报后稍等即可看到

### Q: 端口 5000 被占用？

- 关闭已运行的 Flask 进程：`taskkill /F /IM python.exe`
- 或修改 `app.py` 最后一行的端口号

---

## 十、项目文件结构

```
电脑端/
├── index.html          # 主页面（导航、任务调度、无人机监控）
├── css/
│   └── style.css       # 全局样式
├── js/
│   ├── ui.js           # UI 交互逻辑（调度、士兵追踪、危险区域）
│   ├── map.js          # Leaflet 地图模块（航点、标记、航线）
│   ├── websocket.js    # MAVROS 通信模块（roslibjs 话题/服务）
│   └── roslib.min.js   # roslibjs 库（WebSocket 连接 ROS）
└── server/
    └── app.py          # Flask 服务器（静态文件 + REST API）
```
