Browse Source

agv任务管理

master
han\hanst 7 months ago
parent
commit
0144830e35
  1. 52
      src/main/java/com/gaotao/modules/automatedWarehouse/controller/AgvTaskController.java
  2. 18
      src/main/java/com/gaotao/modules/automatedWarehouse/mapper/AgvTaskMapper.java
  3. 18
      src/main/java/com/gaotao/modules/automatedWarehouse/service/AgvTaskService.java
  4. 15
      src/main/java/com/gaotao/modules/automatedWarehouse/service/impl/AgvTaskServiceImpl.java
  5. 136
      src/main/java/com/gaotao/modules/automatedWarehouse/task/AgvTaskScheduler.java
  6. 59
      src/main/resources/mapper/automatedWarehouse/AgvTaskMapper.xml

52
src/main/java/com/gaotao/modules/automatedWarehouse/controller/AgvTaskController.java

@ -8,6 +8,7 @@ import com.gaotao.modules.automatedWarehouse.entity.tusk.CreateTaskRequest;
import com.gaotao.modules.automatedWarehouse.entity.tusk.TuskResponse;
import com.gaotao.modules.automatedWarehouse.service.AgvTaskService;
import com.gaotao.modules.automatedWarehouse.service.TuskClientService;
import com.gaotao.modules.automatedWarehouse.task.AgvTaskScheduler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@ -27,6 +28,9 @@ public class AgvTaskController {
@Autowired
private TuskClientService tuskClientService;
@Autowired
private AgvTaskScheduler agvTaskScheduler;
/**
* 获取AGV运输任务列表分页查询排除已完成状态
* @param data 查询条件
@ -173,4 +177,52 @@ public class AgvTaskController {
return R.error().put("msg", "测试TUSK连接异常: " + e.getMessage());
}
}
// ==================== AGV任务调度接口 ====================
/**
* 手动触发AGV任务优先级调度
* @return 调度结果
*/
@PostMapping("/manualSchedule")
public R manualSchedule() {
try {
agvTaskScheduler.manualSchedule();
return R.ok().put("msg", "AGV任务调度执行成功");
} catch (Exception e) {
return R.error().put("msg", "AGV任务调度执行失败: " + e.getMessage());
}
}
/**
* 获取待下发的AGV任务列表
* @return 待下发任务列表
*/
@PostMapping("/getPendingTasks")
public R getPendingTasks() {
try {
List<WmsTransportTask> pendingTasks = agvTaskService.getPendingTasksByPriority();
return R.ok().put("tasks", pendingTasks).put("count", pendingTasks.size());
} catch (Exception e) {
return R.error().put("msg", "获取待下发任务失败: " + e.getMessage());
}
}
/**
* 获取当前执行中的任务数量
* @return 执行中任务数量
*/
@PostMapping("/getExecutingTaskCount")
public R getExecutingTaskCount() {
try {
int executingCount = agvTaskService.getExecutingTaskCount();
int canDispatchCount = Math.max(0, 10 - executingCount);
return R.ok()
.put("executingCount", executingCount)
.put("canDispatchCount", canDispatchCount)
.put("maxTaskLimit", 10);
} catch (Exception e) {
return R.error().put("msg", "获取执行中任务数量失败: " + e.getMessage());
}
}
}

18
src/main/java/com/gaotao/modules/automatedWarehouse/mapper/AgvTaskMapper.java

@ -30,4 +30,22 @@ public interface AgvTaskMapper extends BaseMapper<WmsTransportTask> {
* @return 明细列表
*/
List<WmsTransportTaskDetail> getTransportTaskDetails(@Param("taskNo") String taskNo);
/**
* 获取所有未下发的AGV任务按优先级降序排列
* @return 未下发的任务列表
*/
List<WmsTransportTask> getPendingTasksByPriority();
/**
* 更新任务状态为已下发
* @param taskNo 任务号
*/
void updateTaskStatusToDispatched(@Param("taskNo") String taskNo);
/**
* 获取当前正在执行中的任务数量
* @return 执行中的任务数量
*/
int getExecutingTaskCount();
}

18
src/main/java/com/gaotao/modules/automatedWarehouse/service/AgvTaskService.java

@ -24,4 +24,22 @@ public interface AgvTaskService {
* @return 明细列表
*/
List<WmsTransportTaskDetail> getTransportTaskDetails(String taskNo);
/**
* 获取所有未下发的AGV任务按优先级降序排列
* @return 未下发的任务列表
*/
List<WmsTransportTask> getPendingTasksByPriority();
/**
* 更新任务状态为已下发
* @param taskNo 任务号
*/
void updateTaskStatusToDispatched(String taskNo);
/**
* 获取当前正在执行中的任务数量
* @return 执行中的任务数量
*/
int getExecutingTaskCount();
}

15
src/main/java/com/gaotao/modules/automatedWarehouse/service/impl/AgvTaskServiceImpl.java

@ -32,4 +32,19 @@ public class AgvTaskServiceImpl implements AgvTaskService {
public List<WmsTransportTaskDetail> getTransportTaskDetails(String taskNo) {
return agvTaskMapper.getTransportTaskDetails(taskNo);
}
@Override
public List<WmsTransportTask> getPendingTasksByPriority() {
return agvTaskMapper.getPendingTasksByPriority();
}
@Override
public void updateTaskStatusToDispatched(String taskNo) {
agvTaskMapper.updateTaskStatusToDispatched(taskNo);
}
@Override
public int getExecutingTaskCount() {
return agvTaskMapper.getExecutingTaskCount();
}
}

136
src/main/java/com/gaotao/modules/automatedWarehouse/task/AgvTaskScheduler.java

@ -0,0 +1,136 @@
package com.gaotao.modules.automatedWarehouse.task;
import com.gaotao.common.utils.AgvClientUtil;
import com.gaotao.modules.automatedWarehouse.entity.WmsTransportTask;
import com.gaotao.modules.automatedWarehouse.service.AgvTaskService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
/**
* AGV任务优先级调度定时任务
* 每分钟执行一次获取所有未下发的AGV任务按优先级排序后下发优先级最高的任务
*/
@Slf4j
@Component
public class AgvTaskScheduler {
@Autowired
private AgvTaskService agvTaskService;
@Autowired
private AgvClientUtil agvClientUtil;
/**
* 定时任务每分钟执行一次AGV任务优先级调度
* cron表达式0 * * * * ? 表示每分钟的第0秒执行
*
* 调度策略
* - 如果执行中任务数 >= 10则不下发新任务
* - 如果执行中任务数 < 10则下发多个优先级高的任务但总数不超过10
*/
@Scheduled(cron = "0 * * * * ?")
public void scheduleAgvTaskByPriority() {
log.info("=== 开始执行AGV任务优先级调度定时任务 ===");
try {
// 1. 检查当前执行中的任务数量
int executingCount = agvTaskService.getExecutingTaskCount();
log.info("当前执行中的任务数量:{}", executingCount);
// 2. 如果执行中任务数 >= 10则不下发新任务
if (executingCount >= 10) {
log.info("执行中任务数量已达到上限(10个),暂不下发新任务");
return;
}
// 3. 计算可以下发的任务数量
int canDispatchCount = 10 - executingCount;
log.info("可以下发的任务数量:{}", canDispatchCount);
// 4. 获取所有未下发的AGV任务按优先级降序排列
List<WmsTransportTask> pendingTasks = agvTaskService.getPendingTasksByPriority();
if (pendingTasks == null || pendingTasks.isEmpty()) {
log.info("当前没有待下发的AGV任务");
return;
}
log.info("找到 {} 个待下发的AGV任务", pendingTasks.size());
// 5. 选择要下发的任务取优先级最高的几个数量不超过可下发数量
int actualDispatchCount = Math.min(canDispatchCount, pendingTasks.size());
List<WmsTransportTask> tasksToDispatch = pendingTasks.subList(0, actualDispatchCount);
log.info("准备下发 {} 个优先级最高的任务", actualDispatchCount);
// 6. 批量下发任务
int successCount = 0;
for (WmsTransportTask task : tasksToDispatch) {
try {
log.info("下发任务:taskNo={}, priority={}, fromLocation={}, toLocation={}",
task.getTaskNo(), task.getPriority(), task.getFromLocation(), task.getToLocation());
// 下发任务到AGV系统
dispatchTaskToAgv(task);
// 更新任务状态为已下发
agvTaskService.updateTaskStatusToDispatched(task.getTaskNo());
successCount++;
log.info("任务下发成功:taskNo={}", task.getTaskNo());
} catch (Exception e) {
log.error("任务下发失败:taskNo={}, error={}", task.getTaskNo(), e.getMessage());
// 继续下发其他任务不中断整个流程
}
}
log.info("本次调度完成,成功下发 {} 个任务", successCount);
} catch (Exception e) {
log.error("=== AGV任务优先级调度定时任务执行失败 ===", e);
}
log.info("=== AGV任务优先级调度定时任务执行完成 ===");
}
/**
* 将任务下发到AGV系统
* @param task 运输任务
*/
private void dispatchTaskToAgv(WmsTransportTask task) {
try {
// 构建目标点列表从起始位置到目标位置
List<String> targets = Arrays.asList(task.getFromLocation(), task.getToLocation());
// 调用AGV接口创建任务
agvClientUtil.createTask(
task.getTaskNo(), // 任务ID
targets, // 目标点列表
"DEFAULT_CONFIG", // 配置ID可根据需要调整
task.getPriority() // 优先级
);
log.info("成功调用AGV接口创建任务:taskNo={}, targets={}, priority={}",
task.getTaskNo(), targets, task.getPriority());
} catch (Exception e) {
log.error("下发AGV任务失败:taskNo={}, error={}", task.getTaskNo(), e.getMessage());
throw new RuntimeException("下发AGV任务失败:" + e.getMessage(), e);
}
}
/**
* 手动触发AGV任务调度用于测试或手动执行
*/
public void manualSchedule() {
log.info("手动触发AGV任务优先级调度");
scheduleAgvTaskByPriority();
}
}

59
src/main/resources/mapper/automatedWarehouse/AgvTaskMapper.xml

@ -86,4 +86,63 @@
ORDER BY seq_no ASC
</select>
<!-- 获取所有未下发的AGV任务,按优先级降序排列 -->
<select id="getPendingTasksByPriority" resultType="com.gaotao.modules.automatedWarehouse.entity.WmsTransportTask">
SELECT
id,
site,
item_no as itemNo,
task_no as taskNo,
source_type as sourceType,
source_bill_no as sourceBillNo,
source_line_id as sourceLineId,
part_no as partNo,
qty,
batch_no as batchNo,
serial_no as serialNo,
from_location as fromLocation,
to_location as toLocation,
pallet_id as palletId,
agv_code as agvCode,
priority,
status,
wms_send_time as wmsSendTime,
wcs_receive_time as wcsReceiveTime,
start_time as startTime,
complete_time as completeTime,
error_code as errorCode,
error_msg as errorMsg,
created_by as createdBy,
created_time as createdTime,
updated_time as updatedTime,
wcs_task_id as wcsTaskId,
finish_qty as finishQty,
wms_status as wmsStatus
FROM wms_transport_task
WHERE status IN ('待下发', '未下发', 'PENDING', 'CREATED')
AND from_location IS NOT NULL
AND to_location IS NOT NULL
ORDER BY
CASE WHEN priority IS NULL THEN 0 ELSE priority END DESC,
created_time ASC
</select>
<!-- 更新任务状态为已下发 -->
<update id="updateTaskStatusToDispatched">
UPDATE wms_transport_task
SET
status = '已下发',
wms_send_time = NOW(),
updated_time = NOW()
WHERE task_no = #{taskNo}
</update>
<!-- 获取当前正在执行中的任务数量 -->
<select id="getExecutingTaskCount" resultType="int">
SELECT COUNT(*)
FROM wms_transport_task
WHERE status IN ('已下发', '执行中', '运行中', 'DISPATCHED', 'EXECUTING', 'RUNNING')
AND (complete_time IS NULL OR complete_time = '')
</select>
</mapper>
Loading…
Cancel
Save