|
|
@ -1,13 +1,12 @@ |
|
|
package com.galaxis.rcs.ptr; |
|
|
package com.galaxis.rcs.ptr; |
|
|
|
|
|
|
|
|
import com.fasterxml.jackson.annotation.JsonIgnore; |
|
|
|
|
|
import com.galaxis.rcs.common.entity.RcsTaskPlan; |
|
|
import com.galaxis.rcs.common.entity.RcsTaskPlan; |
|
|
import com.yvan.event.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.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.plan.path.PathUtils; |
|
|
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; |
|
|
@ -15,25 +14,24 @@ 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.base.Joiner; |
|
|
import com.google.common.collect.Queues; |
|
|
import com.google.common.collect.Queues; |
|
|
import com.yvan.event.EventManager; |
|
|
import com.yvan.LccUtils; |
|
|
|
|
|
import com.yvan.event.AgvEventType; |
|
|
import com.yvan.logisticsModel.ExecutorItem; |
|
|
import com.yvan.logisticsModel.ExecutorItem; |
|
|
import com.yvan.logisticsModel.LogisticsRuntime; |
|
|
import com.yvan.logisticsModel.LogisticsRuntime; |
|
|
import com.yvan.logisticsModel.StaticItem; |
|
|
import com.yvan.logisticsModel.StaticItem; |
|
|
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.BannerUtils; |
|
|
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; |
|
|
|
|
|
|
|
|
import java.util.*; |
|
|
import java.util.*; |
|
|
import java.util.concurrent.BlockingQueue; |
|
|
import java.util.concurrent.BlockingQueue; |
|
|
import java.util.concurrent.CopyOnWriteArraySet; |
|
|
|
|
|
import java.util.concurrent.locks.LockSupport; |
|
|
import java.util.concurrent.locks.LockSupport; |
|
|
|
|
|
|
|
|
//0.4m/ss // a max 1.2m/s
|
|
|
/** |
|
|
//90 = 3.5s cl2
|
|
|
* 侧叉式AGV执行器 |
|
|
//90 = 5s // cLX
|
|
|
*/ |
|
|
@Slf4j |
|
|
@Slf4j |
|
|
public abstract class PtrAgvItem extends ExecutorItem { |
|
|
public abstract class PtrAgvItem extends ExecutorItem { |
|
|
private static final int BLOCKING_QUEUE_CAPACITY = 100; |
|
|
private static final int BLOCKING_QUEUE_CAPACITY = 100; |
|
|
@ -67,34 +65,28 @@ public abstract class PtrAgvItem extends ExecutorItem { |
|
|
public double orientation; |
|
|
public double orientation; |
|
|
|
|
|
|
|
|
// 任务模式
|
|
|
// 任务模式
|
|
|
public AmrTaskMode taskMode; |
|
|
private AmrTaskMode __taskMode; |
|
|
|
|
|
|
|
|
private volatile boolean isManualMode = false; |
|
|
|
|
|
private volatile boolean isPaused = false; |
|
|
private volatile boolean isPaused = false; |
|
|
private volatile PosDirection lastPausedPosition; |
|
|
private volatile PosDirection lastPausedPosition; |
|
|
private volatile boolean isOnline = false; |
|
|
private volatile boolean isOnline = false; |
|
|
|
|
|
|
|
|
// 执行中的任务
|
|
|
// 执行中的任务
|
|
|
@JsonIgnore |
|
|
|
|
|
public List<PtrAgvDeviceTask> runningDeviceTaskList = new ArrayList<>(); |
|
|
public List<PtrAgvDeviceTask> runningDeviceTaskList = new ArrayList<>(); |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* 当前执行的任务规划列表 |
|
|
* 当前执行的任务规划列表 |
|
|
*/ |
|
|
*/ |
|
|
@JsonIgnore |
|
|
|
|
|
public volatile PlanTaskSequence planTaskSequence; |
|
|
public volatile PlanTaskSequence planTaskSequence; |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* 当前执行的设备任务列表 |
|
|
* 当前执行的设备任务列表 |
|
|
*/ |
|
|
*/ |
|
|
@JsonIgnore |
|
|
|
|
|
final BlockingQueue<PtrAgvDeviceTask> deviceTaskQueue = Queues.newArrayBlockingQueue(BLOCKING_QUEUE_CAPACITY); |
|
|
final BlockingQueue<PtrAgvDeviceTask> deviceTaskQueue = Queues.newArrayBlockingQueue(BLOCKING_QUEUE_CAPACITY); |
|
|
|
|
|
|
|
|
@JsonIgnore |
|
|
|
|
|
final Cl2DeviceConnector cl2DeviceConnector = new Cl2DeviceConnector(this.runtime); |
|
|
final Cl2DeviceConnector cl2DeviceConnector = new Cl2DeviceConnector(this.runtime); |
|
|
|
|
|
|
|
|
@JsonIgnore |
|
|
final AmrMessageHandler amrMessageHandler; |
|
|
public final AmrMessageHandler amrMessageHandler; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* 连接器线程 |
|
|
* 连接器线程 |
|
|
@ -107,23 +99,6 @@ public abstract class PtrAgvItem extends ExecutorItem { |
|
|
this.amrMessageHandler = logisticsRuntime.amrMessageHandler; |
|
|
this.amrMessageHandler = logisticsRuntime.amrMessageHandler; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
public void stop() { |
|
|
|
|
|
// 停止连接器线程
|
|
|
|
|
|
stopConnector(); |
|
|
|
|
|
// 清理任务序列
|
|
|
|
|
|
if (planTaskSequence != null) { |
|
|
|
|
|
planTaskSequence = null; |
|
|
|
|
|
} |
|
|
|
|
|
// 清理设备任务队列
|
|
|
|
|
|
deviceTaskQueue.clear(); |
|
|
|
|
|
// 清理运行中的设备任务列表
|
|
|
|
|
|
runningDeviceTaskList.clear(); |
|
|
|
|
|
// 更新Redis状态
|
|
|
|
|
|
updateRedisStatus(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
@Override |
|
|
public boolean isRunning() { |
|
|
public boolean isRunning() { |
|
|
return connectorThread.isRunning(); |
|
|
return connectorThread.isRunning(); |
|
|
@ -131,11 +106,11 @@ public abstract class PtrAgvItem extends ExecutorItem { |
|
|
|
|
|
|
|
|
public abstract RcsConfigMessage getConfig(); |
|
|
public abstract RcsConfigMessage getConfig(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
@Override |
|
|
public void start() { |
|
|
public void start() { |
|
|
this.amrMessageHandler.registeHeartBeatSet(this); |
|
|
this.amrMessageHandler.registeHeartBeatSet(this); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 查询当前状态
|
|
|
// 查询当前状态
|
|
|
requestCurrentStatus(); |
|
|
requestCurrentStatus(); |
|
|
this.isRunning = true; |
|
|
this.isRunning = true; |
|
|
@ -143,9 +118,23 @@ public abstract class PtrAgvItem extends ExecutorItem { |
|
|
this.startConnector(); |
|
|
this.startConnector(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public synchronized void shutdown() { |
|
|
@Override |
|
|
this.stopConnector(); |
|
|
public void stop() { |
|
|
|
|
|
// 停止连接器线程
|
|
|
|
|
|
stopConnector(); |
|
|
|
|
|
|
|
|
this.amrMessageHandler.unregisteHeartBeatSet(this); |
|
|
this.amrMessageHandler.unregisteHeartBeatSet(this); |
|
|
|
|
|
|
|
|
|
|
|
// 清理任务序列
|
|
|
|
|
|
if (planTaskSequence != null) { |
|
|
|
|
|
planTaskSequence = null; |
|
|
|
|
|
} |
|
|
|
|
|
// 清理设备任务队列
|
|
|
|
|
|
deviceTaskQueue.clear(); |
|
|
|
|
|
// 清理运行中的设备任务列表
|
|
|
|
|
|
runningDeviceTaskList.clear(); |
|
|
|
|
|
// 更新Redis状态
|
|
|
|
|
|
updateRedisStatus(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public synchronized void dispatchTask(PlanTaskSequence taskSequence) { |
|
|
public synchronized void dispatchTask(PlanTaskSequence taskSequence) { |
|
|
@ -153,27 +142,19 @@ public abstract class PtrAgvItem extends ExecutorItem { |
|
|
throw new IllegalStateException("AGV is not free to accept new tasks"); |
|
|
throw new IllegalStateException("AGV is not free to accept new tasks"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (isManualMode) { |
|
|
|
|
|
throw new IllegalStateException("AGV is in manual mode and cannot accept tasks"); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
this.planTaskSequence = taskSequence; |
|
|
this.planTaskSequence = taskSequence; |
|
|
buildPlanToDeviceTask(); |
|
|
buildPlanToDeviceTask(); |
|
|
fireEvent(AgvEventType.PLAN_TASK_SEQUENCE_ACCEPT, this, taskSequence); |
|
|
this.runtime.eventManager.firePlanTaskSequenceAcceptEvent(this, taskSequence); |
|
|
connectorThread.resumeProcessing(); |
|
|
connectorThread.resumeProcessing(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private void fireEvent(AgvEventType agvEventType, Object... args) { |
|
|
|
|
|
this.runtime.eventManager.fireEvent(agvEventType, args); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public synchronized void pauseTask() { |
|
|
public synchronized void pauseTask() { |
|
|
if (planTaskSequence == null) { |
|
|
if (planTaskSequence == null) { |
|
|
throw new IllegalStateException("No active task to pause"); |
|
|
throw new IllegalStateException("No active task to pause"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
isPaused = true; |
|
|
isPaused = true; |
|
|
lastPausedPosition = new PosDirection(logicX, logicY, direction); |
|
|
lastPausedPosition = new PosDirection(logicX, logicY, PathUtils.getDirectionByArmDirection(direction)); |
|
|
|
|
|
|
|
|
// 发送停止指令
|
|
|
// 发送停止指令
|
|
|
RcsSRMessage stopMsg = new RcsSRMessage(this.runtime); |
|
|
RcsSRMessage stopMsg = new RcsSRMessage(this.runtime); |
|
|
@ -188,7 +169,7 @@ public abstract class PtrAgvItem extends ExecutorItem { |
|
|
log.error("Failed to send stop command to AGV {}", this.getId(), e); |
|
|
log.error("Failed to send stop command to AGV {}", this.getId(), e); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
fireEvent(AgvEventType.PLAN_TASK_SEQUENCE_PAUSE, this); |
|
|
this.runtime.eventManager.firePlanTaskSequencePauseEvent(this, planTaskSequence); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public synchronized void resumeTask() { |
|
|
public synchronized void resumeTask() { |
|
|
@ -199,14 +180,14 @@ public abstract class PtrAgvItem extends ExecutorItem { |
|
|
// 检查当前位置是否与暂停位置一致
|
|
|
// 检查当前位置是否与暂停位置一致
|
|
|
if (Math.abs(logicX - lastPausedPosition.logicX()) > 1 || |
|
|
if (Math.abs(logicX - lastPausedPosition.logicX()) > 1 || |
|
|
Math.abs(logicY - lastPausedPosition.logicY()) > 1 || |
|
|
Math.abs(logicY - lastPausedPosition.logicY()) > 1 || |
|
|
direction != lastPausedPosition.direction()) { |
|
|
PathUtils.getDirectionByArmDirection(direction) != lastPausedPosition.direction()) { |
|
|
// 需要返回暂停位置
|
|
|
// 需要返回暂停位置
|
|
|
throw new RuntimeException("AGV position has changed since pause, cannot resume task safely"); |
|
|
throw new RuntimeException("AGV position has changed since pause, cannot resume task safely"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
isPaused = false; |
|
|
isPaused = false; |
|
|
connectorThread.resumeProcessing(); |
|
|
connectorThread.resumeProcessing(); |
|
|
fireEvent(AgvEventType.PLAN_TASK_SEQUENCE_RESUME, this); |
|
|
this.runtime.eventManager.firePlanTaskSequenceResumeEvent(this, planTaskSequence); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@SneakyThrows |
|
|
@SneakyThrows |
|
|
@ -221,7 +202,7 @@ public abstract class PtrAgvItem extends ExecutorItem { |
|
|
deviceTaskQueue.clear(); |
|
|
deviceTaskQueue.clear(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
fireEvent(AgvEventType.PLAN_TASK_SEQUENCE_CANCEL, this); |
|
|
this.runtime.eventManager.firePlanTaskSequenceCancelEvent(this, planTaskSequence); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@SneakyThrows |
|
|
@SneakyThrows |
|
|
@ -234,18 +215,6 @@ public abstract class PtrAgvItem extends ExecutorItem { |
|
|
amrMessageHandler.sendCmdSetLocation(this.getId(), setLoc); |
|
|
amrMessageHandler.sendCmdSetLocation(this.getId(), setLoc); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public void setControlMode(ControlMode mode) { |
|
|
|
|
|
// 硬件控制模式设置逻辑
|
|
|
|
|
|
this.isManualMode = (mode == ControlMode.MANUAL); |
|
|
|
|
|
|
|
|
|
|
|
if (mode != ControlMode.FULL_AUTO && planTaskSequence != null) { |
|
|
|
|
|
cancelTask(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 更新Redis状态
|
|
|
|
|
|
updateRedisStatus(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@SneakyThrows |
|
|
@SneakyThrows |
|
|
public void requestCurrentStatus() { |
|
|
public void requestCurrentStatus() { |
|
|
amrMessageHandler.sendCmdQueryStatus(this.getId()); |
|
|
amrMessageHandler.sendCmdQueryStatus(this.getId()); |
|
|
@ -265,9 +234,9 @@ public abstract class PtrAgvItem extends ExecutorItem { |
|
|
if (this.isPaused) { |
|
|
if (this.isPaused) { |
|
|
return false; |
|
|
return false; |
|
|
} |
|
|
} |
|
|
// if (this.taskMode != AmrTaskMode.AMR_FREE_MODE) {
|
|
|
// if (this.taskMode != AmrTaskMode.AMR_FREE_MODE) {
|
|
|
// return false;
|
|
|
// return false;
|
|
|
// }
|
|
|
// }
|
|
|
return this.isOnline; |
|
|
return this.isOnline; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -278,9 +247,17 @@ public abstract class PtrAgvItem extends ExecutorItem { |
|
|
for (PtrAgvDeviceTask task : runningDeviceTaskList) { |
|
|
for (PtrAgvDeviceTask task : runningDeviceTaskList) { |
|
|
task.taskGroupStatus = taskStatus; |
|
|
task.taskGroupStatus = taskStatus; |
|
|
if (taskStatus == 4) { |
|
|
if (taskStatus == 4) { |
|
|
|
|
|
|
|
|
|
|
|
this.runtime.eventManager.fireDeviceTaskCompleteEvent(this, task); |
|
|
|
|
|
task.taskStatus = 4; |
|
|
|
|
|
|
|
|
// 更新计划任务
|
|
|
// 更新计划任务
|
|
|
List<RcsTaskPlan> planTaskList = planTaskSequence.taskList.stream().filter(pt -> task.movePlanTaskId.equals(pt.getPlanTaskId()) || task.planTaskIdSet.contains(pt.getPlanTaskId())).toList(); |
|
|
List<RcsTaskPlan> planTaskList = planTaskSequence.taskList.stream().filter(pt -> task.movePlanTaskId.equals(pt.getPlanTaskId()) || task.planTaskIdSet.contains(pt.getPlanTaskId())).toList(); |
|
|
for (RcsTaskPlan planTask : planTaskList) { |
|
|
for (RcsTaskPlan planTask : planTaskList) { |
|
|
|
|
|
if (PlanTaskStatus.FINISHED.toString().equals(planTask.getPlanTaskStatus())) { |
|
|
|
|
|
continue; |
|
|
|
|
|
} |
|
|
|
|
|
this.runtime.eventManager.firePlanTaskCompleteEvent(this, planTaskSequence, planTask); |
|
|
planTask.setPlanTaskStatus(PlanTaskStatus.FINISHED.toString()); |
|
|
planTask.setPlanTaskStatus(PlanTaskStatus.FINISHED.toString()); |
|
|
planTaskSequence.savePlanTask(planTask); |
|
|
planTaskSequence.savePlanTask(planTask); |
|
|
} |
|
|
} |
|
|
@ -288,7 +265,7 @@ public abstract class PtrAgvItem extends ExecutorItem { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (planTaskSequence != null && planTaskSequence.isAllCompleted()) { |
|
|
if (planTaskSequence != null && planTaskSequence.isAllCompleted()) { |
|
|
fireEvent(AgvEventType.PLAN_TASK_SEQUENCE_COMPLETE, this); |
|
|
this.runtime.eventManager.firePlanTaskSequenceCompleteEvent(this, planTaskSequence); |
|
|
this.runningDeviceTaskList.clear(); |
|
|
this.runningDeviceTaskList.clear(); |
|
|
planTaskSequence = null; |
|
|
planTaskSequence = null; |
|
|
} |
|
|
} |
|
|
@ -304,18 +281,21 @@ public abstract class PtrAgvItem extends ExecutorItem { |
|
|
this.logicY = logicY; |
|
|
this.logicY = logicY; |
|
|
this.direction = direction; |
|
|
this.direction = direction; |
|
|
|
|
|
|
|
|
|
|
|
LCCDirection oldLccDirection = PathUtils.getDirectionByArmDirection(oldDirection); |
|
|
|
|
|
LCCDirection newLccDirection = PathUtils.getDirectionByArmDirection(direction); |
|
|
|
|
|
|
|
|
// 更新Redis
|
|
|
// 更新Redis
|
|
|
updateRedisStatus(); |
|
|
updateRedisStatus(); |
|
|
|
|
|
|
|
|
// 触发位置变化事件
|
|
|
// 触发位置变化事件
|
|
|
if (oldX != logicX || oldY != logicY) { |
|
|
if (oldX != logicX || oldY != logicY) { |
|
|
fireEvent(AgvEventType.POS_CHANGED, this, |
|
|
this.runtime.eventManager.firePosChangedEvent(this, |
|
|
new PosDirection(logicX, logicY, direction), |
|
|
new PosDirection(logicX, logicY, newLccDirection), |
|
|
new PosDirection(oldX, oldY, oldDirection)); |
|
|
new PosDirection(oldX, oldY, oldLccDirection)); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (oldDirection != direction) { |
|
|
if (oldDirection != direction) { |
|
|
fireEvent(AgvEventType.DIRECTION_CHANGED, this, direction, oldDirection); |
|
|
this.runtime.eventManager.fireDirectionChangedEvent(this, newLccDirection, oldLccDirection); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
boolean needCompute = false; |
|
|
boolean needCompute = false; |
|
|
@ -340,19 +320,18 @@ public abstract class PtrAgvItem extends ExecutorItem { |
|
|
for (int i = 0; i <= finishTargetIndex; i++) { |
|
|
for (int i = 0; i <= finishTargetIndex; i++) { |
|
|
PtrAgvDeviceTask task = runningDeviceTaskList.get(i); |
|
|
PtrAgvDeviceTask task = runningDeviceTaskList.get(i); |
|
|
task.taskStatus = 4; // 标记为完成
|
|
|
task.taskStatus = 4; // 标记为完成
|
|
|
fireEvent(AgvEventType.DEVICE_TASK_COMPLETE, this, task); |
|
|
this.runtime.eventManager.fireDeviceTaskCompleteEvent(this, task); |
|
|
|
|
|
|
|
|
// 更新计划任务
|
|
|
// 更新计划任务
|
|
|
RcsTaskPlan planTask = planTaskSequence.getByPlanTaskId(task.movePlanTaskId); |
|
|
RcsTaskPlan planTask = planTaskSequence.getByPlanTaskId(task.movePlanTaskId); |
|
|
if (planTask != null && !PlanTaskStatus.FINISHED.toString().equals(planTask.getPlanTaskStatus())) { |
|
|
if (planTask != null && !PlanTaskStatus.FINISHED.toString().equals(planTask.getPlanTaskStatus())) { |
|
|
fireEvent(AgvEventType.DEVICE_TASK_COMPLETE, this, planTaskSequence, planTask); |
|
|
|
|
|
planTask.setPlanTaskStatus(PlanTaskStatus.FINISHED.toString()); |
|
|
planTask.setPlanTaskStatus(PlanTaskStatus.FINISHED.toString()); |
|
|
planTaskSequence.savePlanTask(planTask); |
|
|
this.runtime.eventManager.firePlanTaskCompleteEvent(this, planTaskSequence, planTask); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (planTaskSequence.isAllCompleted()) { |
|
|
if (planTaskSequence.isAllCompleted()) { |
|
|
fireEvent(AgvEventType.PLAN_TASK_SEQUENCE_COMPLETE, this); |
|
|
this.runtime.eventManager.firePlanTaskSequenceCompleteEvent(this, planTaskSequence); |
|
|
this.runningDeviceTaskList.clear(); |
|
|
this.runningDeviceTaskList.clear(); |
|
|
planTaskSequence = null; |
|
|
planTaskSequence = null; |
|
|
} |
|
|
} |
|
|
@ -397,7 +376,14 @@ public abstract class PtrAgvItem extends ExecutorItem { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public void updateTaskMode(int taskMode) { |
|
|
public void updateTaskMode(int taskMode) { |
|
|
this.taskMode = AmrTaskMode.fromValue(taskMode); |
|
|
this.setTaskMode(AmrTaskMode.fromValue(taskMode)); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void setTaskMode(AmrTaskMode taskMode) { |
|
|
|
|
|
var originalMode = this.__taskMode; |
|
|
|
|
|
this.__taskMode = taskMode; |
|
|
|
|
|
this.runtime.eventManager.fireModeChangeEvent(this, taskMode, originalMode); |
|
|
|
|
|
updateRedisStatus(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public void updateRedisStatus() { |
|
|
public void updateRedisStatus() { |
|
|
@ -411,11 +397,10 @@ public abstract class PtrAgvItem extends ExecutorItem { |
|
|
statusMap.put("direction", String.valueOf(direction)); |
|
|
statusMap.put("direction", String.valueOf(direction)); |
|
|
statusMap.put("orientation", String.valueOf(orientation)); |
|
|
statusMap.put("orientation", String.valueOf(orientation)); |
|
|
statusMap.put("soc", this.battery == null ? "-1" : String.valueOf(this.battery.SOC)); |
|
|
statusMap.put("soc", this.battery == null ? "-1" : String.valueOf(this.battery.SOC)); |
|
|
statusMap.put("mode", isManualMode ? "MANUAL" : "AUTO"); |
|
|
statusMap.put("mode", this.__taskMode.toString()); |
|
|
statusMap.put("taskStatus", getTaskStatus()); |
|
|
statusMap.put("taskStatus", getTaskStatus()); |
|
|
|
|
|
|
|
|
redis.hPutAll(statusKey, statusMap); |
|
|
redis.hPutAll(statusKey, statusMap); |
|
|
redis.kExpire(statusKey, 10); // 10秒过期
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public void handleHeartbeat(AmrHeartbeatMessage heartbeat) { |
|
|
public void handleHeartbeat(AmrHeartbeatMessage heartbeat) { |
|
|
@ -433,7 +418,7 @@ public abstract class PtrAgvItem extends ExecutorItem { |
|
|
|
|
|
|
|
|
// 检查低电量
|
|
|
// 检查低电量
|
|
|
if (this.battery.SOC < 20) { |
|
|
if (this.battery.SOC < 20) { |
|
|
fireEvent(AgvEventType.LOW_BATTERY, this); |
|
|
this.runtime.eventManager.fireLowBatteryEvent(this); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
updateRedisStatus(); |
|
|
updateRedisStatus(); |
|
|
@ -441,13 +426,13 @@ public abstract class PtrAgvItem extends ExecutorItem { |
|
|
|
|
|
|
|
|
public void handleOnlineEvent() { |
|
|
public void handleOnlineEvent() { |
|
|
isOnline = true; |
|
|
isOnline = true; |
|
|
fireEvent(AgvEventType.ONLINE, this); |
|
|
this.runtime.eventManager.fireOnlineEvent(this); |
|
|
requestCurrentStatus(); |
|
|
requestCurrentStatus(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public void handleOfflineEvent() { |
|
|
public void handleOfflineEvent() { |
|
|
isOnline = false; |
|
|
isOnline = false; |
|
|
fireEvent(AgvEventType.OFFLINE, this); |
|
|
this.runtime.eventManager.fireOfflineEvent(this); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private String getTaskStatus() { |
|
|
private String getTaskStatus() { |
|
|
@ -787,13 +772,12 @@ public abstract class PtrAgvItem extends ExecutorItem { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// planQueue.addAll(sequence.taskList);
|
|
|
|
|
|
deviceTaskQueue.addAll(deviceTaskList); |
|
|
deviceTaskQueue.addAll(deviceTaskList); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public boolean isSamePosition(PosDirection startPos) { |
|
|
public boolean isSamePosition(PosDirection startPos) { |
|
|
return this.logicX == startPos.logicX() && this.logicY == startPos.logicY() && this.direction == startPos.direction(); |
|
|
return this.logicX == startPos.logicX() && this.logicY == startPos.logicY() && |
|
|
|
|
|
PathUtils.getDirectionByArmDirection(this.direction) == startPos.direction(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private static class CDirection { |
|
|
private static class CDirection { |
|
|
|