huang
2025-12-05 73aa66976e35252378be3f09be2474193ccd0bf6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
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;
    }
}