✨ feat(native-planning): 添加 Rust ICSP 原生规划核心及 C# 互操作集成

* 新增 Rust 原生 ICSP 规划库 (Cargo 项目, CubicSpline 算法, FFI 接口)
* 新增 Flyshot.Native.Planning C# 互操作项目 (P/Invoke 封装)
* 更新 ControllerClientCompat 适配新的规划接口
* 添加构建脚本 (Copy-NativePlanningArtifacts.ps1)
* 新增互操作测试及一致性对比测试
* 更新解决方案文件和设计文档
This commit is contained in:
2026-06-23 15:36:01 +08:00
parent bb21e0923d
commit 9c56ee825e
30 changed files with 2674 additions and 2 deletions

View File

@@ -106,6 +106,113 @@ public sealed class RuntimeOrchestrationTests
Assert.Single(bundle.Result.TriggerTimeline);
}
/// <summary>
/// 验证普通轨迹使用准确字串 icsp_rust 时会真实调用 Rust DLL,并在结果中标记原生后端。
/// </summary>
[Fact]
public void ControllerClientTrajectoryOrchestrator_PlanOrdinaryTrajectory_UsesRustPlanner()
{
var orchestrator = new ControllerClientTrajectoryOrchestrator();
var robot = TestRobotFactory.CreateRobotProfile();
var bundle = orchestrator.PlanOrdinaryTrajectory(
robot,
[
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.001, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.002, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.003, 0.0, 0.0, 0.0, 0.0, 0.0]
],
new TrajectoryExecutionOptions(method: "icsp_rust"));
Assert.Equal(PlanningMethod.IcspRust, bundle.PlannedTrajectory.Method);
Assert.Equal(PlanningMethod.IcspRust, bundle.Result.Method);
}
/// <summary>
/// 验证飞拍轨迹使用准确字串 icsp_rust 时会真实调用 Rust DLL,同时保留触发时间轴。
/// </summary>
[Fact]
public void ControllerClientTrajectoryOrchestrator_PlanUploadedFlyshot_UsesRustPlanner()
{
var orchestrator = new ControllerClientTrajectoryOrchestrator();
var robot = TestRobotFactory.CreateRobotProfile();
var uploaded = TestRobotFactory.CreateUploadedTrajectoryWithSingleShot();
var bundle = orchestrator.PlanUploadedFlyshot(
robot,
uploaded,
new FlyshotExecutionOptions(method: "icsp_rust", useCache: false));
Assert.Equal(PlanningMethod.IcspRust, bundle.PlannedTrajectory.Method);
Assert.Equal(PlanningMethod.IcspRust, bundle.Result.Method);
Assert.Single(bundle.Result.ShotEvents);
Assert.Single(bundle.Result.TriggerTimeline);
}
/// <summary>
/// 验证普通轨迹默认 icsp 仍使用现有 C# 规划器。
/// </summary>
[Fact]
public void ControllerClientTrajectoryOrchestrator_PlanOrdinaryTrajectory_KeepsManagedIcspPlanner()
{
var orchestrator = new ControllerClientTrajectoryOrchestrator();
var robot = TestRobotFactory.CreateRobotProfile();
var bundle = orchestrator.PlanOrdinaryTrajectory(
robot,
[
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.001, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.002, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.003, 0.0, 0.0, 0.0, 0.0, 0.0]
],
new TrajectoryExecutionOptions(method: "icsp"));
Assert.Equal(PlanningMethod.Icsp, bundle.PlannedTrajectory.Method);
Assert.Equal(PlanningMethod.Icsp, bundle.Result.Method);
}
/// <summary>
/// 验证 self-adapt-icsp 仍使用 C# 自适应规划器,不切换到 Rust。
/// </summary>
[Fact]
public void ControllerClientTrajectoryOrchestrator_PlanUploadedFlyshot_KeepsManagedSelfAdaptPlanner()
{
var orchestrator = new ControllerClientTrajectoryOrchestrator();
var robot = new RobotProfile(
name: "ManagedSelfAdaptTestRobot",
modelPath: "Models/ManagedSelfAdaptTest.robot",
degreesOfFreedom: 6,
jointLimits: Enumerable.Range(1, 6)
.Select(static index => new JointLimit($"J{index}", 1.0, 2.0, 10.0))
.ToArray(),
jointCouplings: [],
servoPeriod: TimeSpan.FromMilliseconds(8),
triggerPeriod: TimeSpan.FromMilliseconds(8));
var uploaded = new ControllerClientCompatUploadedTrajectory(
name: "managed-self-adapt",
waypoints:
[
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
[0.4, 0.1, 0.0, 0.0, 0.0, 0.0],
[0.8, 0.3, 0.0, 0.0, 0.0, 0.0],
[1.0, 0.2, 0.0, 0.0, 0.0, 0.0]
],
shotFlags: [false, true, false, false],
offsetValues: [0, 0, 0, 0],
addressGroups: [[], [7], [], []]);
var bundle = orchestrator.PlanUploadedFlyshot(
robot,
uploaded,
new FlyshotExecutionOptions(method: "self-adapt-icsp", useCache: false));
Assert.Equal(PlanningMethod.SelfAdaptIcsp, bundle.PlannedTrajectory.Method);
Assert.Equal(PlanningMethod.SelfAdaptIcsp, bundle.Result.Method);
Assert.Single(bundle.Result.TriggerTimeline);
}
/// <summary>
/// 验证飞拍规划会把规划限速倍率纳入速度/加速度/Jerk 限制,而不是复用运行时下发倍率。
/// </summary>