| | |
| | | IMU_ERROR(0xF1, "IMU异常状态"), |
| | | ERROR(0xFF, "故障状态"), |
| | | ; |
| | | // IDLE(0x00, "IDLE"), |
| | | // STRAIGHT(0x01, "直行状态"), |
| | | // TURN(0x03, "TURN"), |
| | | // CHARGE(0x07, "CHARGE"), |
| | | // LOW_POWER(0x08, "低功耗状态"), |
| | | // PAUSE(0x09, "定时暂停状态"), |
| | | // ROTATE(0x0A, "旋转标定状态"), |
| | | // MOTION(0x0B, "取放货状态"), |
| | | // TEMP(0x0C, "预留"), |
| | | // LOST(0xF0, "丢失地址码状态"), |
| | | // IMU_ERROR(0xF1, "IMU异常状态"), |
| | | // ERROR(0xFF, "故障状态"), |
| | | // ; |
| | | |
| | | public Integer val; |
| | | |
| | |
| | | |
| | | export const ANIMATE_DURING_TIME = 1000; |
| | | |
| | | export const MAP_MODE = Object.freeze({ |
| | | OBSERVER_MODE: "1", |
| | |
| | | DEVICE_SELECTED_EFFECT_COLOR, |
| | | POINT_ROUTE_DIRECTION, |
| | | DEVICE_SPRITE_TINT_DARK, |
| | | ANIMATE_DURING_TIME, |
| | | } from './constants'; |
| | | import { getRouteList } from './http'; |
| | | import PointRoute from "./PointRoute"; |
| | |
| | | const endRotation = sprite.rotation + rotationDifference; |
| | | |
| | | new TWEEDLE.Tween(sprite) |
| | | .to({ rotation: endRotation }, 1000) |
| | | .to({ rotation: endRotation }, ANIMATE_DURING_TIME) |
| | | .easing(TWEEDLE.Easing.Linear.None) |
| | | .onUpdate(() => { |
| | | // agv |
| | |
| | | .to({ |
| | | x: codeSprite.position.x, |
| | | y: codeSprite.position.y |
| | | }, 1000) |
| | | }, ANIMATE_DURING_TIME) |
| | | .easing(TWEEDLE.Easing.Linear.None) |
| | | .start(); |
| | | } |
| | |
| | | @Autowired |
| | | private MainService mainService; |
| | | @Autowired |
| | | private MainLockWrapService mainLockWrapService; |
| | | @Autowired |
| | | private SnowflakeIdWorker snowflakeIdWorker; |
| | | @Autowired |
| | | private CodeService codeService; |
| | |
| | | if (null == endCode) { |
| | | return R.error(); |
| | | } |
| | | if (!mainService.buildMinorTask(agv, agvDetail, param.getTaskMode(), endCode.getData())) { |
| | | if (!mainLockWrapService.buildMinorTask(agv, agvDetail, param.getTaskMode(), endCode.getData())) { |
| | | return R.error(); |
| | | } |
| | | break; |
| | | case TO_CHARGE: |
| | | case TO_STANDBY: |
| | | if (!mainService.buildMinorTask(agv, agvDetail, param.getTaskMode(), null)) { |
| | | if (!mainLockWrapService.buildMinorTask(agv, agvDetail, param.getTaskMode(), null)) { |
| | | return R.error(); |
| | | } |
| | | break; |
| | |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.zy.acs.manager.core.domain.AgvTaskDto; |
| | | import com.zy.acs.manager.core.service.MainLockWrapService; |
| | | import com.zy.acs.manager.core.service.MainService; |
| | | import com.zy.acs.manager.core.service.TrafficService; |
| | | import com.zy.acs.manager.manager.entity.Bus; |
| | |
| | | @Autowired |
| | | private MainService mainService; |
| | | @Autowired |
| | | private MainLockWrapService mainLockWrapService; |
| | | @Autowired |
| | | private ActionService actionService; |
| | | @Autowired |
| | | private SegmentService segmentService; |
| | |
| | | } |
| | | |
| | | for (AgvTaskDto dto : taskDtoList) { |
| | | mainService.buildMajorTask(dto.getAgvId(), dto.getTaskList()); |
| | | mainLockWrapService.buildMajorTask(dto.getAgvId(), dto.getTaskList()); |
| | | } |
| | | this.lock.unlock(); |
| | | } |
| | |
| | | import com.zy.acs.common.enums.AgvStatusType; |
| | | import com.zy.acs.common.utils.RedisSupport; |
| | | import com.zy.acs.framework.common.DateUtils; |
| | | import com.zy.acs.manager.core.service.MainLockWrapService; |
| | | import com.zy.acs.manager.core.service.MainService; |
| | | import com.zy.acs.manager.manager.entity.*; |
| | | import com.zy.acs.manager.manager.enums.*; |
| | |
| | | private FuncStaService funcStaService; |
| | | @Autowired |
| | | private MainService mainService; |
| | | @Autowired |
| | | private MainLockWrapService mainLockWrapService; |
| | | @Autowired |
| | | private TaskService taskService; |
| | | @Autowired |
| | |
| | | continue; |
| | | } |
| | | |
| | | mainService.buildMinorTask(agv, agvDetail, TaskTypeType.TO_CHARGE, null); |
| | | mainLockWrapService.buildMinorTask(agv, agvDetail, TaskTypeType.TO_CHARGE, null); |
| | | } |
| | | } |
| | | } |
| | |
| | | } |
| | | // } |
| | | |
| | | mainService.buildMinorTask(agv, agvDetail, TaskTypeType.TO_STANDBY, null); |
| | | mainLockWrapService.buildMinorTask(agv, agvDetail, TaskTypeType.TO_STANDBY, null); |
| | | } |
| | | } |
| | | |
New file |
| | |
| | | package com.zy.acs.manager.core.service; |
| | | |
| | | import com.zy.acs.framework.exception.CoolException; |
| | | import com.zy.acs.manager.manager.entity.Agv; |
| | | import com.zy.acs.manager.manager.entity.AgvDetail; |
| | | import com.zy.acs.manager.manager.entity.Task; |
| | | import com.zy.acs.manager.manager.enums.TaskTypeType; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.interceptor.TransactionAspectSupport; |
| | | |
| | | import java.util.List; |
| | | import java.util.concurrent.TimeUnit; |
| | | import java.util.concurrent.locks.ReentrantLock; |
| | | |
| | | /** |
| | | * Created by vincent on 11/12/2024 |
| | | */ |
| | | @Slf4j |
| | | @Service |
| | | public class MainLockWrapService { |
| | | |
| | | private static final int LOCK_TIMEOUT = 5; |
| | | private final ReentrantLock lock = new ReentrantLock(Boolean.TRUE); |
| | | |
| | | @Autowired |
| | | private MainService mainService; |
| | | |
| | | public void buildMajorTask(Long agvId, List<Task> taskList) { |
| | | boolean lockAcquired = false; |
| | | try { |
| | | if (!(lockAcquired = this.lock.tryLock(LOCK_TIMEOUT, TimeUnit.SECONDS))) { |
| | | throw new CoolException("failed to generate [major task] action, cause can not acquire lock ..."); |
| | | } |
| | | |
| | | mainService.buildMajorTask(agvId, taskList); |
| | | } catch (Exception e) { |
| | | |
| | | log.error("MainLockWrapService.buildMajorTask[task]", e); |
| | | TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); |
| | | } finally { |
| | | if (lockAcquired) { |
| | | this.lock.unlock(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | public boolean buildMinorTask(Agv agv, AgvDetail agvDetail, TaskTypeType taskType, String destination) { |
| | | boolean lockAcquired = false; |
| | | try { |
| | | if (!(lockAcquired = this.lock.tryLock(LOCK_TIMEOUT, TimeUnit.SECONDS))) { |
| | | throw new CoolException("failed to generate [minor task] actions, cause can not acquire lock ..."); |
| | | } |
| | | // log.info("buildMinorTask AGV[{}] lock time: {}", agv.getUuid(), System.currentTimeMillis()); |
| | | |
| | | return mainService.buildMinorTask(agv, agvDetail, taskType, destination); |
| | | } catch (Exception e) { |
| | | log.error("MainLockWrapService.buildMinorTask[task]", e); |
| | | TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); |
| | | |
| | | return false; |
| | | } finally { |
| | | |
| | | if (lockAcquired) { |
| | | this.lock.unlock(); |
| | | } |
| | | // log.info("buildMinorTask AGV[{}] unlock time: {}", agv.getUuid(), System.currentTimeMillis()); |
| | | } |
| | | } |
| | | |
| | | } |
| | |
| | | import com.zy.acs.framework.common.SnowflakeIdWorker; |
| | | import com.zy.acs.framework.exception.CoolException; |
| | | import com.zy.acs.manager.common.domain.TaskDto; |
| | | import com.zy.acs.manager.common.domain.param.HandlerPublishParam; |
| | | import com.zy.acs.manager.common.exception.BusinessException; |
| | | import com.zy.acs.manager.common.utils.CommonUtil; |
| | | import com.zy.acs.manager.core.domain.AgvBackpackDto; |
| | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Component; |
| | | import org.springframework.transaction.annotation.Propagation; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.transaction.interceptor.TransactionAspectSupport; |
| | | |
| | | import java.util.*; |
| | | import java.util.concurrent.TimeUnit; |
| | | import java.util.concurrent.locks.ReentrantLock; |
| | | import java.util.stream.Collectors; |
| | | |
| | |
| | | |
| | | /** |
| | | * 解析取放货集合任务,进行最优的排列组合顺序 ( 车辆此时是空闲且静止的 ) |
| | | * todo: {@link com.zy.acs.manager.core.HandlerController#controlAgv(String, HandlerPublishParam)} |
| | | */ |
| | | @Transactional |
| | | public synchronized void buildMajorTask(Long agvId, List<Task> taskList) { |
| | | if (Cools.isEmpty(taskList)) { return; } |
| | | boolean lockAcquired = false; |
| | | @Transactional(propagation = Propagation.REQUIRES_NEW) |
| | | public void buildMajorTask(Long agvId, List<Task> taskList) { |
| | | if (Cools.isEmpty(agvId, taskList)) { return; } |
| | | try { |
| | | if (!(lockAcquired = this.lock.tryLock(LOCK_TIMEOUT, TimeUnit.SECONDS))) { |
| | | throw new CoolException("generate [task] action fail, cause can not acquire lock ..."); |
| | | } |
| | | |
| | | // valid ----------------------------------------------- |
| | | Agv agv = agvService.getById(agvId); |
| | | if (!agvService.judgeEnable(agv.getId(), true)) { |
| | |
| | | |
| | | } catch (Exception e) { |
| | | |
| | | log.error("mainService.mergeMajorTask[task]", e); |
| | | log.error("mainService.buildMajorTask[task]", e); |
| | | TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); |
| | | } finally { |
| | | |
| | | if (lockAcquired) { |
| | | this.lock.unlock(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 充电 回待机位任务 |
| | | */ |
| | | @Transactional |
| | | public synchronized boolean buildMinorTask(Agv agv, AgvDetail agvDetail, TaskTypeType taskType, String destination) { |
| | | @Transactional(propagation = Propagation.REQUIRES_NEW) // although there is a Transactional here that the lock is isolated, but we can't join the caller's Transactional |
| | | public boolean buildMinorTask(Agv agv, AgvDetail agvDetail, TaskTypeType taskType, String destination) { |
| | | if (Cools.isEmpty(agv, taskType)) { return false; } |
| | | boolean lockAcquired = false; |
| | | try { |
| | | if (!(lockAcquired = this.lock.tryLock(LOCK_TIMEOUT, TimeUnit.SECONDS))) { |
| | | throw new CoolException("generate [task] action fail, cause can not acquire lock ..."); |
| | | } |
| | | |
| | | if (null == agvDetail) { |
| | | agvDetail = agvDetailService.selectByAgvId(agv.getId()); |
| | | } |
| | |
| | | TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); |
| | | |
| | | return false; |
| | | } finally { |
| | | |
| | | if (lockAcquired) { |
| | | this.lock.unlock(); |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | private AgvDetailService agvDetailService; |
| | | @Autowired |
| | | private TaskService taskService; |
| | | // @Autowired |
| | | // private MainService mainService; |
| | | @Autowired |
| | | private MainService mainService; |
| | | private MainLockWrapService mainLockWrapService; |
| | | @Autowired |
| | | private CodeService codeService; |
| | | @Autowired |
| | |
| | | if (null == randomCode) { |
| | | return; |
| | | } |
| | | if (mainService.buildMinorTask(agv, agvDetail, TaskTypeType.MOVE, randomCode.getData())) { |
| | | if (mainLockWrapService.buildMinorTask(agv, agvDetail, TaskTypeType.MOVE, randomCode.getData())) { |
| | | log.info(agv.getUuid() + "开始走行演示..."); |
| | | } |
| | | } |
| | |
| | | @Autowired |
| | | private MainService mainService; |
| | | @Autowired |
| | | private MainLockWrapService mainLockWrapService; |
| | | @Autowired |
| | | private MapService mapService; |
| | | @Autowired |
| | | private MapDataDispatcher mapDataDispatcher; |
| | |
| | | if (!Cools.isEmpty(waitingSegList)) { |
| | | for (Segment waitingSeg : waitingSegList) { |
| | | if (!waitingSeg.getId().equals(segment.getId())) { |
| | | log.error("AGV[{}] 任务异常,服务器错误!!!", agv.getUuid()); |
| | | return; |
| | | } |
| | | } |
| | |
| | | |
| | | } else { |
| | | |
| | | return mainService.buildMinorTask(agv, null, TaskTypeType.MOVE, endCodeData); |
| | | return mainLockWrapService.buildMinorTask(agv, null, TaskTypeType.MOVE, endCodeData); |
| | | } |
| | | |
| | | return true; |
| | |
| | | @Slf4j |
| | | public class AgvSimulatorTask implements Runnable { |
| | | |
| | | public static final int ACTION_DURING_TIME = 1000; |
| | | |
| | | private final Agv agv; |
| | | private final AgvDetailService agvDetailService; |
| | | private final ActionService actionService; |
| | |
| | | // 模拟电量消耗 |
| | | // agvDetail.setVol(agvDetail.getVol() - 0.1 * distanceToMove); // 根据距离消耗电量 |
| | | |
| | | Thread.sleep(1000); |
| | | Thread.sleep(ACTION_DURING_TIME); |
| | | |
| | | agvDetailService.updateById(agvDetail); |
| | | |
| | |
| | | // 模拟电量消耗? |
| | | // agvDetail.setVol(agvDetail.getVol() - 0.05 * (angleToRotate / 15.0)); // 根据角度消耗电量 |
| | | |
| | | Thread.sleep(1000); |
| | | Thread.sleep(ACTION_DURING_TIME); |
| | | agvDetailService.updateById(agvDetail); |
| | | action.setActionSts(ActionStsType.FINISH.val()); |
| | | actionService.updateById(action); |