CSR对象防抖动和精度配置介绍
更新时间: 2026/01/04
在Gitcode上查看源码

一、防抖算法与配置方法介绍

防抖配置关键字为 @Debounce,当前防抖方法有四种,分别为一致性防抖Cont,二值持续一致性防抖ContBin,中值滤波防抖Median,均值平均防抖MidAvg。 为某个对象的属性配置防抖,配置方法为在对象中用@Debounce配置属性名和防抖器路径的键值对,防抖器路径形如"$/Defines/{防抖器名}",防抖器名必须遵循如下规则:防抖类名+下划线+自定义名,防抖器需要定义在与Objects同级的Defines中。要求该属性是数字并且必须来自CSR,也就是usage是CSR。注意:不能为Scanner和Accessor对象的属性配置@Debounce防抖,如果要为这样的属性配置防抖,请用原生的Debounce关键字,而不是@Debounce。 下文将逐个介绍这四种防抖方法的具体算法、适用范围和配置方法示例,其中,配置方法示例基于下方源CSR

json
{
    "Objects": {
        "Event_1": {
            "Type": "xxx",
            "Id": 1,
            "TestProp": 1
        }
    }
}

在这个源CSR配置中,对象Event_1中有TestProp属性,且这一属性来自CSR,下文将为这一属性配置不同的防抖动算法。

1.一致性防抖 Cont

一致性防抖算法配置需要两个关键字,稳定次数Num和默认稳定值DefaultValue,防抖算法为当同一个值连续出现Num次时才认为这个值是稳定的,防抖器会输出这个值,当稳定值尚未出现时,输出DefaultValue。这种防抖算法的适用场景是,当一个属性稳定时应当长期取一个定值,而短暂的变化被视为不稳定,比如这个属性只能取有限个整数值,每个取值都代表一个不同的状态。 若要为上文的源CSR的Event_1对象TestProp属性配置一个稳定次数为5、默认值为1的Cont防抖算法,则需进行如下修改:

json
{
    "Objects": {
        "Event_1": {
            "Type": "xxx",
            "Id": 1,
            "TestProp": 1,
            "@Debounce": {
                "TestProp": "$/Defines/Cont_N5D1"
            }
        }
    },
    "Defines": {
        "Cont_N5D1": {
            "Num": 5,
            "DefaultValue": 1
        }
    }
}

其中,防抖器名为Cont_N5D1,自定义名为N5D1,可以换成其他的字符串,"$/Defines/Cont_N5D1"是防抖器路径,Defines与Objects同级,TestProp是Event_1的属性。

2.二值持续一致性防抖 ContBin

二值持续一致性防抖配置需要三个关键字,高电平稳定次数NumH,低电平稳定次数NumL和默认稳定值DefaultValue,防抖算法为当高电平(也就是1)连续出现NumH次时才认为这个值是稳定的,防抖器才会输出这个值,当低电平(也就是1)连续出现NumL次时才认为这个值是稳定的,防抖器才会输出这个值,当稳定值尚未出现时,输出DefaultValue。这种防抖算法的适用场景是,当一个属性只能取值为0和1,并且稳定时应当长期取一个定值,而短暂的变化被视为不稳定,比如开关的状态。 若要为上文的源CSR的Event_1对象TestProp属性配置一个高电平稳定次数为5、低电平稳定次数为4、默认值为1的ContBin防抖算法,则需进行如下修改:

json
{
    "Objects": {
        "Event_1": {
            "Type": "xxx",
            "Id": 1,
            "TestProp": 1,
            "@Debounce": {
                "TestProp": "$/Defines/ContBin_H5L4D1"
            }
        }
    },
    "Defines": {
        "ContBin_H5L4D1": {
            "NumH": 5,
            "NumL": 4,
            "DefaultValue": 1
        }
    }
}

其中,防抖器名为ContBin_H5L4D1,自定义名为H5L4D1,可以换成其他的字符串,"$/Defines/ContBin_H5L4D1"是防抖器路径,Defines与Objects同级,TestProp是Event_1的属性。

3.中值滤波防抖 Median

中值滤波防抖算法配置需要三个关键字,窗口大小WindowSize,是否有符号IsSigned和默认稳定值DefaultValue,防抖算法为,存储最近输入的WindowSize个值,取中位数作为输出,当输出的值不足WindowSize个时,空余位置将被以DefaultValue填充。当IsSigned为true时防抖算法只考虑8位整型数。此种防抖算法的适用场景是,要被配置的属性稳定时不是一个固定值,而是在一个范围内小幅度变化,比如风扇的转速。 若要为上文的源CSR的Event_1对象TestProp属性配置一个窗口大小为5、无符号、默认值为1的Median防抖算法,则需进行如下修改:

json
{
    "Objects": {
        "Event_1": {
            "Type": "xxx",
            "Id": 1,
            "TestProp": 1,
            "@Debounce": {
                "TestProp": "$/Defines/Median_W5UD1"
            }
        }
    },
    "Defines": {
        "Median_W5UD1": {
            "WindowSize": 5,
            "IsSigned": false,
            "DefaultValue": 1
        }
    }
}

其中,防抖器名为Median_W5UD1,自定义名为W5UD1,可以换成其他的字符串,"$/Defines/Median_W5UD1"是防抖器路径,Defines与Objects同级,TestProp是Event_1的属性。

4.均值平均防抖 MidAvg

均值平均防抖算法配置需要三个关键字,窗口大小WindowSize,是否有符号IsSigned和默认稳定值DefaultValue,防抖算法为,存储最近输入的WindowSize个值,当WindowSize小于等于3时取平均值作为输出,否则去掉一个最大值和一个最小值后取平均值输出,当输出的值不足WindowSize个时,空余位置将被以DefaultValue填充。当IsSigned为true时防抖算法只考虑8位整型数。与中值滤波防抖Median类似,此种防抖算法的适用场景与中值滤波防抖Median类似,也需要被配置的属性稳定时不是一个固定值,而是在一个范围内小幅度变化,比如风扇转速。 若要为上文的源CSR的Event_1对象TestProp属性配置一个窗口大小为5、无符号、默认值为1的MidAvg防抖算法,则需进行如下修改:

json
{
    "Objects": {
        "Event_1": {
            "Type": "xxx",
            "Id": 1,
            "TestProp": 1,
            "@Debounce": {
                "TestProp": "$/Defines/MidAvg_W5UD1"
            }
        }
    },
    "Defines": {
        "MidAvg_W5UD1": {
            "WindowSize": 5,
            "IsSigned": false,
            "DefaultValue": 1
        }
    }
}

其中,防抖器名为MidAvg_W5UD1,自定义名为W5UD1,可以换成其他的字符串,"$/Defines/MidAvg_W5UD1"是防抖器路径,Defines与Objects同级,TestProp是Event_1的属性。

二、精度算法与配置介绍

1.精度算法介绍

精度配置关键字为 @Precision,精度算法为,配置一个精度值,属性的值根据这一精度值进行向下取整,比如,属性原本应当取值3124,精度配置为100,那么属性实际将取值3124//100*100=3100(“//”是整数除法)。

2.精度配置方法介绍

为某个对象的属性配置精度,配置方法为在对象中用@Precision配置属性名和精度值的键值对。这一配置同样要求属性来自CSR,不一定要在sr文件中明确写出,需要存在并且是个数字属性。与@Debounce不同的是,@Precision可以为Scanner和Accessor对象中的属性配置。 以精度10为例,以下方CSR为例

json
{
    "Objects": {
        "Event_1": {
            "Type": "xxx",
            "Id": 1,
            "TestProp": 10
        }
    }
}

对象Event_1中有TestProp属性且该属性来自CSR,若要为此属性配置精度10,则需将其改为

json
{
    "Objects": {
        "Event_1": {
            "Type": "xxx",
            "Id": 1,
            "TestProp": 10,
            "@Precision": {
                "TestProp": 10
            }
        }
    }
}

三、数据收集

libmc4lua版本>=1.100.55的情况下,在一键收集时,对象上树属性如果配置了防抖动和精度,则配置将被收集到dump_info/AppDump/{组件名}/mdb_info.log中,打印到属性的详细信息部分。格式如下:

log
/bmc/kepler/Scanner/Scanner_xxx bmc.kepler.Scanner
.Status
  signature:  y
  value:      3
  flags:      emits-change
  readonly:   true
.Value
  signature:  t
  value:      0
  flags:      emits-change
  readonly:   true
  debounce:   type: cont, cont num: 5, default value: 5
  precision:  100

其中,属性Value被配置了防抖和精度,最后两行就是属性对应的防抖动和精度配置。而属性Status没有被配置防抖动和精度,不会打印对应的行。

四、提醒与警告

1.同步属性与引用属性防抖配置

对于同步属性和引用属性,如果配置防抖,将导致不可预测的后果。例如,有属性A和与A同步的同步属性B,给B配置Cont防抖,Num为2,DefaultValue为10,属性A和B的初始值都是10,属性A接收到值为20的更新,将更新为20,但此时属性B刚接收到一次值为20的更新,防抖器会认为这个值不稳定,属性B的取值会是默认值10,且属性A后续无论接收到多少次值为20的更新,都会因为与当前值相同而不再触发更新,属性B因此将永远无法接到第二次值为20的更新,将永远保持值为10的状态。也就是说,配置了防抖的同步属性和引用属性将可能与源属性不一致,在运行时这可能导致结果不符合预期。若要为同步属性和引用属性配置防抖,务必谨慎,务必三思而后行

2.关键字冲突

若为同一属性用@Default配置了默认值又配置了防抖算法,则防抖器中的默认值@DefaultValue会被@Default中的默认值覆盖。

3.计算顺序

同一个属性如果同时配置了防抖和精度,那么当前的计算机制是先计算防抖,再计算精度,而不是相反。因此,对于高频小幅度变化的属性,假设变化范围是101到109,如果配置一致性防抖Cont和精度10,并不会先进行精度计算将101到109之间的值全都变成100再进行一致性防抖计算,而是先进行一致性防抖计算再进行精度计算,而高频变化又可能导致一致性防抖长期难以稳定,因此高频小幅度变化属性无论是否配置精度都不适合配置一致性防抖。