o09DOF.cs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. using ArduinoBluetoothAPI;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using UnityEngine;
  6. public class o09DOF
  7. {
  8. static Vector3 AccIdentity = new Vector3(0, -1, 0);
  9. static Vector3 MagIdentity = new Vector3(-1, 2, 0).normalized;
  10. public class State
  11. {
  12. public long TimeGap;
  13. public Vector3 Acc = AccIdentity;
  14. public Vector3 Gyr;
  15. public Vector3 Mag = MagIdentity;
  16. public Quaternion Qua;
  17. public float Variance = 1;
  18. }
  19. List<State> States = new List<State>();
  20. Vector3 AccOld;
  21. Vector3 GyrOld;
  22. Vector3 MagOld;
  23. long TimeGapOld;
  24. /////////////////////g degree/ms
  25. public Quaternion o06DOFUpdate(Vector3 AccOld, Vector3 GyrOld, Vector3 MagOld, long TimeGapOld)
  26. {
  27. //Debug.Log(TimeGapOld);
  28. var Acc = this.AccOld;
  29. var Gyr = this.GyrOld;
  30. var Mag = this.MagOld;
  31. float TimeGap = (TimeGapOld + this.TimeGapOld) / 2;
  32. this.AccOld = AccOld;
  33. this.GyrOld = GyrOld;
  34. this.MagOld = MagOld;
  35. this.TimeGapOld = TimeGapOld;
  36. if (this.TimeGapOld <= 0)
  37. return Quaternion.identity;
  38. var Last = States.LastOrDefault() ?? new State();
  39. States.Add(new State());
  40. if (States.Count > 10)
  41. States.RemoveAt(0);
  42. var state = States.Last();
  43. state.Acc = Acc;
  44. state.Gyr = Gyr;
  45. state.Mag = Mag;
  46. //Debug.Log(TimeGap);
  47. /*
  48. var Accwit = GameObject.Find("Accwit");
  49. var Gyrwit = GameObject.Find("Gyrwit");
  50. var Magwit = GameObject.Find("Magwit");/**/
  51. var LastQuaternion = Last.Qua;
  52. //var LastQuaternion = Gyrwit.transform.localRotation;
  53. var newQua = new Quaternion();
  54. newQua.eulerAngles = Gyr * TimeGap;
  55. var quaGyr = LastQuaternion * newQua;
  56. float AccLengthToAngle = 90;//1倍引力差相当于多少度方差
  57. float MagLengthToAngle = 90;//1倍磁力差相当于多少度方差
  58. /*
  59. *
  60. float GyrVariance = state.Variance + TimeGap/200 + Mathf.Pow((Gyr * TimeGap).magnitude * 0.03f,2);
  61. float AccVariance = TimeGap / 30 + Mathf.Pow((Acc.magnitude - 9.8f) / 9.8f * AccLengthToAngle, 2)+ Mathf.Pow(Vector3.Angle(Acc,Last.Acc) * 0.5f, 2);
  62. //Debug.Log(Mag.magnitude);
  63. float MagVariance = TimeGap / 100 + Mathf.Pow((Mag.magnitude - 500) / 500 * MagLengthToAngle, 2) + Mathf.Pow(Vector3.Angle(Mag, Last.Mag) * 0.1f, 2);
  64. /**/
  65. float GyrVariance = state.Variance + TimeGap / 100 + (Gyr * TimeGap).magnitude * 0.05f;
  66. float AccVariance = TimeGap / 30 + Mathf.Sqrt(Mathf.Pow((Acc.magnitude - 9.8f) / 9.8f * AccLengthToAngle, 2) + Mathf.Pow(Vector3.Angle(Acc, Last.Acc) * 0.5f, 2));
  67. Debug.Log(AccVariance);
  68. float MagVariance = TimeGap / 100 + Mathf.Sqrt(Mathf.Pow((Mag.magnitude - 500) / 500 * MagLengthToAngle, 2) + Mathf.Pow(Vector3.Angle(Mag, Last.Mag) * 0.1f, 2));
  69. state.Variance = state.Variance * AccVariance / (state.Variance + AccVariance);
  70. state.Variance = state.Variance * MagVariance / (state.Variance + MagVariance);
  71. var quaAccMag = o0Project.o0.FormQuaternion(AccIdentity, MagIdentity, Acc, Mag, AccVariance / (AccVariance + MagVariance));
  72. var quaMinRate = GyrVariance / (GyrVariance + Mathf.Max(AccVariance, MagVariance));
  73. var quaMaxRate = GyrVariance / (GyrVariance + Mathf.Min(AccVariance, MagVariance));
  74. Quaternion quaFirst = Quaternion.Slerp(quaGyr, quaAccMag, quaMinRate).normalized;
  75. float quaSecondRate = (quaMaxRate - quaMinRate) / (1 - quaMinRate);
  76. state.Qua = AccVariance < MagVariance ? o0Project.o0.FormQuaternion(quaFirst, AccIdentity, Acc, quaSecondRate) : o0Project.o0.FormQuaternion(quaFirst, MagIdentity, Mag, quaSecondRate);
  77. return state.Qua;
  78. //Image1.DrawLine();
  79. }
  80. public void Calibrate()
  81. {
  82. AccIdentity = AccOld;
  83. MagIdentity = MagOld;
  84. }
  85. }