VdaSegmentedPathCache.cs
7.12 KB
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
using Rcs.Domain.Enums;
namespace Rcs.Application.Services.PathFind.Models;
/// <summary>
/// VDA5050分段路径缓存
/// @author zzy
/// 2026-02-05 更新:支持两层切割结构
/// 2026-02-06 更新:支持网络动作执行状态跟踪
/// 2026-03-03 更新:添加姿态信息
/// </summary>
public class VdaSegmentedPathCache
{
public Guid TaskId { get; set; }
public string TaskCode { get; set; } = string.Empty;
public Guid RobotId { get; set; }
public Guid MapId { get; set; }
public string MapCode { get; set; } = string.Empty;
public DateTime CreatedAt { get; set; }
/// <summary>
/// 当前路口段索引(第一层)
/// </summary>
public int CurrentJunctionIndex { get; set; }
/// <summary>
/// 当前资源段索引(第二层)
/// </summary>
public int CurrentResourceIndex { get; set; }
/// <summary>
/// 路口切割后的段落列表
/// </summary>
public List<VdaJunctionSegmentCache> JunctionSegments { get; set; } = new();
/// <summary>
/// 上一次发送的最大 SequenceId,用于后续段延续编号
/// @author zzy
/// 2026-02-25 新增:解决分段发送时 sequenceId 从0重新开始的问题
/// </summary>
public int LastSentSequenceId { get; set; }
/// <summary>
/// 当前活跃的网络动作上下文ID(用于跟踪正在执行的网络动作)
/// @author zzy
/// </summary>
public string? ActiveNetActionContextId { get; set; }
/// <summary>
/// 网络动作执行状态
/// @author zzy
/// </summary>
public NetActionExecutionStatus? NetActionStatus { get; set; }
/// <summary>
/// 是否正在等待网络动作完成
/// @author zzy
/// </summary>
public bool IsWaitingForNetAction =>
NetActionStatus == NetActionExecutionStatus.Executing ||
NetActionStatus == NetActionExecutionStatus.WaitingAsyncResponse;
/// <summary>
/// 姿态信息
/// @author zzy
/// 2026-03-03 新增:存储终点姿态信息
/// </summary>
public VdaPoseInfo? PoseInfo { get; set; }
/// <summary>
/// 路径版本号(用于并发更新对齐)
/// 作者:codex
/// </summary>
public long PlanVersion { get; set; } = 1;
/// <summary>
/// 路由模式(示例值:Normal/HoldingAtWaitNode/QueueingForJunction/Detouring/Rejoining...)
/// 作者:codex
/// </summary>
public string RouteMode { get; set; } = "Normal";
/// <summary>
/// 原始目标节点编码(用于避让后回归)
/// 作者:codex
/// </summary>
public string? OriginalGoalNodeCode { get; set; }
/// <summary>
/// 当前活动补丁ID
/// 作者:codex
/// </summary>
public Guid? ActivePatchId { get; set; }
/// <summary>
/// 等待截止时间(UTC)
/// 作者:codex
/// </summary>
public DateTime? HoldUntilUtc { get; set; }
/// <summary>
/// 等待节点编码
/// 作者:codex
/// </summary>
public string? HoldNodeCode { get; set; }
/// <summary>
/// 连续通过次数(用于防抖)
/// 作者:codex
/// </summary>
public int StablePassCount { get; set; } = 0;
/// <summary>
/// 上一次决策编码
/// 作者:codex
/// </summary>
public string? LastDecisionCode { get; set; }
/// <summary>
/// 连续冲突失败计数(用于进入阻塞保护态 Blocked)
/// </summary>
public int ConsecutiveConflictFailCount { get; set; } = 0;
/// <summary>
/// 阻塞模式原因(Blocked)
/// </summary>
public string? BlockedReason { get; set; }
}
/// <summary>
/// 路口切割段缓存(第一层)
/// @author zzy
/// </summary>
public class VdaJunctionSegmentCache
{
/// <summary>
/// 资源/模板切割后的子段列表
/// </summary>
public List<VdaSegmentCacheItem> ResourceSegments { get; set; } = new();
}
/// <summary>
/// VDA5050分段缓存项(第二层)
/// @author zzy
/// 2026-02-06 更新:添加网络动作相关字段
/// </summary>
public class VdaSegmentCacheItem
{
public bool IsSent { get; set; } = false;
public List<PathSegmentWithCode> Segments { get; set; } = new();
/// <summary>
/// 段来源编码(Base/Avoidance/Merged)
/// 作者:codex
/// </summary>
public string SegmentOrigin { get; set; } = "Base";
/// <summary>
/// 终点网络动作上下文ID列表(用于关联网络动作执行状态)
/// @author zzy
/// </summary>
public List<string> EndNodeNetActionContextIds { get; set; } = new();
/// <summary>
/// 起点网络动作上下文ID列表(用于关联网络动作执行状态)
/// @author zzy
/// </summary>
public List<string> StartNodeNetActionContextIds { get; set; } = new();
/// <summary>
/// 是否已执行终点网络动作
/// @author zzy
/// </summary>
public bool IsEndNodeNetActionExecuted { get; set; } = false;
/// <summary>
/// 是否已执行起点网络动作
/// @author zzy
/// </summary>
public bool IsStartNodeNetActionExecuted { get; set; } = false;
/// <summary>
/// 获取该段的终点网络动作ID列表(仅返回动作申请类型的网络动作)
/// @author zzy
/// 2026-02-06 更新:从字典Keys获取,过滤只返回ActionType为Apply的网络动作
/// </summary>
public List<Guid> GetEndNodeNetActionIds()
{
if (Segments.Count == 0)
{
return new List<Guid>();
}
var lastSegment = Segments.Last();
if (lastSegment.EndNodeNetActionTypes == null || lastSegment.EndNodeNetActionTypes.Count == 0)
{
return new List<Guid>();
}
// 从字典Keys中获取ActionType为Apply的网络动作ID
return lastSegment.EndNodeNetActionTypes
.Where(kv => kv.Value == ActionType.Apply)
.Select(kv => kv.Key)
.ToList();
}
/// <summary>
/// 获取该段的起点网络动作ID列表(仅返回动作申请类型的网络动作)
/// @author zzy
/// 2026-02-06 更新:从字典Keys获取,过滤只返回ActionType为Apply的网络动作
/// </summary>
public List<Guid> GetStartNodeNetActionIds()
{
if (Segments.Count == 0)
{
return new List<Guid>();
}
var firstSegment = Segments.First();
if (firstSegment.StartNodeNetActionTypes == null || firstSegment.StartNodeNetActionTypes.Count == 0)
{
return new List<Guid>();
}
// 从字典Keys中获取ActionType为Apply的网络动作ID
return firstSegment.StartNodeNetActionTypes
.Where(kv => kv.Value == ActionType.Apply)
.Select(kv => kv.Key)
.ToList();
}
}
/// <summary>
/// VDA5050姿态信息
/// @author zzy
/// 2026-03-03 创建:存储路径终点的姿态信息
/// </summary>
public class VdaPoseInfo
{
/// <summary>
/// 终点货叉与车头的夹角(弧度)
/// 0表示货叉在车头方向,π表示货叉在车尾方向
/// @author zzy
/// </summary>
public double EndForkAngleOffset { get; set; }
}