布尔开关的简单低通滤波器
Simple Low Pass Filter for Boolean switch
在 C# 中 Class 如果更改之间的间隔太短,则需要过滤掉或忽略 Update 方法中的布尔更改。
本质上我需要所谓的'Low Pass Filter'
假设我们在 Update 或 FixedUpdate 中有以下内容
if (myBoolean condition){
myVal =0;
}else{
myVal= _rawInput;
}
上面的 myBoolean 条件切换得太快了。我需要 'filter out' 或忽略这些短时间间隔。
我已经尝试使用此低通滤波器 class 与移动加速度计输入一起使用,但没有成功,因为它假定被过滤的值是一个浮点数。
http://devblog.aliasinggames.com/accelerometer-unity/有人可以帮忙吗?
低通滤波器?
using System;
using System.Linq;
public class Program
{
public static bool MyValue = false;
public static DateTime lastChange { get; set; } = DateTime.MinValue;
public static void ChangeValue(bool b)
{
// do nothing if not 2s passed since last trigger AND the value is different
// dont reset the timer if we would change it to the same value
if (DateTime.Now - lastChange < TimeSpan.FromSeconds(2) || MyValue == b)
return;
// change it and remember change time
lastChange = DateTime.Now;
MyValue = b;
Console.WriteLine($"Bool changed from {!b} to {b}. Time: {lastChange.ToLongTimeString()}");
}
public static void Main(string[] args)
{
for (int i = 0; i < 10000000; i++)
{
ChangeValue(!MyValue);
}
}
}
输出:
Bool changed from False to True. Time: 23:29:23
Bool changed from True to False. Time: 23:29:25
Bool changed from False to True. Time: 23:29:27
整个循环运行大约 7 秒 - 即每秒大约 115 万次触发来更改它。
你可以把它变成 class:
public class FilteredBool
{
private bool _inputValue;
private bool _outputValue;
private TimeSpan _minimumTime = TimeSpan.FromSeconds(5);
private DateTime _lastChangeTime = DateTime.MinValue;
public bool Value
{
get
{
if (_outputValue != _inputValue)
{
if (_lastChangeTime + _minimumTime < DateTime.Now)
_outputValue = _inputValue;
}
return _outputValue;
}
set
{
if (_inputValue != value)
{
_inputValue = value;
_lastChangeTime = DateTime.Now;
}
}
}
public TimeSpan MinimumTime
{
get { return _minimumTime; }
set { _minimumTime = value; }
}
public static implicit operator bool(FilteredBool value)
{
return value.Value;
}
}
这有一个 bool
的隐式运算符,因此您可以只替换任何采用 bool
(或 if
)的函数调用,而不必调用 .Value
.没有返回 FilteredBool
的隐式运算符,因为这需要设置过滤时间。如果你愿意,你可以添加这个,我觉得这将是一个延伸。
OP
感谢伟大的解决方案。作为布尔低通滤波器的快速破解,我还想知道是否可以简单地使用计数器和模运算,本质上是 'slowing down' FixedUpdate 方法。布尔值永远不会比模运算(或余数)= 零的间隔更快地变化。没有考虑过实施细节。想法?
在 C# 中 Class 如果更改之间的间隔太短,则需要过滤掉或忽略 Update 方法中的布尔更改。
本质上我需要所谓的'Low Pass Filter'
假设我们在 Update 或 FixedUpdate 中有以下内容
if (myBoolean condition){
myVal =0;
}else{
myVal= _rawInput;
}
上面的 myBoolean 条件切换得太快了。我需要 'filter out' 或忽略这些短时间间隔。
我已经尝试使用此低通滤波器 class 与移动加速度计输入一起使用,但没有成功,因为它假定被过滤的值是一个浮点数。 http://devblog.aliasinggames.com/accelerometer-unity/有人可以帮忙吗?
低通滤波器?
using System;
using System.Linq;
public class Program
{
public static bool MyValue = false;
public static DateTime lastChange { get; set; } = DateTime.MinValue;
public static void ChangeValue(bool b)
{
// do nothing if not 2s passed since last trigger AND the value is different
// dont reset the timer if we would change it to the same value
if (DateTime.Now - lastChange < TimeSpan.FromSeconds(2) || MyValue == b)
return;
// change it and remember change time
lastChange = DateTime.Now;
MyValue = b;
Console.WriteLine($"Bool changed from {!b} to {b}. Time: {lastChange.ToLongTimeString()}");
}
public static void Main(string[] args)
{
for (int i = 0; i < 10000000; i++)
{
ChangeValue(!MyValue);
}
}
}
输出:
Bool changed from False to True. Time: 23:29:23
Bool changed from True to False. Time: 23:29:25
Bool changed from False to True. Time: 23:29:27
整个循环运行大约 7 秒 - 即每秒大约 115 万次触发来更改它。
你可以把它变成 class:
public class FilteredBool
{
private bool _inputValue;
private bool _outputValue;
private TimeSpan _minimumTime = TimeSpan.FromSeconds(5);
private DateTime _lastChangeTime = DateTime.MinValue;
public bool Value
{
get
{
if (_outputValue != _inputValue)
{
if (_lastChangeTime + _minimumTime < DateTime.Now)
_outputValue = _inputValue;
}
return _outputValue;
}
set
{
if (_inputValue != value)
{
_inputValue = value;
_lastChangeTime = DateTime.Now;
}
}
}
public TimeSpan MinimumTime
{
get { return _minimumTime; }
set { _minimumTime = value; }
}
public static implicit operator bool(FilteredBool value)
{
return value.Value;
}
}
这有一个 bool
的隐式运算符,因此您可以只替换任何采用 bool
(或 if
)的函数调用,而不必调用 .Value
.没有返回 FilteredBool
的隐式运算符,因为这需要设置过滤时间。如果你愿意,你可以添加这个,我觉得这将是一个延伸。
OP 感谢伟大的解决方案。作为布尔低通滤波器的快速破解,我还想知道是否可以简单地使用计数器和模运算,本质上是 'slowing down' FixedUpdate 方法。布尔值永远不会比模运算(或余数)= 零的间隔更快地变化。没有考虑过实施细节。想法?