using System;
using System.Configuration;
using System.IO;
using XP.Common.Logging.Interfaces;
using XP.Hardware.MotionControl.Abstractions.Enums;
namespace XP.Hardware.MotionControl.Config
{
///
/// 运动控制配置加载器 | Motion Control Configuration Loader
/// 从 App.config 加载轴范围、几何原点和运行参数(PLC 信号名称已硬编码在 MotionSignalNames 中)
/// Loads axis ranges, geometry origins and runtime params from App.config (PLC signal names hardcoded in MotionSignalNames)
///
public class ConfigLoader
{
private const string P = "MotionControl";
///
/// 加载运动控制配置 | Load motion control configuration
///
public static MotionControlConfig LoadConfig(string configFilePath = null, ILoggerService logger = null)
{
var config = new MotionControlConfig();
try
{
if (!string.IsNullOrEmpty(configFilePath) && File.Exists(configFilePath))
{
var fileMap = new ExeConfigurationFileMap { ExeConfigFilename = configFilePath };
var cfg = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
LoadAll(config, (k, d) => cfg.AppSettings.Settings[k]?.Value ?? d);
}
else
{
LoadAll(config, (k, d) => ConfigurationManager.AppSettings[k] ?? d);
}
}
catch (Exception ex)
{
logger?.Error(ex, "运动控制配置加载失败,使用默认值 | MotionControl config load failed, using defaults: {Message}", ex.Message);
}
return config;
}
private static void LoadAll(MotionControlConfig config, Func get)
{
// 直线轴 | Linear axes
config.LinearAxes[AxisId.SourceZ] = LoadLinear("SourceZ", get);
config.LinearAxes[AxisId.DetectorZ] = LoadLinear("DetectorZ", get);
config.LinearAxes[AxisId.StageX] = LoadLinear("StageX", get);
config.LinearAxes[AxisId.StageY] = LoadLinear("StageY", get);
// 旋转轴 | Rotary axes
config.RotaryAxes[RotaryAxisId.DetectorSwing] = LoadRotary("DetectorSwing", get);
config.RotaryAxes[RotaryAxisId.StageRotation] = LoadRotary("StageRotation", get);
config.RotaryAxes[RotaryAxisId.FixtureRotation] = LoadRotary("FixtureRotation", get);
// 几何原点 | Geometry origins
config.Geometry.SourceZOrigin = Dbl(get($"{P}:Geometry:SourceZOrigin", "0"));
config.Geometry.DetectorZOrigin = Dbl(get($"{P}:Geometry:DetectorZOrigin", "0"));
config.Geometry.StageRotationCenterZ = Dbl(get($"{P}:Geometry:StageRotationCenterZ", "0"));
config.Geometry.SwingPivotOffset = Dbl(get($"{P}:Geometry:SwingPivotOffset", "0"));
config.Geometry.SwingRadius = Dbl(get($"{P}:Geometry:SwingRadius", "0"));
// 运行参数 | Runtime parameters
config.PollingInterval = Int(get($"{P}:PollingInterval", "100"));
config.DefaultVelocity = Int(get($"{P}:DefaultVelocity", "100"));
}
private static LinearAxisConfig LoadLinear(string name, Func get)
{
var p = $"{P}:{name}:";
return new LinearAxisConfig
{
Min = Dbl(get(p + "Min", "0")),
Max = Dbl(get(p + "Max", "0")),
Origin = Dbl(get(p + "Origin", "0"))
};
}
private static RotaryAxisConfig LoadRotary(string name, Func get)
{
var p = $"{P}:{name}:";
return new RotaryAxisConfig
{
Min = Dbl(get(p + "Min", "0")),
Max = Dbl(get(p + "Max", "0")),
Origin = Dbl(get(p + "Origin", "0")),
Enabled = bool.TryParse(get(p + "Enabled", "true"), out var e) && e
};
}
private static double Dbl(string v) => double.TryParse(v, out var r) ? r : 0;
private static int Int(string v) => int.TryParse(v, out var r) ? r : 0;
}
}