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; } }