Axis9Handler_SDK.cs 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. using System;
  2. using UnityEngine;
  3. using Newtonsoft.Json;
  4. using System.Reflection;
  5. namespace SmartBowSDK
  6. {
  7. public class Axis9Handler_SDK : AxisBaseHandler_SDK
  8. {
  9. private o0.Bow.o09AxisAfterXiaMenFromDll_SDK _9Axis;
  10. private AttitudeJson_SDK attitudeJson = new AttitudeJson_SDK();
  11. public o0.Geometry.Vector<int> GyrByteIndex = new o0.Geometry.Vector<int>(-3, -2, -1);
  12. public o0.Geometry.Vector<int> AccByteIndex = new o0.Geometry.Vector<int>(-3, -2, -1);
  13. public o0.Geometry.Vector<int> MagByteIndex = new o0.Geometry.Vector<int>(3, 2, -1);/**///9轴 usb向上 pcb向右 电池向左
  14. public Axis9Handler_SDK(AimHandler_SDK aimHandler) : base(aimHandler) { }
  15. public override void Init()
  16. {
  17. _9Axis = new o0.Bow.o09AxisAfterXiaMenFromDll_SDK(GyrByteIndex, AccByteIndex, MagByteIndex);
  18. LoadIdentity();
  19. }
  20. public override void Update(byte[] bytes)
  21. {
  22. UpdateCheckGyrCompleted();
  23. o0.Geometry.Quaternion Qua = o0.Geometry.Quaternion.Identity;
  24. try
  25. {
  26. lock (_9Axis)
  27. Qua = _9Axis.Update(new byte[] { bytes[13], bytes[14], bytes[15], bytes[16], bytes[17], bytes[18] },
  28. new byte[] { bytes[7], bytes[8], bytes[9], bytes[10], bytes[11], bytes[12] },
  29. new byte[] { bytes[19], bytes[20], bytes[21], bytes[22], bytes[23], bytes[24] },
  30. bytes[1], bytes[2], bytes[3], bytes[4]);/**///9轴
  31. }
  32. catch (Exception e)
  33. {
  34. Debug.LogError(e);
  35. }
  36. m_aimHandler.SetNewRotation(Qua);
  37. UpdateCheckMagCompleted();
  38. }
  39. private void UpdateCheckGyrCompleted()
  40. {
  41. if (_9Axis.Attitude.GyrCalibrate && GetGyrProgress() >= 1)
  42. {
  43. StopGyrCalibration();
  44. SaveCalibrateRecord();
  45. }
  46. }
  47. private bool _magCompleted;
  48. private void UpdateCheckMagCompleted()
  49. {
  50. bool magCompleted = IsMagCompleted();
  51. if (magCompleted && !_magCompleted)
  52. SaveCalibrateRecord();
  53. _magCompleted = magCompleted;
  54. }
  55. private void CorrectMagCompleted()
  56. {
  57. _magCompleted = IsMagCompleted();
  58. }
  59. public override void DoIdentity()
  60. {
  61. if (_9Axis.States.Count == 0) return; //没数据时触发视角归位会产生NAN,从而导致算法崩坏
  62. SetIdentityAndSave();
  63. m_aimHandler.SetNewRotation(_9Axis.getLastState().Qua);
  64. }
  65. public override void NotifyAxisOnShot()
  66. {
  67. _9Axis.OnShot(100, 100, 100000);
  68. }
  69. public override void StartGyrCalibration()
  70. {
  71. _9Axis.Attitude.GyrCalibrate = true;
  72. }
  73. public override void StopGyrCalibration()
  74. {
  75. _9Axis.Attitude.GyrCalibrate = false;
  76. }
  77. public override bool IsGyrCalibrating()
  78. {
  79. return _9Axis.Attitude.GyrCalibrate;
  80. }
  81. public override float GetGyrProgress()
  82. {
  83. return _9Axis.Attitude.GyrCalibrater.Count / 2000f;
  84. }
  85. public override bool IsGyrCompleted()
  86. {
  87. return _9Axis.Attitude.GyrCalibrater.Count >= 2000;
  88. }
  89. public override void StartMagCalibration()
  90. {
  91. _9Axis.Attitude.MagCalibrater = new o0.IMU.MagnetometerAutoCalibrater(0.001d);
  92. }
  93. public override bool IsMagCompleted()
  94. {
  95. return _9Axis.Attitude.MagCalibrater.Complete;
  96. }
  97. public override void SaveCalibrateRecord()
  98. {
  99. try
  100. {
  101. SmartBowLogger.Log(this, "开始序列化九轴数据");
  102. string record = attitudeJson.Stringify(_9Axis.Attitude);
  103. if (!string.IsNullOrEmpty(record))
  104. {
  105. SmartBowLogger.Log(this, $"九轴数据序列化完成(长度{record.Length})\nGyrMeanLen:{_9Axis.Attitude.GyrCalibrater.Mean.Length}\nMagVariance:{_9Axis.Attitude.MagCalibrater.Variance}");
  106. if (!IsGyrCompleted())
  107. {
  108. SmartBowLogger.LogWarning(this, "陀螺仪未校准,因校准数据不完整无法上传!");
  109. return;
  110. }
  111. if (!IsMagCompleted())
  112. {
  113. SmartBowLogger.LogWarning(this, "地磁计未校准,因校准数据不完整无法上传!");
  114. return;
  115. }
  116. string macAddress = m_aimHandler.smartBowHelper.bluetoothAim.macAddress;
  117. if (macAddress == null)
  118. {
  119. Debug.Log("MacAddress为null,无法上传校准记录!");
  120. return;
  121. }
  122. m_aimHandler.smartBowHelper.smartBowNetwork.SaveCalibrateRecord(macAddress, record);
  123. }
  124. }
  125. catch (Exception e)
  126. {
  127. Debug.LogError(e);
  128. }
  129. }
  130. public override void ResumeCalibrateRecord(string record)
  131. {
  132. try
  133. {
  134. SmartBowLogger.Log(this, $"成功加载服务端的九轴数据(长度{record.Length})");
  135. _9Axis.Attitude = attitudeJson.Parse<o0.IMU._9AxisPreProcessor>(record);
  136. SmartBowLogger.Log(this, $"九轴数据恢复成功\nGyrMeanLen:{_9Axis.Attitude.GyrCalibrater.Mean.Length}\nMagVariance:{_9Axis.Attitude.MagCalibrater.Variance}");
  137. if (!IsAxisRight())
  138. {
  139. _9Axis.Attitude = new o0.IMU._9AxisPreProcessor(GyrByteIndex, AccByteIndex, MagByteIndex);
  140. SmartBowLogger.LogWarning(this, "跟保存的轴向不相同,重置校准记录!");
  141. }
  142. }
  143. catch (Exception e)
  144. {
  145. Debug.LogError(e);
  146. }
  147. CorrectMagCompleted();
  148. }
  149. //判断轴向是否正确
  150. private bool IsAxisRight()
  151. {
  152. object o = _9Axis.Attitude;
  153. Type t = o.GetType();
  154. var _gyr = t.GetField("GyrByteIndex", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(o);
  155. var _acc = t.GetField("AccByteIndex", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(o);
  156. var _mag = t.GetField("MagByteIndex", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(o);
  157. bool gyrEqual = GyrByteIndex.Equals(_gyr);
  158. bool accEqual = AccByteIndex.Equals(_acc);
  159. bool magEqual = MagByteIndex.Equals(_mag);
  160. return gyrEqual && accEqual && magEqual;
  161. }
  162. private void LoadIdentity()
  163. {
  164. try
  165. {
  166. string accStr = PlayerPrefs.GetString("AccIdentity0", "");
  167. if (accStr.Length > 0)
  168. {
  169. double[] arr = JsonConvert.DeserializeObject<double[]>(accStr);
  170. var v = new o0.Geometry.Vector<double>(arr);
  171. if (!double.IsNaN(v.x) && !double.IsInfinity(v.x)
  172. && !double.IsNaN(v.y) && !double.IsInfinity(v.y)
  173. && !double.IsNaN(v.z) && !double.IsInfinity(v.z)
  174. )
  175. {
  176. _9Axis.AccIdentity = v;
  177. }
  178. }
  179. string magStr = PlayerPrefs.GetString("MagIdentity0", "");
  180. if (magStr.Length > 0)
  181. {
  182. double[] arr = JsonConvert.DeserializeObject<double[]>(magStr);
  183. var v = new o0.Geometry.Vector<double>(arr);
  184. if (!double.IsNaN(v.x) && !double.IsInfinity(v.x)
  185. && !double.IsNaN(v.y) && !double.IsInfinity(v.y)
  186. && !double.IsNaN(v.z) && !double.IsInfinity(v.z)
  187. )
  188. {
  189. _9Axis.MagIdentity = v;
  190. }
  191. }
  192. }
  193. catch (Exception e)
  194. {
  195. Debug.LogError(e);
  196. }
  197. }
  198. private void SetIdentityAndSave()
  199. {
  200. _9Axis.SetIdentity();
  201. var a = _9Axis.AccIdentity;
  202. var m = _9Axis.MagIdentity;
  203. PlayerPrefs.SetString("AccIdentity0", JsonConvert.SerializeObject(new double[]{
  204. a.x, a.y, a.z
  205. }));
  206. PlayerPrefs.SetString("MagIdentity0", JsonConvert.SerializeObject(new double[]{
  207. m.x, m.y, m.z
  208. }));
  209. }
  210. }
  211. }