| New file |
| | |
| | | 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: |
| | | 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); |
| | | } |
| | | } |