ShootCheck.cs 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. using System;
  2. using UnityEngine;
  3. using UnityEngine.UI;
  4. using ArduinoBluetoothAPI;
  5. public class ShootCheck : MonoBehaviour
  6. {
  7. [SerializeField] Text text;
  8. CMD cmd = new CMD();
  9. bool locked = false;
  10. float maxAcc = 0;
  11. public float shootSpeed;
  12. public static ShootCheck ins;
  13. void Start()
  14. {
  15. ins = this;
  16. BluetoothDispatcher.shoot = OnDataReceived;
  17. }
  18. void OnDestroy()
  19. {
  20. ins = null;
  21. }
  22. public void OnBluetoothReady(BluetoothShoot bluetoothShoot) {
  23. bluetoothShoot.WriteData(JsonUtility.ToJson(cmd).Replace("\"", ""));
  24. }
  25. public void OnDataReceived(byte[] bytes) {
  26. for (int i = 0; i < bytes.Length / 10; i++)
  27. {
  28. float acc = ToAcceleratedSpeed(bytes[i * 10 + 7], bytes[i * 10 + 8]);
  29. if (ins.check(acc))
  30. {
  31. if (ArmBow.ins != null)
  32. {
  33. ArmBow.ins.ADS_fire();
  34. }
  35. }
  36. }
  37. }
  38. float ToAcceleratedSpeed(byte b1, byte b2)
  39. {
  40. int value = TwoByteToInt(b1, b2);
  41. return (float)value / 32768 * 16;
  42. }
  43. int TwoByteToInt(byte b1, byte b2)
  44. {
  45. ushort twoByte = (ushort)(b1 * 256 + b2);
  46. short shortNum = (short)twoByte;
  47. return (int)shortNum;
  48. }
  49. bool check(float acc)
  50. {
  51. DebugLine.show(acc);
  52. if (locked)
  53. {
  54. return false;
  55. }
  56. if (acc > cmd.getAcc() && acc > maxAcc)
  57. {
  58. maxAcc = acc;
  59. return false;
  60. } else if (acc < cmd.getAcc() && maxAcc != 0) {
  61. shootSpeed = maxAcc;
  62. Log("最大加速度:" + maxAcc);
  63. maxAcc = 0;
  64. Dolock();
  65. Invoke("Unlock", 0.8f);
  66. return true;
  67. }
  68. return false;
  69. }
  70. void Dolock()
  71. {
  72. locked = true;
  73. }
  74. void Unlock()
  75. {
  76. locked = false;
  77. }
  78. void Log(string text)
  79. {
  80. if (this.text != null)
  81. {
  82. this.text.text = text;
  83. } else {
  84. Debug.Log(text);
  85. }
  86. }
  87. }
  88. [Serializable]
  89. class CMD {
  90. public string ax = "y";
  91. public int a = 6000;
  92. public int r = 2;
  93. public float getAcc() {
  94. return a * 0.0005f;
  95. }
  96. }
  97. // public class ShootCheck : MonoBehaviour
  98. // {
  99. // float[] accList = new float[30];
  100. // int dataCount = 0;
  101. // float gravity = 0;
  102. // float maxAcc = 0;
  103. // bool hasReachShootThreshold = false;
  104. // bool locked = false;
  105. // int hitCount = 0;
  106. // float rangeAcc; //最新几帧的平均值
  107. // [SerializeField] Text text;
  108. // public float shootSpeed;
  109. // public static ShootCheck ins;
  110. // void Start()
  111. // {
  112. // ins = this;
  113. // BluetoothDispatcher.shoot = OnDataReceived;
  114. // }
  115. // void OnDestroy()
  116. // {
  117. // ins = null;
  118. // }
  119. // float[] ays = new float[4];
  120. // public void OnDataReceived(byte[] bytes) {
  121. // Debug.Log("射击模块数据长度" + bytes.Length);
  122. // ays[0] = ToAcceleratedSpeed(bytes[7], bytes[8]);
  123. // ays[1] = ToAcceleratedSpeed(bytes[17], bytes[18]);
  124. // ays[2] = ToAcceleratedSpeed(bytes[27], bytes[28]);
  125. // ays[3] = ToAcceleratedSpeed(bytes[37], bytes[38]);
  126. // foreach (float ay in ays)
  127. // {
  128. // try
  129. // {
  130. // if (ins.check(ay))
  131. // {
  132. // if (ArmBow.ins != null)
  133. // {
  134. // ArmBow.ins.ADS_fire();
  135. // }
  136. // }
  137. // }
  138. // catch (Exception e)
  139. // {
  140. // Debug.Log(e.Message);
  141. // }
  142. // }
  143. // }
  144. // float ToAcceleratedSpeed(byte b1, byte b2)
  145. // {
  146. // int value = TwoByteToInt(b1, b2);
  147. // return (float)value / 32768 * 16;
  148. // }
  149. // int TwoByteToInt(byte b1, byte b2)
  150. // {
  151. // ushort twoByte = (ushort)(b1 * 256 + b2);
  152. // short shortNum = (short)twoByte;
  153. // return (int)shortNum;
  154. // }
  155. // int validFrameCount = 0;
  156. // bool check(float acc)
  157. // {
  158. // DebugLine.show(acc);
  159. // DebugLine.showSteady(gravity);
  160. // for (int i = accList.Length - 1; i > 0; i--)
  161. // {
  162. // accList[i] = accList[i - 1];
  163. // }
  164. // accList[0] = acc;
  165. // dataCount++;
  166. // if (locked)
  167. // {
  168. // return false;
  169. // }
  170. // if (hasReachShootThreshold) {
  171. // validFrameCount++;
  172. // if (acc <= gravity) {
  173. // hitCount++;
  174. // shootSpeed = maxAcc - gravity;
  175. // Log("第" + hitCount + "次识别射箭\n过滤正轴重力" + gravity.ToString("#0.000") + "后\n所得最大加速度峰值" + (maxAcc - gravity).ToString("#0.000") + "\n有效帧数" + validFrameCount);
  176. // maxAcc = 0;
  177. // validFrameCount = 0;
  178. // hasReachShootThreshold = false;
  179. // Dolock();
  180. // Invoke("Unlock", 0.8f);
  181. // return true;
  182. // } else if (acc > maxAcc) {
  183. // maxAcc = acc;
  184. // }
  185. // if (validFrameCount > 20)
  186. // {
  187. // maxAcc = 0;
  188. // validFrameCount = 0;
  189. // hasReachShootThreshold = false;
  190. // Log("不符合短时间爆发加速");
  191. // }
  192. // // if (this.isSteady()) {
  193. // // hitCount++;
  194. // // shootSpeed = integral / 16f;
  195. // // Log("第" + hitCount + "次识别射箭\n振幅:" + integral);
  196. // // integral = 0;
  197. // // validFrameCount = 0;
  198. // // hasReachShootThreshold = false;
  199. // // return true;
  200. // // } else {
  201. // // integral += Mathf.Abs(acc - gravity);
  202. // // }
  203. // return false;
  204. // }
  205. // if (dataCount > steadyFrameCount)
  206. // {
  207. // if (isSteady())
  208. // {
  209. // gravity = Mathf.Clamp(rangeAcc, -0.981f, 0.981f);
  210. // }
  211. // if (acc - gravity > 2)
  212. // {
  213. // hasReachShootThreshold = true;
  214. // maxAcc = acc;
  215. // // integral += Mathf.Abs(acc - gravity);
  216. // }
  217. // }
  218. // return false;
  219. // }
  220. // // float integral = 0;
  221. // int steadyFrameCount = 6;
  222. // bool isSteady() {
  223. // float totalAcc = 0;
  224. // for (int i = 0; i < steadyFrameCount; i++)
  225. // {
  226. // totalAcc += accList[i];
  227. // }
  228. // rangeAcc = totalAcc / steadyFrameCount;
  229. // float squareAcc = 0;
  230. // for (int i = 0; i < steadyFrameCount; i++)
  231. // {
  232. // squareAcc += (float) Mathf.Pow(accList[i] - rangeAcc, 2);
  233. // }
  234. // squareAcc /= steadyFrameCount;
  235. // return squareAcc < 0.00012;
  236. // }
  237. // void Dolock()
  238. // {
  239. // this.locked = true;
  240. // }
  241. // void Unlock()
  242. // {
  243. // this.locked = false;
  244. // }
  245. // void Log(string text)
  246. // {
  247. // if (this.text != null)
  248. // {
  249. // this.text.text = text;
  250. // } else {
  251. // Debug.Log(text);
  252. // }
  253. // }
  254. // }