Compare commits
4 Commits
87d691f927
...
707baaefb0
| Author | SHA1 | Date | |
|---|---|---|---|
| 707baaefb0 | |||
| 0f36d8b4d1 | |||
| db17d50ef6 | |||
| 6d39c4296e |
@ -112,7 +112,7 @@ public class InspectionRobotController extends BaseController
|
|||||||
@ApiOperation("获取机器人地图列表")
|
@ApiOperation("获取机器人地图列表")
|
||||||
@PreAuthorize("@ss.hasPermi('inspection:robot:query')")
|
@PreAuthorize("@ss.hasPermi('inspection:robot:query')")
|
||||||
@GetMapping("/{robotId}/maps")
|
@GetMapping("/{robotId}/maps")
|
||||||
public AjaxResult getRobotMapList(@PathVariable("robotId") String robotId)
|
public AjaxResult getRobotMapList(@PathVariable String robotId)
|
||||||
{
|
{
|
||||||
AgvCommand.AgvMapStatus robotMapList = inspectionRobotService.getRobotMapList(robotId);
|
AgvCommand.AgvMapStatus robotMapList = inspectionRobotService.getRobotMapList(robotId);
|
||||||
return success(robotMapList.getMapsList());
|
return success(robotMapList.getMapsList());
|
||||||
@ -125,26 +125,12 @@ public class InspectionRobotController extends BaseController
|
|||||||
@PreAuthorize("@ss.hasPermi('inspection:robot:edit')")
|
@PreAuthorize("@ss.hasPermi('inspection:robot:edit')")
|
||||||
@Log(title = "绑定机器人地图", businessType = BusinessType.UPDATE)
|
@Log(title = "绑定机器人地图", businessType = BusinessType.UPDATE)
|
||||||
@PostMapping("/{robotId}/bind-map/{mapId}")
|
@PostMapping("/{robotId}/bind-map/{mapId}")
|
||||||
public AjaxResult bindRobotMap(@PathVariable("robotId") String robotId,
|
public AjaxResult bindRobotMap(@PathVariable String robotId,
|
||||||
@PathVariable("mapId") String mapId)
|
@PathVariable String mapId)
|
||||||
{
|
{
|
||||||
return toAjax(inspectionRobotService.bindRobotMap(robotId, mapId));
|
return toAjax(inspectionRobotService.bindRobotMap(robotId, mapId));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 上传地图到机器人
|
|
||||||
*/
|
|
||||||
@ApiOperation("上传地图到机器人")
|
|
||||||
@PreAuthorize("@ss.hasPermi('inspection:robot:edit')")
|
|
||||||
@Log(title = "上传地图到机器人", businessType = BusinessType.OTHER)
|
|
||||||
@PostMapping("/{robotId}/upload-map/{mapId}")
|
|
||||||
public AjaxResult uploadMapToRobot(@PathVariable("robotId") String robotId,
|
|
||||||
@PathVariable("mapId") String mapId)
|
|
||||||
{
|
|
||||||
String result = inspectionRobotService.uploadMapToRobot(robotId, mapId);
|
|
||||||
return success(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从机器人下载地图
|
* 从机器人下载地图
|
||||||
*/
|
*/
|
||||||
@ -153,7 +139,7 @@ public class InspectionRobotController extends BaseController
|
|||||||
@Log(title = "从机器人下载地图", businessType = BusinessType.INSERT)
|
@Log(title = "从机器人下载地图", businessType = BusinessType.INSERT)
|
||||||
@GetMapping("/{robotId}/download-map")
|
@GetMapping("/{robotId}/download-map")
|
||||||
public AjaxResult downloadMapFromRobot(
|
public AjaxResult downloadMapFromRobot(
|
||||||
@PathVariable(value = "robotId") @ApiParam("机器人ID") String robotId,
|
@PathVariable @ApiParam("机器人ID") String robotId,
|
||||||
@RequestParam(value = "mapName") @ApiParam("地图名称") String mapName
|
@RequestParam(value = "mapName") @ApiParam("地图名称") String mapName
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@ -161,6 +147,19 @@ public class InspectionRobotController extends BaseController
|
|||||||
return success(mapId);
|
return success(mapId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传地图(从源机器人下载到目标机器人)
|
||||||
|
*/
|
||||||
|
@ApiOperation("上传地图到机器人")
|
||||||
|
@PreAuthorize("@ss.hasPermi('inspection:robot:edit')")
|
||||||
|
@Log(title = "上传地图到机器人", businessType = BusinessType.OTHER)
|
||||||
|
@PostMapping("/{robotId}/upload-map-from-source")
|
||||||
|
public AjaxResult uploadMapFromSource(@PathVariable String robotId)
|
||||||
|
{
|
||||||
|
String result = inspectionRobotService.uploadMapFromSource(robotId);
|
||||||
|
return success(result);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 同步机器人状态
|
* 同步机器人状态
|
||||||
*/
|
*/
|
||||||
@ -168,10 +167,43 @@ public class InspectionRobotController extends BaseController
|
|||||||
@PreAuthorize("@ss.hasPermi('inspection:robot:edit')")
|
@PreAuthorize("@ss.hasPermi('inspection:robot:edit')")
|
||||||
@Log(title = "同步机器人状态", businessType = BusinessType.UPDATE)
|
@Log(title = "同步机器人状态", businessType = BusinessType.UPDATE)
|
||||||
@PostMapping("/{robotId}/sync-status")
|
@PostMapping("/{robotId}/sync-status")
|
||||||
public AjaxResult syncRobotStatus(@PathVariable("robotId") String robotId)
|
public AjaxResult syncRobotStatus(@PathVariable String robotId)
|
||||||
{
|
{
|
||||||
return success(inspectionRobotService.syncRobotStatus(robotId));
|
return success(inspectionRobotService.syncRobotStatus(robotId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取机器人实时位置
|
||||||
|
*/
|
||||||
|
@ApiOperation("获取机器人实时位置")
|
||||||
|
@PreAuthorize("@ss.hasPermi('inspection:robot:query')")
|
||||||
|
@GetMapping("/{robotId}/location")
|
||||||
|
public AjaxResult getRobotRealtimeLocation(@PathVariable String robotId)
|
||||||
|
{
|
||||||
|
AgvCommand.AgvRobotLocation location = inspectionRobotService.getRobotRealtimeLocation(robotId);
|
||||||
|
return success(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导航到指定位置(坐标)
|
||||||
|
*/
|
||||||
|
@ApiOperation("导航到指定位置")
|
||||||
|
@PreAuthorize("@ss.hasPermi('inspection:robot:edit')")
|
||||||
|
@Log(title = "导航到指定位置", businessType = BusinessType.OTHER)
|
||||||
|
@PostMapping("/{robotId}/navigate-to-position")
|
||||||
|
public AjaxResult navigateToPosition(
|
||||||
|
@PathVariable @ApiParam("机器人ID") String robotId,
|
||||||
|
@RequestParam @ApiParam("X坐标(米)") Double x,
|
||||||
|
@RequestParam @ApiParam("Y坐标(米)") Double y,
|
||||||
|
@RequestParam(required = false) @ApiParam("朝向角(弧度)") Double theta,
|
||||||
|
@RequestParam(required = false) @ApiParam("任务ID") String taskId
|
||||||
|
)
|
||||||
|
{
|
||||||
|
AgvCommand.RobotGoTargetResData result = inspectionRobotService.navigateToPosition(
|
||||||
|
robotId, x, y, theta, taskId
|
||||||
|
);
|
||||||
|
return success(result);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -79,6 +79,20 @@ public interface EdgeAgvService {
|
|||||||
AgvCommand.RobotGoTargetResData robotGoTarget(EdgeCommonVO edgeCommonVO, String sourceId, String targetId,
|
AgvCommand.RobotGoTargetResData robotGoTarget(EdgeCommonVO edgeCommonVO, String sourceId, String targetId,
|
||||||
String taskId, String operation, Double jackHeight);
|
String taskId, String operation, Double jackHeight);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自由导航到指定坐标位置(命令码3051,使用freego参数)
|
||||||
|
* 直接导航到指定的X、Y坐标和角度,不依赖站点
|
||||||
|
* 注意:此命令会取消当前正在执行的任务,仅支持双轮差速底盘
|
||||||
|
*
|
||||||
|
* @param edgeCommonVO 边缘通用参数
|
||||||
|
* @param freeGoPoint 自由导航目标点(包含x、y、theta)
|
||||||
|
* @param taskId 任务ID(可选,建议提供)
|
||||||
|
* @return 导航任务下发结果
|
||||||
|
*/
|
||||||
|
AgvCommand.RobotGoTargetResData robotGoTargetWithFreeGo(EdgeCommonVO edgeCommonVO,
|
||||||
|
AgvCommand.FreeGoPoint freeGoPoint,
|
||||||
|
String taskId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 暂停当前导航任务(命令码3001)
|
* 暂停当前导航任务(命令码3001)
|
||||||
* 暂停AGV当前正在执行的导航任务,AGV将减速停止
|
* 暂停AGV当前正在执行的导航任务,AGV将减速停止
|
||||||
|
|||||||
@ -156,6 +156,46 @@ public class EdgeAgvServiceImpl implements EdgeAgvService {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AgvCommand.RobotGoTargetResData robotGoTargetWithFreeGo(EdgeCommonVO edgeCommonVO,
|
||||||
|
AgvCommand.FreeGoPoint freeGoPoint,
|
||||||
|
String taskId) {
|
||||||
|
if (freeGoPoint == null) {
|
||||||
|
throw new GlobalException("自由导航目标点不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
AgvServiceGrpc.AgvServiceBlockingStub stub = grpcServiceManager.getGrpcClient(
|
||||||
|
edgeCommonVO.getTerminalId(), AgvServiceGrpc.AgvServiceBlockingStub.class);
|
||||||
|
|
||||||
|
// 构建请求数据,使用freego参数
|
||||||
|
AgvCommand.RobotGoTargetReqData.Builder dataBuilder = AgvCommand.RobotGoTargetReqData.newBuilder()
|
||||||
|
.setSourceId("SELF_POSITION") // 从当前位置开始
|
||||||
|
.setId("SELF_POSITION") // 不使用站点ID
|
||||||
|
.setFreego(freeGoPoint); // 设置自由导航点
|
||||||
|
|
||||||
|
// 设置可选参数
|
||||||
|
if (StrUtil.isNotBlank(taskId)) {
|
||||||
|
dataBuilder.setTaskId(taskId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AgvCommand.RobotGoTargetCommand.Request request = AgvCommand.RobotGoTargetCommand.Request.newBuilder()
|
||||||
|
.setHeader(EdgeCommonUtil.buildRequest(edgeCommonVO.getDeviceId()))
|
||||||
|
.setData(dataBuilder.build())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
AgvCommand.RobotGoTargetResData result = executeGrpcCall(() -> stub.robotGoTarget(request)).getData();
|
||||||
|
|
||||||
|
if (result.getRetCode() != 0) {
|
||||||
|
throw new GlobalException("自由导航任务下发失败: " + result.getErrMsg());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AgvCommand.RobotTaskPauseCommand.Feedback.Result robotTaskPause(EdgeCommonVO edgeCommonVO) {
|
public AgvCommand.RobotTaskPauseCommand.Feedback.Result robotTaskPause(EdgeCommonVO edgeCommonVO) {
|
||||||
AgvServiceGrpc.AgvServiceBlockingStub stub = grpcServiceManager.getGrpcClient(
|
AgvServiceGrpc.AgvServiceBlockingStub stub = grpcServiceManager.getGrpcClient(
|
||||||
|
|||||||
@ -73,15 +73,6 @@ public interface IInspectionRobotService extends IService<InspectionRobot>
|
|||||||
*/
|
*/
|
||||||
int bindRobotMap(String robotId, String mapId);
|
int bindRobotMap(String robotId, String mapId);
|
||||||
|
|
||||||
/**
|
|
||||||
* 上传地图到机器人
|
|
||||||
*
|
|
||||||
* @param robotId 机器人ID
|
|
||||||
* @param mapId 地图ID
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
String uploadMapToRobot(String robotId, String mapId);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从机器人下载地图
|
* 从机器人下载地图
|
||||||
*
|
*
|
||||||
@ -91,6 +82,14 @@ public interface IInspectionRobotService extends IService<InspectionRobot>
|
|||||||
*/
|
*/
|
||||||
String downloadMapFromRobot(String robotId, String mapName);
|
String downloadMapFromRobot(String robotId, String mapName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传地图(从源机器人下载到目标机器人)
|
||||||
|
*
|
||||||
|
* @param robotId 目标机器人ID
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
String uploadMapFromSource(String robotId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 同步机器人状态(电量、位置等)
|
* 同步机器人状态(电量、位置等)
|
||||||
*
|
*
|
||||||
@ -99,4 +98,25 @@ public interface IInspectionRobotService extends IService<InspectionRobot>
|
|||||||
*/
|
*/
|
||||||
InspectionRobot syncRobotStatus(String robotId);
|
InspectionRobot syncRobotStatus(String robotId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取机器人实时位置
|
||||||
|
*
|
||||||
|
* @param robotId 机器人ID
|
||||||
|
* @return 机器人位置信息(包含X、Y坐标、角度、当前站点等)
|
||||||
|
*/
|
||||||
|
AgvCommand.AgvRobotLocation getRobotRealtimeLocation(String robotId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导航到指定位置(坐标)
|
||||||
|
*
|
||||||
|
* @param robotId 机器人ID
|
||||||
|
* @param x X坐标(米)
|
||||||
|
* @param y Y坐标(米)
|
||||||
|
* @param theta 朝向角(弧度)
|
||||||
|
* @param taskId 任务ID(可选)
|
||||||
|
* @return 导航任务下发结果
|
||||||
|
*/
|
||||||
|
AgvCommand.RobotGoTargetResData navigateToPosition(String robotId, Double x, Double y,
|
||||||
|
Double theta, String taskId);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
package com.cmvr.inspection.service.impl;
|
package com.cmvr.inspection.service.impl;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@ -180,49 +181,6 @@ public class InspectionRobotServiceImpl extends ServiceImpl<InspectionRobotMappe
|
|||||||
return inspectionRobotMapper.updateInspectionRobot(robot);
|
return inspectionRobotMapper.updateInspectionRobot(robot);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 上传地图到机器人
|
|
||||||
*
|
|
||||||
* @param robotId 机器人ID
|
|
||||||
* @param mapId 地图ID
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String uploadMapToRobot(String robotId, String mapId)
|
|
||||||
{
|
|
||||||
InspectionRobot robot = inspectionRobotMapper.selectInspectionRobotById(robotId);
|
|
||||||
if (robot == null) {
|
|
||||||
throw new GlobalException("机器人不存在");
|
|
||||||
}
|
|
||||||
|
|
||||||
InspectionMap map = inspectionMapMapper.selectInspectionMapById(mapId);
|
|
||||||
if (map == null) {
|
|
||||||
throw new GlobalException("地图不存在");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (StrUtil.isBlank(map.getMapFilePath())) {
|
|
||||||
throw new GlobalException("地图文件路径不存在");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 从文件路径读取地图内容
|
|
||||||
String mapContent = readMapFile(map.getMapFilePath());
|
|
||||||
if (StrUtil.isBlank(mapContent)) {
|
|
||||||
throw new GlobalException("地图文件内容为空");
|
|
||||||
}
|
|
||||||
|
|
||||||
EdgeCommonVO edgeCommonVO = new EdgeCommonVO();
|
|
||||||
edgeCommonVO.setTerminalId(robot.getTerminalId());
|
|
||||||
edgeCommonVO.setDeviceId(robot.getRobotCode());
|
|
||||||
|
|
||||||
AgvCommand.AgvUploadMapResult result = edgeAgvService.robotConfigUploadMap(edgeCommonVO, mapContent);
|
|
||||||
|
|
||||||
if (result.getRetCode() != 0) {
|
|
||||||
throw new GlobalException("上传地图失败: " + result.getErrMsg());
|
|
||||||
}
|
|
||||||
|
|
||||||
return "上传成功";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从机器人下载地图
|
* 从机器人下载地图
|
||||||
*
|
*
|
||||||
@ -264,6 +222,75 @@ public class InspectionRobotServiceImpl extends ServiceImpl<InspectionRobotMappe
|
|||||||
return result.getMapContent();
|
return result.getMapContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传地图(从源机器人下载到目标机器人)
|
||||||
|
*
|
||||||
|
* @param robotId 目标机器人ID
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String uploadMapFromSource(String robotId)
|
||||||
|
{
|
||||||
|
// 1. 获取目标机器人信息
|
||||||
|
InspectionRobot targetRobot = inspectionRobotMapper.selectInspectionRobotById(robotId);
|
||||||
|
if (targetRobot == null) {
|
||||||
|
throw new GlobalException("目标机器人不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 获取地图信息
|
||||||
|
InspectionMap map = inspectionMapMapper.selectInspectionMapById(targetRobot.getCurrentMapId());
|
||||||
|
if (map == null) {
|
||||||
|
throw new GlobalException("地图不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 检查地图是否有来源机器人ID和地图名称
|
||||||
|
if (StrUtil.isBlank(map.getMapSourceRobotId())) {
|
||||||
|
throw new GlobalException("地图未配置来源机器人ID");
|
||||||
|
}
|
||||||
|
if (StrUtil.isBlank(map.getMapSourceName())) {
|
||||||
|
throw new GlobalException("地图未配置来源地图名称");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 获取来源机器人信息
|
||||||
|
InspectionRobot sourceRobot = inspectionRobotMapper.selectInspectionRobotById(map.getMapSourceRobotId());
|
||||||
|
if (sourceRobot == null) {
|
||||||
|
throw new GlobalException("来源机器人不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 从来源机器人下载地图JSON
|
||||||
|
EdgeCommonVO sourceEdgeVO = new EdgeCommonVO();
|
||||||
|
sourceEdgeVO.setTerminalId(sourceRobot.getTerminalId());
|
||||||
|
sourceEdgeVO.setDeviceId(sourceRobot.getRobotCode());
|
||||||
|
|
||||||
|
AgvCommand.AgvDownloadMapResult downloadResult = edgeAgvService.robotConfigDownloadMap(
|
||||||
|
sourceEdgeVO, map.getMapSourceName()
|
||||||
|
);
|
||||||
|
|
||||||
|
if (downloadResult.getRetCode() != 0) {
|
||||||
|
throw new GlobalException("从来源机器人下载地图失败: " + downloadResult.getErrMsg());
|
||||||
|
}
|
||||||
|
|
||||||
|
String mapContent = downloadResult.getMapContent();
|
||||||
|
if (StrUtil.isBlank(mapContent)) {
|
||||||
|
throw new GlobalException("下载的地图内容为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. 上传地图到目标机器人
|
||||||
|
EdgeCommonVO targetEdgeVO = new EdgeCommonVO();
|
||||||
|
targetEdgeVO.setTerminalId(targetRobot.getTerminalId());
|
||||||
|
targetEdgeVO.setDeviceId(targetRobot.getRobotCode());
|
||||||
|
|
||||||
|
AgvCommand.AgvUploadMapResult uploadResult = edgeAgvService.robotConfigUploadMap(
|
||||||
|
targetEdgeVO, mapContent
|
||||||
|
);
|
||||||
|
|
||||||
|
if (uploadResult.getRetCode() != 0) {
|
||||||
|
throw new GlobalException("上传地图到目标机器人失败: " + uploadResult.getErrMsg());
|
||||||
|
}
|
||||||
|
|
||||||
|
return "上传成功";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 同步机器人状态(电量、位置等)
|
* 同步机器人状态(电量、位置等)
|
||||||
*
|
*
|
||||||
@ -306,15 +333,62 @@ public class InspectionRobotServiceImpl extends ServiceImpl<InspectionRobotMappe
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 读取地图文件内容
|
* 获取机器人实时位置
|
||||||
*
|
*
|
||||||
* @param filePath 文件路径
|
* @param robotId 机器人ID
|
||||||
* @return 文件内容
|
* @return 机器人位置信息(包含X、Y坐标、角度、当前站点等)
|
||||||
*/
|
*/
|
||||||
private String readMapFile(String filePath)
|
@Override
|
||||||
|
public AgvCommand.AgvRobotLocation getRobotRealtimeLocation(String robotId)
|
||||||
{
|
{
|
||||||
// TODO: 实现文件读取逻辑
|
InspectionRobot robot = inspectionRobotMapper.selectInspectionRobotById(robotId);
|
||||||
return "";
|
if (robot == null) {
|
||||||
|
throw new GlobalException("机器人不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
EdgeCommonVO edgeCommonVO = new EdgeCommonVO();
|
||||||
|
edgeCommonVO.setTerminalId(robot.getTerminalId());
|
||||||
|
edgeCommonVO.setDeviceId(robot.getRobotCode());
|
||||||
|
|
||||||
|
return edgeAgvService.getRobotLocation(edgeCommonVO);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导航到指定位置(坐标)
|
||||||
|
*
|
||||||
|
* @param robotId 机器人ID
|
||||||
|
* @param x X坐标(米)
|
||||||
|
* @param y Y坐标(米)
|
||||||
|
* @param theta 朝向角(弧度)
|
||||||
|
* @param taskId 任务ID(可选)
|
||||||
|
* @return 导航任务下发结果
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public AgvCommand.RobotGoTargetResData navigateToPosition(String robotId, Double x, Double y,
|
||||||
|
Double theta, String taskId)
|
||||||
|
{
|
||||||
|
InspectionRobot robot = inspectionRobotMapper.selectInspectionRobotById(robotId);
|
||||||
|
if (robot == null) {
|
||||||
|
throw new GlobalException("机器人不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x == null || y == null) {
|
||||||
|
throw new GlobalException("X和Y坐标不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建自由导航点
|
||||||
|
AgvCommand.FreeGoPoint freeGoPoint = AgvCommand.FreeGoPoint.newBuilder()
|
||||||
|
.setX(x)
|
||||||
|
.setY(y)
|
||||||
|
.setTheta(theta != null ? theta : 0.0)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
EdgeCommonVO edgeCommonVO = new EdgeCommonVO();
|
||||||
|
edgeCommonVO.setTerminalId(robot.getTerminalId());
|
||||||
|
edgeCommonVO.setDeviceId(robot.getRobotCode());
|
||||||
|
|
||||||
|
// 调用边缘端接口,使用freego参数进行自由导航
|
||||||
|
return edgeAgvService.robotGoTargetWithFreeGo(edgeCommonVO, freeGoPoint, taskId);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -63,6 +63,9 @@ public enum ActionEnum {
|
|||||||
BIO_HEAD_SPEAK_STOP("EDGE", "BIO_HEAD_SPEAK_STOP", "停止说话"),
|
BIO_HEAD_SPEAK_STOP("EDGE", "BIO_HEAD_SPEAK_STOP", "停止说话"),
|
||||||
BIO_HEAD_SPECIAL_EXPRESSION("EDGE", "BIO_HEAD_SPECIAL_EXPRESSION", "表情,1:高兴,2:惊讶,3:疲惫"),
|
BIO_HEAD_SPECIAL_EXPRESSION("EDGE", "BIO_HEAD_SPECIAL_EXPRESSION", "表情,1:高兴,2:惊讶,3:疲惫"),
|
||||||
|
|
||||||
|
// --------------- agv ---------------
|
||||||
|
AGV_MOVE_TO_POINT("EDGE", "AGV_MOVE_TO_POINT", "移动到指定点"),
|
||||||
|
|
||||||
// 大模型行为
|
// 大模型行为
|
||||||
// ---------------获取触控坐标---------------
|
// ---------------获取触控坐标---------------
|
||||||
TOUCH_COORDINATES("LLM", "TOUCH_COORDINATES", "获取触控坐标"),
|
TOUCH_COORDINATES("LLM", "TOUCH_COORDINATES", "获取触控坐标"),
|
||||||
|
|||||||
@ -0,0 +1,89 @@
|
|||||||
|
package com.cmvr.test.flow.runtime.operator.edge;
|
||||||
|
|
||||||
|
import cmvr.api.AgvCommand;
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import com.cmvr.common.exception.GlobalException;
|
||||||
|
import com.cmvr.edge.client.model.EdgeCommonVO;
|
||||||
|
import com.cmvr.edge.client.service.EdgeAgvService;
|
||||||
|
import com.cmvr.test.enums.ActionEnum;
|
||||||
|
import com.cmvr.test.flow.runtime.message.TaskNodeExecuteMessage;
|
||||||
|
import com.cmvr.test.flow.runtime.message.TaskNodeExecuteResult;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AGV边缘操作服务
|
||||||
|
* 处理AGV相关的设备行为,如移动到指定位置
|
||||||
|
*
|
||||||
|
* @author cmvr-iot
|
||||||
|
* @since 2026-06-29
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class EdgeAgvOperateService implements EdgeOperateService {
|
||||||
|
|
||||||
|
private final EdgeAgvService edgeAgvService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supports(ActionEnum action) {
|
||||||
|
return action.name().startsWith("AGV_");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TaskNodeExecuteResult execute(TaskNodeExecuteMessage message) {
|
||||||
|
ActionEnum action = message.getAction();
|
||||||
|
JSONObject inputParams = message.getInputParams();
|
||||||
|
String terminalId = message.getTerminalId();
|
||||||
|
|
||||||
|
// 从输入参数中获取机器人ID
|
||||||
|
String deviceId = inputParams.getString("deviceId");
|
||||||
|
|
||||||
|
if (deviceId == null || deviceId.isEmpty()) {
|
||||||
|
throw new GlobalException("机器人ID(deviceId)不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case AGV_MOVE_TO_POINT: {
|
||||||
|
log.info("执行AGV移动到指定位置操作,机器人ID: {}", deviceId);
|
||||||
|
|
||||||
|
// 从输入参数中获取坐标信息
|
||||||
|
Double x = inputParams.getDouble("x");
|
||||||
|
Double y = inputParams.getDouble("y");
|
||||||
|
Double theta = inputParams.getDouble("theta");
|
||||||
|
String taskId = inputParams.getString("taskId");
|
||||||
|
|
||||||
|
// 参数验证
|
||||||
|
if (x == null || y == null) {
|
||||||
|
throw new GlobalException("X和Y坐标不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建自由导航点
|
||||||
|
AgvCommand.FreeGoPoint freeGoPoint = AgvCommand.FreeGoPoint.newBuilder()
|
||||||
|
.setX(x)
|
||||||
|
.setY(y)
|
||||||
|
.setTheta(theta != null ? theta : 0.0)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// 构建边缘端通用参数
|
||||||
|
EdgeCommonVO edgeCommonVO = new EdgeCommonVO();
|
||||||
|
edgeCommonVO.setTerminalId(terminalId);
|
||||||
|
edgeCommonVO.setDeviceId(deviceId);
|
||||||
|
|
||||||
|
// 直接调用边缘端AGV服务执行导航
|
||||||
|
AgvCommand.RobotGoTargetResData result =
|
||||||
|
edgeAgvService.robotGoTargetWithFreeGo(edgeCommonVO, freeGoPoint, taskId);
|
||||||
|
|
||||||
|
log.info("AGV移动任务下发成功,返回码: {}", result.getRetCode());
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new GlobalException("不支持的AGV操作类型: " + action);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TaskNodeExecuteResult.success();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -12,6 +12,7 @@ import com.cmvr.edge.client.service.EdgeCameraService;
|
|||||||
import com.cmvr.edge.client.service.EdgeHlcService;
|
import com.cmvr.edge.client.service.EdgeHlcService;
|
||||||
import com.cmvr.edge.client.service.EdgeMicrophoneService;
|
import com.cmvr.edge.client.service.EdgeMicrophoneService;
|
||||||
import com.cmvr.edge.client.service.EdgeSpeakerService;
|
import com.cmvr.edge.client.service.EdgeSpeakerService;
|
||||||
|
import com.cmvr.edge.client.service.EdgeAgvService;
|
||||||
import com.cmvr.llm.service.LLMAiAgentPlatformService;
|
import com.cmvr.llm.service.LLMAiAgentPlatformService;
|
||||||
import com.cmvr.llm.service.LLMAiTtsService;
|
import com.cmvr.llm.service.LLMAiTtsService;
|
||||||
import com.cmvr.test.enums.ActionEnum;
|
import com.cmvr.test.enums.ActionEnum;
|
||||||
@ -29,8 +30,8 @@ public class FlowActionExecutorService {
|
|||||||
private final EdgeMicrophoneService edgeMicrophoneService;
|
private final EdgeMicrophoneService edgeMicrophoneService;
|
||||||
private final EdgeSpeakerService edgeSpeakerService;
|
private final EdgeSpeakerService edgeSpeakerService;
|
||||||
private final EdgeHlcService edgeHlcService;
|
private final EdgeHlcService edgeHlcService;
|
||||||
private final LLMAiTtsService llmAiTtsService;
|
|
||||||
private final LLMAiAgentPlatformService llmAiAgentPlatformService;
|
private final LLMAiAgentPlatformService llmAiAgentPlatformService;
|
||||||
|
private final EdgeAgvService edgeAgvService;
|
||||||
|
|
||||||
public String actionExecute(FlowActionRequestVO req) {
|
public String actionExecute(FlowActionRequestVO req) {
|
||||||
|
|
||||||
@ -104,6 +105,44 @@ public class FlowActionExecutorService {
|
|||||||
edgeFacialExpressionVO.setDeviceId(deviceId);
|
edgeFacialExpressionVO.setDeviceId(deviceId);
|
||||||
return edgeBioHeadService.setExpression(edgeFacialExpressionVO);
|
return edgeBioHeadService.setExpression(edgeFacialExpressionVO);
|
||||||
|
|
||||||
|
// ==== AGV ====
|
||||||
|
case AGV_MOVE_TO_POINT: {
|
||||||
|
log.info("执行AGV移动到指定位置操作");
|
||||||
|
|
||||||
|
// 从payload中获取机器人ID和坐标信息
|
||||||
|
String deviceId1 = payload.getString("deviceId");
|
||||||
|
if (StrUtil.isEmpty(deviceId1)) {
|
||||||
|
throw new GlobalException("机器人ID(deviceId)不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
Double x = payload.getDouble("x");
|
||||||
|
Double y = payload.getDouble("y");
|
||||||
|
Double theta = payload.getDouble("theta");
|
||||||
|
String taskId = payload.getString("taskId");
|
||||||
|
|
||||||
|
// 参数验证
|
||||||
|
if (x == null || y == null) {
|
||||||
|
throw new GlobalException("X和Y坐标不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建自由导航点
|
||||||
|
cmvr.api.AgvCommand.FreeGoPoint freeGoPoint = cmvr.api.AgvCommand.FreeGoPoint.newBuilder()
|
||||||
|
.setX(x)
|
||||||
|
.setY(y)
|
||||||
|
.setTheta(theta != null ? theta : 0.0)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// 直接调用边缘端AGV服务
|
||||||
|
cmvr.api.AgvCommand.RobotGoTargetResData result =
|
||||||
|
edgeAgvService.robotGoTargetWithFreeGo(edgeCommonVO, freeGoPoint, taskId);
|
||||||
|
|
||||||
|
log.info("AGV移动任务下发成功,返回码: {}", result.getRetCode());
|
||||||
|
|
||||||
|
// 返回结果字符串
|
||||||
|
return String.format("AGV移动任务下发成功, retCode=%d, errMsg=%s",
|
||||||
|
result.getRetCode(), result.getErrMsg());
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new UnsupportedOperationException("未实现的 EDGE Action: " + action.name());
|
throw new UnsupportedOperationException("未实现的 EDGE Action: " + action.name());
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user