| | |
| | | import com.zy.acs.manager.common.domain.param.HandlerPublishParam; |
| | | import com.zy.acs.manager.common.exception.BusinessException; |
| | | import com.zy.acs.manager.core.domain.AgvBackpackDto; |
| | | import com.zy.acs.manager.core.domain.Lane; |
| | | import com.zy.acs.manager.core.domain.LaneDto; |
| | | import com.zy.acs.manager.core.domain.TaskPosDto; |
| | | import com.zy.acs.manager.core.integrate.conveyor.ConveyorStationService; |
| | | import com.zy.acs.manager.core.service.astart.MapDataDispatcher; |
| | |
| | | @Autowired |
| | | private SegmentService segmentService; |
| | | @Autowired |
| | | private TrafficService trafficService; |
| | | private LaneService laneService; |
| | | @Autowired |
| | | private AgvModelService agvModelService; |
| | | @Autowired |
| | | private LaneService laneService; |
| | | private LaneBuilder laneBuilder; |
| | | @Autowired |
| | | private ActionSorter actionSorter; |
| | | @Autowired |
| | |
| | | |
| | | |
| | | // generate travel |
| | | travelService.finishAll(agvId); |
| | | Travel travel = new Travel(); |
| | | travel.setUuid(String.valueOf(snowflakeIdWorker.nextId()).substring(3)); |
| | | travel.setTravelId(String.valueOf(snowflakeIdWorker.nextId()).substring(3)); |
| | |
| | | task.setOriCode(agvDetail.getCode()); |
| | | task.setDestCode(endCode.getId()); |
| | | // lane |
| | | Lane destLane = laneService.search(endCode.getData()); |
| | | if (null != destLane) { |
| | | task.setDestLaneHash(destLane.getHashCode()); |
| | | LaneDto destLaneDto = laneBuilder.search(endCode.getData()); |
| | | if (null != destLaneDto) { |
| | | task.setDestLaneHash(destLaneDto.getHashCode()); |
| | | } |
| | | task.setPriority(taskType.equals(TaskTypeType.TO_CHARGE)?2:1); |
| | | task.setTaskSts(TaskStsType.ASSIGN.val()); |
| | |
| | | } |
| | | |
| | | // generate travel |
| | | travelService.finishAll(agvId); |
| | | Travel travel = new Travel(); |
| | | travel.setUuid(String.valueOf(snowflakeIdWorker.nextId()).substring(3)); |
| | | travel.setTravelId(String.valueOf(snowflakeIdWorker.nextId()).substring(3)); |
| | |
| | | |
| | | AgvModel agvModel = agvModelService.getByAgvId(agvId); |
| | | Double workDirection = agvModel.getWorkDirection(); |
| | | final double oppWorkDir = (workDirection + 180) % 360; |
| | | boolean backupAction = null != agvModel.getBackupAction() && agvModel.getBackupActionBool(); |
| | | boolean needUndocking = null != agvModel.getNeedUndocking() && agvModel.getNeedUndockingBool(); |
| | | AgvSpeedType agvSpeedType = AgvSpeedType.query(agvModel.getTravelSpeed()); |
| | |
| | | String next = pathListPart.get(i); |
| | | |
| | | Code nextCode = codeService.getCacheByData(next); |
| | | // 车头朝前的下一个行走方向 |
| | | Double nextDirection = mapService.calculateDirection(lastCode, nextCode, angleOffsetVal); |
| | | |
| | | // 第一步:如果下一个方向正好是作业方向的相反方向,则重置下一个方向为作业方向,标记 reverse = true |
| | | // 反向角 |
| | | final double oppLastDir = (lastDirection + 180) % 360; |
| | | // 是否倒退行走 |
| | | boolean reverse = false; |
| | | if (nextDirection.equals((workDirection + 180) % 360)) { |
| | | nextDirection = workDirection; |
| | | reverse = true; |
| | | } |
| | | |
| | | // 第二步:判断当前节点是否可以旋转 |
| | | if (!lastCode.getCornerBool()) { |
| | | // 如果是作业方向,但是小车在巷道内方向错误,则停止 |
| | | if (reverse && !lastDirection.equals(nextDirection)) { |
| | | throw new CoolException(agvNo + "号小车方向错误,请推至转弯点手动调整"); |
| | | // 巷道逻辑 |
| | | if (!laneBuilder.isInitialized()) { |
| | | throw new CoolException("lanes are not initialized"); |
| | | } |
| | | LaneDto lastLaneDto = laneBuilder.search(lastCode.getData()); |
| | | LaneDto nextLaneDto = laneBuilder.search(nextCode.getData()); |
| | | // 进入巷道角度 |
| | | Double lastLaneDir = laneService.getLaneDirection(lastLaneDto); |
| | | Double nextLaneDir = laneService.getLaneDirection(nextLaneDto); |
| | | |
| | | // 巷道强制转弯,优先级 > workDirection |
| | | if (null != nextLaneDir) { |
| | | nextDirection = nextLaneDir; |
| | | |
| | | if (!lastDirection.equals(nextDirection)) { |
| | | if (!lastCode.getCornerBool()) { |
| | | throw new CoolException(agvNo + "号小车进入巷道需调整方向为 " + nextDirection + "°,请推至转弯点手动调整"); |
| | | } |
| | | // turn |
| | | actionList.add(new Action( |
| | | null, // 编号s |
| | | task.getBusId(), // 总线 |
| | | task.getId(), // 任务 |
| | | null, // 动作号 |
| | | null, // 优先级 |
| | | ActionTypeType.TurnCorner.desc, // 名称 |
| | | (double) mapService.spinDirection(lastCode).val, // 属性值 |
| | | lastCode.getData(), // 地面码 |
| | | String.valueOf(nextDirection), // 动作参数 |
| | | ActionTypeType.TurnCorner.val(), // 动作类型 |
| | | actionPrepareSts, // 动作进度 |
| | | agvId, // AGV |
| | | now // 工作时间 |
| | | )); |
| | | lastDirection = nextDirection; |
| | | } |
| | | // 如果不是作业方向,判断是否相反方向,如果反方向则倒退行走 |
| | | if (nextDirection.equals((lastDirection + 180) % 360)) { |
| | | nextDirection = lastDirection; |
| | | reverse = true; |
| | | } else if (null != lastLaneDir) { |
| | | nextDirection = lastLaneDir; |
| | | |
| | | if (!lastDirection.equals(nextDirection)) { |
| | | if (!lastCode.getCornerBool()) { |
| | | throw new CoolException(agvNo + "号小车离开巷道需调整方向为 " + nextDirection + "°,请推至转弯点手动调整"); |
| | | } |
| | | } |
| | | } else { |
| | | if (!lastDirection.equals(nextDirection)) { |
| | | // 如果下个节点方向与当前agv方向相反,则倒退行走,但是如果当前agv方向正好与工作方向相反,则旋转至工作方向 |
| | | if (nextDirection.equals((lastDirection + 180) % 360) && !workDirection.equals((lastDirection + 180) % 360)) { |
| | | |
| | | // 如果下一个方向正好是作业方向的相反方向,则重置下一个方向为作业方向,标记 reverse = true |
| | | if (nextDirection.equals(oppWorkDir)) { |
| | | nextDirection = workDirection; |
| | | reverse = true; |
| | | } |
| | | |
| | | // 判断当前节点是否可以旋转 |
| | | if (!lastCode.getCornerBool()) { |
| | | // 如果是作业方向,但是小车在巷道内方向错误,则停止 |
| | | if (reverse && !lastDirection.equals(nextDirection)) { |
| | | throw new CoolException(agvNo + "号小车方向错误,请推至转弯点手动调整"); |
| | | } |
| | | // 如果不是作业方向(另一组相反方向),判断是否相反方向,如果反方向则倒退行走 |
| | | if (nextDirection.equals(oppLastDir)) { |
| | | // 倒退时,因为agv方向没变,所以下一个方向还是agv方向,故nextDirection = lastDirection; |
| | | nextDirection = lastDirection; |
| | | reverse = true; |
| | | } else { |
| | | // turn |
| | | actionList.add(new Action( |
| | | null, // 编号s |
| | | task.getBusId(), // 总线 |
| | | task.getId(), // 任务 |
| | | null, // 动作号 |
| | | null, // 优先级 |
| | | ActionTypeType.TurnCorner.desc, // 名称 |
| | | (double) mapService.spinDirection(lastCode).val, // 属性值 |
| | | lastCode.getData(), // 地面码 |
| | | String.valueOf(nextDirection), // 动作参数 |
| | | ActionTypeType.TurnCorner.val(), // 动作类型 |
| | | actionPrepareSts, // 动作进度 |
| | | agvId, // AGV |
| | | now // 工作时间 |
| | | )); |
| | | } |
| | | // 总结:1.如果是作业组(差180°)方向,那么agv方向必须是作业方向,如果 reverse 则说明倒退,这时候nextDirection肯定会等于作业方向(前面赋值了),如果不相同,则报错 |
| | | // 2.如果不是作业组方向(另一组相反方向差180°),因为此函数不能旋转,所以差180°时只能倒退,倒退的时候因为agv不会旋转,所以nextDirection要变成agv方向 |
| | | } else { |
| | | if (!lastDirection.equals(nextDirection)) { |
| | | // 如果下一个方向与agv方向相反,则倒退行走,避免进行毫无意义的转弯动作。 |
| | | // 但是要注意:如果agv方向与工作方向正好相反,则需要旋转至工作方向,也就是为什么要加!workDirection.equals(oppLastDir)判断 |
| | | if (nextDirection.equals(oppLastDir) && !workDirection.equals(oppLastDir)) { |
| | | // 倒退时,因为agv方向没变,所以下一个方向还是agv方向,故nextDirection = lastDirection; |
| | | nextDirection = lastDirection; |
| | | reverse = true; |
| | | } else { |
| | | // turn |
| | | actionList.add(new Action( |
| | | null, // 编号s |
| | | task.getBusId(), // 总线 |
| | | task.getId(), // 任务 |
| | | null, // 动作号 |
| | | null, // 优先级 |
| | | ActionTypeType.TurnCorner.desc, // 名称 |
| | | (double) mapService.spinDirection(lastCode).val, // 属性值 |
| | | lastCode.getData(), // 地面码 |
| | | String.valueOf(nextDirection), // 动作参数 |
| | | ActionTypeType.TurnCorner.val(), // 动作类型 |
| | | actionPrepareSts, // 动作进度 |
| | | agvId, // AGV |
| | | now // 工作时间 |
| | | )); |
| | | |
| | | lastDirection = nextDirection; |
| | | lastDirection = nextDirection; |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | } |
| | | |
| | | // run |
| | | ActionTypeType actionType = ActionTypeType.StraightAheadTurnable; |
| | | if (reverse) { |
| | | actionType = ActionTypeType.StraightBackTurnable; |
| | | } |
| | | ActionTypeType actionType = reverse ? ActionTypeType.StraightBackTurnable : ActionTypeType.StraightAheadTurnable; |
| | | CodeGap gap = codeGapService.findByCodeOfBoth(lastCode.getId(), nextCode.getId()); |
| | | actionList.add(new Action( |
| | | null, // 编号 |