package com.algo.model;
|
|
import java.util.List;
|
import java.util.Objects;
|
|
/**
|
* AGV状态信息
|
* 包含AGV的完整状态数据,包括剩余路径和CTU物理参数
|
*/
|
public class AGVStatus {
|
|
/**
|
* AGV编号
|
*/
|
private String agvId;
|
|
/**
|
* AGV状态
|
*/
|
private int status;
|
|
/**
|
* AGV当前位置
|
*/
|
private String position;
|
|
/**
|
* 空背篓数量
|
*/
|
private String empty;
|
|
/**
|
* AGV方向角度
|
*/
|
private String direction;
|
|
/**
|
* 电压电量值
|
*/
|
private int vol;
|
|
/**
|
* 异常码,0表示正常
|
*/
|
private int error;
|
|
/**
|
* 背篓数据列表
|
*/
|
private List<BackpackData> backpack;
|
|
/**
|
* 低电量设定阈值,低于该值可以去自动充电也可以继续做任务
|
*/
|
private int autoCharge;
|
|
/**
|
* 最低电量,电量低于该值必须去充电
|
*/
|
private int lowVol;
|
|
/**
|
* CTU剩余未完成的路径,格式与输出路径相同
|
*/
|
private PlannedPath remainingPath;
|
|
/**
|
* CTU物理参数配置
|
*/
|
private CTUPhysicalConfig physicalConfig;
|
|
/**
|
* 当前执行路径中的位置索引(从剩余路径开始计算)
|
*/
|
private int currentPathIndex;
|
|
/**
|
* 预计到达下一个路径点的时间戳(毫秒)
|
*/
|
private long nextPointArrivalTime;
|
|
// 构造函数
|
public AGVStatus() {
|
this.physicalConfig = new CTUPhysicalConfig(); // 使用默认配置
|
this.currentPathIndex = 0;
|
this.nextPointArrivalTime = System.currentTimeMillis();
|
}
|
|
public AGVStatus(String agvId, int status, String position, String empty,
|
String direction, int vol, int error, List<BackpackData> backpack,
|
int autoCharge, int lowVol) {
|
this.agvId = agvId;
|
this.status = status;
|
this.position = position;
|
this.empty = empty;
|
this.direction = direction;
|
this.vol = vol;
|
this.error = error;
|
this.backpack = backpack;
|
this.autoCharge = autoCharge;
|
this.lowVol = lowVol;
|
this.physicalConfig = new CTUPhysicalConfig(); // 使用默认配置
|
this.currentPathIndex = 0;
|
this.nextPointArrivalTime = System.currentTimeMillis();
|
}
|
|
// 原有的Getter和Setter方法
|
public String getAgvId() {
|
return agvId;
|
}
|
|
public void setAgvId(String agvId) {
|
this.agvId = agvId;
|
}
|
|
public int getStatus() {
|
return status;
|
}
|
|
public void setStatus(int status) {
|
this.status = status;
|
}
|
|
public String getPosition() {
|
return position;
|
}
|
|
public void setPosition(String position) {
|
this.position = position;
|
}
|
|
public String getEmpty() {
|
return empty;
|
}
|
|
public void setEmpty(String empty) {
|
this.empty = empty;
|
}
|
|
public String getDirection() {
|
return direction;
|
}
|
|
public void setDirection(String direction) {
|
this.direction = direction;
|
}
|
|
public int getVol() {
|
return vol;
|
}
|
|
public void setVol(int vol) {
|
this.vol = vol;
|
}
|
|
public int getError() {
|
return error;
|
}
|
|
public void setError(int error) {
|
this.error = error;
|
}
|
|
public List<BackpackData> getBackpack() {
|
return backpack;
|
}
|
|
public void setBackpack(List<BackpackData> backpack) {
|
this.backpack = backpack;
|
}
|
|
public int getAutoCharge() {
|
return autoCharge;
|
}
|
|
public void setAutoCharge(int autoCharge) {
|
this.autoCharge = autoCharge;
|
}
|
|
public int getLowVol() {
|
return lowVol;
|
}
|
|
public void setLowVol(int lowVol) {
|
this.lowVol = lowVol;
|
}
|
|
// 新增的剩余路径和物理参数相关的Getter和Setter方法
|
public PlannedPath getRemainingPath() {
|
return remainingPath;
|
}
|
|
public void setRemainingPath(PlannedPath remainingPath) {
|
this.remainingPath = remainingPath;
|
}
|
|
public CTUPhysicalConfig getPhysicalConfig() {
|
return physicalConfig;
|
}
|
|
public void setPhysicalConfig(CTUPhysicalConfig physicalConfig) {
|
this.physicalConfig = physicalConfig;
|
}
|
|
public int getCurrentPathIndex() {
|
return currentPathIndex;
|
}
|
|
public void setCurrentPathIndex(int currentPathIndex) {
|
this.currentPathIndex = currentPathIndex;
|
}
|
|
public long getNextPointArrivalTime() {
|
return nextPointArrivalTime;
|
}
|
|
public void setNextPointArrivalTime(long nextPointArrivalTime) {
|
this.nextPointArrivalTime = nextPointArrivalTime;
|
}
|
|
/**
|
* 检查CTU是否有剩余未完成的路径
|
*
|
* @return true如果有剩余路径
|
*/
|
public boolean hasRemainingPath() {
|
return remainingPath != null &&
|
remainingPath.getCodeList() != null &&
|
!remainingPath.getCodeList().isEmpty() &&
|
currentPathIndex < remainingPath.getCodeList().size();
|
}
|
|
/**
|
* 获取剩余路径的长度(从当前位置开始)
|
*
|
* @return 剩余路径点数量
|
*/
|
public int getRemainingPathLength() {
|
if (!hasRemainingPath()) {
|
return 0;
|
}
|
return remainingPath.getCodeList().size() - currentPathIndex;
|
}
|
|
/**
|
* 获取当前正在执行的路径点
|
*
|
* @return 当前路径点,如果没有则返回null
|
*/
|
public PathCode getCurrentPathCode() {
|
if (!hasRemainingPath()) {
|
return null;
|
}
|
return remainingPath.getCodeList().get(currentPathIndex);
|
}
|
|
/**
|
* 获取下一个要到达的路径点
|
*
|
* @return 下一个路径点,如果没有则返回null
|
*/
|
public PathCode getNextPathCode() {
|
if (!hasRemainingPath() || currentPathIndex + 1 >= remainingPath.getCodeList().size()) {
|
return null;
|
}
|
return remainingPath.getCodeList().get(currentPathIndex + 1);
|
}
|
|
/**
|
* 检查AGV是否可用(空闲且非故障状态)
|
*
|
* @return true如果AGV可用
|
*/
|
public boolean isAvailable() {
|
return error == 0 && status == 0 && vol > lowVol;
|
}
|
|
/**
|
* 检查CTU是否可以接受新任务(考虑剩余路径)
|
*
|
* @return true如果可以接受新任务
|
*/
|
public boolean canAcceptNewTask() {
|
// 如果有剩余路径,需要等待完成后才能接受新任务
|
// 除非剩余路径很短(比如只有1个点)
|
if (hasRemainingPath()) {
|
int remainingLength = getRemainingPathLength();
|
return remainingLength <= 1; // 允许在即将完成当前路径时接受新任务
|
}
|
return isAvailable();
|
}
|
|
/**
|
* 获取可用的背篓数量
|
*
|
* @return 可用背篓数量
|
*/
|
public int getAvailableBackpackCount() {
|
if (backpack == null || backpack.isEmpty()) {
|
return 0;
|
}
|
|
int count = 0;
|
for (BackpackData bp : backpack) {
|
if (!bp.isLoaded() && bp.getTaskId() == null) {
|
count++;
|
}
|
}
|
return count;
|
}
|
|
/**
|
* 查找可用的背篓位置
|
*
|
* @return 可用背篓的索引,如果没有可用则返回-1
|
*/
|
public int findAvailableBackpackIndex() {
|
if (backpack == null || backpack.isEmpty()) {
|
return -1;
|
}
|
|
for (BackpackData bp : backpack) {
|
if (!bp.isLoaded() && bp.getTaskId() == null) {
|
return bp.getIndex();
|
}
|
}
|
return -1;
|
}
|
|
/**
|
* 检查AGV是否需要充电
|
*
|
* @return true如果需要充电
|
*/
|
public boolean needsCharging() {
|
return vol <= autoCharge;
|
}
|
|
/**
|
* 检查AGV是否必须充电
|
*
|
* @return true如果必须充电
|
*/
|
public boolean mustCharge() {
|
return vol <= lowVol;
|
}
|
|
@Override
|
public boolean equals(Object o) {
|
if (this == o) return true;
|
if (o == null || getClass() != o.getClass()) return false;
|
AGVStatus agvStatus = (AGVStatus) o;
|
return Objects.equals(agvId, agvStatus.agvId);
|
}
|
|
@Override
|
public int hashCode() {
|
return Objects.hash(agvId);
|
}
|
|
@Override
|
public String toString() {
|
return "AGVStatus{" +
|
"agvId='" + agvId + '\'' +
|
", status=" + status +
|
", position='" + position + '\'' +
|
", empty='" + empty + '\'' +
|
", direction='" + direction + '\'' +
|
", vol=" + vol +
|
", error=" + error +
|
", backpack=" + (backpack != null ? backpack.size() : 0) +
|
", autoCharge=" + autoCharge +
|
", lowVol=" + lowVol +
|
", hasRemainingPath=" + hasRemainingPath() +
|
", remainingPathLength=" + getRemainingPathLength() +
|
", physicalConfig=" + physicalConfig +
|
'}';
|
}
|
}
|