diff --git a/README.md b/README.md index 3507e6d..ffac5d3 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ - 宿主只保留 ASP.NET Core HTTP 控制器层,以及其后端 `Flyshot.ControllerClientCompat` 兼容服务。 - `ExecuteTrajectory` 与 `ExecuteFlyShotTraj` 已经接入 `Planning + Triggering + Runtime` 链路;Web 状态页已通过 `/status` 和 `/api/status/snapshot` 暴露当前兼容层与运行时状态。 - `Flyshot.Core.Planning` 的 ICSP / self-adapt-icsp 轨迹已经完成旧系统导出轨迹对齐;`doubles` 仍未实现。 -- `Flyshot.Native.Planning` 已提供显式 Rust ICSP 规划入口,通过 C ABI 调用 `flyshot_native_planning`;普通轨迹和飞拍轨迹可使用准确参数 `method="icsp_rust"` 选择该后端,默认 `icsp` 仍使用 C# `ICspPlanner`。 +- `Flyshot.Native.Planning` 已提供显式 Rust ICSP 规划入口,通过 C ABI 调用 `flyshot_planning`;普通轨迹和飞拍轨迹可使用准确参数 `method="icsp_rust"` 选择该后端,默认 `icsp` 仍使用 C# `ICspPlanner`。 - `Flyshot.Runtime.Fanuc` 已固化 `10010 / 10012 / 60015` 基础协议帧编解码。`10010` 状态通道以 `j519 协议.pcap` 和 `Rvbust/uttc-20260428/20260428.pcap` 真机抓包确认为 90B 固定帧。 - 2026-04-28 UTTC 抓包确认:UDP 60015 命令 `target[0..5]` 为关节角度制 `deg`,`JointDetialTraj.txt` 为弧度制 `rad`,`speed_ratio=0.7` 体现为 UDP 下发时间轴约 `1.427730x` 拉伸;2026-04-30 实体机确认 `speed_ratio` 不影响生成的 `JointTraj.txt` 规划时长,当前实际生成约 `7.4s` 轨迹。 - 2026-04-30 本机 `50001/TCP+JSON` 抓包确认:`ExecuteFlyShotTraj(save_traj=true,use_cache=false)` 请求只显式携带规划方法、保存、缓存和等待参数,不携带 `JointLimits / acc_limit / jerk_limit / velocity / acceleration / jerk`。因此旧系统不可见的有效规划限制不再继续假设来自公开链路,新系统按 replacement-only 内部参数限制规划加速度。 @@ -96,13 +96,15 @@ Windows x64 需要安装: .\build\Copy-NativePlanningArtifacts.ps1 -Configuration Release ``` -脚本会通过 `vcvars64.bat` 初始化 MSVC 环境,构建 -`native/flyshot-native-planning/target/release/flyshot_native_planning.dll`, -并默认复制到 `tests/Flyshot.Core.Tests/bin/Release/net8.0/`。发布服务时可通过 +脚本会执行 `cargo build --release`,构建 +`native/flyshot-native-planning/target/release/flyshot_planning.dll`, +并默认复制到 `src/Libs/flyshot_planning.dll` 与 +`tests/Flyshot.Core.Tests/bin/Release/net8.0/`。发布服务时可通过 `-DestinationDirectories` 把原生库复制到实际发布目录。 Linux x64 在已安装 `stable-x86_64-unknown-linux-gnu` 工具链的 Linux 环境执行同一脚本, -产物为 `libflyshot_native_planning.so`。Windows 第一阶段不要求交叉编译 Linux 原生库。 +产物为 `libflyshot_planning.so`,默认写入 `src/Libs/libflyshot_planning.so`。 +Windows 第一阶段不要求交叉编译 Linux 原生库。 剩余 Todo: diff --git a/build/Copy-NativePlanningArtifacts.ps1 b/build/Copy-NativePlanningArtifacts.ps1 index 91e9e5b..768825d 100644 --- a/build/Copy-NativePlanningArtifacts.ps1 +++ b/build/Copy-NativePlanningArtifacts.ps1 @@ -1,94 +1,76 @@ +<# +.SYNOPSIS +构建 Rust ICSP 原生规划库并复制到 src/Libs 与可选目标目录。 + +.DESCRIPTION +在 Windows x64 上通过 cargo release 构建 flyshot_planning,默认写入 +src/Libs/flyshot_planning.dll;Linux x64 写入 src/Libs/libflyshot_planning.so。 +可通过 -DestinationDirectories 额外复制到测试或发布输出目录。 + +.PARAMETER Configuration +传递给 dotnet 相关路径的构建配置名,默认 Release。 + +.PARAMETER DestinationDirectories +除 src/Libs 外需要覆盖复制的额外目标目录列表。 +#> + +[CmdletBinding()] param( - [ValidateSet("Debug", "Release")] - [string]$Configuration = "Release", + [ValidateSet('Debug', 'Release')] + [string]$Configuration = 'Release', [string[]]$DestinationDirectories = @() ) -$ErrorActionPreference = "Stop" +$ErrorActionPreference = 'Stop' +Set-StrictMode -Version Latest -# 从脚本位置定位仓库根目录,确保从任意工作目录调用都得到一致结果。 -$repositoryRoot = Split-Path -Parent $PSScriptRoot -$manifestPath = Join-Path $repositoryRoot "native/flyshot-native-planning/Cargo.toml" -$cargoExecutable = if ($IsWindows) { "cargo.exe" } else { "cargo" } -$cargoPath = Join-Path $HOME ".cargo/bin/$cargoExecutable" -if (-not (Test-Path -LiteralPath $cargoPath)) { - throw "未找到 Rust Cargo:$cargoPath。请先通过 rustup 安装 stable-x86_64-pc-windows-msvc。" +$repositoryRoot = (Resolve-Path (Join-Path $PSScriptRoot '..')).Path +$cargoManifest = Join-Path $repositoryRoot 'native\flyshot-native-planning\Cargo.toml' +$libsDirectory = Join-Path $repositoryRoot 'src\Libs' +$cargoProfile = if ($Configuration -eq 'Debug') { 'debug' } else { 'release' } +$targetDirectory = Join-Path $repositoryRoot "native\flyshot-native-planning\target\$cargoProfile" + +if ($IsLinux -or (-not $IsWindows -and -not $IsMacOS)) +{ + $artifactFileName = 'libflyshot_planning.so' +} +else +{ + $artifactFileName = 'flyshot_planning.dll' } -$cargoArguments = @("build", "--manifest-path", $manifestPath) -if ($Configuration -eq "Release") { - $cargoArguments += "--release" +$builtArtifactPath = Join-Path $targetDirectory $artifactFileName +$libsArtifactPath = Join-Path $libsDirectory $artifactFileName + +Write-Host "正在构建 Rust 原生规划库 ($Configuration) ..." +& cargo build --manifest-path $cargoManifest --$Configuration +if ($LASTEXITCODE -ne 0) +{ + throw "cargo build 失败,退出码:$LASTEXITCODE" } -if ($IsWindows) { - # Windows MSVC 目标必须在 VS C++ 开发者环境中运行,避免 PATH 中其他 link.exe 抢占。 - $vswherePath = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" - if (-not (Test-Path -LiteralPath $vswherePath)) { - throw "未找到 vswhere.exe,无法定位 Visual Studio C++ Build Tools。" +if (-not (Test-Path -LiteralPath $builtArtifactPath -PathType Leaf)) +{ + throw "未找到构建产物:$builtArtifactPath" +} + +New-Item -ItemType Directory -Path $libsDirectory -Force | Out-Null +Copy-Item -LiteralPath $builtArtifactPath -Destination $libsArtifactPath -Force +Write-Host "已复制到:$libsArtifactPath" + +$defaultTestOutput = Join-Path $repositoryRoot "tests\Flyshot.Core.Tests\bin\$Configuration\net8.0" +$allDestinations = @($DestinationDirectories) + @($defaultTestOutput) + +foreach ($destination in $allDestinations | Where-Object { -not [string]::IsNullOrWhiteSpace($_) } | Select-Object -Unique) +{ + $absoluteDestination = [System.IO.Path]::GetFullPath($destination) + if (-not (Test-Path -LiteralPath $absoluteDestination -PathType Container)) + { + Write-Host "跳过不存在的目标目录:$absoluteDestination" + continue } - $installationPath = & $vswherePath -latest -products * ` - -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 ` - -property installationPath - if ([string]::IsNullOrWhiteSpace($installationPath)) { - throw "未找到已安装的 Visual Studio C++ x64 编译工具。" - } - - $vcvarsPath = Join-Path $installationPath "VC/Auxiliary/Build/vcvars64.bat" - if (-not (Test-Path -LiteralPath $vcvarsPath)) { - throw "未找到 VS x64 开发者环境脚本:$vcvarsPath" - } - - $quotedArguments = $cargoArguments | ForEach-Object { '"' + $_.Replace('"', '\"') + '"' } - $command = 'call "{0}" >nul && "{1}" {2}' -f ` - $vcvarsPath, $cargoPath, ($quotedArguments -join " ") - & cmd.exe /d /c $command - if ($LASTEXITCODE -ne 0) { - throw "Rust 原生规划库构建失败,退出码:$LASTEXITCODE" - } -} -else { - & $cargoPath @cargoArguments - if ($LASTEXITCODE -ne 0) { - throw "Rust 原生规划库构建失败,退出码:$LASTEXITCODE" - } -} - -$profileDirectory = if ($Configuration -eq "Release") { "release" } else { "debug" } -$libraryName = if ($IsWindows) { - "flyshot_native_planning.dll" -} -elseif ($IsLinux) { - "libflyshot_native_planning.so" -} -else { - throw "当前脚本仅支持 Windows x64 和 Linux x64。" -} -$sourcePath = Join-Path $repositoryRoot "native/flyshot-native-planning/target/$profileDirectory/$libraryName" -if (-not (Test-Path -LiteralPath $sourcePath)) { - throw "Rust 构建已结束,但未找到原生库:$sourcePath" -} - -# 未显式指定目标时,默认复制到对应配置的 Core 测试输出目录。 -if ($DestinationDirectories.Count -eq 0) { - $DestinationDirectories = @( - (Join-Path $repositoryRoot "tests/Flyshot.Core.Tests/bin/$Configuration/net8.0") - ) -} - -foreach ($destinationDirectory in $DestinationDirectories) { - $destinationPath = if ([System.IO.Path]::IsPathRooted($destinationDirectory)) { - $destinationDirectory - } - else { - Join-Path $repositoryRoot $destinationDirectory - } - $resolvedDestination = [System.IO.Path]::GetFullPath( - $destinationPath) - New-Item -ItemType Directory -Force -Path $resolvedDestination | Out-Null - Copy-Item -LiteralPath $sourcePath ` - -Destination (Join-Path $resolvedDestination $libraryName) ` - -Force - Write-Host "已复制原生规划库到:$resolvedDestination" + Copy-Item -LiteralPath $builtArtifactPath -Destination (Join-Path $absoluteDestination $artifactFileName) -Force + Write-Host "已复制到:$absoluteDestination\$artifactFileName" } diff --git a/native/flyshot-native-planning/Cargo.lock b/native/flyshot-native-planning/Cargo.lock index 01366c1..483863d 100644 --- a/native/flyshot-native-planning/Cargo.lock +++ b/native/flyshot-native-planning/Cargo.lock @@ -3,5 +3,5 @@ version = 4 [[package]] -name = "flyshot-native-planning" +name = "flyshot_planning" version = "0.1.0" diff --git a/native/flyshot-native-planning/Cargo.toml b/native/flyshot-native-planning/Cargo.toml index df0b305..027d6b5 100644 --- a/native/flyshot-native-planning/Cargo.toml +++ b/native/flyshot-native-planning/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "flyshot-native-planning" +name = "flyshot_planning" version = "0.1.0" edition = "2021" diff --git a/scripts/Publish-Obfuscated.ps1 b/scripts/Publish-Obfuscated.ps1 index 99ef877..9d4f9b2 100644 --- a/scripts/Publish-Obfuscated.ps1 +++ b/scripts/Publish-Obfuscated.ps1 @@ -427,6 +427,13 @@ function Install-ObfuscatedAssemblies $_.Name -like 'Flyshot*.pdb' } | Remove-Item -Force + + # Rust ICSP 原生库必须随框架依赖包一起交付,否则 method=icsp_rust 会在运行时加载失败。 + $nativePlanningLibraryPath = Join-Path $PublishedDirectory 'flyshot_planning.dll' + if (-not (Test-Path -LiteralPath $nativePlanningLibraryPath -PathType Leaf)) + { + throw "发布目录缺少 Rust 原生规划库 flyshot_planning.dll:$nativePlanningLibraryPath" + } } <# diff --git a/src/Flyshot.Native.Planning/NativePlanningLibraryResolver.cs b/src/Flyshot.Native.Planning/NativePlanningLibraryResolver.cs index f03ec96..8197a11 100644 --- a/src/Flyshot.Native.Planning/NativePlanningLibraryResolver.cs +++ b/src/Flyshot.Native.Planning/NativePlanningLibraryResolver.cs @@ -17,7 +17,7 @@ public sealed class NativePlanningLibraryResolver /// /// 原生规划库的逻辑名称。 /// - public const string LogicalLibraryName = "flyshot_native_planning"; + public const string LogicalLibraryName = "flyshot_planning"; private readonly Func _resolveLibraryPath; @@ -92,8 +92,8 @@ public sealed class NativePlanningLibraryResolver string fileName = platform.OperatingSystem switch { - "Windows" => "flyshot_native_planning.dll", - "Linux" => "libflyshot_native_planning.so", + "Windows" => "flyshot_planning.dll", + "Linux" => "libflyshot_planning.so", _ => throw new NativePlanningException( $"Rust 原生规划库不支持当前操作系统:{platform.OperatingSystem}。", errorCode: -1003) diff --git a/src/Flyshot.Server.Host/Flyshot.Server.Host.csproj b/src/Flyshot.Server.Host/Flyshot.Server.Host.csproj index 2065feb..2867803 100644 --- a/src/Flyshot.Server.Host/Flyshot.Server.Host.csproj +++ b/src/Flyshot.Server.Host/Flyshot.Server.Host.csproj @@ -16,6 +16,9 @@ + + + diff --git a/src/Libs/flyshot_planning.dll b/src/Libs/flyshot_planning.dll new file mode 100644 index 0000000..6454182 Binary files /dev/null and b/src/Libs/flyshot_planning.dll differ diff --git a/src/Libs/libflyshot_planning.so b/src/Libs/libflyshot_planning.so new file mode 100644 index 0000000..5b3f408 Binary files /dev/null and b/src/Libs/libflyshot_planning.so differ diff --git a/tests/Flyshot.Core.Tests/Flyshot.Core.Tests.csproj b/tests/Flyshot.Core.Tests/Flyshot.Core.Tests.csproj index 99129ec..c0c4b40 100644 --- a/tests/Flyshot.Core.Tests/Flyshot.Core.Tests.csproj +++ b/tests/Flyshot.Core.Tests/Flyshot.Core.Tests.csproj @@ -32,4 +32,10 @@ + + + + + +