using System; using UnityEngine; using UnityEngine.UI; using ArduinoBluetoothAPI; using BestHTTP.WebSocket; public class ShootCheck : MonoBehaviour { [SerializeField] Text text; CMD cmd = new CMD(); bool locked = false; float maxAcc = 0; public float shootSpeed; public static ShootCheck ins; [SerializeField] InputField ipInputField = default; WebSocket webSocket; void Start() { ins = this; BluetoothDispatcher.shoot = OnDataReceived; } //用户输入时的变化 public void ChangedValue(string value) { ipInputField.ActivateInputField(); Debug.Log("输入了"+value); } public void EndValue(string value) { Debug.Log("最终内容"+value); } //socket public void StartSocket() { //socket string ipStr = ipInputField.text;//ipInputField.GetComponentInChildren(); string serverIP = ipStr;//"192.168.0.107"; // serverIP = "192.168.0.103"; string address = "ws://" + serverIP + ":8088/Ble/"; webSocket = new WebSocket(new Uri(address)); #if !UNITY_WEBGL webSocket.StartPingThread = true; #endif // Subscribe to the WS events webSocket.OnOpen += OnOpen; webSocket.OnMessage += OnMessageRecv; webSocket.OnBinary += OnBinaryRecv; webSocket.OnClosed += OnClosed; webSocket.OnError += OnError; // Debug.Log("OnOpen: "); // Start connecting to the server webSocket.Open(); } public void Destroy() { if (webSocket != null) { webSocket.Close(); webSocket = null; } } void OnOpen(WebSocket ws) { // Debug.Log("OnOpen: "); webSocket.Send("unity"); } void OnMessageRecv(WebSocket ws, string message) { Debug.LogFormat("OnMessageRecv: msg={0}", message); } void OnBinaryRecv(WebSocket ws, byte[] data) { Debug.LogFormat("OnBinaryRecv: len={0}", data.Length); } void OnClosed(WebSocket ws, UInt16 code, string message) { Debug.LogFormat("OnClosed: code={0}, msg={1}", code, message); webSocket = null; } void OnError(WebSocket ws, Exception ex) { string errorMsg = string.Empty; #if !UNITY_WEBGL || UNITY_EDITOR if (ws.InternalRequest.Response != null) { errorMsg = string.Format("Status Code from Server: {0} and Message: {1}", ws.InternalRequest.Response.StatusCode, ws.InternalRequest.Response.Message); } #endif Debug.LogFormat("OnError: error occured: {0}\n", (ex != null ? ex.Message : "Unknown Error " + errorMsg)); webSocket = null; } //socket void OnDestroy() { ins = null; } public void OnBluetoothReady(BluetoothShoot bluetoothShoot) { bluetoothShoot.WriteData(JsonUtility.ToJson(cmd).Replace("\"", "")); } public void OnDataReceived(byte[] bytes) { string str = ""; for (int i = 0; i < (bytes.Length-2)/6; i++) { // float acc = ToAcceleratedSpeed(bytes[i * 10 + 7], bytes[i * 10 + 8]); // string t = "(采样时间:"+(int)bytes[i * 10 + 5] + "分"+ (int)bytes[i * 10 + 6]+"秒"+ TwoByteToInt(bytes[i * 10 + 3], bytes[i * 10 + 4])+"毫秒)" ; float acc = ToAcceleratedSpeed(bytes[i * 6 + 5], bytes[i * 6 + 6]); string t = "(采样时间:"+(int)bytes[i * 6 + 3] + "分"+ (int)bytes[i * 6 + 4]+"秒"+ TwoByteToInt(bytes[i * 6 + 1], bytes[i * 6 + 2])+"毫秒)" ; str += "加速度:"+acc+t+"\n"; // ts[3] = "(采样时间:"+(int)bytes[33] + "分"+ (int)bytes[34]+"秒"+ TwoByteToInt(bytes[31], bytes[32])+"毫秒)" ; if (ins.check(acc)) { if (ArmBow.ins != null) { ArmBow.ins.ADS_fire(); webSocket.Send(str); } } } } float ToAcceleratedSpeed(byte b1, byte b2) { int value = TwoByteToInt(b1, b2); return (float)value / 32768 * 16; // return (float)value; } int TwoByteToInt(byte b1, byte b2) { ushort twoByte = (ushort)(b1 * 256 + b2); short shortNum = (short)twoByte; return (int)shortNum; } bool check(float acc) { DebugLine.show(acc); if (locked) { return false; } if (acc > cmd.getAcc() && acc > maxAcc) { maxAcc = acc; return false; } else if (acc < cmd.getAcc() && maxAcc != 0) { shootSpeed = maxAcc; // Log("最大加速度:" + maxAcc); maxAcc = 0; Dolock(); Invoke("Unlock", 0.8f); return true; } return false; } void Dolock() { locked = true; } void Unlock() { locked = false; } void Log(string text) { if (this.text != null) { this.text.text = text; } else { Debug.Log(text); } } } [Serializable] class CMD { public string ax = "y"; public int a = 1000; public int r = 2; public float getAcc() { return a * 0.0005f; } } // public class ShootCheck : MonoBehaviour // { // float[] accList = new float[30]; // int dataCount = 0; // float gravity = 0; // float maxAcc = 0; // bool hasReachShootThreshold = false; // bool locked = false; // int hitCount = 0; // float rangeAcc; //最新几帧的平均值 // [SerializeField] Text text; // public float shootSpeed; // public static ShootCheck ins; // void Start() // { // ins = this; // BluetoothDispatcher.shoot = OnDataReceived; // } // void OnDestroy() // { // ins = null; // } // float[] ays = new float[4]; // public void OnDataReceived(byte[] bytes) { // Debug.Log("射击模块数据长度" + bytes.Length); // ays[0] = ToAcceleratedSpeed(bytes[7], bytes[8]); // ays[1] = ToAcceleratedSpeed(bytes[17], bytes[18]); // ays[2] = ToAcceleratedSpeed(bytes[27], bytes[28]); // ays[3] = ToAcceleratedSpeed(bytes[37], bytes[38]); // foreach (float ay in ays) // { // try // { // if (ins.check(ay)) // { // if (ArmBow.ins != null) // { // ArmBow.ins.ADS_fire(); // } // } // } // catch (Exception e) // { // Debug.Log(e.Message); // } // } // } // float ToAcceleratedSpeed(byte b1, byte b2) // { // int value = TwoByteToInt(b1, b2); // return (float)value / 32768 * 16; // } // int TwoByteToInt(byte b1, byte b2) // { // ushort twoByte = (ushort)(b1 * 256 + b2); // short shortNum = (short)twoByte; // return (int)shortNum; // } // int validFrameCount = 0; // bool check(float acc) // { // DebugLine.show(acc); // DebugLine.showSteady(gravity); // for (int i = accList.Length - 1; i > 0; i--) // { // accList[i] = accList[i - 1]; // } // accList[0] = acc; // dataCount++; // if (locked) // { // return false; // } // if (hasReachShootThreshold) { // validFrameCount++; // if (acc <= gravity) { // hitCount++; // shootSpeed = maxAcc - gravity; // Log("第" + hitCount + "次识别射箭\n过滤正轴重力" + gravity.ToString("#0.000") + "后\n所得最大加速度峰值" + (maxAcc - gravity).ToString("#0.000") + "\n有效帧数" + validFrameCount); // maxAcc = 0; // validFrameCount = 0; // hasReachShootThreshold = false; // Dolock(); // Invoke("Unlock", 0.8f); // return true; // } else if (acc > maxAcc) { // maxAcc = acc; // } // if (validFrameCount > 20) // { // maxAcc = 0; // validFrameCount = 0; // hasReachShootThreshold = false; // Log("不符合短时间爆发加速"); // } // // if (this.isSteady()) { // // hitCount++; // // shootSpeed = integral / 16f; // // Log("第" + hitCount + "次识别射箭\n振幅:" + integral); // // integral = 0; // // validFrameCount = 0; // // hasReachShootThreshold = false; // // return true; // // } else { // // integral += Mathf.Abs(acc - gravity); // // } // return false; // } // if (dataCount > steadyFrameCount) // { // if (isSteady()) // { // gravity = Mathf.Clamp(rangeAcc, -0.981f, 0.981f); // } // if (acc - gravity > 2) // { // hasReachShootThreshold = true; // maxAcc = acc; // // integral += Mathf.Abs(acc - gravity); // } // } // return false; // } // // float integral = 0; // int steadyFrameCount = 6; // bool isSteady() { // float totalAcc = 0; // for (int i = 0; i < steadyFrameCount; i++) // { // totalAcc += accList[i]; // } // rangeAcc = totalAcc / steadyFrameCount; // float squareAcc = 0; // for (int i = 0; i < steadyFrameCount; i++) // { // squareAcc += (float) Mathf.Pow(accList[i] - rangeAcc, 2); // } // squareAcc /= steadyFrameCount; // return squareAcc < 0.00012; // } // void Dolock() // { // this.locked = true; // } // void Unlock() // { // this.locked = false; // } // void Log(string text) // { // if (this.text != null) // { // this.text.text = text; // } else { // Debug.Log(text); // } // } // }