feat(flyshot): 引入飞拍执行侧最终发送队列构建与校验机制

* 新增 FlyshotExecutionSendSequenceBuilder,负责在运行时前构建最终 8ms 发送队列,并进行离散限幅校验。
* 引入 FlyshotPreparedExecution 类,封装最终发送结果及相关诊断信息。
* 调整 ControllerClientCompatService 和 FanucControllerRuntime,确保运行时直接使用预生成的发送队列,避免临场重采样。
* 更新 TrajectoryResult 和 PlannedExecutionBundle,支持准备好的执行队列。
* 增加单元测试,验证非 1 倍 speedRatio 下的执行行为与预生成队列的使用。
This commit is contained in:
2026-05-09 19:06:49 +08:00
parent f7e2bb0e7b
commit 74761bb5da
11 changed files with 1185 additions and 75 deletions

View File

@@ -53,6 +53,8 @@ public sealed class ControllerClientTrajectoryOrchestrator
/// </summary>
/// <param name="robot">当前机器人配置。</param>
/// <param name="waypoints">普通轨迹关节路点。</param>
/// <param name="options">执行参数。</param>
/// <param name="planningSpeedScale">规划速度倍率。</param>
/// <returns>包含规划轨迹、空触发时间轴和执行结果的结果包。</returns>
public PlannedExecutionBundle PlanOrdinaryTrajectory(
RobotProfile robot,
@@ -107,6 +109,9 @@ public sealed class ControllerClientTrajectoryOrchestrator
/// </summary>
/// <param name="robot">当前机器人配置。</param>
/// <param name="uploaded">兼容层保存的上传轨迹。</param>
/// <param name="options">执行参数。</param>
/// <param name="settings">兼容层机器人设置。</param>
/// <param name="planningSpeedScale">规划速度倍率。</param>
/// <returns>包含规划轨迹、触发时间轴和执行结果的结果包。</returns>
public PlannedExecutionBundle PlanUploadedFlyshot(
RobotProfile robot,
@@ -135,21 +140,13 @@ public sealed class ControllerClientTrajectoryOrchestrator
var method = ParseFlyshotMethod(options.Method);
var cacheKey = CreateFlyshotCacheKey(planningRobot, uploaded, options, settings, effectivePlanningSpeedScale);
//if (options.UseCache && _flyshotCache.TryGetValue(cacheKey, out var cachedBundle))
//{
// _logger?.LogInformation("PlanUploadedFlyshot 命中缓存: name={Name}, cacheKey={CacheKey}", uploaded.Name, cacheKey);
// var executionTrajectory = ApplyExecutionTiming(cachedBundle.PlannedTrajectory, settings);
// var executionTimeline = _shotTimelineBuilder.Build(
// executionTrajectory,
// holdCycles: settings.IoKeepCycles,
// samplePeriod: planningRobot.ServoPeriod,
// useDo: settings.UseDo);
// // 命中缓存时只替换 TrajectoryResult 的 usedCache 标志,规划轨迹和触发时间轴保持不可变复用。
// return new PlannedExecutionBundle(
// cachedBundle.PlannedTrajectory,
// executionTimeline,
// CreateResult(executionTrajectory, executionTimeline, usedCache: true, shapeTrajectoryEdges: false));
//}
if (options.UseCache && _flyshotCache.TryGetValue(cacheKey, out var cachedBundle))
{
_logger?.LogInformation("PlanUploadedFlyshot 命中缓存: name={Name}, cacheKey={CacheKey}", uploaded.Name, cacheKey);
// 命中缓存时只替换 TrajectoryResult 的 usedCache 标志,规划轨迹和触发时间轴保持不可变复用。
return cachedBundle;
}
var request = new TrajectoryRequest(
robot: planningRobot,