增加任务列表 mock 接口设计方案
This commit is contained in:
parent
317721d1a8
commit
4978c9ffaf
@ -1,5 +1,9 @@
|
||||
## TODO Lists
|
||||
|
||||
### [2025-10-09]
|
||||
|
||||
- [ ] (功能)模拟无人车平台,返回任务列表
|
||||
|
||||
### [2025-09-05]
|
||||
|
||||
- [x] 模拟收到进出港航班信息,访问路由接口,获取路由信息并保存处理,同时发给前端显示路由
|
||||
@ -12,7 +16,7 @@
|
||||
- [ ] 任务指定
|
||||
|
||||
- [ ] 无人车上行接口
|
||||
- [ ] 状态上报
|
||||
- [x] 状态上报
|
||||
- [ ] 视频流
|
||||
- [ ] 任务列表
|
||||
- [ ] 任务执行状态
|
||||
|
||||
40
doc/requirement/数据中台SDK问题.md
Normal file
40
doc/requirement/数据中台SDK问题.md
Normal file
@ -0,0 +1,40 @@
|
||||
# 关于SDK的要了解的几个问题
|
||||
|
||||
## webService服务器的IP地址和端口号
|
||||
这个是数据中台服务的 IP 地址和端口?问谁可以获取到?
|
||||
|
||||
## 调用路由接口需要的信息,从哪些事件获取?
|
||||
包括:
|
||||
inRunway :进港跑道编号 35
|
||||
outRunway:出港跑道编号 34
|
||||
contactCross:联络道口 F1
|
||||
seat:目的机位 138
|
||||
|
||||
文档中找到:
|
||||
【动态航班机位分配变更事件(CRAFTSEAT)】中有机位信息
|
||||
【动态航班本站到达事件(ARR)】有到达信息
|
||||
【推出开车事件(AXOT)】有进出港标志
|
||||
【跑道号分配变更事件(RUNWAY)】有进出港标志和跑道信息
|
||||
|
||||
没有找到:联络道口信息
|
||||
|
||||
## 如何接收我们需要的事件?
|
||||
receiveMessage()会接收所有的事件,还是会只返回我们需要的事件?
|
||||
业务上是否需要进行接口申请和授权的流程?
|
||||
|
||||
## 如何使用接收数据接口MessageResult receiveMessage()接口
|
||||
为了持续获取航班进出港事件,是不是需要持续调用这个接口?类似:
|
||||
|
||||
```java
|
||||
public void receiveLoop() {
|
||||
while (true) {
|
||||
Message message = receive(); // 接收消息
|
||||
|
||||
if (message != null) {
|
||||
// 用新线程处理消息
|
||||
new Thread(() -> handleMessage(message)).start();
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
807
doc/working/20250110_任务清单接口设计方案.md
Normal file
807
doc/working/20250110_任务清单接口设计方案.md
Normal file
@ -0,0 +1,807 @@
|
||||
# 任务清单接口设计方案
|
||||
|
||||
**日期**: 2025-01-10
|
||||
**版本**: v1.0
|
||||
**目标**: 为无人车平台Mock服务增加任务清单接口
|
||||
|
||||
---
|
||||
|
||||
## 📋 需求背景
|
||||
|
||||
由无人车侧的平台(mock)提供一个单独的任务清单接口,可以返回无人车所有的可执行任务。然后,我们的应用请求这个接口,选择某个任务,下发给无人车去执行。
|
||||
|
||||
**核心概念**: 任务池/任务库 - 预定义的可执行任务模板清单
|
||||
|
||||
---
|
||||
|
||||
## 🎯 接口设计
|
||||
|
||||
### 接口信息
|
||||
|
||||
- **方法**: `GET /api/v1/missions/available`
|
||||
- **认证**: Bearer Token (JWT)
|
||||
- **响应**: `application/json; charset=utf-8`
|
||||
- **功能**: 返回无人车平台的所有可执行任务清单
|
||||
|
||||
### 查询参数
|
||||
|
||||
| 参数名 | 类型 | 必填 | 描述 | 示例 |
|
||||
|--------|------|------|------|------|
|
||||
| missionType | string | 否 | 任务类型筛选 | PATROL_TRANSPORT, CARGO_TRANSPORT |
|
||||
| priority | integer | 否 | 优先级筛选 | 1-5 |
|
||||
| minBatteryLevel | integer | 否 | 最低电量要求 | 30 |
|
||||
| limit | integer | 否 | 返回数量限制 | 10 |
|
||||
| offset | integer | 否 | 分页偏移量 | 0 |
|
||||
|
||||
### 请求头
|
||||
|
||||
| Header | 必填 | 示例 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| Authorization | 是 | Bearer eyJhbGciOi... | JWT 鉴权令牌 |
|
||||
| Content-Type | 是 | application/json | 固定为 JSON |
|
||||
| Accept | 否 | application/json | 建议显式声明 |
|
||||
|
||||
---
|
||||
|
||||
## 📦 数据结构设计
|
||||
|
||||
### 任务对象 (Mission)
|
||||
|
||||
```json
|
||||
{
|
||||
"missionId": "MISSION_TEMPLATE_001",
|
||||
"missionName": "T1航站楼巡逻",
|
||||
"missionType": "PATROL_TRANSPORT",
|
||||
"description": "T1航站楼周边区域巡逻任务",
|
||||
"priority": 3,
|
||||
"estimatedDuration": 1800000,
|
||||
"totalMileage": 2500.0,
|
||||
"waypoints": [
|
||||
{
|
||||
"waypointId": "WP_001",
|
||||
"latitude": 36.354068,
|
||||
"longitude": 120.083410,
|
||||
"waypointType": "START",
|
||||
"name": "T1航站楼东侧",
|
||||
"altitude": 10.5,
|
||||
"estimatedArrivalTime": null
|
||||
},
|
||||
{
|
||||
"waypointId": "WP_002",
|
||||
"latitude": 36.355123,
|
||||
"longitude": 120.084567,
|
||||
"waypointType": "CHECKPOINT",
|
||||
"name": "巡逻检查点A",
|
||||
"altitude": 11.2,
|
||||
"estimatedArrivalTime": null
|
||||
},
|
||||
{
|
||||
"waypointId": "WP_003",
|
||||
"latitude": 36.356789,
|
||||
"longitude": 120.085234,
|
||||
"waypointType": "END",
|
||||
"name": "T1航站楼北侧",
|
||||
"altitude": 10.8,
|
||||
"estimatedArrivalTime": null
|
||||
}
|
||||
],
|
||||
"requirements": {
|
||||
"vehicleType": "UNMANNED",
|
||||
"minBatteryLevel": 30,
|
||||
"requiredSensors": ["GPS", "LIDAR", "CAMERA"],
|
||||
"weatherConditions": "CLEAR | LIGHT_RAIN"
|
||||
},
|
||||
"metadata": {
|
||||
"createdTime": 1736175000000,
|
||||
"createdBy": "system",
|
||||
"tags": ["patrol", "security", "routine"],
|
||||
"zone": "TERMINAL_1"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 字段说明
|
||||
|
||||
#### 基础信息
|
||||
- `missionId` (string): 任务唯一标识
|
||||
- `missionName` (string): 任务名称
|
||||
- `missionType` (string): 任务类型
|
||||
- `description` (string): 任务描述
|
||||
- `priority` (integer): 优先级 1-5,数字越大优先级越高
|
||||
|
||||
#### 时间和里程
|
||||
- `estimatedDuration` (integer): 预计执行时长(毫秒)
|
||||
- `totalMileage` (number): 预计总里程(米)
|
||||
|
||||
#### 路径点 (waypoints)
|
||||
- `waypointId` (string): 路径点ID
|
||||
- `latitude` (number): 纬度 (WGS84)
|
||||
- `longitude` (number): 经度 (WGS84)
|
||||
- `waypointType` (string): 路径点类型
|
||||
- `START`: 起点
|
||||
- `CHECKPOINT`: 检查点
|
||||
- `WAYPOINT`: 普通路径点
|
||||
- `END`: 终点
|
||||
- `name` (string): 路径点名称
|
||||
- `altitude` (number, 可选): 海拔高度(米)
|
||||
- `estimatedArrivalTime` (integer, 可选): 预计到达时间(毫秒,UTC)
|
||||
|
||||
#### 任务要求 (requirements)
|
||||
- `vehicleType` (string): 车辆类型要求
|
||||
- `minBatteryLevel` (integer): 最低电量要求 (0-100)
|
||||
- `requiredSensors` (array): 必需的传感器列表
|
||||
- `weatherConditions` (string): 可执行天气条件
|
||||
|
||||
#### 元数据 (metadata)
|
||||
- `createdTime` (integer): 创建时间(毫秒,UTC)
|
||||
- `createdBy` (string): 创建者
|
||||
- `tags` (array): 标签列表
|
||||
- `zone` (string): 区域标识
|
||||
|
||||
---
|
||||
|
||||
## 📡 响应格式
|
||||
|
||||
### 成功响应 (200 OK)
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "success",
|
||||
"timestamp": 1736175610000,
|
||||
"data": {
|
||||
"total": 5,
|
||||
"missions": [
|
||||
{
|
||||
"missionId": "MISSION_TEMPLATE_001",
|
||||
"missionName": "T1航站楼巡逻",
|
||||
"missionType": "PATROL_TRANSPORT",
|
||||
"description": "T1航站楼周边区域巡逻任务",
|
||||
"priority": 3,
|
||||
"estimatedDuration": 1800000,
|
||||
"totalMileage": 2500.0,
|
||||
"waypoints": [...],
|
||||
"requirements": {...},
|
||||
"metadata": {...}
|
||||
},
|
||||
{
|
||||
"missionId": "MISSION_TEMPLATE_002",
|
||||
"missionName": "货物运输-仓库A到登机口B3",
|
||||
"missionType": "CARGO_TRANSPORT",
|
||||
"priority": 4,
|
||||
"estimatedDuration": 900000,
|
||||
"totalMileage": 1200.0,
|
||||
"waypoints": [...],
|
||||
"requirements": {...},
|
||||
"metadata": {...}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 错误响应
|
||||
|
||||
#### 401 未授权
|
||||
```json
|
||||
{
|
||||
"code": 401,
|
||||
"message": "Unauthorized: Invalid or expired token",
|
||||
"timestamp": 1736175610000,
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 400 参数错误
|
||||
```json
|
||||
{
|
||||
"code": 400,
|
||||
"message": "Invalid parameter: missionType must be one of [PATROL_TRANSPORT, CARGO_TRANSPORT, PASSENGER_TRANSPORT]",
|
||||
"timestamp": 1736175610000,
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🗂️ 任务类型定义
|
||||
|
||||
### 标准任务类型
|
||||
|
||||
| 任务类型 | 代码 | 描述 |
|
||||
|---------|------|------|
|
||||
| 巡逻运输 | PATROL_TRANSPORT | 定期巡逻和安全检查 |
|
||||
| 货物运输 | CARGO_TRANSPORT | 货物运输和配送 |
|
||||
| 客运服务 | PASSENGER_TRANSPORT | 旅客运输服务 |
|
||||
| 应急响应 | EMERGENCY_RESPONSE | 应急事件响应 |
|
||||
| 维护检查 | MAINTENANCE_INSPECTION | 设施维护和检查 |
|
||||
| 清洁作业 | CLEANING_OPERATION | 清洁和环境维护 |
|
||||
|
||||
---
|
||||
|
||||
## 🔧 实现方案
|
||||
|
||||
### 1. 数据存储结构
|
||||
|
||||
在 `mock_unmanned_vehicle.py` 中定义任务池:
|
||||
|
||||
```python
|
||||
# 可执行任务清单(任务模板库)
|
||||
AVAILABLE_MISSIONS = [
|
||||
{
|
||||
"missionId": "MISSION_TEMPLATE_001",
|
||||
"missionName": "T1航站楼巡逻",
|
||||
"missionType": "PATROL_TRANSPORT",
|
||||
"description": "T1航站楼周边区域巡逻任务",
|
||||
"priority": 3,
|
||||
"estimatedDuration": 1800000,
|
||||
"totalMileage": 2500.0,
|
||||
"waypoints": [
|
||||
{
|
||||
"waypointId": "WP_T1_001",
|
||||
"latitude": 36.354068,
|
||||
"longitude": 120.083410,
|
||||
"waypointType": "START",
|
||||
"name": "T1航站楼东侧",
|
||||
"altitude": 10.5
|
||||
},
|
||||
{
|
||||
"waypointId": "WP_T1_002",
|
||||
"latitude": 36.355123,
|
||||
"longitude": 120.084567,
|
||||
"waypointType": "CHECKPOINT",
|
||||
"name": "巡逻检查点A",
|
||||
"altitude": 11.2
|
||||
},
|
||||
{
|
||||
"waypointId": "WP_T1_003",
|
||||
"latitude": 36.356789,
|
||||
"longitude": 120.085234,
|
||||
"waypointType": "END",
|
||||
"name": "T1航站楼北侧",
|
||||
"altitude": 10.8
|
||||
}
|
||||
],
|
||||
"requirements": {
|
||||
"vehicleType": "UNMANNED",
|
||||
"minBatteryLevel": 30,
|
||||
"requiredSensors": ["GPS", "LIDAR", "CAMERA"],
|
||||
"weatherConditions": "CLEAR | LIGHT_RAIN"
|
||||
},
|
||||
"metadata": {
|
||||
"createdTime": 1736175000000,
|
||||
"createdBy": "system",
|
||||
"tags": ["patrol", "security", "routine"],
|
||||
"zone": "TERMINAL_1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"missionId": "MISSION_TEMPLATE_002",
|
||||
"missionName": "货物运输-仓库A到登机口B3",
|
||||
"missionType": "CARGO_TRANSPORT",
|
||||
"description": "从货物仓库A运输至B3登机口",
|
||||
"priority": 4,
|
||||
"estimatedDuration": 900000,
|
||||
"totalMileage": 1200.0,
|
||||
"waypoints": [
|
||||
{
|
||||
"waypointId": "WP_CARGO_001",
|
||||
"latitude": 36.352000,
|
||||
"longitude": 120.082000,
|
||||
"waypointType": "START",
|
||||
"name": "货物仓库A",
|
||||
"altitude": 9.5
|
||||
},
|
||||
{
|
||||
"waypointId": "WP_CARGO_002",
|
||||
"latitude": 36.353500,
|
||||
"longitude": 120.083500,
|
||||
"waypointType": "WAYPOINT",
|
||||
"name": "运输通道中点",
|
||||
"altitude": 10.0
|
||||
},
|
||||
{
|
||||
"waypointId": "WP_CARGO_003",
|
||||
"latitude": 36.355000,
|
||||
"longitude": 120.085000,
|
||||
"waypointType": "END",
|
||||
"name": "B3登机口",
|
||||
"altitude": 10.2
|
||||
}
|
||||
],
|
||||
"requirements": {
|
||||
"vehicleType": "UNMANNED",
|
||||
"minBatteryLevel": 25,
|
||||
"requiredSensors": ["GPS", "CAMERA"],
|
||||
"weatherConditions": "CLEAR | LIGHT_RAIN | CLOUDY",
|
||||
"maxCargoWeight": 500
|
||||
},
|
||||
"metadata": {
|
||||
"createdTime": 1736175100000,
|
||||
"createdBy": "system",
|
||||
"tags": ["cargo", "logistics", "high-priority"],
|
||||
"zone": "CARGO_AREA"
|
||||
}
|
||||
},
|
||||
{
|
||||
"missionId": "MISSION_TEMPLATE_003",
|
||||
"missionName": "T2航站楼接驳",
|
||||
"missionType": "PASSENGER_TRANSPORT",
|
||||
"description": "T2航站楼旅客接驳服务",
|
||||
"priority": 5,
|
||||
"estimatedDuration": 600000,
|
||||
"totalMileage": 800.0,
|
||||
"waypoints": [
|
||||
{
|
||||
"waypointId": "WP_T2_001",
|
||||
"latitude": 36.358000,
|
||||
"longitude": 120.086000,
|
||||
"waypointType": "START",
|
||||
"name": "T2到达大厅",
|
||||
"altitude": 11.0
|
||||
},
|
||||
{
|
||||
"waypointId": "WP_T2_002",
|
||||
"latitude": 36.359000,
|
||||
"longitude": 120.087000,
|
||||
"waypointType": "END",
|
||||
"name": "T2出发大厅",
|
||||
"altitude": 11.5
|
||||
}
|
||||
],
|
||||
"requirements": {
|
||||
"vehicleType": "UNMANNED",
|
||||
"minBatteryLevel": 40,
|
||||
"requiredSensors": ["GPS", "LIDAR", "CAMERA", "ULTRASONIC"],
|
||||
"weatherConditions": "CLEAR | CLOUDY",
|
||||
"maxPassengerCount": 4
|
||||
},
|
||||
"metadata": {
|
||||
"createdTime": 1736175200000,
|
||||
"createdBy": "system",
|
||||
"tags": ["passenger", "shuttle", "high-priority"],
|
||||
"zone": "TERMINAL_2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"missionId": "MISSION_TEMPLATE_004",
|
||||
"missionName": "跑道周边应急巡查",
|
||||
"missionType": "EMERGENCY_RESPONSE",
|
||||
"description": "跑道周边区域应急巡查任务",
|
||||
"priority": 5,
|
||||
"estimatedDuration": 1200000,
|
||||
"totalMileage": 3500.0,
|
||||
"waypoints": [
|
||||
{
|
||||
"waypointId": "WP_RUNWAY_001",
|
||||
"latitude": 36.360000,
|
||||
"longitude": 120.088000,
|
||||
"waypointType": "START",
|
||||
"name": "跑道17端",
|
||||
"altitude": 8.0
|
||||
},
|
||||
{
|
||||
"waypointId": "WP_RUNWAY_002",
|
||||
"latitude": 36.365000,
|
||||
"longitude": 120.090000,
|
||||
"waypointType": "CHECKPOINT",
|
||||
"name": "跑道中段检查点",
|
||||
"altitude": 8.5
|
||||
},
|
||||
{
|
||||
"waypointId": "WP_RUNWAY_003",
|
||||
"latitude": 36.370000,
|
||||
"longitude": 120.092000,
|
||||
"waypointType": "END",
|
||||
"name": "跑道35端",
|
||||
"altitude": 9.0
|
||||
}
|
||||
],
|
||||
"requirements": {
|
||||
"vehicleType": "UNMANNED",
|
||||
"minBatteryLevel": 50,
|
||||
"requiredSensors": ["GPS", "LIDAR", "CAMERA", "THERMAL"],
|
||||
"weatherConditions": "ANY",
|
||||
"emergencyLightRequired": true
|
||||
},
|
||||
"metadata": {
|
||||
"createdTime": 1736175300000,
|
||||
"createdBy": "system",
|
||||
"tags": ["emergency", "runway", "critical"],
|
||||
"zone": "RUNWAY_AREA"
|
||||
}
|
||||
},
|
||||
{
|
||||
"missionId": "MISSION_TEMPLATE_005",
|
||||
"missionName": "停机坪维护巡检",
|
||||
"missionType": "MAINTENANCE_INSPECTION",
|
||||
"description": "停机坪设施维护巡检",
|
||||
"priority": 2,
|
||||
"estimatedDuration": 2400000,
|
||||
"totalMileage": 4200.0,
|
||||
"waypoints": [
|
||||
{
|
||||
"waypointId": "WP_APRON_001",
|
||||
"latitude": 36.351000,
|
||||
"longitude": 120.081000,
|
||||
"waypointType": "START",
|
||||
"name": "停机坪A1",
|
||||
"altitude": 10.0
|
||||
},
|
||||
{
|
||||
"waypointId": "WP_APRON_002",
|
||||
"latitude": 36.352500,
|
||||
"longitude": 120.082500,
|
||||
"waypointType": "CHECKPOINT",
|
||||
"name": "停机坪A5",
|
||||
"altitude": 10.2
|
||||
},
|
||||
{
|
||||
"waypointId": "WP_APRON_003",
|
||||
"latitude": 36.354000,
|
||||
"longitude": 120.084000,
|
||||
"waypointType": "CHECKPOINT",
|
||||
"name": "停机坪B2",
|
||||
"altitude": 10.5
|
||||
},
|
||||
{
|
||||
"waypointId": "WP_APRON_004",
|
||||
"latitude": 36.355500,
|
||||
"longitude": 120.085500,
|
||||
"waypointType": "END",
|
||||
"name": "停机坪B8",
|
||||
"altitude": 10.8
|
||||
}
|
||||
],
|
||||
"requirements": {
|
||||
"vehicleType": "UNMANNED",
|
||||
"minBatteryLevel": 35,
|
||||
"requiredSensors": ["GPS", "CAMERA", "INSPECTION_TOOLS"],
|
||||
"weatherConditions": "CLEAR | CLOUDY"
|
||||
},
|
||||
"metadata": {
|
||||
"createdTime": 1736175400000,
|
||||
"createdBy": "system",
|
||||
"tags": ["maintenance", "inspection", "routine"],
|
||||
"zone": "APRON_AREA"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
# 任务类型枚举
|
||||
MISSION_TYPES = {
|
||||
"PATROL_TRANSPORT": "巡逻运输",
|
||||
"CARGO_TRANSPORT": "货物运输",
|
||||
"PASSENGER_TRANSPORT": "客运服务",
|
||||
"EMERGENCY_RESPONSE": "应急响应",
|
||||
"MAINTENANCE_INSPECTION": "维护检查",
|
||||
"CLEANING_OPERATION": "清洁作业"
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 接口处理函数
|
||||
|
||||
```python
|
||||
@app.route('/api/v1/missions/available', methods=['GET', 'OPTIONS'])
|
||||
def get_available_missions():
|
||||
"""
|
||||
获取可执行任务清单
|
||||
|
||||
查询参数:
|
||||
- missionType: 任务类型筛选
|
||||
- priority: 优先级筛选
|
||||
- minBatteryLevel: 最低电量要求
|
||||
- limit: 返回数量限制
|
||||
- offset: 分页偏移量
|
||||
"""
|
||||
# 处理 CORS 预检请求
|
||||
if request.method == 'OPTIONS':
|
||||
return '', 200
|
||||
|
||||
try:
|
||||
# 获取查询参数
|
||||
mission_type = request.args.get('missionType')
|
||||
priority = request.args.get('priority', type=int)
|
||||
min_battery = request.args.get('minBatteryLevel', type=int)
|
||||
limit = request.args.get('limit', type=int, default=100)
|
||||
offset = request.args.get('offset', type=int, default=0)
|
||||
|
||||
# 筛选任务
|
||||
filtered_missions = AVAILABLE_MISSIONS.copy()
|
||||
|
||||
# 按任务类型筛选
|
||||
if mission_type:
|
||||
if mission_type not in MISSION_TYPES:
|
||||
return jsonify({
|
||||
"code": 400,
|
||||
"message": f"Invalid missionType. Must be one of {list(MISSION_TYPES.keys())}",
|
||||
"timestamp": int(time.time() * 1000),
|
||||
"data": None
|
||||
}), 400
|
||||
filtered_missions = [m for m in filtered_missions if m["missionType"] == mission_type]
|
||||
|
||||
# 按优先级筛选
|
||||
if priority is not None:
|
||||
if priority < 1 or priority > 5:
|
||||
return jsonify({
|
||||
"code": 400,
|
||||
"message": "Invalid priority. Must be between 1 and 5",
|
||||
"timestamp": int(time.time() * 1000),
|
||||
"data": None
|
||||
}), 400
|
||||
filtered_missions = [m for m in filtered_missions if m["priority"] == priority]
|
||||
|
||||
# 按电量要求筛选
|
||||
if min_battery is not None:
|
||||
if min_battery < 0 or min_battery > 100:
|
||||
return jsonify({
|
||||
"code": 400,
|
||||
"message": "Invalid minBatteryLevel. Must be between 0 and 100",
|
||||
"timestamp": int(time.time() * 1000),
|
||||
"data": None
|
||||
}), 400
|
||||
filtered_missions = [
|
||||
m for m in filtered_missions
|
||||
if m["requirements"]["minBatteryLevel"] <= min_battery
|
||||
]
|
||||
|
||||
# 分页处理
|
||||
total = len(filtered_missions)
|
||||
paginated_missions = filtered_missions[offset:offset + limit]
|
||||
|
||||
# 构造响应
|
||||
response = {
|
||||
"code": 200,
|
||||
"message": "success",
|
||||
"timestamp": int(time.time() * 1000),
|
||||
"data": {
|
||||
"total": total,
|
||||
"limit": limit,
|
||||
"offset": offset,
|
||||
"missions": paginated_missions
|
||||
}
|
||||
}
|
||||
|
||||
logging.info(f"返回 {len(paginated_missions)} 个可执行任务 (总数: {total})")
|
||||
return jsonify(response), 200
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"获取任务清单失败: {str(e)}")
|
||||
return jsonify({
|
||||
"code": 500,
|
||||
"message": f"Internal server error: {str(e)}",
|
||||
"timestamp": int(time.time() * 1000),
|
||||
"data": None
|
||||
}), 500
|
||||
```
|
||||
|
||||
### 3. CORS 配置
|
||||
|
||||
确保在文件中已有 CORS 配置:
|
||||
|
||||
```python
|
||||
@app.after_request
|
||||
def after_request(response):
|
||||
"""添加 CORS 头"""
|
||||
response.headers.add('Access-Control-Allow-Origin', '*')
|
||||
response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization,Accept,X-Request-Id')
|
||||
response.headers.add('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE,OPTIONS')
|
||||
return response
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧪 测试用例
|
||||
|
||||
### 1. 获取所有任务
|
||||
|
||||
```bash
|
||||
curl -X GET "http://localhost:5000/api/v1/missions/available" \
|
||||
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." \
|
||||
-H "Accept: application/json"
|
||||
```
|
||||
|
||||
### 2. 按任务类型筛选
|
||||
|
||||
```bash
|
||||
curl -X GET "http://localhost:5000/api/v1/missions/available?missionType=CARGO_TRANSPORT" \
|
||||
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." \
|
||||
-H "Accept: application/json"
|
||||
```
|
||||
|
||||
### 3. 按优先级筛选
|
||||
|
||||
```bash
|
||||
curl -X GET "http://localhost:5000/api/v1/missions/available?priority=5" \
|
||||
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." \
|
||||
-H "Accept: application/json"
|
||||
```
|
||||
|
||||
### 4. 按电量要求筛选
|
||||
|
||||
```bash
|
||||
curl -X GET "http://localhost:5000/api/v1/missions/available?minBatteryLevel=50" \
|
||||
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." \
|
||||
-H "Accept: application/json"
|
||||
```
|
||||
|
||||
### 5. 分页查询
|
||||
|
||||
```bash
|
||||
curl -X GET "http://localhost:5000/api/v1/missions/available?limit=2&offset=0" \
|
||||
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." \
|
||||
-H "Accept: application/json"
|
||||
```
|
||||
|
||||
### 6. 组合筛选
|
||||
|
||||
```bash
|
||||
curl -X GET "http://localhost:5000/api/v1/missions/available?missionType=PATROL_TRANSPORT&priority=3&limit=10" \
|
||||
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." \
|
||||
-H "Accept: application/json"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📐 实施步骤
|
||||
|
||||
### Phase 1: 基础实现 ✅
|
||||
|
||||
1. 在 `mock_unmanned_vehicle.py` 中添加任务池数据结构(约200行)
|
||||
2. 实现 `/api/v1/missions/available` 接口(约80行)
|
||||
3. 添加基本的任务类型和优先级筛选
|
||||
4. 测试接口基本功能
|
||||
|
||||
### Phase 2: 增强功能
|
||||
|
||||
1. 添加更多样化的任务模板(不同区域、不同类型)
|
||||
2. 实现高级筛选(按区域、按标签、按天气条件等)
|
||||
3. 添加任务搜索功能(按名称、描述关键字)
|
||||
4. 优化分页性能
|
||||
|
||||
### Phase 3: 集成与扩展
|
||||
|
||||
1. 与任务下发接口集成(下一步需求)
|
||||
2. 添加任务状态管理(可执行、进行中、已完成)
|
||||
3. 实现任务动态更新机制
|
||||
4. 添加任务执行统计和历史记录
|
||||
|
||||
---
|
||||
|
||||
## 🔗 与现有系统的集成
|
||||
|
||||
### 与 `/status` 接口的关系
|
||||
|
||||
- `/status` 接口:返回车辆当前正在执行的任务状态
|
||||
- `/missions/available` 接口:返回可供选择的任务清单
|
||||
|
||||
### 数据一致性
|
||||
|
||||
任务模板中的字段结构应与 `missionContext` 保持一致:
|
||||
|
||||
```python
|
||||
# 当任务被分配给车辆时,从任务模板创建任务实例
|
||||
def assign_mission_to_vehicle(vehicle_id, mission_template_id):
|
||||
template = get_mission_template(mission_template_id)
|
||||
|
||||
# 创建任务实例
|
||||
mission_instance = {
|
||||
"missionId": f"{template['missionId']}_INSTANCE_{timestamp}",
|
||||
"missionType": template["missionType"],
|
||||
"startTime": int(time.time() * 1000),
|
||||
"estimatedEndTime": int(time.time() * 1000) + template["estimatedDuration"],
|
||||
"progress": 0.0,
|
||||
"totalMileage": template["totalMileage"],
|
||||
"waypoints": [
|
||||
{**wp, "status": "PENDING"}
|
||||
for wp in template["waypoints"]
|
||||
]
|
||||
}
|
||||
|
||||
# 更新车辆数据
|
||||
vehicle_data["mission_id"] = mission_instance["missionId"]
|
||||
vehicle_data["mission_type"] = mission_instance["missionType"]
|
||||
vehicle_data["mission_start_time"] = mission_instance["startTime"]
|
||||
|
||||
return mission_instance
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 后续扩展方向
|
||||
|
||||
### 1. 任务下发接口
|
||||
|
||||
```
|
||||
POST /api/v1/vehicles/{vehicleId}/missions
|
||||
```
|
||||
|
||||
用于将选中的任务分配给指定车辆。
|
||||
|
||||
### 2. 任务管理接口
|
||||
|
||||
```
|
||||
GET /api/v1/missions/{missionId} # 获取任务详情
|
||||
PUT /api/v1/missions/{missionId} # 更新任务
|
||||
DELETE /api/v1/missions/{missionId} # 删除任务
|
||||
POST /api/v1/missions # 创建新任务模板
|
||||
```
|
||||
|
||||
### 3. 任务执行控制
|
||||
|
||||
```
|
||||
POST /api/v1/vehicles/{vehicleId}/missions/{missionId}/pause # 暂停任务
|
||||
POST /api/v1/vehicles/{vehicleId}/missions/{missionId}/resume # 恢复任务
|
||||
POST /api/v1/vehicles/{vehicleId}/missions/{missionId}/cancel # 取消任务
|
||||
```
|
||||
|
||||
### 4. 任务统计与分析
|
||||
|
||||
```
|
||||
GET /api/v1/missions/statistics # 任务统计信息
|
||||
GET /api/v1/missions/history # 任务执行历史
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✅ 验收标准
|
||||
|
||||
1. **接口可访问性**
|
||||
- [ ] 接口正常响应 200 状态码
|
||||
- [ ] 支持 CORS 跨域请求
|
||||
- [ ] JWT 认证正常工作
|
||||
|
||||
2. **数据完整性**
|
||||
- [ ] 每个任务包含所有必需字段
|
||||
- [ ] 路径点数据完整且符合规范
|
||||
- [ ] 任务类型和状态枚举值正确
|
||||
|
||||
3. **筛选功能**
|
||||
- [ ] 按任务类型筛选正常
|
||||
- [ ] 按优先级筛选正常
|
||||
- [ ] 按电量要求筛选正常
|
||||
- [ ] 多条件组合筛选正常
|
||||
|
||||
4. **分页功能**
|
||||
- [ ] limit 和 offset 参数正常工作
|
||||
- [ ] total 字段返回正确的总数
|
||||
- [ ] 边界情况处理正确
|
||||
|
||||
5. **错误处理**
|
||||
- [ ] 无效参数返回 400 错误
|
||||
- [ ] 未授权访问返回 401 错误
|
||||
- [ ] 服务器错误返回 500 错误
|
||||
- [ ] 错误消息清晰易懂
|
||||
|
||||
6. **性能要求**
|
||||
- [ ] 响应时间 < 500ms
|
||||
- [ ] 支持并发请求
|
||||
- [ ] 日志记录完整
|
||||
|
||||
---
|
||||
|
||||
## 📝 附录
|
||||
|
||||
### A. 坐标系统说明
|
||||
|
||||
所有坐标使用 **WGS84 坐标系**:
|
||||
- 纬度范围: -90 ~ 90
|
||||
- 经度范围: -180 ~ 180
|
||||
- 青岛胶东国际机场参考中心: (120.0834104, 36.35406879)
|
||||
|
||||
### B. 时间格式说明
|
||||
|
||||
所有时间戳使用 **毫秒级 UTC 时间**:
|
||||
- 格式: Unix timestamp (milliseconds)
|
||||
- 示例: 1736175610000
|
||||
- 转换: `int(time.time() * 1000)`
|
||||
|
||||
### C. 参考文档
|
||||
|
||||
- 通用无人车运行状态API: `doc/requirement/universal_autonomous_vehicle_api_min_required.md`
|
||||
- Mock服务主文件: `tools/mock_unmanned_vehicle.py`
|
||||
- 项目说明文档: `CLAUDE.md`
|
||||
|
||||
---
|
||||
|
||||
**文档结束**
|
||||
Loading…
Reference in New Issue
Block a user