# 换机器人接口文档 本文档描述了VWED系统换机器人功能的API接口,用于在任务执行过程中动态更换执行机器人。 ## 基础信息 - 基础路径:`/api/vwed-task-record` - 接口标签:`VWED任务运行记录` - 版本:v1.0 ## 功能概述 换机器人功能允许在任务执行过程中更换执行机器人,主要用于以下场景: 1. **机器人故障**:当前执行机器人出现硬件或软件故障 2. **电量不足**:当前机器人电量过低,需要更换到电量充足的机器人 3. **性能优化**:根据实际情况选择更合适的机器人执行任务 4. **负载均衡**:优化机器人资源分配,提高系统整体效率 该功能支持两种场景: - **未载货场景**:机器人尚未携带货物,从原任务中自动提取参数 - **已载货场景**:机器人已经携带货物,需要指定目标库位和执行动作 ## 接口清单 | 序号 | 接口名称 | 接口路径 | 请求方式 | 接口描述 | | --- | --- | --- | --- | --- | | 1 | 换机器人 | `/switch-robot/{task_record_id}` | POST | 动态更换任务执行机器人 | --- ## 接口详情 ### 1. 换机器人 #### 接口说明 在任务执行过程中动态更换执行机器人。系统会终止当前任务的所有待执行块,动态添加新的任务块(选择机器人 → 获取库位 → 执行通用动作),并通过调度器实时生效,保持任务连续运行。 **核心特性**: - ✅ 支持未载货和已载货两种场景 - ✅ 智能参数提取(未载货时从原任务自动提取) - ✅ 实时生效(无需重启任务) - ✅ 保持任务ID不变 - ✅ 完整的操作日志记录 #### 请求路径 ``` POST /api/vwed-task-record/switch-robot/{task_record_id} ``` #### 路径参数 | 参数名 | 类型 | 是否必须 | 描述 | | --- | --- | --- | --- | | task_record_id | string | 是 | 任务记录ID,必须是正在运行中的任务 | #### 请求头 | 参数名 | 类型 | 是否必须 | 描述 | | --- | --- | --- | --- | | Content-Type | string | 是 | application/json | | x-access-token | string | 否 | 系统任务令牌,用于主系统认证 | #### 请求体参数 | 参数名 | 类型 | 是否必须 | 描述 | | --- | --- | --- | --- | | robot_name | string | 否 | 机器人名称(如:AGV_001) | | robot_group | string | 否 | 机器人组(如:group_A) | | robot_label_group | string | 否 | 机器人标签组(如:label_1) | | switch_reason | string | 是 | 更换原因(如:机器人电量不足、机器人故障等) | | has_cargo | boolean | 是 | 是否载货,true-已载货,false-未载货 | | site_id | string | 条件必填 | 库位ID(已载货时必填,如:AP540) | | action | string | 条件必填 | 执行动作(已载货时必填,如:pick、drop) | **参数说明**: - `robot_name`、`robot_group`、`robot_label_group` 至少提供一个,用于选择新的机器人 - 当 `has_cargo=true` 时,`site_id` 和 `action` 为必填项 - 当 `has_cargo=false` 时,系统会从原任务定义中自动提取 `site_id` 和 `action` #### 响应结果 **成功响应**: ```json { "code": 200, "message": "换机器人成功(未载货场景)", "data": { "task_record_id": "550e8400-e29b-41d4-a716-446655440000", "switch_reason": "机器人AGV_001电量不足", "has_cargo": false, "robot_name": "AGV_002", "robot_group": "group_A", "robot_label_group": "label_1", "site_id": "AP154", "action": "pick", "key_route": "LM532", "added_blocks": 1 } } ``` **失败响应**: 1. 任务记录不存在: ```json { "code": 404, "message": "未找到任务记录 {task_record_id}" } ``` 2. 任务状态错误: ```json { "code": 400, "message": "任务状态为 {status},只能对运行中的任务换机器人" } ``` 3. 任务定义格式错误: ```json { "code": 400, "message": "任务定义格式不正确" } ``` 4. 已载货场景参数不足: ```json { "code": 400, "message": "已载货场景需要提供库位ID和执行动作" } ``` 5. 系统异常: ```json { "code": 500, "message": "换机器人失败: {错误详情}" } ``` #### 响应字段说明 | 字段名 | 类型 | 描述 | | --- | --- | --- | | task_record_id | string | 任务记录ID | | switch_reason | string | 更换原因 | | has_cargo | boolean | 是否载货 | | robot_name | string | 新机器人名称 | | robot_group | string | 新机器人组 | | robot_label_group | string | 新机器人标签组 | | site_id | string | 目标库位ID | | action | string | 执行动作(pick/drop/其他) | | key_route | string | 关键路径(从原任务提取或使用site_id) | | added_blocks | integer | 添加的新任务块数量(固定为1,包含3个子块) | --- ## 使用场景和示例 ### 场景1:未载货 - 机器人电量不足 **业务场景**: 机器人AGV_001正在前往取货点的途中,尚未取货,系统检测到其电量不足,需要更换为电量充足的AGV_002继续执行任务。 **请求示例**: ```bash curl -X POST "http://localhost:8000/api/vwed-task-record/switch-robot/550e8400-e29b-41d4-a716-446655440000" \ -H "Content-Type: application/json" \ -H "x-access-token: your-token-here" \ -d '{ "robot_name": "AGV_002", "robot_group": "group_A", "robot_label_group": "label_1", "switch_reason": "机器人AGV_001电量不足,更换为AGV_002", "has_cargo": false }' ``` **响应示例**: ```json { "code": 200, "message": "换机器人成功(未载货场景)", "data": { "task_record_id": "550e8400-e29b-41d4-a716-446655440000", "switch_reason": "机器人AGV_001电量不足,更换为AGV_002", "has_cargo": false, "robot_name": "AGV_002", "robot_group": "group_A", "robot_label_group": "label_1", "site_id": "AP154", "action": "pick", "key_route": "LM532", "added_blocks": 1 } } ``` **系统行为**: 1. 终止当前任务的所有待执行块 2. 从原任务定义中自动提取: - `site_id`: "AP154"(目标取货点) - `action`: "pick"(取货动作) - `key_route`: "LM532"(关键路径) 3. 添加3个新任务块: - 选择机器人块:选择AGV_002 - 获取库位块:获取AP154库位信息 - 执行通用动作块:执行pick动作 4. 更新任务定义并通过调度器实时生效 5. AGV_002继续执行原任务的剩余步骤 --- ### 场景2:已载货 - 机器人故障需要转运 **业务场景**: 机器人AGV_001已经在AP154取货,正在前往目标放货点AP540的途中发生故障。需要将货物转运到临时库位AP300,然后更换为AGV_003继续执行任务。 **请求示例**: ```bash curl -X POST "http://localhost:8000/api/vwed-task-record/switch-robot/550e8400-e29b-41d4-a716-446655440000" \ -H "Content-Type: application/json" \ -H "x-access-token: your-token-here" \ -d '{ "robot_name": "AGV_003", "robot_group": "group_B", "switch_reason": "机器人AGV_001故障,货物转运至AP300后更换为AGV_003", "has_cargo": true, "site_id": "AP300", "action": "drop" }' ``` **响应示例**: ```json { "code": 200, "message": "换机器人成功(已载货场景)", "data": { "task_record_id": "550e8400-e29b-41d4-a716-446655440000", "switch_reason": "机器人AGV_001故障,货物转运至AP300后更换为AGV_003", "has_cargo": true, "robot_name": "AGV_003", "robot_group": "group_B", "robot_label_group": null, "site_id": "AP300", "action": "drop", "key_route": "LM532", "added_blocks": 1 } } ``` **系统行为**: 1. 终止当前任务的所有待执行块 2. 使用请求参数: - `site_id`: "AP300"(临时转运点) - `action`: "drop"(放货动作) 3. 添加3个新任务块: - 选择机器人块:选择AGV_003 - 获取库位块:获取AP300库位信息 - 执行通用动作块:执行drop动作 4. 更新任务定义并通过调度器实时生效 5. AGV_001将货物放到AP300后,AGV_003接管任务继续执行 --- ## 技术实现说明 ### 处理流程 ``` 1. 接收换机器人请求 ↓ 2. 验证任务状态(必须是RUNNING) ↓ 3. 解析任务定义 ↓ 4. 终止调度器中的当前任务 ↓ 5. 终止所有待执行的任务块 ↓ 6. 提取或使用参数 ├─ 未载货:从原任务提取 keyRoute, targetSiteLabel, action └─ 已载货:使用请求参数 site_id, action ↓ 7. 构建3个新任务块 ├─ CSelectAgvBp:选择机器人块 ├─ GetIdleSiteBp:获取库位块 └─ CAgvOperationBp:执行通用动作块 ↓ 8. 更新任务定义(追加新块到rootBlock) ↓ 9. 更新数据库(task_def_detail, ended_reason) ↓ 10. 通知调度器更新任务定义(实时生效) ↓ 11. 返回换机器人结果 ``` ### 核心数据结构 **添加的任务块结构**: ```json { "id": "new_block_id_1", "name": "switch_robot_xxx", "blockType": "CSelectAgvBp", "label": "选择执行机器人(换机器人)", "description": "换机器人: {switch_reason}", "inputParams": { "vehicle": {"value": "AGV_002", "type": "Simple", "required": false}, "group": {"value": "group_A", "type": "Simple", "required": false}, "label_group": {"value": "label_1", "type": "Simple", "required": false}, "keyRoute": {"value": "LM532", "type": "Simple", "required": true} }, "children": { "default": [ { "id": "new_block_id_2", "name": "get_site_xxx", "blockType": "GetIdleSiteBp", "label": "获取库位(换机器人)", "inputParams": { "siteId": {"value": "AP154", "type": "Simple", "required": false}, "locked": {"value": false, "type": "Simple", "required": true}, "lock": {"value": true, "type": "Simple", "required": false} }, "children": {} }, { "id": "new_block_id_3", "name": "action_xxx", "blockType": "CAgvOperationBp", "label": "机器人通用动作(换机器人)", "inputParams": { "targetSiteLabel": {"value": "AP154", "type": "Simple", "required": true}, "task": {"value": "pick", "type": "Simple", "required": false}, "spin": {"value": "", "type": "Simple", "required": false} }, "children": {} } ] } } ``` ### 数据库变更 **任务记录表(vwed_taskrecord)**: - `task_def_detail`:更新为包含新任务块的定义 - `ended_reason`:记录换机器人原因,格式:`换机器人(未载货/已载货): {switch_reason}` **任务块记录表(vwed_blockrecord)**: - 所有未完成的块: - `status`:更新为 2002(CANCEL) - `ended_on`:记录终止时间 - `ended_reason`:记录终止原因,格式:`换机器人终止: {switch_reason}` --- ## 注意事项和最佳实践 ### 使用限制 1. **任务状态要求**: - 只能对状态为 `RUNNING`(1001)的任务执行换机器人操作 - 已完成、失败、取消的任务无法换机器人 2. **参数要求**: - 至少提供一个机器人选择参数(robot_name、robot_group、robot_label_group) - 已载货场景必须提供 site_id 和 action 3. **并发控制**: - 同一任务不应同时执行多次换机器人操作 - 建议在调用前检查任务当前状态 ### 最佳实践 1. **参数选择**: - 优先使用 `robot_name` 指定具体机器人 - 使用 `robot_group` 让系统从组中自动选择 - 使用 `robot_label_group` 基于标签筛选机器人 2. **未载货场景**: - 系统会自动从原任务中提取参数,无需手动指定 site_id 和 action - 适用于机器人尚未开始实际操作的情况 3. **已载货场景**: - 必须明确指定目标库位和动作 - 建议先将货物放到临时库位,再更换机器人继续后续任务 - action 常用值:`pick`(取货)、`drop`(放货) 4. **错误处理**: - 换机器人失败时,原任务会保持原状态 - 建议实现重试机制 - 记录详细的换机器人日志用于问题追溯 5. **监控和日志**: - 通过 `ended_reason` 字段追踪换机器人历史 - 通过任务块记录查看被终止的块 - 建议在业务系统中记录换机器人操作日志 --- ## 错误码说明 | 错误码 | 错误信息 | 说明 | 解决方案 | | --- | --- | --- | --- | | 404 | 未找到任务记录 | 任务记录ID不存在 | 检查任务记录ID是否正确 | | 400 | 只能对运行中的任务换机器人 | 任务状态不是RUNNING | 确认任务正在运行中 | | 400 | 任务定义解析失败 | 任务定义JSON格式错误 | 检查任务定义数据完整性 | | 400 | 任务定义格式不正确 | 缺少必要的定义字段 | 确保任务定义包含detail和rootBlock | | 400 | 已载货场景需要提供库位ID和执行动作 | 已载货时缺少site_id或action | 补充完整的请求参数 | | 500 | 换机器人失败 | 系统内部错误 | 查看详细错误日志,联系技术支持 | --- ## 相关接口 - [获取任务记录详情](./任务记录接口文档.md#5-获取任务记录详情):查看换机器人后的任务状态 - [获取任务块运行记录](./任务记录接口文档.md#1-获取任务块运行记录):查看被终止的块和新添加的块 - [获取任务执行结果](./任务记录接口文档.md#4-获取任务执行结果):查看完整的任务执行历史 - [终止任务](./任务记录接口文档.md#3-终止任务):如果换机器人失败,可以终止任务 --- ## 更新日志 | 版本 | 日期 | 更新内容 | 作者 | | --- | --- | --- | --- | | v1.0 | 2025-10-09 | 初始版本,支持未载货和已载货两种场景 | Claude | --- ## 技术支持 如有问题,请联系: - 技术文档:[VWED任务模块接口文档](./README.md) - 问题反馈:提交Issue到项目仓库