#
luxiaotao1123
2024-11-11 3e77828236068dd269e43aa33106f6b9c781775e
#
3个文件已修改
1个文件已添加
238 ■■■■■ 已修改文件
zy-acs-common/src/main/java/com/zy/acs/common/enums/AgvCompleteType.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/PatrolService.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/fake/AgvSimulatorTask.java 170 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/fake/FakeProcessor.java 58 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-common/src/main/java/com/zy/acs/common/enums/AgvCompleteType.java
@@ -50,4 +50,11 @@
        return null;
    }
    public int getCode() {
        return code;
    }
    public String getDesc() {
        return desc;
    }
}
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/PatrolService.java
@@ -34,8 +34,11 @@
public class PatrolService {
    private static final int SCHEDULE_TIME_INTERVAL = 1;
    private static final Map<String, ScheduledFuture<?>> AGV_PATROL_MAP = new ConcurrentHashMap<>();
    private final RedisSupport redis = RedisSupport.defaultRedisSupport;
    private ScheduledExecutorService scheduler = null;
    @Autowired
zy-acs-manager/src/main/java/com/zy/acs/manager/fake/AgvSimulatorTask.java
New file
@@ -0,0 +1,170 @@
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);
    }
}
zy-acs-manager/src/main/java/com/zy/acs/manager/fake/FakeProcessor.java
@@ -3,30 +3,42 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zy.acs.common.constant.RedisConstant;
import com.zy.acs.common.domain.AgvProtocol;
import com.zy.acs.common.domain.protocol.AGV_01_DOWN;
import com.zy.acs.common.domain.protocol.AGV_01_UP;
import com.zy.acs.common.utils.RedisSupport;
import com.zy.acs.framework.common.Cools;
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.enums.ActionStsType;
import com.zy.acs.manager.manager.enums.StatusType;
import com.zy.acs.manager.manager.service.ActionService;
import com.zy.acs.manager.manager.service.AgvDetailService;
import com.zy.acs.manager.manager.service.AgvService;
import com.zy.acs.manager.manager.service.CodeService;
import com.zy.acs.manager.system.service.ConfigService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
 * Created by vincent on 11/9/2024
 */
@Slf4j
@Component
public class FakeProcessor {
    private final RedisSupport redis = RedisSupport.defaultRedisSupport;
    public static final Map<Long, Boolean> AGV_PROCESSING_MAP = new ConcurrentHashMap<>();
    private ExecutorService executorService;
    @Autowired
    private AgvService agvService;
@@ -36,6 +48,8 @@
    private ActionService actionService;
    @Autowired
    private ConfigService configService;
    @Autowired
    private CodeService codeService;
    /**
     * 1.AgvDataService.dataProcess [ agvDetail: vol, code, agvAngle, agvStatus ]
@@ -52,22 +66,33 @@
        }
        List<Agv> agvList = agvService.list(new LambdaQueryWrapper<Agv>().eq(Agv::getStatus, StatusType.ENABLE.val));
        for (Agv agv : agvList) {
            AgvDetail agvDetail = agvDetailService.selectByAgvId(agv.getId());
        // init executorService
        if (null == this.executorService) {
            int count = agvList.size() > 30 ? agvList.size() : 20;
            this.executorService = Executors.newFixedThreadPool(count);
        }
            this.processRunning(agv);
        this.responseTheRequest();
        for (Agv agv : agvList) {
            AGV_PROCESSING_MAP.putIfAbsent(agv.getId(), false);
            this.processOnline(agv);
        }
    }
    private void processRunning(Agv agv) {
        List<Action> actionList = actionService.queryLatestGroup(agv.getId(), ActionStsType.ISSUED);
        if (!Cools.isEmpty(actionList)) {
            for (Action action : actionList) {
            if (!AGV_PROCESSING_MAP.get(agv.getId())) {
                List<Action> actionList = actionService.queryLatestGroup(agv.getId(), ActionStsType.ISSUED);
                if (!Cools.isEmpty(actionList)) {
                    executorService.submit(new AgvSimulatorTask(
                            agv
                            , redis
                            , agvDetailService
                            , actionService
                            , codeService
                            , actionList
                    ));
                }
            }
        }
    }
@@ -82,11 +107,14 @@
                Thread.sleep(100);
            } catch (InterruptedException ignore) {}
            AGV_01_DOWN agv_01_down = (AGV_01_DOWN) protocol.getMessageBody();
//            redis.setObject(RedisConstant.AGV_PATH_UP_FLAG
//                    , protocol.getAgvNo() + "_" + agv_01_up.getSerialNo()
//                    , agv_01_up);
            AGV_01_UP agv_01_up = new AGV_01_UP();
            agv_01_up.setSerialNo(agv_01_down.getSerialNo());
            redis.setObject(RedisConstant.AGV_PATH_UP_FLAG
                    , protocol.getAgvNo() + "_" + agv_01_up.getSerialNo()
                    , agv_01_up);
        }
    }