package com.mes.interaction.vehicle.coordination; import com.mes.device.entity.DeviceConfig; import com.mes.device.service.DeviceConfigService; import com.mes.device.service.DeviceGroupRelationService; import com.mes.device.vo.DeviceGroupVO; import com.mes.interaction.vehicle.model.VehiclePath; import com.mes.interaction.vehicle.model.VehicleStatus; import com.mes.interaction.vehicle.model.VehicleState; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; /** * 车辆协调服务 * 负责在多个大车实例中选择和分配任务 * * @author mes * @since 2025-01-XX */ @Slf4j @Service public class VehicleCoordinationService { @Autowired private VehicleStatusManager statusManager; @Autowired private DeviceConfigService deviceConfigService; @Autowired private DeviceGroupRelationService deviceGroupRelationService; /** * 从设备组中选择一个可用的大车实例 * * @param groupId 设备组ID * @return 可用的设备配置,如果没有可用车辆则返回null */ public DeviceConfig selectAvailableVehicle(Long groupId) { if (groupId == null) { log.warn("设备组ID为空,无法选择车辆"); return null; } // 1. 获取设备组中的所有设备 List groupDevices = deviceGroupRelationService.getGroupDevices(groupId); if (groupDevices == null || groupDevices.isEmpty()) { log.warn("设备组 {} 中没有设备", groupId); return null; } // 2. 过滤出大车类型的设备 List vehicles = groupDevices.stream() .filter(d -> DeviceConfig.DeviceType.LOAD_VEHICLE.equals(d.getDeviceType())) .collect(Collectors.toList()); if (vehicles.isEmpty()) { log.warn("设备组 {} 中没有大车设备", groupId); return null; } // 3. 过滤出可用的车辆 List availableVehicles = vehicles.stream() .filter(v -> { String deviceId = v.getId() != null ? v.getId().toString() : null; if (deviceId == null) { deviceId = v.getDeviceCode(); } return statusManager.isVehicleAvailable(deviceId); }) .collect(Collectors.toList()); if (availableVehicles.isEmpty()) { log.warn("设备组 {} 中没有可用的大车设备", groupId); return null; } // 4. 选择策略(简单策略:选择第一个可用的,可以扩展为按优先级、负载等选择) DeviceGroupVO.DeviceInfo selected = availableVehicles.get(0); // 5. 获取完整的设备配置 DeviceConfig deviceConfig = null; if (selected.getId() != null) { deviceConfig = deviceConfigService.getDeviceById(selected.getId()); } else if (selected.getDeviceCode() != null) { deviceConfig = deviceConfigService.getDeviceByCode(selected.getDeviceCode()); } if (deviceConfig != null) { log.info("选择可用车辆: deviceId={}, deviceName={}", deviceConfig.getDeviceId(), deviceConfig.getDeviceName()); } return deviceConfig; } /** * 检查路径冲突 * * @param deviceId 设备ID * @param plannedPath 计划路径 * @return true表示有冲突,false表示无冲突 */ public boolean hasPathConflict(String deviceId, VehiclePath plannedPath) { if (deviceId == null || plannedPath == null) { return false; } // 获取所有执行中的车辆 List executingVehicles = statusManager.getExecutingVehicles(); // 排除自己 executingVehicles = executingVehicles.stream() .filter(v -> !v.getDeviceId().equals(deviceId)) .collect(Collectors.toList()); // 检查路径是否冲突 for (VehicleStatus vehicle : executingVehicles) { if (vehicle.getCurrentTask() != null) { VehiclePath existingPath = vehicle.getCurrentTask().getPlannedPath(); if (existingPath != null && plannedPath.conflictsWith(existingPath)) { log.warn("检测到路径冲突: deviceId={}, 与 deviceId={} 的路径冲突", deviceId, vehicle.getDeviceId()); return true; } } } return false; } /** * 获取设备组中所有大车设备 * * @param groupId 设备组ID * @return 大车设备列表 */ public List getVehiclesInGroup(Long groupId) { if (groupId == null) { return Collections.emptyList(); } List groupDevices = deviceGroupRelationService.getGroupDevices(groupId); if (groupDevices == null || groupDevices.isEmpty()) { return Collections.emptyList(); } return groupDevices.stream() .filter(d -> DeviceConfig.DeviceType.LOAD_VEHICLE.equals(d.getDeviceType())) .map(d -> { if (d.getId() != null) { return deviceConfigService.getDeviceById(d.getId()); } else if (d.getDeviceCode() != null) { return deviceConfigService.getDeviceByCode(d.getDeviceCode()); } return null; }) .filter(d -> d != null) .collect(Collectors.toList()); } /** * 获取设备组中所有可用的大车设备 * * @param groupId 设备组ID * @return 可用的大车设备列表 */ public List getAvailableVehiclesInGroup(Long groupId) { return getVehiclesInGroup(groupId).stream() .filter(v -> statusManager.isVehicleAvailable(v.getDeviceId())) .collect(Collectors.toList()); } /** * 检查设备组中是否有可用的大车 * * @param groupId 设备组ID * @return true表示有可用车辆,false表示没有 */ public boolean hasAvailableVehicle(Long groupId) { return selectAvailableVehicle(groupId) != null; } }