一个轴信息类AxisInfo实现

public class AxisInfo : INamed<string>
{
    private const int DriveTypeBlockNumber = 0;

    private const int FirmwareBlockNumber = 6;

    private readonly int axisNumber;

    private ComponentType? axisType;

    private int? servoRate;

    private float? maximumAmperage;

    private float? maximumVoltage;

    private CommandOutputType? commandOutputType;

    private readonly Controller controller;

    private MotionDriveInformation containingDrive;

    private Version firmwareVersion;

    private int fpgaVersion;

    private FlashConfigStatus flashConfigStatus;

    public int Number => axisNumber;

    public ComponentType AxisType
    {
        get
        {
            if (!axisType.HasValue)
            {
                int pdwOne_ = 0;
                int pdwTwo_ = 0;
                int pdwThree_ = 0;
                int pdwFour_ = 0;
                ExceptionResolver.ResolveThrow(controller, Wrapper.AerStatusGetDriveInfoBlockEx(controller.Handle.Value, 0, axisNumber, ref pdwOne_, ref pdwTwo_, ref pdwThree_, ref pdwFour_));
                if (!Global.CoreDriveIdMappings.TryGetValue((Drive)pdwFour_, out var value))
                {
                    value = ComponentType.Unknown;
                }

                axisType = value;
            }

            return axisType.Value;
        }
    }

    public int ServoRate
    {
        get
        {
            if (!servoRate.HasValue)
            {
                int pdwServoRate_ = 0;
                ExceptionResolver.ResolveThrow(controller, Wrapper.AerStatusGetAxisServoRate(controller.Handle.Value, axisNumber, ref pdwServoRate_));
                servoRate = pdwServoRate_;
            }

            return servoRate.Value;
        }
    }

    public float MaximumAmperage
    {
        get
        {
            if (!maximumAmperage.HasValue)
            {
                float pdwPeakRating_ = 0f;
                ExceptionResolver.ResolveThrow(controller, Wrapper.AerStatusGetAmpPeakRating(controller.Handle.Value, axisNumber, ref pdwPeakRating_));
                maximumAmperage = pdwPeakRating_;
            }

            return maximumAmperage.Value;
        }
    }

    public float MaximumVoltage
    {
        get
        {
            if (!maximumVoltage.HasValue)
            {
                maximumVoltage = (float)(double)controller.Commands.Execute($"DRIVEINFO(@{axisNumber}, DATAITEM_MaximumVoltage)");
            }

            return maximumVoltage.Value;
        }
    }

    public CommandOutputType CommandOutputType
    {
        get
        {
            if (!commandOutputType.HasValue)
            {
                commandOutputType = (CommandOutputType)(double)controller.Commands.Execute($"DRIVEINFO(@{axisNumber}, DATAITEM_CommandOutputType)");
            }

            return commandOutputType.Value;
        }
    }

    public string Name => controller.Parameters.Axes[axisNumber].AxisNameParameter.CachedValue;

    internal Controller Controller => controller;

    public MotionDriveInformation Drive
    {
        get
        {
            return containingDrive;
        }
        internal set
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }

            containingDrive = value;
        }
    }

    public Version FirmwareVersion
    {
        get
        {
            if (firmwareVersion == null)
            {
                int pdwOne_ = 0;
                int pdwTwo_ = 0;
                int pdwThree_ = 0;
                int pdwFour_ = 0;
                ExceptionResolver.ResolveThrow(controller, Wrapper.AerStatusGetDriveInfoBlockEx(controller.Handle.Value, 6, axisNumber, ref pdwOne_, ref pdwTwo_, ref pdwThree_, ref pdwFour_));
                firmwareVersion = new Version(pdwOne_, pdwTwo_, pdwThree_, pdwFour_);
            }

            return firmwareVersion;
        }
    }

    public int FPGAVersion => fpgaVersion;

    public FlashConfigStatus FlashConfigStatus
    {
        get
        {
            if (flashConfigStatus == null)
            {
                int flashConfigstatus_ = 0;
                ExceptionResolver.ResolveThrow(controller, Wrapper.AerGetFlashConfigStatus(controller.Handle.Value, axisNumber, ref flashConfigstatus_));
                flashConfigStatus = new FlashConfigStatus(flashConfigstatus_);
            }

            return flashConfigStatus;
        }
    }

    internal AxisInfo(Controller controller, int axisNumber, int fpgaVersion)
    {
        this.controller = controller;
        this.axisNumber = axisNumber;
        this.fpgaVersion = fpgaVersion;
    }

    internal void invalidateData()
    {
        axisType = null;
        servoRate = null;
        maximumAmperage = null;
        firmwareVersion = null;
        maximumVoltage = null;
        commandOutputType = null;
    }
}

AxisInfo 是一个表示轴信息的类,实现了 INamed<string> 接口,主要用于运动控制系统中轴(axis)相关信息的封装和管理。

类结构概述

核心字段

  • axisNumber: 轴编号

  • 多个可空字段用于缓存信息:axisTypeservoRatemaximumAmperage

  • controller: 关联的控制器对象

  • containingDrive: 所属的驱动信息

主要属性

  1. 基本信息:

    • Number: 轴编号

    • Name: 轴名称(来自控制器参数)

    • Controller: 关联的控制器

  2. 技术规格:

    • AxisType: 轴类型

    • ServoRate: 伺服速率

    • MaximumAmperage: 最大电流

    • MaximumVoltage: 最大电压

  3. 版本信息:

    • FirmwareVersion: 固件版本

    • FPGAVersion: FPGA版本

    • FlashConfigStatus: 闪存配置状态

  4. 驱动信息:

    • Drive: 所属驱动信息

    • CommandOutputType: 命令输出类型

关键设计特点

1. 延迟加载模式

大多数属性采用延迟加载设计,首次访问时才从控制器获取数据:

public ComponentType AxisType
{
    get
    {
        if (!axisType.HasValue)
        {
            // 从控制器获取数据
            int pdwOne_ = 0;
            // ...调用Wrapper方法获取数据...
            axisType = value;
        }
        return axisType.Value;
    }
}

这种设计:

  • 减少不必要的控制器调用

  • 提高性能(只在需要时获取数据)

  • 通过字段缓存已获取的数据

2. 异常处理机制

使用ExceptionResolver.ResolveThrow统一处理底层调用异常:

ExceptionResolver.ResolveThrow(controller, 
    Wrapper.AerStatusGetDriveInfoBlockEx(...));

3. 数据失效机制

提供invalidateData()方法清空缓存,强制下次访问时重新获取:

internal void invalidateData()
{
    axisType = null;
    servoRate = null;
    // ...其他字段置空...
}

4. 控制器集成

通过Controller对象执行命令和获取参数:

maximumVoltage = (float)(double)controller.Commands.Execute(
    $"DRIVEINFO(@{axisNumber}, DATAITEM_MaximumVoltage)");

典型使用场景

1. 获取轴信息

var axis = new AxisInfo(controller, axisNumber, fpgaVersion);
Console.WriteLine($"Axis {axis.Number}: {axis.Name}");
Console.WriteLine($"Type: {axis.AxisType}, Servo Rate: {axis.ServoRate}Hz");

2. 监控轴状态

if (axis.MaximumAmperage > threshold)
{
    // 处理过流情况
}

3. 固件升级检查

if (axis.FirmwareVersion < requiredVersion)
{
    // 提示需要升级固件
}

设计模式分析

  1. 代理模式:

    • 作为控制器和轴信息之间的代理

    • 隐藏底层复杂的调用细节

  2. 缓存模式:

    • 属性值首次获取后缓存

    • 通过invalidateData可清除缓存

  3. 延迟初始化:

    • 数据只在首次访问时加载

潜在改进建议

  1. 线程安全:

    • 当前实现不是线程安全的

    • 可添加锁机制保护字段访问

  2. 属性变更通知:

    • 可考虑实现INotifyPropertyChanged

    • 便于UI绑定和数据监控

  3. 更细粒度的失效控制:

    • 当前invalidateData重置所有数据

    • 可改为按属性失效

  4. 异步支持:

    • 添加异步方法获取数据

    • 避免阻塞UI线程

与INamed<string>的关系

实现INamed<string>接口使得该类可以:

  • 用于基于名称的集合(如NamedConstantCollection)

  • 提供标准化的名称访问方式

  • 与其他命名对象保持一致的接口

public string Name => controller.Parameters.Axes[axisNumber].AxisNameParameter.CachedValue;

总结

AxisInfo类是一个设计精良的运动控制轴信息封装类,具有以下优点:

  1. 良好的封装性,隐藏底层实现细节

  2. 高效的延迟加载机制

  3. 灵活的数据失效管理

  4. 与控制器深度集成

  5. 清晰的命名和职责划分

这种设计非常适合工业控制系统中对设备信息的建模和管理。

### 设置 ECharts 图表中 Y 的最大值和最小值 在 ECharts 中,可以通过 `option.yAxis` 的属性来控制 Y 的显示效果。具体来说,为了设置 Y 的最大值 (`max`) 和最小值 (`min`) ,可以在初始化图表时或更新图表配置项时指定这些参数。 对于数值型 Y 而言,`max` 和 `min` 属性支持多种型的赋值方式: - **固定数值**:直接给定具体的数字作为最大/最小边界。 ```javascript option = { yAxis: [{ type: 'value', min: 0, max: 100 }] }; ``` - **自动调整**:"auto" 关键字可以让系统根据数据集自动决定合适的上下限[^3]。 - **基于数据范围**:使用 "dataMin" 或 "dataMax" 来让界限紧贴实际存在的最低点或最高点;也可以在此基础上加上偏移量以增加额外空间。 ```javascript option = { yAxis: [{ type: 'value', min: 'dataMin', max: function(value) { return value.max + 20; } // 基于数据最大值加20 }] }; ``` 另外,在某些情况下可能希望先让图表完成一次绘制后再去获取并设定新的极值,则可通过访问已创建好的实例对象来进行操作[^2]。例如: ```javascript var myChart = echarts.init(document.getElementById('main')); // ...其他配置... myChart.setOption(option); // 获取当前Y的实际最大最小值 setTimeout(function () { var axisInfo = myChart.getModel().getComponent('yAxis').axis; console.log(axisInfo.getExtent()); // 输出[minValue,maxValue] // 更新选项中的Y范围 myChart.setOption({ yAxis: [{ min: minValueFromLogic, max: maxValueFromLogic }] }); }, 0); ``` 上述方法允许开发者灵活地定制化自己的可视化需求,无论是静态还是动态场景下都能很好地满足应用要求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值