using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using o0.Geometry; using o0.Num; using UnityEngine; namespace o0.Bow { public class DistanceToAxis//测试版 { public DistanceToAxis() { DistanceQueue = new SortedQueue(); Distance = 0.6; } Vector LastAcc; Vector LockAcc;//静止状态下加速计向量,仅通过陀螺仪短时校准,长时校准不保证准确性,也无必要性 double LockMS; double LastGapMS; Vector Speed;//每秒 SortedQueue DistanceQueue; double Distance; /////////////////////////////////////////////////Acc长度以1为标准 public void Update(Vector Gyr, Vector Acc, Vector Mag, double GapMS)//务必仅在射箭瞄准游戏过程中调用 { if(LastAcc == default) { LastAcc = Acc; return; } if (Gyr.Length * 1000 < 1 // 陀螺仪计算的每秒移动小于1度 && (LastAcc - Acc).Length / GapMS * 1000 < 1// 加速计计算的每秒移动小于1度 && Acc.Length < 1.05 && Acc.Length > 0.95 && LastAcc.Length < 1.05 && LastAcc.Length > 0.95)//则当做静止状态,此时记录加速计长度 { LockAcc = Acc; LockMS = 0; LastGapMS = GapMS; Speed = Vector.Zero; //Debug.Log(Gyr.Length * 1000 + " | " + Acc.Length + " | " + (LastAcc - Acc).Length / GapMS * 1000); LastAcc = Acc; return; } if(LockAcc != default) { var GyrOperator = -Geometry.Quaternion.Euler((Gyr * GapMS).To()); LockAcc = (GyrOperator * LockAcc.To()).To(); Speed = (GyrOperator * Speed.To()).To(); Speed += (Acc - LockAcc) * 9.8 * (LastGapMS + GapMS) / 1000 / 2; if (LockMS < 250 && Gyr.Length * 1000 > 5) { var distance = Speed.Length / (Gyr.Length * 1000) * 180 / Math.PI;//臂长 if(distance < 1) { if (DistanceQueue.Count > 100) DistanceQueue.Dequeue(); DistanceQueue.Enqueue(distance); if(DistanceQueue.Count > 30) { var mid = DistanceQueue.Count >> 1; var max = mid + 10; var list = new List(); for (var i = mid - 9; i < max; ++i) list.Add(DistanceQueue[i]); Distance = list.Mean(); } } //Debug.Log(Distance); } // TestVector.SetAcc((Acc - LockAcc).ToUnityVector(), 1); // TestVector.SetMag(Speed.ToUnityVector(), 1); //Debug.Log(Gyr.Length); LastGapMS = GapMS; LockMS += GapMS; } LastAcc = Acc; return; } //默认轴在后方 z为负 //////// 米/秒 度/毫秒 public Vector GyrToSpeed(Vector Gyr, double GapMS) { var GyrOperator = Geometry.Quaternion.Euler((Gyr * GapMS).To()).Inversed; var axis = Vector.Back * Distance; axis = (GyrOperator * axis.To() - axis.To()).To() / GapMS * 1000; // TestVector.SetAcc(axis.ToUnityVector(), 2); //Debug.Log(axis); return axis; }/**/ Vector LastSpeed = default; public Vector AccCorrection(Vector Gyr, Vector Acc, double GapMS) { Vector Speed = GyrToSpeed(Gyr, GapMS); if (LastSpeed == default) { LastSpeed = Speed; //Debug.Log(Acc.z); //var Speed = return Acc; } var GyrOperator = Geometry.Quaternion.Euler((Gyr * GapMS).To()).Inversed; var RotatedLastSpeed = GyrOperator * LastSpeed.To(); var AccCorrection = (Speed - RotatedLastSpeed.To()) / 9.8 / GapMS * 1000; // TestVector.SetMag(AccCorrection.ToUnityVector(), 2); // TestVector.SetAcc((Acc + AccCorrection).ToUnityVector(), 3); LastSpeed = Speed; return Acc + AccCorrection;//因为Acc是反的 } } }