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<DeviceGroupVO.DeviceInfo> groupDevices = deviceGroupRelationService.getGroupDevices(groupId);
|
if (groupDevices == null || groupDevices.isEmpty()) {
|
log.warn("设备组 {} 中没有设备", groupId);
|
return null;
|
}
|
|
// 2. 过滤出大车类型的设备
|
List<DeviceGroupVO.DeviceInfo> 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<DeviceGroupVO.DeviceInfo> 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<VehicleStatus> 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<DeviceConfig> getVehiclesInGroup(Long groupId) {
|
if (groupId == null) {
|
return Collections.emptyList();
|
}
|
|
List<DeviceGroupVO.DeviceInfo> 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<DeviceConfig> 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;
|
}
|
}
|