package com.zy.acs.manager.fake;
|
|
import com.zy.acs.common.constant.RedisConstant;
|
import com.zy.acs.common.domain.AgvProtocol;
|
import com.zy.acs.common.domain.protocol.AGV_11_UP;
|
import com.zy.acs.common.enums.AgvCompleteType;
|
import com.zy.acs.common.utils.RedisSupport;
|
import com.zy.acs.manager.manager.entity.Action;
|
import com.zy.acs.manager.manager.entity.Agv;
|
import com.zy.acs.manager.manager.entity.AgvDetail;
|
import com.zy.acs.manager.manager.entity.Code;
|
import com.zy.acs.manager.manager.enums.ActionStsType;
|
import com.zy.acs.manager.manager.enums.ActionTypeType;
|
import com.zy.acs.manager.manager.service.ActionService;
|
import com.zy.acs.manager.manager.service.AgvDetailService;
|
import com.zy.acs.manager.manager.service.CodeService;
|
import lombok.extern.slf4j.Slf4j;
|
|
import java.util.List;
|
import java.util.Objects;
|
|
/**
|
* Created by vincent on 11/11/2024
|
*/
|
@Slf4j
|
public class AgvSimulatorTask implements Runnable {
|
|
private final Agv agv;
|
private final AgvDetailService agvDetailService;
|
private final ActionService actionService;
|
private final CodeService codeService;
|
private final List<Action> actionList;
|
|
private final RedisSupport redis;
|
|
private final String groupId;
|
|
public AgvSimulatorTask(
|
Agv agv
|
, RedisSupport redis
|
, AgvDetailService agvDetailService
|
, ActionService actionService
|
, CodeService codeService
|
, List<Action> actionList
|
) {
|
this.agv = agv;
|
this.redis = redis;
|
this.agvDetailService = agvDetailService;
|
this.actionService = actionService;
|
this.codeService = codeService;
|
this.actionList = actionList;
|
|
this.groupId = actionList.get(0).getGroupId();
|
}
|
|
@Override
|
public void run() {
|
try {
|
FakeProcessor.AGV_PROCESSING_MAP.put(agv.getId(), true);
|
String qrCode = null;
|
for (Action action : actionList) {
|
processAction(agv, action);
|
qrCode = action.getCode();
|
}
|
this.finishActionList(qrCode);
|
} catch (Exception e) {
|
log.error("AgvSimulatorTask AGV[{}]", agv.getUuid(), e);
|
} finally {
|
FakeProcessor.AGV_PROCESSING_MAP.put(agv.getId(), false);
|
}
|
}
|
|
private void processAction(Agv agv, Action action) throws InterruptedException {
|
AgvDetail agvDetail = agvDetailService.selectByAgvId(agv.getId());
|
if (agvDetail == null) {
|
return;
|
}
|
|
switch (Objects.requireNonNull(ActionTypeType.get(action.getActionTypeEl()))) {
|
case TurnCorner:
|
simulateRotating(agv, agvDetail, action);
|
break;
|
case StraightBackUnturnable:
|
case StraightBackTurnable:
|
case StraightAheadUnturnable:
|
case StraightAheadTurnable:
|
case FinishPath:
|
case DockingCharge:
|
simulateWalking(agv, agvDetail, action);
|
break;
|
case ReadyTakeFromShelvesLoc:
|
case ReadyReleaseToShelvesLoc:
|
break;
|
default:
|
log.warn("Unknown action type {} for AGV ID {}.", action.getActionType(), agv.getId());
|
break;
|
}
|
}
|
|
|
private void simulateWalking(Agv agv, AgvDetail agvDetail, Action action) throws InterruptedException {
|
Code currCode = codeService.getById(agvDetail.getRecentCode());
|
Code code = codeService.selectByData(action.getCode());
|
|
agvDetail.setPos(1);
|
agvDetail.setCode(code.getId());
|
|
// 模拟电量消耗
|
// agvDetail.setVol(agvDetail.getVol() - 0.1 * distanceToMove); // 根据距离消耗电量
|
|
agvDetailService.updateById(agvDetail);
|
|
Thread.sleep(1000);
|
|
action.setActionSts(ActionStsType.FINISH.val());
|
actionService.updateById(action);
|
|
|
}
|
|
/**
|
* 模拟AGV旋转
|
*
|
* @param agv 当前AGV
|
* @param agvDetail AGV详细信息
|
* @param action 当前动作
|
*/
|
private void simulateRotating(Agv agv, AgvDetail agvDetail, Action action) throws InterruptedException {
|
// Double agvAngle = agvDetail.getAgvAngle();
|
// double actionAngle = Double.parseDouble(action.getParams());
|
|
|
|
double totalAngle = Double.parseDouble(action.getParams()); // 假设Action有angle属性
|
double stepAngle = 45.0; // 每秒旋转15度,具体值根据需求调整
|
double actionProgress = 0.0;
|
|
while (actionProgress < totalAngle) {
|
double angleToRotate = Math.min(stepAngle, totalAngle - actionProgress);
|
// 更新AGV的角度
|
double newAngle = (agvDetail.getAgvAngle() + angleToRotate) % 360;
|
agvDetail.setAgvAngle(newAngle);
|
|
// 模拟电量消耗
|
// agvDetail.setVol(agvDetail.getVol() - 0.05 * (angleToRotate / 15.0)); // 根据角度消耗电量
|
|
// 更新AGV详细信息
|
agvDetailService.updateById(agvDetail);
|
|
// 模拟实际执行时间
|
Thread.sleep(1000); // 每秒执行一次
|
|
actionProgress += angleToRotate;
|
}
|
|
// 动作完成,更新状态
|
action.setActionSts(ActionStsType.FINISH.val());
|
actionService.updateById(action);
|
}
|
|
private void finishActionList(String qrCode) {
|
// 1.complete data
|
AGV_11_UP agv_11_up = new AGV_11_UP();
|
agv_11_up.setSerialNo(groupId);
|
agv_11_up.setCompleteCode(AgvCompleteType.ENTIRE_PATH_COMPLETE.getCode());
|
agv_11_up.setCompleteType(AgvCompleteType.ENTIRE_PATH_COMPLETE);
|
agv_11_up.setQrCode(qrCode);
|
|
AgvProtocol agvProtocol = AgvProtocol.build(this.agv.getUuid()).setMessageBody(agv_11_up);
|
redis.push(RedisConstant.AGV_COMPLETE_FLAG, agvProtocol);
|
}
|
}
|