|
|
@@ -0,0 +1,434 @@
|
|
|
+using System;
|
|
|
+using UnityEngine;
|
|
|
+
|
|
|
+namespace o0Aien
|
|
|
+{
|
|
|
+ public interface IFilter<T>
|
|
|
+ {
|
|
|
+ void Update(ref T value, T measuredValue);
|
|
|
+ }/**/
|
|
|
+ public abstract class Filter<T>: IFilter<T>
|
|
|
+ {
|
|
|
+ abstract public void Update(ref T value, T measuredValue);
|
|
|
+ }
|
|
|
+ public class NullFilter<T> : Filter<T>
|
|
|
+ {
|
|
|
+ public override void Update(ref T value, T measuredValue)
|
|
|
+ {
|
|
|
+ value = measuredValue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ public class FilterVector2<TFilter> : Filter<Vector2> where TFilter : Filter<float>
|
|
|
+ {
|
|
|
+ public Filter<float> this[int index]
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ return filter[index];
|
|
|
+ }
|
|
|
+ set
|
|
|
+ {
|
|
|
+ filter[index] = value;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ public Filter<float> X
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ return filter[0];
|
|
|
+ }
|
|
|
+ set
|
|
|
+ {
|
|
|
+ filter[0] = value;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ public Filter<float> Y
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ return filter[1];
|
|
|
+ }
|
|
|
+ set
|
|
|
+ {
|
|
|
+ filter[1] = value;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ protected Filter<float>[] filter;
|
|
|
+ public FilterVector2()
|
|
|
+ {
|
|
|
+ }
|
|
|
+ public FilterVector2(TFilter x, TFilter y)
|
|
|
+ {
|
|
|
+ filter = new Filter<float>[] { x, y };
|
|
|
+ }
|
|
|
+ public override void Update(ref Vector2 value, Vector2 measuredValue)
|
|
|
+ {
|
|
|
+ var v = new float[2];
|
|
|
+ for (var i = 0;i<2;++i)
|
|
|
+ filter[i].Update(ref v[i],measuredValue[i]);
|
|
|
+ value = new Vector2(v[0],v[1]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ public class FilterVector3<TFilter>: Filter<Vector3> where TFilter : Filter<float>
|
|
|
+ {
|
|
|
+ public Filter<float> this[int index]
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ return filter[index];
|
|
|
+ }
|
|
|
+ set
|
|
|
+ {
|
|
|
+ filter[index] = value;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ public Filter<float> X
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ return filter[0];
|
|
|
+ }
|
|
|
+ set
|
|
|
+ {
|
|
|
+ filter[0] = value;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ public Filter<float> Y
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ return filter[1];
|
|
|
+ }
|
|
|
+ set
|
|
|
+ {
|
|
|
+ filter[1] = value;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ public Filter<float> Z
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ return filter[2];
|
|
|
+ }
|
|
|
+ set
|
|
|
+ {
|
|
|
+ filter[2] = value;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ protected Filter<float>[] filter;
|
|
|
+ public FilterVector3()
|
|
|
+ {
|
|
|
+ filter = new Filter<float>[3];
|
|
|
+ }
|
|
|
+ public FilterVector3(TFilter x, TFilter y, TFilter z)
|
|
|
+ {
|
|
|
+ filter = new Filter<float>[] { x, y, z };
|
|
|
+ }
|
|
|
+ public override void Update(ref Vector3 value, Vector3 measuredValue)
|
|
|
+ {
|
|
|
+ var v = new float[2];
|
|
|
+ for (var i = 0; i < 3; ++i)
|
|
|
+ filter[i].Update(ref v[i], measuredValue[i]);
|
|
|
+ value = new Vector3(v[0], v[1], v[2]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ public class FilterStoreValue<T>: Filter<T>
|
|
|
+ {
|
|
|
+ protected Filter<T> filter;
|
|
|
+ protected T value = default;
|
|
|
+ public T Value { get
|
|
|
+ {
|
|
|
+ return value;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ public FilterStoreValue(Filter<T> filter)
|
|
|
+ {
|
|
|
+ this.filter = filter;
|
|
|
+ }
|
|
|
+ public T Update(T measuredValue)
|
|
|
+ {
|
|
|
+ filter.Update(ref value, measuredValue);
|
|
|
+ return value;
|
|
|
+ }
|
|
|
+
|
|
|
+ public override void Update(ref T value, T measuredValue)
|
|
|
+ {
|
|
|
+ filter.Update(ref value, measuredValue);
|
|
|
+ this.value = value;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ public class o0SigmoidIntegrationFilter : Filter<float>
|
|
|
+ {
|
|
|
+ static public float SigmoidIntegration(float to)//计算优化过的sigmoid算法
|
|
|
+ {
|
|
|
+ if (to > 700)
|
|
|
+ return to - 0.00671534848911797f;
|
|
|
+ return (float)Math.Log(1 + Math.Pow(Math.E, to)) - 0.00671534848911797f;
|
|
|
+ }
|
|
|
+ public o0SigmoidIntegrationFilter(float noise)//数据 的 噪音值大小
|
|
|
+ {
|
|
|
+ this.noise = Mathf.Abs(noise);
|
|
|
+ }
|
|
|
+ //public float value { get; protected set; } = default;
|
|
|
+ float noise = 10;
|
|
|
+
|
|
|
+ public override void Update(ref float value, float measuredValue)
|
|
|
+ {
|
|
|
+ if (value == default)
|
|
|
+ {
|
|
|
+ value = measuredValue;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ var noiseBuffer = noise / 10;
|
|
|
+ float sigmoidResult = SigmoidIntegration(Math.Abs(measuredValue - value) / noiseBuffer - 5) * noiseBuffer;//处理value过大时为无穷
|
|
|
+ if (measuredValue > value)
|
|
|
+ value += sigmoidResult;
|
|
|
+ else
|
|
|
+ value -= sigmoidResult;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ public class o0SigmoidIntegrationFilterVector3 : Filter<Vector3>
|
|
|
+ {
|
|
|
+ public o0SigmoidIntegrationFilterVector3(float noise)
|
|
|
+ {
|
|
|
+ this.noise = Mathf.Abs(noise);
|
|
|
+ }
|
|
|
+ //public Vector3 value { get; protected set; } = default;
|
|
|
+ float noise = 10;
|
|
|
+
|
|
|
+ public override void Update(ref Vector3 value, Vector3 measuredValue)
|
|
|
+ {
|
|
|
+ if (value == default)
|
|
|
+ {
|
|
|
+ value = measuredValue;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ var noiseBuffer = noise / 10;
|
|
|
+ var differenceVector = measuredValue - value;
|
|
|
+ float sigmoidResult = o0SigmoidIntegrationFilter.SigmoidIntegration(differenceVector.magnitude / noiseBuffer - 5) * noiseBuffer;//处理value过大时为无穷
|
|
|
+ value += sigmoidResult * differenceVector.normalized;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ public class o0SigmoidIntegrationFilterQuaternion : Filter<Quaternion>
|
|
|
+ {
|
|
|
+ public o0SigmoidIntegrationFilterQuaternion(float noise)
|
|
|
+ {
|
|
|
+ this.noise = Mathf.Abs(noise);
|
|
|
+ }
|
|
|
+ //public Vector3 value { get; protected set; } = default;
|
|
|
+ float noise = 10;
|
|
|
+
|
|
|
+ public override void Update(ref Quaternion value, Quaternion measuredValue)
|
|
|
+ {
|
|
|
+ if (value == default)
|
|
|
+ {
|
|
|
+ value = measuredValue;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ var noiseBuffer = noise / 10;
|
|
|
+ var difference = Quaternion.Angle(measuredValue, value);
|
|
|
+ //var differenceVector = measuredValue - value;
|
|
|
+ float sigmoidResult = o0SigmoidIntegrationFilter.SigmoidIntegration(difference / noiseBuffer - 5) * noiseBuffer;//处理value过大时为无穷
|
|
|
+ value = Quaternion.Slerp(value, measuredValue, sigmoidResult);
|
|
|
+ //value += sigmoidResult * differenceVector.normalized;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public class o0Filter3 : Filter<float>
|
|
|
+ {
|
|
|
+ public o0Filter3(float noise)
|
|
|
+ {
|
|
|
+ this.noise = Mathf.Abs(noise);
|
|
|
+ }
|
|
|
+ //public float value { get; protected set; } = float.MinValue;
|
|
|
+ float noise = 10;
|
|
|
+
|
|
|
+ float accelerationChangeLimit;
|
|
|
+ public override void Update(ref float value, float measuredValue)
|
|
|
+ {
|
|
|
+ if (Mathf.Abs(value - measuredValue) <= noise)
|
|
|
+ {
|
|
|
+ value += (measuredValue - value) * 0.1f;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (measuredValue > value)
|
|
|
+ value += (measuredValue - noise - value) * 0.7f + noise * 0.1f;
|
|
|
+ else
|
|
|
+ value += (measuredValue + noise - value) * 0.7f - noise * 0.1f;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ public class o0Filter: Filter<float>
|
|
|
+ {
|
|
|
+ public o0Filter(float accelerationLimit)
|
|
|
+ {
|
|
|
+ }
|
|
|
+ //public float value { get; protected set; } = float.MinValue;
|
|
|
+ float noise = 6;
|
|
|
+
|
|
|
+ float accelerationChangeLimit;
|
|
|
+ public override void Update(ref float value, float measuredValue)
|
|
|
+ {
|
|
|
+ if (value == float.MinValue)
|
|
|
+ {
|
|
|
+ value = measuredValue;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (Mathf.Abs(measuredValue - value) > noise)
|
|
|
+ {
|
|
|
+ float targetValue = value;
|
|
|
+ if (value < measuredValue - noise)
|
|
|
+ {
|
|
|
+ targetValue = measuredValue - noise;
|
|
|
+ }
|
|
|
+ else if (value > measuredValue + noise)
|
|
|
+ {
|
|
|
+ targetValue = measuredValue + noise;
|
|
|
+ }/**/
|
|
|
+ value = value + (targetValue - value) * 0.9f;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ value = value + (measuredValue - value) * 0.1f;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ public class o0AccelerationExFilter: Filter<float>
|
|
|
+ {
|
|
|
+ public o0AccelerationExFilter(float accelerationChangeLimit)//正数
|
|
|
+ {
|
|
|
+ this.accelerationChangeLimit = Mathf.Abs(accelerationChangeLimit);
|
|
|
+ }
|
|
|
+ //public float value { get; protected set; } = float.MinValue;
|
|
|
+ float speed = 0;
|
|
|
+ float acceleration = 0;
|
|
|
+ float accelerationChangeLimit;
|
|
|
+ public override void Update(ref float value, float measuredValue)
|
|
|
+ {
|
|
|
+ if (value == float.MinValue)
|
|
|
+ {
|
|
|
+ value = measuredValue;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (Mathf.Abs(value + speed - measuredValue) <= acceleration + accelerationChangeLimit)
|
|
|
+ {
|
|
|
+ if(Mathf.Abs(value + speed - measuredValue) >= acceleration - accelerationChangeLimit)
|
|
|
+ acceleration = Mathf.Abs(value + speed - measuredValue);
|
|
|
+ else
|
|
|
+ acceleration -= accelerationChangeLimit;
|
|
|
+ speed = measuredValue - value;
|
|
|
+ value = measuredValue;
|
|
|
+ }
|
|
|
+ else if (value + speed + acceleration + accelerationChangeLimit < measuredValue)
|
|
|
+ {
|
|
|
+ acceleration += accelerationChangeLimit;
|
|
|
+ speed += acceleration;
|
|
|
+ value += speed;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ acceleration += accelerationChangeLimit;
|
|
|
+ speed -= acceleration;
|
|
|
+ value += speed;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ public class o0AccelerationFilter: Filter<float>
|
|
|
+ {
|
|
|
+ public o0AccelerationFilter(float accelerationLimit)//正数
|
|
|
+ {
|
|
|
+ this.accelerationLimit = Mathf.Abs(accelerationLimit);
|
|
|
+ }
|
|
|
+ //public float value { get; protected set; } = float.MinValue;
|
|
|
+ float speed = 0;
|
|
|
+ float accelerationLimit;
|
|
|
+ public override void Update(ref float value, float measuredValue)
|
|
|
+ {
|
|
|
+ if (value == float.MinValue)
|
|
|
+ {
|
|
|
+ value = measuredValue;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (Mathf.Abs(value + speed - measuredValue) <= accelerationLimit)
|
|
|
+ {
|
|
|
+ speed = measuredValue - value;
|
|
|
+ value = measuredValue;
|
|
|
+ }
|
|
|
+ else if (value + speed + accelerationLimit < measuredValue)
|
|
|
+ {
|
|
|
+ speed += accelerationLimit;
|
|
|
+ value += speed;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ speed -= accelerationLimit;
|
|
|
+ value += speed;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ public class o0SpeedFilter: Filter<float>
|
|
|
+ {
|
|
|
+ public o0SpeedFilter(float speedLimit)//正数
|
|
|
+ {
|
|
|
+ this.speedLimit = Mathf.Abs(speedLimit);
|
|
|
+ }
|
|
|
+ //public float value { get; protected set; } = float.MinValue;
|
|
|
+ float speedLimit = 0;
|
|
|
+ public override void Update(ref float value, float measuredValue)
|
|
|
+ {
|
|
|
+ if (value == float.MinValue)
|
|
|
+ {
|
|
|
+ value = measuredValue;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (Mathf.Abs(value - measuredValue) <= speedLimit)
|
|
|
+ {
|
|
|
+ value = measuredValue;
|
|
|
+ }
|
|
|
+ else if (value + speedLimit < measuredValue)
|
|
|
+ {
|
|
|
+ value += speedLimit;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ value -= speedLimit;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ public class o0KalmanFilter: Filter<float>
|
|
|
+ {
|
|
|
+ float measuredValueDeviation;
|
|
|
+ float estimatedValueDeviation;
|
|
|
+ public o0KalmanFilter(float measuredValueDeviation)
|
|
|
+ {
|
|
|
+ this.measuredValueDeviation = measuredValueDeviation;
|
|
|
+ this.estimatedValueDeviation = measuredValueDeviation;
|
|
|
+ }
|
|
|
+ //public float value { get; protected set; } = float.MinValue;
|
|
|
+ public override void Update(ref float value, float measuredValue)
|
|
|
+ {
|
|
|
+ if (value == float.MinValue)
|
|
|
+ {
|
|
|
+ value = measuredValue;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ float measuredValueDeviationSquare = measuredValueDeviation * measuredValueDeviation;
|
|
|
+ float estimatedValueDeviationSquare = estimatedValueDeviation * estimatedValueDeviation;
|
|
|
+
|
|
|
+ float H = Mathf.Sqrt(estimatedValueDeviationSquare / (estimatedValueDeviationSquare + measuredValueDeviationSquare));
|
|
|
+ float OptimalValue = value + H * (measuredValue - value);
|
|
|
+ float OptimalValueDeviation = Mathf.Sqrt((1 - H) * estimatedValueDeviationSquare);
|
|
|
+ (value, estimatedValueDeviation) = this.nextEstimatedValue(OptimalValue, OptimalValueDeviation);
|
|
|
+ }
|
|
|
+ public virtual (float, float) nextEstimatedValue(float OptimalValue, float OptimalValueDeviation)
|
|
|
+ {
|
|
|
+ return (OptimalValue, OptimalValueDeviation);
|
|
|
+ }/**/
|
|
|
+ }
|
|
|
+}
|