| | |
| | | |
| | | LOCK TABLES `sys_config` WRITE; |
| | | /*!40000 ALTER TABLE `sys_config` DISABLE KEYS */; |
| | | INSERT INTO `sys_config` VALUES (1,'a','b','c',1,'dd','eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee',0,1,NULL,NULL,'2024-09-03 03:23:14',NULL,'2024-09-03 03:23:14','aaavv'),(2,'1','2','3',2,'4','5',1,1,NULL,NULL,'2024-09-03 03:54:51',NULL,'2024-09-03 03:54:51',NULL),(3,'','vb','d',NULL,NULL,NULL,1,1,NULL,2,'2024-09-05 12:40:15',2,'2024-09-05 12:44:52',NULL),(4,NULL,'任务总线接收上限数量','busLimit',2,'1',NULL,1,1,NULL,2,'2024-09-10 05:02:36',2,'2024-09-10 05:02:36',NULL),(5,'3080437672968192','任务总线接收上限数量','busLimit',2,'1',NULL,1,0,NULL,2,'2024-09-10 05:03:35',2,'2024-09-10 05:03:35',NULL),(6,'3080530866208768','货架方向','storeDirection',4,'{\"key\":\"row\", \"acs\": 1}',NULL,1,0,NULL,2,'2024-09-10 05:03:57',2,'2024-09-10 05:03:57',NULL),(7,'3080602718830592','地图x轴偏移角度(默认顺时针0度)','mapAngleOffsetVal',2,'270',NULL,1,1,NULL,2,'2024-09-10 05:04:14',2,'2026-04-07 02:45:38',NULL),(8,'3080671664799744','取放货Agv方向','workDirection',2,'90',NULL,1,1,NULL,2,'2024-09-10 05:04:31',2,'2024-09-10 05:04:31',NULL),(9,'3080749704019968','Agv行走速度','agvSpeed',3,'5',NULL,1,0,NULL,2,'2024-09-10 05:04:49',2,'2024-09-10 05:04:49',NULL),(10,'3080876476858368','巷道坐标同组值','sameGroupXy',3,'X',NULL,1,0,NULL,2,'2024-09-10 05:05:19',2,'2024-11-09 07:46:10',NULL),(11,'5385822480039936','冗余数据转入历史档周期(天)','dataExpiredDays',2,'-1',NULL,1,0,NULL,2,'2024-10-14 04:00:47',2,'2024-11-13 04:20:43',NULL),(12,'7198705308336128','RCS启动任务分配状态','TaskAssignMode',1,'TRUE',NULL,1,0,NULL,2,'2024-10-19 04:04:32',2,'2024-10-19 04:11:08',NULL),(13,'0385233689903104','单巷道车辆容载数量','maxAgvCountInLane',2,'2',NULL,1,0,NULL,2,'2024-10-28 00:06:40',2,'2024-10-28 00:06:40',NULL),(14,'1171843016687616','自动回待机位','automaticStandbyPosition',1,'0',NULL,1,0,NULL,2,'2024-10-30 04:12:22',2,'2024-12-05 05:14:12',NULL),(15,'1174416499015680','自动回待机位间隔(秒)','intervalOfAutoStandby',2,'15',NULL,1,0,NULL,2,'2024-10-30 04:22:36',2,'2024-11-29 06:51:07',NULL),(16,'4749527806246912','虚拟运行','fakeSign',1,'TRUE',NULL,1,0,NULL,2,'2024-11-09 01:08:49',2,'2024-11-09 03:57:04',NULL),(17,'1487422084612096','算法延长时间(单位:毫秒)','algoExtensionTime',2,'0',NULL,1,0,NULL,2,'2024-12-25 05:39:13',2,'2024-12-25 05:39:39',NULL),(18,'7392066282651649','Dashboard-AGV角度偏移量','dashboardAgvAngleOffsetVal',2,'0',NULL,1,0,NULL,2,'2026-01-04 07:15:46',2,'2026-04-07 04:43:26',NULL),(19,'7392156325969920','Dashboard-监控图镜面翻转','dashMapMirror',1,'1',NULL,1,0,NULL,2,'2026-01-04 07:16:07',2,'2026-04-07 04:45:24',NULL),(20,'7405872845094912','移库','TaskAssignMode3',1,'0',NULL,1,0,NULL,2,'2026-01-04 08:10:37',2,'2026-01-06 05:50:13',NULL),(21,'3453459058524160','自动移动','TaskAssignRebootMode',1,'0',NULL,1,0,NULL,2,'2026-01-21 00:41:34',2,'2026-02-09 05:17:48',NULL),(22,'3453459058524161','取放','defaultShelfDepth',2,'0',NULL,1,0,NULL,NULL,'2026-01-26 23:18:15',NULL,'2026-01-26 23:18:15',NULL),(23,'8839085828079616','233223','maintainLocSts',1,'0',NULL,1,0,NULL,2,'2026-04-01 01:54:59',2,'2026-04-01 01:54:59',NULL); |
| | | INSERT INTO `sys_config` VALUES (1,'a','b','c',1,'dd','eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee',0,1,NULL,NULL,'2024-09-03 03:23:14',NULL,'2024-09-03 03:23:14','aaavv'),(2,'1','2','3',2,'4','5',1,1,NULL,NULL,'2024-09-03 03:54:51',NULL,'2024-09-03 03:54:51',NULL),(3,'','vb','d',NULL,NULL,NULL,1,1,NULL,2,'2024-09-05 12:40:15',2,'2024-09-05 12:44:52',NULL),(4,NULL,'任务总线接收上限数量','busLimit',2,'1',NULL,1,1,NULL,2,'2024-09-10 05:02:36',2,'2024-09-10 05:02:36',NULL),(5,'3080437672968192','任务总线接收上限数量','busLimit',2,'1',NULL,1,0,NULL,2,'2024-09-10 05:03:35',2,'2024-09-10 05:03:35',NULL),(6,'3080530866208768','货架方向','storeDirection',4,'{\"key\":\"row\", \"acs\": 1}',NULL,1,0,NULL,2,'2024-09-10 05:03:57',2,'2024-09-10 05:03:57',NULL),(7,'3080602718830592','地图x轴偏移角度(默认顺时针0度)','mapAngleOffsetVal',2,'270',NULL,1,0,NULL,2,'2024-09-10 05:04:14',2,'2026-04-07 02:45:38',NULL),(8,'3080671664799744','取放货Agv方向','workDirection',2,'90',NULL,1,1,NULL,2,'2024-09-10 05:04:31',2,'2024-09-10 05:04:31',NULL),(9,'3080749704019968','Agv行走速度','agvSpeed',3,'5',NULL,1,0,NULL,2,'2024-09-10 05:04:49',2,'2024-09-10 05:04:49',NULL),(10,'3080876476858368','巷道坐标同组值','sameGroupXy',3,'X',NULL,1,0,NULL,2,'2024-09-10 05:05:19',2,'2024-11-09 07:46:10',NULL),(11,'5385822480039936','冗余数据转入历史档周期(天)','dataExpiredDays',2,'-1',NULL,1,0,NULL,2,'2024-10-14 04:00:47',2,'2024-11-13 04:20:43',NULL),(12,'7198705308336128','RCS启动任务分配状态','TaskAssignMode',1,'TRUE',NULL,1,0,NULL,2,'2024-10-19 04:04:32',2,'2024-10-19 04:11:08',NULL),(13,'0385233689903104','单巷道车辆容载数量','maxAgvCountInLane',2,'2',NULL,1,0,NULL,2,'2024-10-28 00:06:40',2,'2024-10-28 00:06:40',NULL),(14,'1171843016687616','自动回待机位','automaticStandbyPosition',1,'0',NULL,1,0,NULL,2,'2024-10-30 04:12:22',2,'2024-12-05 05:14:12',NULL),(15,'1174416499015680','自动回待机位间隔(秒)','intervalOfAutoStandby',2,'15',NULL,1,0,NULL,2,'2024-10-30 04:22:36',2,'2024-11-29 06:51:07',NULL),(16,'4749527806246912','虚拟运行','fakeSign',1,'TRUE',NULL,1,0,NULL,2,'2024-11-09 01:08:49',2,'2024-11-09 03:57:04',NULL),(17,'1487422084612096','算法延长时间(单位:毫秒)','algoExtensionTime',2,'0',NULL,1,0,NULL,2,'2024-12-25 05:39:13',2,'2024-12-25 05:39:39',NULL),(18,'7392066282651649','Dashboard-AGV角度偏移量','dashboardAgvAngleOffsetVal',2,'0',NULL,1,0,NULL,2,'2026-01-04 07:15:46',2,'2026-04-07 04:43:26',NULL),(19,'7392156325969920','Dashboard-监控图镜面翻转','dashMapMirror',1,'1',NULL,1,0,NULL,2,'2026-01-04 07:16:07',2,'2026-04-07 04:45:24',NULL),(20,'7405872845094912','移库','TaskAssignMode3',1,'0',NULL,1,0,NULL,2,'2026-01-04 08:10:37',2,'2026-01-06 05:50:13',NULL),(21,'3453459058524160','自动移动','TaskAssignRebootMode',1,'0',NULL,1,0,NULL,2,'2026-01-21 00:41:34',2,'2026-02-09 05:17:48',NULL),(22,'3453459058524161','取放','defaultShelfDepth',2,'0',NULL,1,0,NULL,NULL,'2026-01-26 23:18:15',NULL,'2026-01-26 23:18:15',NULL),(23,'8839085828079616','233223','maintainLocSts',1,'0',NULL,1,0,NULL,2,'2026-04-01 01:54:59',2,'2026-04-01 01:54:59',NULL); |
| | | /*!40000 ALTER TABLE `sys_config` ENABLE KEYS */; |
| | | UNLOCK TABLES; |
| | | |
| | |
| | | import com.zy.acs.manager.core.service.astart.MapDataDispatcher; |
| | | import com.zy.acs.manager.core.utils.AgvAngleUtils; |
| | | import com.zy.acs.manager.manager.entity.AgvDetail; |
| | | import com.zy.acs.manager.manager.entity.AgvModel; |
| | | import com.zy.acs.manager.manager.entity.Code; |
| | | import com.zy.acs.manager.manager.service.AgvDetailService; |
| | | import com.zy.acs.manager.manager.service.AgvModelService; |
| | | import com.zy.acs.manager.manager.service.AgvService; |
| | | import com.zy.acs.manager.manager.service.CodeService; |
| | | import com.zy.acs.manager.manager.service.JamService; |
| | |
| | | private AgvService agvService; |
| | | @Autowired |
| | | private AgvDetailService agvDetailService; |
| | | @Autowired |
| | | private AgvModelService agvModelService; |
| | | @Autowired |
| | | private CodeService codeService; |
| | | @Autowired |
| | |
| | | private void syncPose(AgvDetail detail, HkState state) { |
| | | HkStateAgvPosition agvPosition = state.getAgvPosition(); |
| | | HkStateVelocity velocity = state.getVelocity(); |
| | | AgvModel agvModel = agvModelService.getByAgvId(detail.getAgvId()); |
| | | |
| | | if (agvPosition != null && agvPosition.getTheta() != null) { |
| | | double angle = normalizeAngle(AgvAngleUtils.fromRadians(agvPosition.getTheta())); |
| | | Double rcsAngle = AgvAngleUtils.fromProtocolRadians(agvPosition.getTheta(), agvModel); |
| | | if (rcsAngle == null) { |
| | | return; |
| | | } |
| | | double angle = normalizeAngle(rcsAngle); |
| | | detail.setAgvAngle(angle); |
| | | detail.setGyroAngle(angle); |
| | | detail.setEncoderAngle(angle); |
| | |
| | | import com.zy.acs.manager.core.integrate.dto.OpenBusSubmitParam; |
| | | import com.zy.acs.manager.core.service.hik.HikOrderPublishService; |
| | | import com.zy.acs.manager.core.service.astart.MapDataDispatcher; |
| | | import com.zy.acs.manager.core.utils.AgvAngleUtils; |
| | | import com.zy.acs.manager.manager.entity.*; |
| | | import com.zy.acs.manager.manager.enums.*; |
| | | import com.zy.acs.manager.manager.service.*; |
| | |
| | | if (Cools.isEmpty(agvId, segmentList)) { return pathTrace; } |
| | | Date now = new Date(); |
| | | long actionPrepareSts = ActionStsType.PREPARE.val(); |
| | | int angleOffsetVal = configService.getVal("mapAngleOffsetVal", Integer.class); |
| | | // Double defaultShelfDepth = configService.getVal("defaultShelfDepth", Double.class); |
| | | // defaultShelfDepth = Optional.ofNullable(defaultShelfDepth).orElse((double) 0); |
| | | String agvNo = agvService.getAgvNo(agvId); |
| | |
| | | |
| | | Code nextCode = codeService.getCacheByData(next); |
| | | // 车头朝前的下一个行走方向 |
| | | Double nextDirection = AgvAngleUtils.calculateDirection(lastCode, nextCode, agvModel); |
| | | Double nextDirection = mapService.calculateDirection(lastCode, nextCode, angleOffsetVal); |
| | | |
| | | // 反向角 |
| | | final double oppLastDir = (lastDirection + 180) % 360; |
| | |
| | | import com.zy.acs.manager.manager.enums.ActionTypeType; |
| | | import com.zy.acs.manager.manager.service.AgvDetailService; |
| | | import com.zy.acs.manager.manager.service.CodeService; |
| | | import com.zy.acs.manager.system.service.ConfigService; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | |
| | | private CodeService codeService; |
| | | @Autowired |
| | | private AgvDetailService agvDetailService; |
| | | @Autowired |
| | | private ConfigService configService; |
| | | @Autowired |
| | | private MapService mapService; |
| | | |
| | | private final RedisSupport redis = RedisSupport.defaultRedisSupport; |
| | | |
| | |
| | | |
| | | NodeCursor currentNode = createNode(actionGroupId, firstAction.getCode(), nodeIndex++, sequenceId++); |
| | | Double currentDirection = resolveInitialNodeDirection(firstAction); |
| | | applyNodeTheta(currentNode.node, currentDirection); |
| | | applyNodeTheta(currentNode.node, currentDirection, agvModel); |
| | | nodes.add(currentNode.node); |
| | | |
| | | for (int i = 0; i < actionList.size(); i++) { |
| | |
| | | switch (actionType) { |
| | | case TurnCorner: |
| | | currentDirection = parseDirectionDegrees(action.getParams()); |
| | | currentNode.node.getActions().add(buildRotateAgvAction(action, currentDirection)); |
| | | currentNode.node.getActions().add(buildRotateAgvAction(action, currentDirection, agvModel)); |
| | | break; |
| | | case StraightAheadTurnable: |
| | | case StraightAheadUnturnable: |
| | | case StraightBackTurnable: |
| | | case StraightBackUnturnable: |
| | | String endCode = findNextMoveEndCode(actionList, i, currentNode.code); |
| | | Double travelDirection = calculateTravelDirection(currentNode.code, endCode, agvModel); |
| | | Double travelDirection = calculateTravelDirection(currentNode.code, endCode); |
| | | Double moveDirection = resolveMoveDirection(currentDirection, travelDirection, actionType, actionGroupId, currentNode.code, endCode); |
| | | Double edgeOrientation = resolveEdgeOrientation(moveDirection, travelDirection); |
| | | HkOrderEdge edge = createEdge(actionGroupId, edgeIndex++, sequenceId++, currentNode, endCode, edgeOrientation, action, agvModel); |
| | | edges.add(edge); |
| | | |
| | | NodeCursor nextNode = createNode(actionGroupId, endCode, nodeIndex++, sequenceId++); |
| | | applyNodeTheta(nextNode.node, moveDirection); |
| | | applyNodeTheta(nextNode.node, moveDirection, agvModel); |
| | | nodes.add(nextNode.node); |
| | | |
| | | currentNode = nextNode; |
| | |
| | | case FinishPath: |
| | | break; |
| | | default: |
| | | currentNode.node.getActions().add(buildNodeAction(action, actionType, toHikThetaRadians(currentDirection))); |
| | | currentNode.node.getActions().add(buildNodeAction(action, actionType, toHikThetaRadians(currentDirection, agvModel))); |
| | | break; |
| | | } |
| | | } |
| | |
| | | return hkAction; |
| | | } |
| | | |
| | | private HkAction buildRotateAgvAction(Action action, Double targetDirection) { |
| | | private HkAction buildRotateAgvAction(Action action, Double targetDirection, AgvModel agvModel) { |
| | | HkAction hkAction = new HkAction(); |
| | | hkAction.setActionId("A" + action.getId()); |
| | | hkAction.setActionDescription(ActionTypeType.TurnCorner.desc); |
| | |
| | | List<HkActionParameter> parameters = new ArrayList<>(); |
| | | addParameter(parameters, "sourceActionType", ActionTypeType.TurnCorner.name()); |
| | | addParameter(parameters, "sourceActionId", action.getId()); |
| | | addParameter(parameters, "angle", toHikThetaRadians(targetDirection)); |
| | | addParameter(parameters, "angle", toHikThetaRadians(targetDirection, agvModel)); |
| | | hkAction.setActionParameters(parameters); |
| | | return hkAction; |
| | | } |
| | |
| | | return parseDouble(params); |
| | | } |
| | | |
| | | private Double toHikThetaRadians(Double thetaDegrees) { |
| | | return AgvAngleUtils.toRadians(thetaDegrees); |
| | | private Double toHikThetaRadians(Double rcsThetaDegrees, AgvModel agvModel) { |
| | | return AgvAngleUtils.toProtocolRadians(rcsThetaDegrees, agvModel); |
| | | } |
| | | |
| | | private void applyNodeTheta(HkOrderNode node, Double directionDegrees) { |
| | | private void applyNodeTheta(HkOrderNode node, Double rcsDirectionDegrees, AgvModel agvModel) { |
| | | if (node == null || node.getNodePosition() == null) { |
| | | return; |
| | | } |
| | | node.getNodePosition().setTheta(toHikThetaRadians(directionDegrees)); |
| | | node.getNodePosition().setTheta(toHikThetaRadians(rcsDirectionDegrees, agvModel)); |
| | | } |
| | | |
| | | private Double calculateTravelDirection(String startCode, String endCode, AgvModel agvModel) { |
| | | private Double calculateTravelDirection(String startCode, String endCode) { |
| | | Code start = codeService.getCacheByData(startCode); |
| | | Code end = codeService.getCacheByData(endCode); |
| | | if (start == null || end == null) { |
| | | throw new CoolException("hik order adaptation failed: code position missing"); |
| | | } |
| | | return AgvAngleUtils.calculateDirection(start, end, agvModel); |
| | | Integer angleOffsetVal = configService.getVal("mapAngleOffsetVal", Integer.class); |
| | | if (angleOffsetVal == null) { |
| | | angleOffsetVal = 0; |
| | | } |
| | | return mapService.calculateDirection(start, end, angleOffsetVal); |
| | | } |
| | | |
| | | private Double resolveMoveDirection(Double currentDirection, |
| | |
| | | |
| | | import com.zy.acs.common.enums.ClockwiseType; |
| | | import com.zy.acs.manager.manager.entity.AgvModel; |
| | | import com.zy.acs.manager.manager.entity.Code; |
| | | |
| | | /** |
| | | * 车型角度工具: |
| | | * 将地图物理方向(默认顺时针)转换为车型自身角度体系。 |
| | | * 仅用于在 RCS 统一角度系 与 车型/协议角度系 之间做转换。 |
| | | */ |
| | | public final class AgvAngleUtils { |
| | | |
| | | private AgvAngleUtils() { |
| | | } |
| | | |
| | | public static Double calculateDirection(Code startCode, Code endCode, AgvModel agvModel) { |
| | | if (startCode == null || endCode == null) { |
| | | return null; |
| | | } |
| | | double deltaX = endCode.getX() - startCode.getX(); |
| | | double deltaY = endCode.getY() - startCode.getY(); |
| | | double mapAngle = Math.toDegrees(Math.atan2(deltaX, deltaY)); |
| | | return toModelAngle(normalizeAngle(mapAngle), agvModel); |
| | | } |
| | | |
| | | public static Double toModelAngle(Double mapAngleDegrees, AgvModel agvModel) { |
| | | if (mapAngleDegrees == null) { |
| | | public static Double toProtocolAngle(Double rcsAngleDegrees, AgvModel agvModel) { |
| | | if (rcsAngleDegrees == null) { |
| | | return null; |
| | | } |
| | | double factor = isClockwise(agvModel) ? 1D : -1D; |
| | | double offset = getAngleOffsetDeg(agvModel); |
| | | return normalizeAngle(factor * normalizeAngle(mapAngleDegrees) + offset); |
| | | return normalizeAngle(factor * normalizeAngle(rcsAngleDegrees) + offset); |
| | | } |
| | | |
| | | public static Double fromModelAngle(Double modelAngleDegrees, AgvModel agvModel) { |
| | | if (modelAngleDegrees == null) { |
| | | public static Double fromProtocolAngle(Double protocolAngleDegrees, AgvModel agvModel) { |
| | | if (protocolAngleDegrees == null) { |
| | | return null; |
| | | } |
| | | double factor = isClockwise(agvModel) ? 1D : -1D; |
| | | double offset = getAngleOffsetDeg(agvModel); |
| | | return normalizeAngle(factor * (normalizeAngle(modelAngleDegrees) - offset)); |
| | | return normalizeAngle(factor * (normalizeAngle(protocolAngleDegrees) - offset)); |
| | | } |
| | | |
| | | public static Double toRadians(Double angleDegrees) { |
| | | if (angleDegrees == null) { |
| | | public static Double toProtocolRadians(Double rcsAngleDegrees, AgvModel agvModel) { |
| | | Double protocolAngleDegrees = toProtocolAngle(rcsAngleDegrees, agvModel); |
| | | if (protocolAngleDegrees == null) { |
| | | return null; |
| | | } |
| | | return Math.toRadians(normalizeAngle(angleDegrees)); |
| | | return Math.toRadians(protocolAngleDegrees); |
| | | } |
| | | |
| | | public static Double fromRadians(Double angleRadians) { |
| | | if (angleRadians == null) { |
| | | public static Double fromProtocolRadians(Double protocolAngleRadians, AgvModel agvModel) { |
| | | if (protocolAngleRadians == null) { |
| | | return null; |
| | | } |
| | | return normalizeAngle(Math.toDegrees(angleRadians)); |
| | | return fromProtocolAngle(Math.toDegrees(protocolAngleRadians), agvModel); |
| | | } |
| | | |
| | | public static Double normalizeAngle(Double angleDegrees) { |
| | |
| | | |
| | | AgvDetail agvDetail = agvDetailService.selectByAgvId(agv.getId()); |
| | | if (agvDetail != null && agvDetail.getAgvAngle() != null) { |
| | | position.setTheta(AgvAngleUtils.toRadians(agvDetail.getAgvAngle())); |
| | | AgvModel agvModel = agvModelService.getByAgvId(agv.getId()); |
| | | position.setTheta(AgvAngleUtils.toProtocolRadians(agvDetail.getAgvAngle(), agvModel)); |
| | | } |
| | | return position; |
| | | } |