AGV任务执行通知请求接口
This commit is contained in:
24
ruoyi-admin/src/main/java/com/ruoyi/common/TaskType.java
Normal file
24
ruoyi-admin/src/main/java/com/ruoyi/common/TaskType.java
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package com.ruoyi.common;
|
||||||
|
|
||||||
|
public class TaskType {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输送线入库(PTL出口)
|
||||||
|
*/
|
||||||
|
public static final String CONV_STOCKIN = "1";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 出库至输送线(PTL入口)---单个或组出库
|
||||||
|
*/
|
||||||
|
public static final String CONV_STOCKOUT_SINGLE_GROUP = "21";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 出库至输送线(PTL入口)---顺序出
|
||||||
|
*/
|
||||||
|
public static final String CONV_STOCKOUT_SEQUENCE = "22";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AGV点到点搬运
|
||||||
|
*/
|
||||||
|
public static final String AGV_MOVE = "3";
|
||||||
|
}
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
package com.ruoyi.device.agv.controller;
|
||||||
|
|
||||||
|
import cn.hutool.http.HttpRequest;
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.ruoyi.common.Constant;
|
||||||
|
import com.ruoyi.common.TaskStatusCode;
|
||||||
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
|
import com.ruoyi.common.core.page.TableDataInfo;
|
||||||
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
import com.ruoyi.device.DeviceCar.domain.DeviceCar;
|
||||||
|
import com.ruoyi.device.agv.domain.ResponseBase;
|
||||||
|
import com.ruoyi.device.agv.domain.agvCallback.AgvCallbackRequest;
|
||||||
|
import com.ruoyi.device.agv.domain.agvCallback.AgvCallbackResponse;
|
||||||
|
import com.ruoyi.device.agv.domain.genAgvSchedulingTask.GenAgvSchedulingTaskRequest;
|
||||||
|
import com.ruoyi.device.agv.domain.genAgvSchedulingTask.GenAgvSchedulingTaskResponse;
|
||||||
|
import com.ruoyi.device.api.domain.RequestLog;
|
||||||
|
import com.ruoyi.schedule.plc.domain.AgvRead;
|
||||||
|
import com.ruoyi.schedule.task.domain.WcsTask;
|
||||||
|
import com.ruoyi.schedule.task.mapper.WcsTaskMapper;
|
||||||
|
import com.ruoyi.schedule.task.service.IWcsTaskService;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Agv操作请求
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/agv/api")
|
||||||
|
@Slf4j
|
||||||
|
public class AgvController extends BaseController {
|
||||||
|
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
WcsTaskMapper wcsTaskMapper;
|
||||||
|
|
||||||
|
@PostMapping("/agvCallback")
|
||||||
|
public AgvCallbackResponse agvCallback(@RequestBody AgvCallbackRequest request) {
|
||||||
|
|
||||||
|
AgvCallbackResponse response = new AgvCallbackResponse();
|
||||||
|
|
||||||
|
response.setCode(0);
|
||||||
|
response.setMessage("success");
|
||||||
|
response.setReqCode(request.getReqCode());
|
||||||
|
|
||||||
|
//请求字符串空校验
|
||||||
|
if (request == null ||
|
||||||
|
StringUtils.isBlank(request.getReqCode()) ||
|
||||||
|
StringUtils.isBlank(request.getReqTime()) ||
|
||||||
|
StringUtils.isBlank(request.getCurrentPositionCode()) ||
|
||||||
|
StringUtils.isBlank(request.getMethod()) ||
|
||||||
|
StringUtils.isBlank(request.getRobotCode()) ||
|
||||||
|
StringUtils.isBlank(request.getTaskCode())
|
||||||
|
) {
|
||||||
|
response.setCode(1);
|
||||||
|
response.setMessage("failed");
|
||||||
|
log.error("【设备执行任务回调接口异常】:{}", JSON.toJSONString(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
//根据回调参数更新任务状态
|
||||||
|
WcsTask task = wcsTaskMapper.selectWcsTaskByTaskId(request.getTaskCode());
|
||||||
|
switch (request.getMethod()){
|
||||||
|
case "start":
|
||||||
|
case "outbin":
|
||||||
|
task.setTaskStatus(TaskStatusCode.TASK_RUNNING);
|
||||||
|
log.info("【更新任务状态】任务号:{},任务执行中",task.getTaskId());
|
||||||
|
break;
|
||||||
|
case "end":
|
||||||
|
task.setTaskStatus(TaskStatusCode.TASK_FINISH);
|
||||||
|
log.info("【更新任务状态】任务号:{},任务自动完成",task.getTaskId());
|
||||||
|
break;
|
||||||
|
case "cancel":
|
||||||
|
task.setTaskStatus(TaskStatusCode.TASK_CANCEL);
|
||||||
|
log.info("【更新任务状态】任务号:{},任务已取消",task.getTaskId());
|
||||||
|
break;
|
||||||
|
case "apply":
|
||||||
|
//task.setTaskStatus(TaskStatusCode.TASK_RUNNING);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
task.setDeviceId(request.getRobotCode());
|
||||||
|
|
||||||
|
wcsTaskMapper.updateWcsTask(task);
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,126 @@
|
|||||||
|
package com.ruoyi.device.agv.domain.agvCallback;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class AgvCallbackRequest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求编号,每个请求都要一个唯一编号,同一个请求重复提交,使用同一编号
|
||||||
|
*/
|
||||||
|
private String reqCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求时间戳,格式: “yyyy-MM-dd HH:mm:ss”
|
||||||
|
*/
|
||||||
|
private String reqTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 地码 X 坐标(mm):任务完成时有值
|
||||||
|
*/
|
||||||
|
private Number cooX;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 地码 Y 坐标(mm):任务完成时有值
|
||||||
|
*/
|
||||||
|
private Number cooY;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前位置编号
|
||||||
|
* 任务开始:该位置为任务起点
|
||||||
|
* 走出储位:该位置为任务起点
|
||||||
|
* 任务单取消:该位置为工作位编号
|
||||||
|
* 任务结束:该位置为任务终点
|
||||||
|
* 取放申请:取放料箱的点
|
||||||
|
*/
|
||||||
|
private String currentPositionCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义字段,不超过2000个字符
|
||||||
|
*/
|
||||||
|
private String data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 地图编号
|
||||||
|
*/
|
||||||
|
private String mapCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 地码编号:任务完成时有值
|
||||||
|
*/
|
||||||
|
private String mapDataCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 仓位编号:叉车与CTU任务时有值
|
||||||
|
*/
|
||||||
|
private String stgBinCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 方法名, 可使用任务类型做为方法名
|
||||||
|
* 默认使用方式:
|
||||||
|
* start : 任务开始
|
||||||
|
* outbin : 走出储位
|
||||||
|
* end : 任务结束
|
||||||
|
* cancel : 任务单取消
|
||||||
|
* apply:CTU料箱取放申请
|
||||||
|
*/
|
||||||
|
private String method;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 货架编号:背货架时有值
|
||||||
|
*/
|
||||||
|
private String podCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 方向:“180”,”0”,”90”,”-90” 分别对应地图的”左”,”右”,”上”,”下”:任务完成时有值
|
||||||
|
*/
|
||||||
|
private String podDir;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 物料编号
|
||||||
|
*/
|
||||||
|
private String materialLot;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AGV编号(同 agvCode )
|
||||||
|
*/
|
||||||
|
private String robotCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前任务单号
|
||||||
|
*/
|
||||||
|
private String taskCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 工作位,与RCS-2000端配置的位置名称一致。任务完成时有值,与生成任务单接口中的wbCode一致。
|
||||||
|
*/
|
||||||
|
private String wbCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 容器编号
|
||||||
|
*/
|
||||||
|
private String ctnrCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 容器类型
|
||||||
|
*/
|
||||||
|
private String ctnrType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 巷道编号
|
||||||
|
*/
|
||||||
|
private String roadWayCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 巷道内顺序号
|
||||||
|
* 巷道尾是0,到巷道头依次递增1
|
||||||
|
*/
|
||||||
|
private String seq;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备编号,如梳齿式工作站、输送线等,一般使用于CTU场景。
|
||||||
|
* 系统根据仓位定位到关联的设备编号。
|
||||||
|
*/
|
||||||
|
private String eqpCode;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package com.ruoyi.device.agv.domain.agvCallback;
|
||||||
|
|
||||||
|
import com.ruoyi.device.agv.domain.ResponseBase;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class AgvCallbackResponse {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 响应码
|
||||||
|
*/
|
||||||
|
private Integer code;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 响应信息
|
||||||
|
*/
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求编号
|
||||||
|
*/
|
||||||
|
private String reqCode;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ import com.alibaba.fastjson2.JSON;
|
|||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.ruoyi.common.Constant;
|
import com.ruoyi.common.Constant;
|
||||||
import com.ruoyi.common.TaskStatusCode;
|
import com.ruoyi.common.TaskStatusCode;
|
||||||
|
import com.ruoyi.common.TaskType;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import com.ruoyi.common.utils.uuid.UUID;
|
import com.ruoyi.common.utils.uuid.UUID;
|
||||||
import com.ruoyi.device.agv.domain.ResponseBase;
|
import com.ruoyi.device.agv.domain.ResponseBase;
|
||||||
@@ -64,33 +65,67 @@ public class Execution {
|
|||||||
//无【待执行】任务
|
//无【待执行】任务
|
||||||
if (tasks.size() == 0) return;
|
if (tasks.size() == 0) return;
|
||||||
|
|
||||||
|
//请求agv/ctu下发指令
|
||||||
|
GenAgvSchedulingTaskRequest request = new GenAgvSchedulingTaskRequest();
|
||||||
|
|
||||||
for (int i = 0; i < tasks.size(); i++) {
|
for (int i = 0; i < tasks.size(); i++) {
|
||||||
|
|
||||||
//请求agv/ctu下发指令
|
//判断任务类型
|
||||||
GenAgvSchedulingTaskRequest request = new GenAgvSchedulingTaskRequest();
|
|
||||||
request.setReqCode(UUID.randomUUID().toString().replace("-", ""));
|
|
||||||
|
|
||||||
//入库类型
|
|
||||||
switch (tasks.get(i).getTaskType()) {
|
switch (tasks.get(i).getTaskType()) {
|
||||||
case "1":
|
case TaskType.CONV_STOCKIN:
|
||||||
request.setTaskTyp("F12");
|
//todo 是否要处理输送线取货工位有多个料箱的情况
|
||||||
|
//todo 是否要处理输送线取货工位有多个料箱的情况
|
||||||
|
|
||||||
|
|
||||||
|
request.setReqCode(UUID.randomUUID().toString().replace("-", ""));
|
||||||
|
|
||||||
|
//设备执行任务内置任务类型初始化
|
||||||
|
switch (tasks.get(i).getTaskType()) {
|
||||||
|
case "1":
|
||||||
|
request.setTaskTyp("F12");
|
||||||
|
break;
|
||||||
|
case "2":
|
||||||
|
request.setTaskTyp("F11");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
log.warn("【向设备下发任务请求】TaskTyp:{},生成任务的请求参数错误,异常的任务类型!", request.getTaskTyp());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//todo 了解CTU货架与工作台输送过程中是否需要另外下发取放料箱的任务
|
||||||
|
//todo 了解CTU货架与工作台输送过程中是否需要另外下发取放料箱的任务
|
||||||
|
|
||||||
|
//添加路径(未测试)
|
||||||
|
//todo 了解AGV/CTU路径的格式/规则
|
||||||
|
//todo 了解AGV/CTU路径的格式/规则
|
||||||
|
List<PositionCodeData> path = new ArrayList<>();
|
||||||
|
path.add(new PositionCodeData(tasks.get(i).getSourceLocation(),"05"));
|
||||||
|
path.add(new PositionCodeData(tasks.get(i).getTargetLocation(),"05"));
|
||||||
|
request.setPositionCodePath(path);
|
||||||
|
|
||||||
|
//wcs任务号---设备任务编号
|
||||||
|
request.setTaskCode(tasks.get(i).getTaskId());
|
||||||
|
|
||||||
|
|
||||||
|
//todo 上层平台是否有【校验料箱是否可入库】接口可用
|
||||||
|
//todo 上层平台是否有【校验料箱是否可入库】接口可用
|
||||||
|
|
||||||
|
|
||||||
|
//todo 是否需要单独请求取放料箱接口
|
||||||
|
//todo 是否需要单独请求取放料箱接口
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "2":
|
case TaskType.CONV_STOCKOUT_SINGLE_GROUP:
|
||||||
request.setTaskTyp("F11");
|
|
||||||
|
break;
|
||||||
|
case TaskType.CONV_STOCKOUT_SEQUENCE:
|
||||||
|
|
||||||
|
break;
|
||||||
|
case TaskType.AGV_MOVE:
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
log.warn("【向设备下发任务请求】TaskTyp:{},生成任务的请求参数错误,异常的任务类型!", request.getTaskTyp());
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//添加路径(未测试)
|
|
||||||
List<PositionCodeData> path = new ArrayList<>();
|
|
||||||
path.add(new PositionCodeData(tasks.get(i).getSourceLocation(),"05"));
|
|
||||||
path.add(new PositionCodeData(tasks.get(i).getTargetLocation(),"05"));
|
|
||||||
request.setPositionCodePath(path);
|
|
||||||
|
|
||||||
//wcs任务号---设备任务编号
|
|
||||||
request.setTaskCode(tasks.get(i).getTaskId());
|
|
||||||
|
|
||||||
//下发成功---更新【任务状态】为下发成功
|
//下发成功---更新【任务状态】为下发成功
|
||||||
if (sendCommand(request)){
|
if (sendCommand(request)){
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import com.ruoyi.schedule.task.domain.WcsTask;
|
|||||||
import com.ruoyi.schedule.task.mapper.WcsTaskMapper;
|
import com.ruoyi.schedule.task.mapper.WcsTaskMapper;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.scheduling.annotation.Scheduled;
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|||||||
@@ -34,8 +34,8 @@ public class Timer {
|
|||||||
execution.executeTask();
|
execution.executeTask();
|
||||||
Thread.sleep(200);
|
Thread.sleep(200);
|
||||||
|
|
||||||
statusUpdate.statusUpdate();
|
//statusUpdate.statusUpdate();
|
||||||
Thread.sleep(200);
|
//Thread.sleep(200);
|
||||||
|
|
||||||
taskFinish.taskFinish();
|
taskFinish.taskFinish();
|
||||||
Thread.sleep(200);
|
Thread.sleep(200);
|
||||||
|
|||||||
Reference in New Issue
Block a user