|
|
@ -4,21 +4,21 @@ import com.fasterxml.jackson.annotation.JsonIgnore; |
|
|
import com.galaxis.rcs.common.entity.RcsTaskPlan; |
|
|
import com.galaxis.rcs.common.entity.RcsTaskPlan; |
|
|
import com.galaxis.rcs.common.enums.AgvEventType; |
|
|
import com.galaxis.rcs.common.enums.AgvEventType; |
|
|
import com.galaxis.rcs.common.enums.LCCDirection; |
|
|
import com.galaxis.rcs.common.enums.LCCDirection; |
|
|
|
|
|
import com.galaxis.rcs.common.enums.PlanTaskStatus; |
|
|
import com.galaxis.rcs.common.enums.PlanTaskType; |
|
|
import com.galaxis.rcs.common.enums.PlanTaskType; |
|
|
import com.galaxis.rcs.connector.cl2.Cl2DeviceConnector; |
|
|
import com.galaxis.rcs.connector.cl2.Cl2DeviceConnector; |
|
|
import com.galaxis.rcs.plan.PlanTaskSequence; |
|
|
import com.galaxis.rcs.plan.PlanTaskSequence; |
|
|
import com.galaxis.rcs.ptr.AgvEventListener; |
|
|
import com.galaxis.rcs.ptr.*; |
|
|
import com.galaxis.rcs.ptr.AmrMessageHandler; |
|
|
|
|
|
import com.galaxis.rcs.ptr.ControlMode; |
|
|
|
|
|
import com.galaxis.rcs.ptr.PosDirection; |
|
|
|
|
|
import com.galaxis.rcs.ptr.receiveEntity.AmrHeartbeatMessage; |
|
|
import com.galaxis.rcs.ptr.receiveEntity.AmrHeartbeatMessage; |
|
|
import com.galaxis.rcs.ptr.receiveEntity.base.CurBatteryData; |
|
|
import com.galaxis.rcs.ptr.receiveEntity.base.CurBatteryData; |
|
|
import com.galaxis.rcs.ptr.sendEntity.RcsConfigMessage; |
|
|
import com.galaxis.rcs.ptr.sendEntity.RcsConfigMessage; |
|
|
import com.galaxis.rcs.ptr.sendEntity.RcsSRMessage; |
|
|
import com.galaxis.rcs.ptr.sendEntity.RcsSRMessage; |
|
|
import com.galaxis.rcs.ptr.sendEntity.RcsSetLocationMessage; |
|
|
import com.galaxis.rcs.ptr.sendEntity.RcsSetLocationMessage; |
|
|
|
|
|
import com.google.common.base.Joiner; |
|
|
import com.google.common.collect.Queues; |
|
|
import com.google.common.collect.Queues; |
|
|
import lombok.SneakyThrows; |
|
|
import lombok.SneakyThrows; |
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
|
|
|
import org.clever.core.BannerUtils; |
|
|
import org.clever.core.json.JsonWrapper; |
|
|
import org.clever.core.json.JsonWrapper; |
|
|
import org.clever.data.redis.Redis; |
|
|
import org.clever.data.redis.Redis; |
|
|
import org.clever.data.redis.RedisAdmin; |
|
|
import org.clever.data.redis.RedisAdmin; |
|
|
@ -63,6 +63,9 @@ public abstract class PtrAgvItem extends ExecutorItem { |
|
|
// agv当前转动角度值
|
|
|
// agv当前转动角度值
|
|
|
public double orientation; |
|
|
public double orientation; |
|
|
|
|
|
|
|
|
|
|
|
// 任务模式
|
|
|
|
|
|
public AmrTaskMode taskMode; |
|
|
|
|
|
|
|
|
private volatile boolean isManualMode = false; |
|
|
private volatile boolean isManualMode = false; |
|
|
private volatile boolean isPaused = false; |
|
|
private volatile boolean isPaused = false; |
|
|
private volatile PosDirection lastPausedPosition; |
|
|
private volatile PosDirection lastPausedPosition; |
|
|
@ -221,7 +224,19 @@ public abstract class PtrAgvItem extends ExecutorItem { |
|
|
|
|
|
|
|
|
public boolean isFree() { |
|
|
public boolean isFree() { |
|
|
// return (this.logisticsRuntime.isRunning() && this.deviceTaskQueue.isEmpty() && this.connectorThread.isRunning());
|
|
|
// return (this.logisticsRuntime.isRunning() && this.deviceTaskQueue.isEmpty() && this.connectorThread.isRunning());
|
|
|
return this.runtime.isRunning() && planTaskSequence == null && deviceTaskQueue.isEmpty() && !isPaused; |
|
|
if (!this.runtime.isRunning()) { |
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
|
|
|
if (planTaskSequence != null && !planTaskSequence.isAllCompleted()) { |
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
|
|
|
if (!deviceTaskQueue.isEmpty()) { |
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
|
|
|
if (this.isPaused) { |
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
|
|
|
return true; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public void updatePosition(int logicX, int logicY, short direction) { |
|
|
public void updatePosition(int logicX, int logicY, short direction) { |
|
|
@ -247,6 +262,62 @@ public abstract class PtrAgvItem extends ExecutorItem { |
|
|
fireEvent(AgvEventType.DIRECTION_CHANGED, this, |
|
|
fireEvent(AgvEventType.DIRECTION_CHANGED, this, |
|
|
oldDirection, direction); |
|
|
oldDirection, direction); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
boolean needCompute = false; |
|
|
|
|
|
|
|
|
|
|
|
// 从 runningDeviceTaskList 里面,找到完成到什么阶段
|
|
|
|
|
|
// 比如 (1,2) -> (2,2) -> (3,2) , 如果 updatePosition=3,2 ,那么前2个任务都要完成
|
|
|
|
|
|
int finishTargetIndex = -1; |
|
|
|
|
|
if (this.runningDeviceTaskList != null && !this.runningDeviceTaskList.isEmpty() && |
|
|
|
|
|
this.planTaskSequence != null && !this.planTaskSequence.isEmpty()) { |
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < runningDeviceTaskList.size(); i++) { |
|
|
|
|
|
PtrAgvDeviceTask task = runningDeviceTaskList.get(i); |
|
|
|
|
|
if (task.checkLogicX == logicX && task.checkLogicY == logicY) { |
|
|
|
|
|
finishTargetIndex = i; |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (finishTargetIndex >= 0) { |
|
|
|
|
|
needCompute = true; |
|
|
|
|
|
// 标记前面的任务都完成了
|
|
|
|
|
|
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); |
|
|
|
|
|
if (planTask != null) { |
|
|
|
|
|
planTask.setPlanTaskStatus(PlanTaskStatus.FINISHED.toString()); |
|
|
|
|
|
planTaskSequence.savePlanTask(planTask); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (planTaskSequence.isAllCompleted()) { |
|
|
|
|
|
fireEvent(AgvEventType.PLAN_COMPLETE, this); |
|
|
|
|
|
planTaskSequence = null; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
BannerUtils.printConfig(log, "updatePosition", new String[]{ |
|
|
|
|
|
"logicX: " + logicX, |
|
|
|
|
|
"logicY: " + logicY, |
|
|
|
|
|
"direction: " + direction, |
|
|
|
|
|
"finishTargetIndex: " + finishTargetIndex, |
|
|
|
|
|
"runningDeviceSize:" + (this.runningDeviceTaskList == null ? "null" : this.runningDeviceTaskList.size()), |
|
|
|
|
|
"planTask:" + (this.planTaskSequence == null ? "null" : |
|
|
|
|
|
("\n" + Joiner.on("\n").join((List) this.planTaskSequence.toPrettyMap().get("items"))) |
|
|
|
|
|
) |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
if (needCompute) { |
|
|
|
|
|
LockSupport.unpark(connectorThread); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
@ -263,46 +334,11 @@ public abstract class PtrAgvItem extends ExecutorItem { |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
boolean needCompute = true; |
|
|
// 任务完成逻辑,在地标检查里
|
|
|
for (PtrAgvDeviceTask task : runningDeviceTaskList) { |
|
|
|
|
|
if (task.seqNo == seqNo) { |
|
|
|
|
|
task.taskGroupStatus = messageStatus; |
|
|
|
|
|
if (task.x == x && task.y == y) { |
|
|
|
|
|
task.taskStatus = 4; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
if (task.taskGroupStatus < 3 /*|| task.taskStatus < 4*/) { |
|
|
|
|
|
needCompute = false; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
if (needCompute) { |
|
|
|
|
|
LockSupport.unpark(connectorThread); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 如果是任务完成事件
|
|
|
|
|
|
if (messageStatus == 4) { |
|
|
|
|
|
fireEvent(AgvEventType.DEVICE_TASK_COMPLETE, this, this.connectorThread.__currentTask); |
|
|
|
|
|
|
|
|
|
|
|
if (isTaskSequenceComplete()) { |
|
|
|
|
|
fireEvent(AgvEventType.PLAN_COMPLETE, this); |
|
|
|
|
|
planTaskSequence = null; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
public void updateTaskMode(int taskMode) { |
|
|
* 检查当前任务序列是否完成 |
|
|
|
|
|
*/ |
|
|
|
|
|
public boolean isTaskSequenceComplete() { |
|
|
|
|
|
if (planTaskSequence == null) { |
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
|
|
|
for (PtrAgvDeviceTask task : runningDeviceTaskList) { |
|
|
|
|
|
if (task.taskGroupStatus < 3 /*|| task.taskStatus < 4*/) { |
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
return true; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public void updateRedisStatus() { |
|
|
public void updateRedisStatus() { |
|
|
@ -451,6 +487,9 @@ public abstract class PtrAgvItem extends ExecutorItem { |
|
|
deviceTask.endPoint = pointItem; |
|
|
deviceTask.endPoint = pointItem; |
|
|
deviceTask.bizTaskId = plan.getBizTaskId(); |
|
|
deviceTask.bizTaskId = plan.getBizTaskId(); |
|
|
deviceTask.planTaskId = plan.getPlanTaskId(); |
|
|
deviceTask.planTaskId = plan.getPlanTaskId(); |
|
|
|
|
|
// 行走任务完成后,检查用的字段
|
|
|
|
|
|
deviceTask.checkLogicX = pointItem.logicX; |
|
|
|
|
|
deviceTask.checkLogicY = pointItem.logicY; |
|
|
deviceTaskList.add(deviceTask); |
|
|
deviceTaskList.add(deviceTask); |
|
|
// 设置新的起点
|
|
|
// 设置新的起点
|
|
|
startPoint = pointItem; |
|
|
startPoint = pointItem; |
|
|
@ -626,6 +665,16 @@ public abstract class PtrAgvItem extends ExecutorItem { |
|
|
}; |
|
|
}; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public short getAmrDirection(LCCDirection lccDirection) { |
|
|
|
|
|
return switch (lccDirection) { |
|
|
|
|
|
case RIGHT -> 0; |
|
|
|
|
|
case DOWN -> 1; |
|
|
|
|
|
case LEFT -> 2; |
|
|
|
|
|
case UP -> 3; |
|
|
|
|
|
default -> -1; // 未知方向
|
|
|
|
|
|
}; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
private String getRedisKey(String type) { |
|
|
private String getRedisKey(String type) { |
|
|
return String.format("lcc:%s:%s:rcs:%s_%s", |
|
|
return String.format("lcc:%s:%s:rcs:%s_%s", |
|
|
runtime.projectUUID, runtime.envId, type, this.getId()); |
|
|
runtime.projectUUID, runtime.envId, type, this.getId()); |
|
|
|