1
zhang
2025-09-11 85392bb7db247c4596d3fbf49c9e00cfd0e76a13
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
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
package com.algo.service;
 
import com.algo.model.Conflict;
import com.algo.model.ExecutingTask;
import com.algo.model.PathCode;
import com.algo.model.PlannedPath;
 
import java.util.*;
 
/**
 * 碰撞解决器
 * 用于解决AGV路径之间的冲突
 */
public class CollisionResolver {
 
    /**
     * 碰撞检测器
     */
    private final CollisionDetector collisionDetector;
 
    /**
     * 构造函数
     *
     * @param collisionDetector 碰撞检测器
     */
    public CollisionResolver(CollisionDetector collisionDetector) {
        this.collisionDetector = collisionDetector;
    }
 
    /**
     * 解决路径冲突
     *
     * @param plannedPaths   规划路径列表
     * @param conflicts      冲突列表
     * @param executingTasks 执行中任务列表
     * @return 解决冲突后的路径列表
     */
    public List<PlannedPath> resolveConflicts(List<PlannedPath> plannedPaths,
                                              List<Conflict> conflicts,
                                              List<ExecutingTask> executingTasks) {
        if (conflicts == null || conflicts.isEmpty()) {
            return plannedPaths;
        }
 
        System.out.println("开始解决 " + conflicts.size() + " 个路径冲突");
 
        // 构建路径字典便于快速访问
        Map<String, PlannedPath> pathsMap = new HashMap<>();
        for (PlannedPath path : plannedPaths) {
            pathsMap.put(path.getAgvId(), path);
        }
 
        // 按时间步排序处理冲突
        List<Conflict> sortedConflicts = new ArrayList<>(conflicts);
        sortedConflicts.sort(Comparator.comparingInt(Conflict::getTimeStep));
 
        // 逐个解决冲突
        for (Conflict conflict : sortedConflicts) {
            resolveSingleConflict(pathsMap, conflict, executingTasks);
        }
 
        List<PlannedPath> resolvedPaths = new ArrayList<>(pathsMap.values());
 
        // 验证解决结果
        List<Conflict> remainingConflicts = collisionDetector.detectConflicts(resolvedPaths);
        System.out.println("冲突解决完成,剩余冲突数量: " + remainingConflicts.size());
 
        return resolvedPaths;
    }
 
    /**
     * 解决单个冲突
     *
     * @param pathsMap       路径映射
     * @param conflict       冲突
     * @param executingTasks 执行中任务列表
     */
    private void resolveSingleConflict(Map<String, PlannedPath> pathsMap,
                                       Conflict conflict,
                                       List<ExecutingTask> executingTasks) {
        String conflictType = conflict.getType();
 
        switch (conflictType) {
            case "vertex":
                resolveVertexConflict(pathsMap, conflict, executingTasks);
                break;
            case "edge":
                resolveEdgeConflict(pathsMap, conflict, executingTasks);
                break;
            case "follow":
                resolveFollowingConflict(pathsMap, conflict, executingTasks);
                break;
            default:
                System.out.println("未知冲突类型: " + conflictType);
        }
    }
 
    /**
     * 解决顶点冲突
     *
     * @param pathsMap       路径映射
     * @param conflict       冲突
     * @param executingTasks 执行中任务列表
     */
    private void resolveVertexConflict(Map<String, PlannedPath> pathsMap,
                                       Conflict conflict,
                                       List<ExecutingTask> executingTasks) {
        String agv1 = conflict.getAgv1();
        String agv2 = conflict.getAgv2();
        int timeStep = conflict.getTimeStep();
 
        // 评估AGV优先级
        AGVPriority priority1 = evaluateAgvPriority(agv1, pathsMap.get(agv1), executingTasks);
        AGVPriority priority2 = evaluateAgvPriority(agv2, pathsMap.get(agv2), executingTasks);
 
        // 优先级低的AGV进行延迟
        if (priority1.priorityScore >= priority2.priorityScore) {
            // agv2优先级低,延迟agv2
            addDelayToPath(pathsMap.get(agv2), timeStep, 1);
            System.out.println("为解决顶点冲突,AGV " + agv2 + " 在时间步 " + timeStep + " 延迟1步");
        } else {
            // agv1优先级低,延迟agv1
            addDelayToPath(pathsMap.get(agv1), timeStep, 1);
            System.out.println("为解决顶点冲突,AGV " + agv1 + " 在时间步 " + timeStep + " 延迟1步");
        }
    }
 
    /**
     * 解决边冲突
     *
     * @param pathsMap       路径映射
     * @param conflict       冲突
     * @param executingTasks 执行中任务列表
     */
    private void resolveEdgeConflict(Map<String, PlannedPath> pathsMap,
                                     Conflict conflict,
                                     List<ExecutingTask> executingTasks) {
        String agv1 = conflict.getAgv1();
        String agv2 = conflict.getAgv2();
        int timeStep = conflict.getTimeStep();
 
        // 评估AGV优先级
        AGVPriority priority1 = evaluateAgvPriority(agv1, pathsMap.get(agv1), executingTasks);
        AGVPriority priority2 = evaluateAgvPriority(agv2, pathsMap.get(agv2), executingTasks);
 
        // 优先级低的AGV进行延迟
        if (priority1.priorityScore >= priority2.priorityScore) {
            // agv2优先级低,延迟agv2
            addDelayToPath(pathsMap.get(agv2), timeStep, 2);
            System.out.println("为解决边冲突,AGV " + agv2 + " 在时间步 " + timeStep + " 延迟2步");
        } else {
            // agv1优先级低,延迟agv1
            addDelayToPath(pathsMap.get(agv1), timeStep, 2);
            System.out.println("为解决边冲突,AGV " + agv1 + " 在时间步 " + timeStep + " 延迟2步");
        }
    }
 
    /**
     * 解决跟随冲突
     *
     * @param pathsMap       路径映射
     * @param conflict       冲突
     * @param executingTasks 执行中任务列表
     */
    private void resolveFollowingConflict(Map<String, PlannedPath> pathsMap,
                                          Conflict conflict,
                                          List<ExecutingTask> executingTasks) {
        String agv1 = conflict.getAgv1();
        String agv2 = conflict.getAgv2();
        int timeStep = conflict.getTimeStep();
 
        // 评估AGV优先级
        AGVPriority priority1 = evaluateAgvPriority(agv1, pathsMap.get(agv1), executingTasks);
        AGVPriority priority2 = evaluateAgvPriority(agv2, pathsMap.get(agv2), executingTasks);
 
        // 优先级低的AGV进行延迟
        if (priority1.priorityScore >= priority2.priorityScore) {
            // agv2优先级低,延迟agv2
            addDelayToPath(pathsMap.get(agv2), timeStep, 1);
            System.out.println("为解决跟随冲突,AGV " + agv2 + " 在时间步 " + timeStep + " 延迟1步");
        } else {
            // agv1优先级低,延迟agv1
            addDelayToPath(pathsMap.get(agv1), timeStep, 1);
            System.out.println("为解决跟随冲突,AGV " + agv1 + " 在时间步 " + timeStep + " 延迟1步");
        }
    }
 
    /**
     * 评估AGV优先级 - 优化版本,只保留必要字段
     *
     * @param agvId          AGV编号
     * @param path           路径
     * @param executingTasks 执行中任务列表
     * @return AGV优先级信息
     */
    private AGVPriority evaluateAgvPriority(String agvId, PlannedPath path, List<ExecutingTask> executingTasks) {
        // 查找对应的执行任务
        ExecutingTask task = null;
        for (ExecutingTask et : executingTasks) {
            if (et.getAgvId().equals(agvId)) {
                task = et;
                break;
            }
        }
 
        double priorityScore = 0.0;
        String explanation = "默认优先级";
 
        if (task != null) {
            String taskStatus = task.getTaskType();
            int taskPriority = task.getPriority();
 
            // 基于任务类型的优先级评分
            switch (taskStatus) {
                case "delivery":
                    priorityScore += 50; // 送货任务优先级高
                    explanation = "送货任务 - 高优先级";
                    break;
                case "pickup":
                    priorityScore += 30; // 取货任务中等优先级
                    explanation = "取货任务 - 中等优先级";
                    break;
                case "charging":
                    priorityScore += 20; // 充电任务低优先级
                    explanation = "充电任务 - 低优先级";
                    break;
                default:
                    priorityScore += 10; // 其他任务最低优先级
                    explanation = "其他任务 - 最低优先级";
            }
 
            // 任务优先级加成
            priorityScore += taskPriority * 10;
 
            // 路径长度因子(路径越短优先级越高)
            if (path != null && path.getCodeList() != null) {
                double pathLengthFactor = Math.max(0, 50 - path.getCodeList().size());
                priorityScore += pathLengthFactor;
            }
        }
 
        return new AGVPriority(agvId, priorityScore, explanation);
    }
 
    /**
     * 为路径添加延迟
     *
     * @param path       路径
     * @param timeStep   延迟开始的时间步
     * @param delaySteps 延迟步数
     */
    private void addDelayToPath(PlannedPath path, int timeStep, int delaySteps) {
        if (path == null || path.getCodeList() == null || path.getCodeList().isEmpty()) {
            return;
        }
 
        List<PathCode> codeList = path.getCodeList();
 
        // 确保时间步在有效范围内
        if (timeStep < 0 || timeStep >= codeList.size()) {
            return;
        }
 
        // 获取延迟位置的路径代码
        PathCode delayCode = codeList.get(timeStep);
 
        // 创建延迟步骤
        List<PathCode> delaySteps_list = new ArrayList<>();
        for (int i = 0; i < delaySteps; i++) {
            PathCode waitCode = new PathCode(delayCode.getCode(), delayCode.getDirection());
            waitCode.setActionType(delayCode.getActionType());
            waitCode.setTaskId(delayCode.getTaskId());
            waitCode.setPosType(delayCode.getPosType());
            waitCode.setLev(delayCode.getLev());
            waitCode.setTargetPoint(false); // 等待步骤不是目标点
            delaySteps_list.add(waitCode);
        }
 
        // 插入延迟步骤
        codeList.addAll(timeStep, delaySteps_list);
 
        // 更新路径
        path.setCodeList(codeList);
    }
 
    /**
     * AGV优先级评估结果内部类 - 优化版本,只保留必要字段
     */
    private static class AGVPriority {
        final String agvId;
        final double priorityScore;
        final String explanation;
 
        public AGVPriority(String agvId, double priorityScore, String explanation) {
            this.agvId = agvId;
            this.priorityScore = priorityScore;
            this.explanation = explanation;
        }
 
        @Override
        public String toString() {
            return String.format("AGV %s: 优先级=%.1f, 说明=%s",
                    agvId, priorityScore, explanation);
        }
    }
}