docs: describe OSQP plugin deployment
This commit is contained in:
@@ -12,7 +12,8 @@ PlanningGridMap -> Hybrid A* CoarsePath -> Local G2 PathSmoothing -> EM Planner
|
|||||||
`PlanningGridMap`、车辆几何和请求快照。它不读取硬件、UI、时钟或当前工作目录。
|
`PlanningGridMap`、车辆几何和请求快照。它不读取硬件、UI、时钟或当前工作目录。
|
||||||
每次计算只处理一个 `DirectionSegmentView`,因此不会跨越换向边界。
|
每次计算只处理一个 `DirectionSegmentView`,因此不会跨越换向边界。
|
||||||
|
|
||||||
此门禁尚未实现 OSQP、LS 横向优化、ST 纵向优化、滚动协调、轨迹发布或动态障碍物。
|
此门禁已提供 solver-neutral `IQpSolver` 契约和固定 OSQP 后端;尚未实现 LS 横向优化、
|
||||||
|
ST 纵向优化、滚动协调、轨迹发布或动态障碍物。
|
||||||
|
|
||||||
## 坐标与符号
|
## 坐标与符号
|
||||||
|
|
||||||
@@ -82,3 +83,87 @@ PASS segmentation
|
|||||||
PASS frenet
|
PASS frenet
|
||||||
PASS corridor
|
PASS corridor
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## OSQP 后端部署与诊断
|
||||||
|
|
||||||
|
横向与纵向规划器只能依赖 `IQpSolver`、`QuadraticProgram`、`QpSolverSettings` 和
|
||||||
|
`QpSolveResult`;它们不得依赖 OSQP 的 P/Invoke 类型。当前后端固定为 OSQP `v1.0.0`,
|
||||||
|
Windows x64、double precision、int32 索引、未打包 settings 和内置 QDLDL algebra。源包布局为:
|
||||||
|
|
||||||
|
```text
|
||||||
|
ClumsyPilot/ThirdParty/OSQP/
|
||||||
|
├── build-win-x64.ps1
|
||||||
|
├── LICENSE
|
||||||
|
├── NOTICE
|
||||||
|
├── VERSION
|
||||||
|
├── SHA256SUMS
|
||||||
|
└── win-x64/osqp.dll
|
||||||
|
```
|
||||||
|
|
||||||
|
`VERSION` 记录且构建脚本强制使用以下开关:
|
||||||
|
|
||||||
|
```text
|
||||||
|
OSQP_ALGEBRA_BACKEND=builtin
|
||||||
|
OSQP_BUILD_SHARED_LIB=ON
|
||||||
|
OSQP_BUILD_STATIC_LIB=OFF
|
||||||
|
OSQP_BUILD_DEMO_EXE=OFF
|
||||||
|
OSQP_BUILD_UNITTESTS=OFF
|
||||||
|
OSQP_USE_FLOAT=OFF
|
||||||
|
OSQP_USE_LONG=OFF
|
||||||
|
OSQP_PACK_SETTINGS=OFF
|
||||||
|
OSQP_ENABLE_PRINTING=OFF
|
||||||
|
OSQP_CODEGEN=OFF
|
||||||
|
OSQP_ENABLE_DERIVATIVES=OFF
|
||||||
|
```
|
||||||
|
|
||||||
|
最终插件发布布局(由后续插件打包阶段负责复制)必须为:
|
||||||
|
|
||||||
|
```text
|
||||||
|
plugins/
|
||||||
|
├── ClumsyPilot.dll
|
||||||
|
├── osqp.dll
|
||||||
|
└── licenses/
|
||||||
|
├── OSQP-LICENSE.txt
|
||||||
|
└── OSQP-NOTICE.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
`OsqpNativeLoader` 只从 `typeof(OsqpNativeLoader).Assembly.Location` 所在目录以绝对路径
|
||||||
|
预加载同级 `osqp.dll`,不读取当前工作目录,也不要求用户修改 `PATH`。它拒绝非 x64
|
||||||
|
进程、缺失或无法加载的 DLL、缺少导出及非 `1.0.0` 版本,并以结构化
|
||||||
|
`SolverUnavailable`/`NativeError` 结果返回;不会让宿主进程因加载失败而崩溃。所有 C API
|
||||||
|
委托均采用 Cdecl,原生 verbose 强制关闭。
|
||||||
|
|
||||||
|
每次 `OsqpNativeSolver.Solve` 独立拥有 P/Q/A/l/u 和可选 warm-start 的固定数组、CSC
|
||||||
|
包装、settings 和 OSQP workspace。它在 `finally` 中按反向顺序释放:先 `osqp_cleanup`
|
||||||
|
workspace,再释放 settings/CSC 块,最后释放托管数组 pin;加载后的模块句柄保留至进程生命周期结束。
|
||||||
|
|
||||||
|
原生状态映射固定如下:
|
||||||
|
|
||||||
|
| OSQP status value | `QpSolveStatus` |
|
||||||
|
| ---: | --- |
|
||||||
|
| 1 | `Solved` |
|
||||||
|
| 2 | `SolvedInaccurate` |
|
||||||
|
| 3, 4 | `PrimalInfeasible` |
|
||||||
|
| 5, 6 | `DualInfeasible` |
|
||||||
|
| 7 | `MaximumIterations` |
|
||||||
|
| 8 | `TimeLimit` |
|
||||||
|
| 9, 10, 11 或未知值 | `NativeError` |
|
||||||
|
|
||||||
|
`SolvedInaccurate` 只在后续规划器完成更严格的独立残差和领域复核后才可发布。调用前取消映射
|
||||||
|
为 `Cancelled`;加载失败映射为 `SolverUnavailable`;OSQP setup、warm-start 或 solve API
|
||||||
|
返回错误时映射为 `NativeError`。
|
||||||
|
|
||||||
|
在仓库根目录运行 OSQP 回归门:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
dotnet run --project ClumsyPilot/tests/EMPlannerVerificationHost/EMPlannerVerificationHost.csproj -- optimization
|
||||||
|
dotnet run --project ClumsyPilot/tests/EMPlannerVerificationHost/EMPlannerVerificationHost.csproj -- osqp
|
||||||
|
```
|
||||||
|
|
||||||
|
`osqp` 会在临时的干净插件目录中验证缺失 DLL、损坏 DLL、绝对路径加载、并发首次加载,以及
|
||||||
|
有界最优、等式最优、不可行和极短时限 QP。成功时包含:
|
||||||
|
|
||||||
|
```text
|
||||||
|
PASS osqp-solve
|
||||||
|
PASS osqp-loader
|
||||||
|
```
|
||||||
|
|||||||
@@ -7,10 +7,10 @@ internal static class Program
|
|||||||
private static int Main(string[] args)
|
private static int Main(string[] args)
|
||||||
{
|
{
|
||||||
if (args.Length != 1 || (args[0] != "foundation" && args[0] != "segmentation" && args[0] != "frenet" &&
|
if (args.Length != 1 || (args[0] != "foundation" && args[0] != "segmentation" && args[0] != "frenet" &&
|
||||||
args[0] != "corridor" && args[0] != "optimization" && args[0] != "osqp-loader" && args[0] != "osqp-probe" &&
|
args[0] != "corridor" && args[0] != "optimization" && args[0] != "osqp" && args[0] != "osqp-loader" && args[0] != "osqp-probe" &&
|
||||||
args[0] != "all-foundation"))
|
args[0] != "all-foundation"))
|
||||||
{
|
{
|
||||||
Console.Error.WriteLine("Usage: EMPlannerVerificationHost foundation|segmentation|frenet|corridor|optimization|osqp-loader|all-foundation");
|
Console.Error.WriteLine("Usage: EMPlannerVerificationHost foundation|segmentation|frenet|corridor|optimization|osqp|osqp-loader|all-foundation");
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@ internal static class Program
|
|||||||
MultiWheelC.TrajectoryPlanning.EMPlanner.OptimizationChecks.Run();
|
MultiWheelC.TrajectoryPlanning.EMPlanner.OptimizationChecks.Run();
|
||||||
Console.WriteLine("PASS optimization");
|
Console.WriteLine("PASS optimization");
|
||||||
}
|
}
|
||||||
if (args[0] == "osqp-loader")
|
if (args[0] == "osqp" || args[0] == "osqp-loader")
|
||||||
{
|
{
|
||||||
MultiWheelC.TrajectoryPlanning.EMPlanner.OsqpChecks.Run();
|
MultiWheelC.TrajectoryPlanning.EMPlanner.OsqpChecks.Run();
|
||||||
Console.WriteLine("PASS osqp-loader");
|
Console.WriteLine("PASS osqp-loader");
|
||||||
|
|||||||
Reference in New Issue
Block a user