|
|
|
@ -16,6 +16,7 @@ import com.galaxis.rcs.ptr.sendEntity.RcsSRMessage; |
|
|
|
import com.galaxis.rcs.ptr.sendEntity.RcsSetLocationMessage; |
|
|
|
import com.google.common.base.Joiner; |
|
|
|
import com.google.common.collect.Queues; |
|
|
|
import com.yvan.logisticsMonitor.task.PlanTask; |
|
|
|
import lombok.SneakyThrows; |
|
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
|
import org.clever.core.BannerUtils; |
|
|
|
@ -27,6 +28,7 @@ import java.util.*; |
|
|
|
import java.util.concurrent.BlockingQueue; |
|
|
|
import java.util.concurrent.CopyOnWriteArraySet; |
|
|
|
import java.util.concurrent.locks.LockSupport; |
|
|
|
import java.util.stream.Collectors; |
|
|
|
|
|
|
|
//0.4m/ss // a max 1.2m/s
|
|
|
|
//90 = 3.5s cl2
|
|
|
|
@ -239,6 +241,29 @@ public abstract class PtrAgvItem extends ExecutorItem { |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
public void updateTask(int logicX, int logicY, short direction, int taskStatus) { |
|
|
|
|
|
|
|
updatePosition(logicX, logicY, direction); |
|
|
|
// 查找当前分组任务
|
|
|
|
for (PtrAgvDeviceTask task : runningDeviceTaskList) { |
|
|
|
task.taskGroupStatus = taskStatus; |
|
|
|
if (taskStatus == 4) { |
|
|
|
// 更新计划任务
|
|
|
|
List<RcsTaskPlan> planTaskList = planTaskSequence.taskList.stream().filter(pt -> task.movePlanTaskId.equals(pt.getPlanTaskId()) || task.planTaskIdSet.contains(pt.getPlanTaskId())).toList(); |
|
|
|
for (RcsTaskPlan planTask : planTaskList) { |
|
|
|
planTask.setPlanTaskStatus(PlanTaskStatus.FINISHED.toString()); |
|
|
|
planTaskSequence.savePlanTask(planTask); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (planTaskSequence.isAllCompleted()) { |
|
|
|
fireEvent(AgvEventType.PLAN_COMPLETE, this); |
|
|
|
this.runningDeviceTaskList.clear(); |
|
|
|
planTaskSequence = null; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public void updatePosition(int logicX, int logicY, short direction) { |
|
|
|
int oldX = this.logicX; |
|
|
|
int oldY = this.logicY; |
|
|
|
@ -273,7 +298,7 @@ public abstract class PtrAgvItem extends ExecutorItem { |
|
|
|
|
|
|
|
for (int i = 0; i < runningDeviceTaskList.size(); i++) { |
|
|
|
PtrAgvDeviceTask task = runningDeviceTaskList.get(i); |
|
|
|
if (task.checkLogicX == logicX && task.checkLogicY == logicY) { |
|
|
|
if (task.checkLogicX == logicX && task.checkLogicY == logicY && task.taskStatus < 4) { |
|
|
|
finishTargetIndex = i; |
|
|
|
break; |
|
|
|
} |
|
|
|
@ -284,13 +309,11 @@ public abstract class PtrAgvItem extends ExecutorItem { |
|
|
|
// 标记前面的任务都完成了
|
|
|
|
for (int i = 0; i <= finishTargetIndex; i++) { |
|
|
|
PtrAgvDeviceTask task = runningDeviceTaskList.get(i); |
|
|
|
|
|
|
|
task.taskStatus = 4; // 标记为完成
|
|
|
|
task.taskGroupStatus = 4; // 标记为任务组完成
|
|
|
|
fireEvent(AgvEventType.DEVICE_TASK_COMPLETE, this, task); |
|
|
|
|
|
|
|
// 更新计划任务
|
|
|
|
RcsTaskPlan planTask = planTaskSequence.getByPlanTaskId(task.planTaskId); |
|
|
|
RcsTaskPlan planTask = planTaskSequence.getByPlanTaskId(task.movePlanTaskId); |
|
|
|
if (planTask != null) { |
|
|
|
planTask.setPlanTaskStatus(PlanTaskStatus.FINISHED.toString()); |
|
|
|
planTaskSequence.savePlanTask(planTask); |
|
|
|
@ -299,6 +322,7 @@ public abstract class PtrAgvItem extends ExecutorItem { |
|
|
|
|
|
|
|
if (planTaskSequence.isAllCompleted()) { |
|
|
|
fireEvent(AgvEventType.PLAN_COMPLETE, this); |
|
|
|
this.runningDeviceTaskList.clear(); |
|
|
|
planTaskSequence = null; |
|
|
|
} |
|
|
|
} |
|
|
|
@ -447,13 +471,16 @@ public abstract class PtrAgvItem extends ExecutorItem { |
|
|
|
if (startPoint == null) { |
|
|
|
log.error("Cl2DeviceConnector robotMove: executorItem={}, task={}, agv当前点位为空 地图上没有标记", this.getId(), sequence.bizTask.getBizTaskId()); |
|
|
|
} |
|
|
|
StaticItem groupStartPoint = startPoint; |
|
|
|
|
|
|
|
Set<Long> rotationPlanTaskIdSet = new HashSet<>(); |
|
|
|
|
|
|
|
// 生成移动报文
|
|
|
|
List<PtrAgvDeviceTask> deviceTaskList = new ArrayList<>(); |
|
|
|
List<Map<String, Object>> linkStore = null; |
|
|
|
// 检查 planList 是不是全都是我的任务
|
|
|
|
for (RcsTaskPlan plan : sequence.taskList) { |
|
|
|
for (int i = 0; i < sequence.taskList.size(); i++) { |
|
|
|
RcsTaskPlan plan = sequence.taskList.get(i); |
|
|
|
String endPointId = plan.getTargetId(); |
|
|
|
|
|
|
|
if (plan.getPlanType().equals(PlanTaskType.MOVE.toString()) || plan.getPlanType().equals(PlanTaskType.MOVE_BACKWARD.toString())) { |
|
|
|
@ -486,7 +513,9 @@ public abstract class PtrAgvItem extends ExecutorItem { |
|
|
|
deviceTask.startPoint = startPoint; |
|
|
|
deviceTask.endPoint = pointItem; |
|
|
|
deviceTask.bizTaskId = plan.getBizTaskId(); |
|
|
|
deviceTask.planTaskId = plan.getPlanTaskId(); |
|
|
|
deviceTask.movePlanTaskId = plan.getPlanTaskId(); |
|
|
|
deviceTask.planTaskIdSet.addAll(rotationPlanTaskIdSet); |
|
|
|
rotationPlanTaskIdSet.clear(); |
|
|
|
// 行走任务完成后,检查用的字段
|
|
|
|
deviceTask.checkLogicX = pointItem.logicX; |
|
|
|
deviceTask.checkLogicY = pointItem.logicY; |
|
|
|
@ -516,12 +545,14 @@ public abstract class PtrAgvItem extends ExecutorItem { |
|
|
|
} else if (r >= 225 && r < 315) { |
|
|
|
direction = CDirection.db; |
|
|
|
} |
|
|
|
rotationPlanTaskIdSet.add(plan.getPlanTaskId()); |
|
|
|
|
|
|
|
} else if (plan.getPlanType().equals(PlanTaskType.LOAD.toString())) { |
|
|
|
|
|
|
|
PtrAgvDeviceTask deviceTask = deviceTaskList.get(deviceTaskList.size() - 1); |
|
|
|
deviceTask.operationType = COperationType.transplantLoadAndUnload; |
|
|
|
deviceTask.pickMode = CPickMode.load; |
|
|
|
deviceTask.planTaskIdSet.add(plan.getPlanTaskId()); |
|
|
|
//处理取货高度
|
|
|
|
StaticItem storeItem = runtime.getStaticItemById(endPointId); |
|
|
|
Map<String, Object> storeItemRaw = storeItem.dt; |
|
|
|
@ -556,17 +587,24 @@ public abstract class PtrAgvItem extends ExecutorItem { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 标记任务分组结束
|
|
|
|
deviceTask.isGroupEnd = true; |
|
|
|
deviceTask.groupEndPoint = deviceTask.endPoint; |
|
|
|
deviceTask.groupStartPoint = groupStartPoint; |
|
|
|
groupStartPoint = deviceTask.endPoint; |
|
|
|
|
|
|
|
} else if (plan.getPlanType().equals(PlanTaskType.UNLOAD.toString())) { |
|
|
|
PtrAgvDeviceTask deviceTask = deviceTaskList.get(deviceTaskList.size() - 1); |
|
|
|
deviceTask.operationType = COperationType.transplantLoadAndUnload; |
|
|
|
deviceTask.pickMode = CPickMode.unload; |
|
|
|
deviceTask.planTaskIdSet.add(plan.getPlanTaskId()); |
|
|
|
// 处理卸货高度
|
|
|
|
StaticItem storeItem = runtime.getStaticItemById(endPointId); |
|
|
|
Map<String, Object> storeItemRaw = storeItem.dt; |
|
|
|
if (storeItemRaw.containsKey("bays") && storeItemRaw.containsKey("level")) { |
|
|
|
if (storeItemRaw.containsKey("bays")) { |
|
|
|
List<Map<String, Object>> bays = (List<Map<String, Object>>) storeItemRaw.get("bays"); |
|
|
|
Map<String, Object> bay = bays.get(plan.getTargetBay()); |
|
|
|
List<Double> levelHeight = (List<Double>) bay.get("levels"); |
|
|
|
List<Double> levelHeight = (List<Double>) bay.get("levelHeight"); |
|
|
|
deviceTask.goodsSlotHeight = (int) Math.round(levelHeight.get(plan.getTargetLevel()) * 1000); |
|
|
|
} else { |
|
|
|
deviceTask.goodsSlotHeight = 1; |
|
|
|
@ -593,11 +631,24 @@ public abstract class PtrAgvItem extends ExecutorItem { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
// 标记任务分组结束
|
|
|
|
deviceTask.isGroupEnd = true; |
|
|
|
deviceTask.groupEndPoint = deviceTask.endPoint; |
|
|
|
deviceTask.groupStartPoint = groupStartPoint; |
|
|
|
groupStartPoint = deviceTask.endPoint; |
|
|
|
|
|
|
|
} else if (plan.getPlanType().equals(PlanTaskType.CHARGE.toString())) { |
|
|
|
PtrAgvDeviceTask deviceTask = deviceTaskList.get(deviceTaskList.size() - 1); |
|
|
|
deviceTask.operationType = COperationType.charge; |
|
|
|
deviceTask.planTaskIdSet.add(plan.getPlanTaskId()); |
|
|
|
// 处理充电距离(车的充电口到充电器被压下后的距离、一般被压下20mm)
|
|
|
|
deviceTask.chargeDirection = 0; |
|
|
|
deviceTask.chargeLocation = 200; |
|
|
|
// 标记任务分组结束
|
|
|
|
deviceTask.isGroupEnd = true; |
|
|
|
deviceTask.groupEndPoint = deviceTask.endPoint; |
|
|
|
deviceTask.groupStartPoint = groupStartPoint; |
|
|
|
groupStartPoint = deviceTask.endPoint; |
|
|
|
} |
|
|
|
|
|
|
|
if (!plan.getExecutorId().equals(this.getId())) { |
|
|
|
@ -605,10 +656,39 @@ public abstract class PtrAgvItem extends ExecutorItem { |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
// 添加结束任务
|
|
|
|
PtrAgvDeviceTask deviceTaskEnd = new PtrAgvDeviceTask(); |
|
|
|
deviceTaskEnd.isLastTask = true; |
|
|
|
deviceTaskList.add(deviceTaskEnd); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 标记任务分组结束
|
|
|
|
PtrAgvDeviceTask deviceTask = deviceTaskList.get(deviceTaskList.size() - 1); |
|
|
|
deviceTask.groupEndPoint = deviceTask.endPoint; |
|
|
|
deviceTask.groupStartPoint = groupStartPoint; |
|
|
|
deviceTask.isGroupEnd = true; |
|
|
|
// 最后一个规划任务为旋转时需要添加一个endDirection
|
|
|
|
if (rotationPlanTaskIdSet.size() > 0) { |
|
|
|
deviceTask.endDirection = direction; |
|
|
|
deviceTask.planTaskIdSet.addAll(rotationPlanTaskIdSet); |
|
|
|
rotationPlanTaskIdSet.clear(); |
|
|
|
} |
|
|
|
|
|
|
|
// 反向标记任务组
|
|
|
|
int lastIndex = deviceTaskList.size() - 1; |
|
|
|
for (int i = deviceTaskList.size() - 1; i >= 0 ; i--) { |
|
|
|
PtrAgvDeviceTask d = deviceTaskList.get(i); |
|
|
|
if (d.isGroupEnd) { |
|
|
|
lastIndex = i; |
|
|
|
} else { |
|
|
|
d.operationType = deviceTaskList.get(lastIndex).operationType; |
|
|
|
d.pickMode = deviceTaskList.get(lastIndex).pickMode; |
|
|
|
d.groupStartPoint = deviceTaskList.get(lastIndex).groupStartPoint; |
|
|
|
d.groupEndPoint = deviceTaskList.get(lastIndex).groupEndPoint; |
|
|
|
d.goodsSlotHeight = deviceTaskList.get(lastIndex).goodsSlotHeight; |
|
|
|
d.goodsSlotDirection = deviceTaskList.get(lastIndex).goodsSlotDirection; |
|
|
|
d.chargeDirection = deviceTaskList.get(lastIndex).chargeDirection; |
|
|
|
d.chargeLocation = deviceTaskList.get(lastIndex).chargeLocation; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// planQueue.addAll(sequence.taskList);
|
|
|
|
deviceTaskQueue.addAll(deviceTaskList); |
|
|
|
|