ShootCheck.cs 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. using System;
  2. using UnityEngine;
  3. using UnityEngine.UI;
  4. using ArduinoBluetoothAPI;
  5. using BestHTTP.WebSocket;
  6. public class ShootCheck : MonoBehaviour
  7. {
  8. [SerializeField] Text text;
  9. CMD cmd = new CMD();
  10. bool locked = false;
  11. float maxAcc = 0;
  12. public float shootSpeed;
  13. public static ShootCheck ins;
  14. WebSocket webSocket;
  15. void Start()
  16. {
  17. ins = this;
  18. BluetoothDispatcher.shoot = OnDataReceived;
  19. //socket
  20. string serverIP = "192.168.1.103";
  21. string address = "ws://" + serverIP + ":8088/Ble/";
  22. webSocket = new WebSocket(new Uri(address));
  23. #if !UNITY_WEBGL
  24. webSocket.StartPingThread = true;
  25. #endif
  26. // Subscribe to the WS events
  27. webSocket.OnOpen += OnOpen;
  28. webSocket.OnMessage += OnMessageRecv;
  29. webSocket.OnBinary += OnBinaryRecv;
  30. webSocket.OnClosed += OnClosed;
  31. webSocket.OnError += OnError;
  32. // Debug.Log("OnOpen: ");
  33. // Start connecting to the server
  34. webSocket.Open();
  35. }
  36. //socket
  37. public void Destroy()
  38. {
  39. if (webSocket != null)
  40. {
  41. webSocket.Close();
  42. webSocket = null;
  43. }
  44. }
  45. void OnOpen(WebSocket ws)
  46. {
  47. // Debug.Log("OnOpen: ");
  48. webSocket.Send("unity");
  49. }
  50. void OnMessageRecv(WebSocket ws, string message)
  51. {
  52. Debug.LogFormat("OnMessageRecv: msg={0}", message);
  53. }
  54. void OnBinaryRecv(WebSocket ws, byte[] data)
  55. {
  56. Debug.LogFormat("OnBinaryRecv: len={0}", data.Length);
  57. }
  58. void OnClosed(WebSocket ws, UInt16 code, string message)
  59. {
  60. Debug.LogFormat("OnClosed: code={0}, msg={1}", code, message);
  61. webSocket = null;
  62. }
  63. void OnError(WebSocket ws, Exception ex)
  64. {
  65. string errorMsg = string.Empty;
  66. #if !UNITY_WEBGL || UNITY_EDITOR
  67. if (ws.InternalRequest.Response != null)
  68. {
  69. errorMsg = string.Format("Status Code from Server: {0} and Message: {1}", ws.InternalRequest.Response.StatusCode, ws.InternalRequest.Response.Message);
  70. }
  71. #endif
  72. Debug.LogFormat("OnError: error occured: {0}\n", (ex != null ? ex.Message : "Unknown Error " + errorMsg));
  73. webSocket = null;
  74. }
  75. //socket
  76. void OnDestroy()
  77. {
  78. ins = null;
  79. }
  80. public void OnBluetoothReady(BluetoothShoot bluetoothShoot) {
  81. bluetoothShoot.WriteData(JsonUtility.ToJson(cmd).Replace("\"", ""));
  82. }
  83. public void OnDataReceived(byte[] bytes) {
  84. string str = "";
  85. for (int i = 0; i < (bytes.Length-2)/6; i++)
  86. {
  87. // float acc = ToAcceleratedSpeed(bytes[i * 10 + 7], bytes[i * 10 + 8]);
  88. // string t = "(采样时间:"+(int)bytes[i * 10 + 5] + "分"+ (int)bytes[i * 10 + 6]+"秒"+ TwoByteToInt(bytes[i * 10 + 3], bytes[i * 10 + 4])+"毫秒)" ;
  89. float acc = ToAcceleratedSpeed(bytes[i * 6 + 5], bytes[i * 6 + 6]);
  90. string t = "(采样时间:"+(int)bytes[i * 6 + 3] + "分"+ (int)bytes[i * 6 + 4]+"秒"+ TwoByteToInt(bytes[i * 6 + 1], bytes[i * 6 + 2])+"毫秒)" ;
  91. str += "加速度:"+acc+t+"\n";
  92. // ts[3] = "(采样时间:"+(int)bytes[33] + "分"+ (int)bytes[34]+"秒"+ TwoByteToInt(bytes[31], bytes[32])+"毫秒)" ;
  93. if (ins.check(acc))
  94. {
  95. if (ArmBow.ins != null)
  96. {
  97. ArmBow.ins.ADS_fire();
  98. webSocket.Send(str);
  99. }
  100. }
  101. }
  102. }
  103. float ToAcceleratedSpeed(byte b1, byte b2)
  104. {
  105. int value = TwoByteToInt(b1, b2);
  106. return (float)value / 32768 * 16;
  107. }
  108. int TwoByteToInt(byte b1, byte b2)
  109. {
  110. ushort twoByte = (ushort)(b1 * 256 + b2);
  111. short shortNum = (short)twoByte;
  112. return (int)shortNum;
  113. }
  114. bool check(float acc)
  115. {
  116. DebugLine.show(acc);
  117. if (locked)
  118. {
  119. return false;
  120. }
  121. if (acc > cmd.getAcc() && acc > maxAcc)
  122. {
  123. maxAcc = acc;
  124. return false;
  125. } else if (acc < cmd.getAcc() && maxAcc != 0) {
  126. shootSpeed = maxAcc;
  127. // Log("最大加速度:" + maxAcc);
  128. maxAcc = 0;
  129. Dolock();
  130. Invoke("Unlock", 0.8f);
  131. return true;
  132. }
  133. return false;
  134. }
  135. void Dolock()
  136. {
  137. locked = true;
  138. }
  139. void Unlock()
  140. {
  141. locked = false;
  142. }
  143. void Log(string text)
  144. {
  145. if (this.text != null)
  146. {
  147. this.text.text = text;
  148. } else {
  149. Debug.Log(text);
  150. }
  151. }
  152. }
  153. [Serializable]
  154. class CMD {
  155. public string ax = "y";
  156. public int a = 6000;
  157. public int r = 2;
  158. public float getAcc() {
  159. return a * 0.0005f;
  160. }
  161. }
  162. // public class ShootCheck : MonoBehaviour
  163. // {
  164. // float[] accList = new float[30];
  165. // int dataCount = 0;
  166. // float gravity = 0;
  167. // float maxAcc = 0;
  168. // bool hasReachShootThreshold = false;
  169. // bool locked = false;
  170. // int hitCount = 0;
  171. // float rangeAcc; //最新几帧的平均值
  172. // [SerializeField] Text text;
  173. // public float shootSpeed;
  174. // public static ShootCheck ins;
  175. // void Start()
  176. // {
  177. // ins = this;
  178. // BluetoothDispatcher.shoot = OnDataReceived;
  179. // }
  180. // void OnDestroy()
  181. // {
  182. // ins = null;
  183. // }
  184. // float[] ays = new float[4];
  185. // public void OnDataReceived(byte[] bytes) {
  186. // Debug.Log("射击模块数据长度" + bytes.Length);
  187. // ays[0] = ToAcceleratedSpeed(bytes[7], bytes[8]);
  188. // ays[1] = ToAcceleratedSpeed(bytes[17], bytes[18]);
  189. // ays[2] = ToAcceleratedSpeed(bytes[27], bytes[28]);
  190. // ays[3] = ToAcceleratedSpeed(bytes[37], bytes[38]);
  191. // foreach (float ay in ays)
  192. // {
  193. // try
  194. // {
  195. // if (ins.check(ay))
  196. // {
  197. // if (ArmBow.ins != null)
  198. // {
  199. // ArmBow.ins.ADS_fire();
  200. // }
  201. // }
  202. // }
  203. // catch (Exception e)
  204. // {
  205. // Debug.Log(e.Message);
  206. // }
  207. // }
  208. // }
  209. // float ToAcceleratedSpeed(byte b1, byte b2)
  210. // {
  211. // int value = TwoByteToInt(b1, b2);
  212. // return (float)value / 32768 * 16;
  213. // }
  214. // int TwoByteToInt(byte b1, byte b2)
  215. // {
  216. // ushort twoByte = (ushort)(b1 * 256 + b2);
  217. // short shortNum = (short)twoByte;
  218. // return (int)shortNum;
  219. // }
  220. // int validFrameCount = 0;
  221. // bool check(float acc)
  222. // {
  223. // DebugLine.show(acc);
  224. // DebugLine.showSteady(gravity);
  225. // for (int i = accList.Length - 1; i > 0; i--)
  226. // {
  227. // accList[i] = accList[i - 1];
  228. // }
  229. // accList[0] = acc;
  230. // dataCount++;
  231. // if (locked)
  232. // {
  233. // return false;
  234. // }
  235. // if (hasReachShootThreshold) {
  236. // validFrameCount++;
  237. // if (acc <= gravity) {
  238. // hitCount++;
  239. // shootSpeed = maxAcc - gravity;
  240. // Log("第" + hitCount + "次识别射箭\n过滤正轴重力" + gravity.ToString("#0.000") + "后\n所得最大加速度峰值" + (maxAcc - gravity).ToString("#0.000") + "\n有效帧数" + validFrameCount);
  241. // maxAcc = 0;
  242. // validFrameCount = 0;
  243. // hasReachShootThreshold = false;
  244. // Dolock();
  245. // Invoke("Unlock", 0.8f);
  246. // return true;
  247. // } else if (acc > maxAcc) {
  248. // maxAcc = acc;
  249. // }
  250. // if (validFrameCount > 20)
  251. // {
  252. // maxAcc = 0;
  253. // validFrameCount = 0;
  254. // hasReachShootThreshold = false;
  255. // Log("不符合短时间爆发加速");
  256. // }
  257. // // if (this.isSteady()) {
  258. // // hitCount++;
  259. // // shootSpeed = integral / 16f;
  260. // // Log("第" + hitCount + "次识别射箭\n振幅:" + integral);
  261. // // integral = 0;
  262. // // validFrameCount = 0;
  263. // // hasReachShootThreshold = false;
  264. // // return true;
  265. // // } else {
  266. // // integral += Mathf.Abs(acc - gravity);
  267. // // }
  268. // return false;
  269. // }
  270. // if (dataCount > steadyFrameCount)
  271. // {
  272. // if (isSteady())
  273. // {
  274. // gravity = Mathf.Clamp(rangeAcc, -0.981f, 0.981f);
  275. // }
  276. // if (acc - gravity > 2)
  277. // {
  278. // hasReachShootThreshold = true;
  279. // maxAcc = acc;
  280. // // integral += Mathf.Abs(acc - gravity);
  281. // }
  282. // }
  283. // return false;
  284. // }
  285. // // float integral = 0;
  286. // int steadyFrameCount = 6;
  287. // bool isSteady() {
  288. // float totalAcc = 0;
  289. // for (int i = 0; i < steadyFrameCount; i++)
  290. // {
  291. // totalAcc += accList[i];
  292. // }
  293. // rangeAcc = totalAcc / steadyFrameCount;
  294. // float squareAcc = 0;
  295. // for (int i = 0; i < steadyFrameCount; i++)
  296. // {
  297. // squareAcc += (float) Mathf.Pow(accList[i] - rangeAcc, 2);
  298. // }
  299. // squareAcc /= steadyFrameCount;
  300. // return squareAcc < 0.00012;
  301. // }
  302. // void Dolock()
  303. // {
  304. // this.locked = true;
  305. // }
  306. // void Unlock()
  307. // {
  308. // this.locked = false;
  309. // }
  310. // void Log(string text)
  311. // {
  312. // if (this.text != null)
  313. // {
  314. // this.text.text = text;
  315. // } else {
  316. // Debug.Log(text);
  317. // }
  318. // }
  319. // }