|
@@ -1,18 +1,14 @@
|
|
|
using System;
|
|
using System;
|
|
|
using UnityEngine;
|
|
using UnityEngine;
|
|
|
using UnityEngine.UI;
|
|
using UnityEngine.UI;
|
|
|
|
|
+using ArduinoBluetoothAPI;
|
|
|
|
|
|
|
|
public class ShootCheck : MonoBehaviour
|
|
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;
|
|
[SerializeField] Text text;
|
|
|
|
|
+ CMD cmd = new CMD();
|
|
|
|
|
+ bool locked = false;
|
|
|
|
|
+ float maxAcc = 0;
|
|
|
public float shootSpeed;
|
|
public float shootSpeed;
|
|
|
public static ShootCheck ins;
|
|
public static ShootCheck ins;
|
|
|
|
|
|
|
@@ -27,29 +23,22 @@ public class ShootCheck : MonoBehaviour
|
|
|
ins = null;
|
|
ins = null;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- float[] ays = new float[4];
|
|
|
|
|
|
|
+ public void OnBluetoothReady(BluetoothShoot bluetoothShoot) {
|
|
|
|
|
+ bluetoothShoot.WriteData(JsonUtility.ToJson(cmd).Replace("\"", ""));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
public void OnDataReceived(byte[] bytes) {
|
|
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)
|
|
|
|
|
|
|
+ for (int i = 0; i < bytes.Length / 10; i++)
|
|
|
{
|
|
{
|
|
|
- try
|
|
|
|
|
|
|
+ float acc = ToAcceleratedSpeed(bytes[i * 10 + 7], bytes[i * 10 + 8]);
|
|
|
|
|
+ if (ins.check(acc))
|
|
|
{
|
|
{
|
|
|
- if (ins.check(ay))
|
|
|
|
|
|
|
+ if (ArmBow.ins != null)
|
|
|
{
|
|
{
|
|
|
- if (ArmBow.ins != null)
|
|
|
|
|
- {
|
|
|
|
|
- ArmBow.ins.ADS_fire();
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ ArmBow.ins.ADS_fire();
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
- catch (Exception e)
|
|
|
|
|
- {
|
|
|
|
|
- Debug.Log(e.Message);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -66,100 +55,36 @@ public class ShootCheck : MonoBehaviour
|
|
|
return (int)shortNum;
|
|
return (int)shortNum;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- int validFrameCount = 0;
|
|
|
|
|
bool check(float acc)
|
|
bool check(float acc)
|
|
|
{
|
|
{
|
|
|
DebugLine.show(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)
|
|
if (locked)
|
|
|
{
|
|
{
|
|
|
return false;
|
|
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 (acc > cmd.getAcc() && acc > maxAcc)
|
|
|
{
|
|
{
|
|
|
- if (isSteady())
|
|
|
|
|
- {
|
|
|
|
|
- gravity = Mathf.Clamp(rangeAcc, -0.981f, 0.981f);
|
|
|
|
|
- }
|
|
|
|
|
- if (acc - gravity > 2)
|
|
|
|
|
- {
|
|
|
|
|
- hasReachShootThreshold = true;
|
|
|
|
|
- maxAcc = acc;
|
|
|
|
|
-
|
|
|
|
|
- // integral += Mathf.Abs(acc - gravity);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ 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;
|
|
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()
|
|
void Dolock()
|
|
|
{
|
|
{
|
|
|
- this.locked = true;
|
|
|
|
|
|
|
+ locked = true;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void Unlock()
|
|
void Unlock()
|
|
|
{
|
|
{
|
|
|
- this.locked = false;
|
|
|
|
|
|
|
+ locked = false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void Log(string text)
|
|
void Log(string text)
|
|
@@ -171,4 +96,186 @@ public class ShootCheck : MonoBehaviour
|
|
|
Debug.Log(text);
|
|
Debug.Log(text);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
-}
|
|
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+[Serializable]
|
|
|
|
|
+class CMD {
|
|
|
|
|
+ public string ax = "y";
|
|
|
|
|
+ public int a = 6000;
|
|
|
|
|
+ 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);
|
|
|
|
|
+// }
|
|
|
|
|
+// }
|
|
|
|
|
+// }
|