✨ feat(*): 添加 ConfigRoot 运行时配置目录隔离
* 新增 ControllerClientCompatOptions.ConfigRoot 及解析方法 * 兼容层默认从运行目录 Config 加载模型、轨迹和配置 * 移除隐式父工作区根目录推断,旧路径仅在显式配置时生效 * Host 项目编译时将 Config 目录复制到输出目录 * 请求响应日志中间件忽略 /api/status/snapshot 高频轮询 * 补充 ConfigRoot 和日志过滤相关单元测试
This commit is contained in:
@@ -9,12 +9,12 @@ namespace Flyshot.ControllerClientCompat;
|
||||
public sealed class ControllerClientCompatRobotCatalog
|
||||
{
|
||||
/// <summary>
|
||||
/// 保存当前现场支持的机器人名称到模型相对路径映射。
|
||||
/// 保存当前现场支持的机器人名称到运行目录模型文件名映射。
|
||||
/// </summary>
|
||||
private static readonly IReadOnlyDictionary<string, string> SupportedRobotModelMap = new Dictionary<string, string>(StringComparer.Ordinal)
|
||||
private static readonly IReadOnlyDictionary<string, string> SupportedRobotModelFileMap = new Dictionary<string, string>(StringComparer.Ordinal)
|
||||
{
|
||||
["FANUC_LR_Mate_200iD"] = Path.Combine("FlyingShot", "FlyingShot", "Models", "LR_Mate_200iD_7L.robot"),
|
||||
["FANUC_LR_Mate_200iD_7L"] = Path.Combine("FlyingShot", "FlyingShot", "Models", "LR_Mate_200iD_7L.robot")
|
||||
["FANUC_LR_Mate_200iD"] = "LR_Mate_200iD_7L.robot",
|
||||
["FANUC_LR_Mate_200iD_7L"] = "LR_Mate_200iD_7L.robot"
|
||||
};
|
||||
|
||||
private readonly ControllerClientCompatOptions _options;
|
||||
@@ -47,39 +47,34 @@ public sealed class ControllerClientCompatRobotCatalog
|
||||
throw new ArgumentException("机器人名称不能为空。", nameof(robotName));
|
||||
}
|
||||
|
||||
if (!SupportedRobotModelMap.TryGetValue(robotName, out var modelRelativePath))
|
||||
if (!SupportedRobotModelFileMap.TryGetValue(robotName, out var modelFileName))
|
||||
{
|
||||
throw new InvalidOperationException($"Unsupported robot name: {robotName}");
|
||||
}
|
||||
|
||||
var workspaceRoot = ResolveWorkspaceRoot();
|
||||
var modelPath = Path.Combine(workspaceRoot, modelRelativePath);
|
||||
var modelPath = ResolveModelPath(modelFileName);
|
||||
return _robotModelLoader.LoadProfile(modelPath, accLimitScale, jerkLimitScale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 解析父工作区根目录,优先使用显式配置。
|
||||
/// 解析机器人模型路径,运行目录 Config/Models 优先,旧父工作区只作为显式兼容入口。
|
||||
/// </summary>
|
||||
/// <returns>包含 `FlyingShot/` 与 `Rvbust/` 的父工作区根目录。</returns>
|
||||
private string ResolveWorkspaceRoot()
|
||||
/// <param name="modelFileName">运行目录 Models 下的机器人模型文件名。</param>
|
||||
/// <returns>可传给 .robot 加载器的模型文件绝对路径。</returns>
|
||||
private string ResolveModelPath(string modelFileName)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(_options.WorkspaceRoot))
|
||||
var configModelPath = Path.Combine(_options.ResolveConfigRoot(), "Models", modelFileName);
|
||||
if (File.Exists(configModelPath))
|
||||
{
|
||||
return Path.GetFullPath(_options.WorkspaceRoot);
|
||||
return configModelPath;
|
||||
}
|
||||
|
||||
var current = new DirectoryInfo(AppContext.BaseDirectory);
|
||||
while (current is not null)
|
||||
var legacyWorkspaceRoot = _options.ResolveLegacyWorkspaceRoot();
|
||||
if (legacyWorkspaceRoot is not null)
|
||||
{
|
||||
// 宿主和测试都从 replacement 仓库内启动;找到 sln 后回退一级就是父工作区根目录。
|
||||
if (File.Exists(Path.Combine(current.FullName, "FlyshotReplacement.sln")))
|
||||
{
|
||||
return Path.GetFullPath(Path.Combine(current.FullName, ".."));
|
||||
}
|
||||
|
||||
current = current.Parent;
|
||||
return Path.Combine(legacyWorkspaceRoot, "FlyingShot", "FlyingShot", "Models", modelFileName);
|
||||
}
|
||||
|
||||
throw new DirectoryNotFoundException("Unable to locate the flyshot workspace root.");
|
||||
return configModelPath;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user