This commit is contained in:
terric 2023-11-26 04:52:27 +08:00
parent 7bb50a7c69
commit 4b32e29d93
13 changed files with 115 additions and 44 deletions

View File

@ -214208,7 +214208,7 @@ AnimationClip:
intParameter: 3 intParameter: 3
messageOptions: 0 messageOptions: 0
- time: 66.333336 - time: 66.333336
functionName: FinishCurrentActionCheck functionName: FinishCurrentLevel
data: data:
objectReferenceParameter: {fileID: 0} objectReferenceParameter: {fileID: 0}
floatParameter: 0 floatParameter: 0

View File

@ -195595,3 +195595,10 @@ AnimationClip:
floatParameter: 0 floatParameter: 0
intParameter: 1 intParameter: 1
messageOptions: 0 messageOptions: 0
- time: 66.53333
functionName: FinishCurrentLevel
data:
objectReferenceParameter: {fileID: 0}
floatParameter: 0
intParameter: 0
messageOptions: 0

View File

@ -581,7 +581,7 @@ GameObject:
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
m_StaticEditorFlags: 0 m_StaticEditorFlags: 0
m_IsActive: 0 m_IsActive: 1
--- !u!224 &406787417813524232 --- !u!224 &406787417813524232
RectTransform: RectTransform:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -2051,7 +2051,7 @@ GameObject:
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
m_StaticEditorFlags: 0 m_StaticEditorFlags: 0
m_IsActive: 1 m_IsActive: 0
--- !u!224 &3096906925272982799 --- !u!224 &3096906925272982799
RectTransform: RectTransform:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0

View File

@ -43,9 +43,9 @@ public class CVEstimator : Singleton<CVEstimator>
} }
YogaManager.Instance.CurrentEstimator.Init(); YogaManager.Instance.CurrentEstimator.Init();
IsRunning = false;
_mainThread = new Thread(new ThreadStart(MainThread)); _mainThread = new Thread(new ThreadStart(MainThread));
_mainThread.Start(); _mainThread.Start();
IsRunning = false;
IsInited = true; IsInited = true;
} }
@ -96,35 +96,45 @@ public class CVEstimator : Singleton<CVEstimator>
{ {
DateTime startTime = DateTime.Now; DateTime startTime = DateTime.Now;
Mat bgrMat = new Mat(); Mat bgrMat = new Mat();
LogPrint.Log("IsRunning: " + IsRunning);
while (IsRunning) while (IsRunning)
{ {
Mat rgbaMat = YogaManager.Instance.RgbaMat; try
if (rgbaMat == null)
{ {
LogPrint.Log("WebCamTexture is null. "); LogPrint.Log("Estimation Thread Running!IsRunning: " + IsRunning);
LogPrint.Log("Re-Estimation."); Mat rgbaMat = YogaManager.Instance.RgbaMat;
continue; //重新检测 if (rgbaMat == null)
} {
Imgproc.cvtColor(rgbaMat, bgrMat, Imgproc.COLOR_RGBA2BGR); LogPrint.Log("WebCamTexture is null. ");
LogPrint.Log("Re-Estimation.");
continue; //重新检测
}
Imgproc.cvtColor(rgbaMat, bgrMat, Imgproc.COLOR_RGBA2BGR);
if (!YogaManager.Instance.CurrentEstimator.Esitmate(bgrMat, rgbaMat, out List<Point> points)) if (!YogaManager.Instance.CurrentEstimator.Esitmate(bgrMat, rgbaMat, out List<Point> points))
{ {
LogPrint.Log("Pose estimation failed. Re-Estimating."); LogPrint.Log("Pose estimation failed. Re-Estimating.");
continue; //重新检测 continue; //重新检测
} }
//更新关键点位检测结果 //更新关键点位检测结果
YogaManager.Instance.AddCurrEstimateKeyPoints(points); YogaManager.Instance.AddCurrEstimateKeyPoints(points);
//等待到下一个更新周期 //等待到下一个更新周期
if (DateTime.Now - startTime > _refreshRate) if (DateTime.Now - startTime > _refreshRate)
{ {
startTime = DateTime.Now; startTime = DateTime.Now;
}
else
{
Thread.Sleep(_refreshRate - (DateTime.Now - startTime));
}
} }
else catch (Exception e)
{ {
Thread.Sleep(_refreshRate - (DateTime.Now - startTime)); LogPrint.Exception(e);
} }
} }
bgrMat.Dispose(); bgrMat.Dispose();
} }

View File

@ -31,18 +31,26 @@ public class HandsHold : PoseBase
public override void ValidationMovement(Vector2 distance, TimeSpan totalTimeSpan, int level) public override void ValidationMovement(Vector2 distance, TimeSpan totalTimeSpan, int level)
{ {
if (totalTimeSpan.TotalMilliseconds / 1000 < 0.05f)
{
LogPrint.Error("TimeSpan too short");
return;
}
var angle = Vector2.SignedAngle(Vector2.down, distance); var angle = Vector2.SignedAngle(Vector2.down, distance);
LogPrint.Log($"Angle:{angle}", PrintLevel.Normal); LogPrint.Log($"Angle:{angle}", PrintLevel.Normal);
if (MathF.Abs(angle) < 10) if (MathF.Abs(angle) < 10)
EventManager.Instance.Dispatch(YogaEventType.Action_Success); //方向不能偏移超过10° EventManager.Instance.Dispatch(YogaEventType.Action_Success); //方向不能偏移超过10°
else else
{
EventManager.Instance.Dispatch(YogaEventType.Action_Fail); EventManager.Instance.Dispatch(YogaEventType.Action_Fail);
return;
}
if (level < 1) if (level < 1)
return; return;
LogPrint.Log($"distance x:{distance.x}, y:{distance.y}, magnitude:{distance.magnitude}", PrintLevel.Normal); LogPrint.Log($"distance x:{distance.x}, y:{distance.y}, magnitude:{distance.magnitude}");
if (distance.magnitude > 5f || distance.magnitude < 0.1f) if (distance.magnitude > 80f || distance.magnitude < 20f)
EventManager.Instance.Dispatch(YogaEventType.Action_MoveDistanceNotAccurate); EventManager.Instance.Dispatch(YogaEventType.Action_MoveDistanceNotAccurate);
else else
EventManager.Instance.Dispatch(YogaEventType.Action_MoveDistanceExactly); EventManager.Instance.Dispatch(YogaEventType.Action_MoveDistanceExactly);

View File

@ -32,18 +32,26 @@ public class HandsUp : PoseBase
public override void ValidationMovement(Vector2 distance, TimeSpan totalTimeSpan, int level) public override void ValidationMovement(Vector2 distance, TimeSpan totalTimeSpan, int level)
{ {
if (totalTimeSpan.TotalMilliseconds / 1000 < 0.05f)
{
LogPrint.Error("TimeSpan too short");
return;
}
var angle = Vector2.SignedAngle(Vector2.up, distance); var angle = Vector2.SignedAngle(Vector2.up, distance);
LogPrint.Log($"Angle:{angle}", PrintLevel.Normal); LogPrint.Log($"Angle:{angle}", PrintLevel.Normal);
if (MathF.Abs(angle) < 10) if (MathF.Abs(angle) < 10)
EventManager.Instance.Dispatch(YogaEventType.Action_Success); //方向不能偏移超过10° EventManager.Instance.Dispatch(YogaEventType.Action_Success); //方向不能偏移超过10°
else else
{
EventManager.Instance.Dispatch(YogaEventType.Action_Fail); EventManager.Instance.Dispatch(YogaEventType.Action_Fail);
return;
}
if (level < 1) if (level < 1)
return; return;
LogPrint.Log($"distance x:{distance.x}, y:{distance.y}, magnitude:{distance.magnitude}", PrintLevel.Normal); LogPrint.Log($"distance x:{distance.x}, y:{distance.y}, magnitude:{distance.magnitude}", PrintLevel.Normal);
if (distance.magnitude > 5f || distance.magnitude < 0.1f) if (distance.magnitude > 80f || distance.magnitude < 20f)
EventManager.Instance.Dispatch(YogaEventType.Action_MoveDistanceNotAccurate); EventManager.Instance.Dispatch(YogaEventType.Action_MoveDistanceNotAccurate);
else else
EventManager.Instance.Dispatch(YogaEventType.Action_MoveDistanceExactly); EventManager.Instance.Dispatch(YogaEventType.Action_MoveDistanceExactly);

View File

@ -20,18 +20,27 @@ public class HeadTurnDown : PoseBase
public override void ValidationMovement(Vector2 distance, TimeSpan totalTimeSpan, int level) public override void ValidationMovement(Vector2 distance, TimeSpan totalTimeSpan, int level)
{ {
if (totalTimeSpan.TotalMilliseconds / 1000 < 0.05f)
{
LogPrint.Error("TimeSpan too short");
return;
}
var angle = Vector2.SignedAngle(Vector2.down, distance); var angle = Vector2.SignedAngle(Vector2.down, distance);
LogPrint.Log($"Angle:{angle}", PrintLevel.Normal); LogPrint.Log($"Angle:{angle}", PrintLevel.Normal);
if (MathF.Abs(angle) < 10) if (MathF.Abs(angle) < 10)
EventManager.Instance.Dispatch(YogaEventType.Action_Success); //方向不能偏移超过10° EventManager.Instance.Dispatch(YogaEventType.Action_Success); //方向不能偏移超过10°
else else
{
EventManager.Instance.Dispatch(YogaEventType.Action_Fail); EventManager.Instance.Dispatch(YogaEventType.Action_Fail);
return;
}
if (level < 1) if (level < 1)
return; return;
LogPrint.Log($"distance x:{distance.x}, y:{distance.y}, magnitude:{distance.magnitude}", PrintLevel.Normal); LogPrint.Log($"distance x:{distance.x}, y:{distance.y}, magnitude:{distance.magnitude}", PrintLevel.Normal);
if (distance.magnitude > 5f || distance.magnitude < 0.1f) if (distance.magnitude > 80f || distance.magnitude < 20f)
EventManager.Instance.Dispatch(YogaEventType.Action_MoveDistanceNotAccurate); EventManager.Instance.Dispatch(YogaEventType.Action_MoveDistanceNotAccurate);
else else
EventManager.Instance.Dispatch(YogaEventType.Action_MoveDistanceExactly); EventManager.Instance.Dispatch(YogaEventType.Action_MoveDistanceExactly);
@ -41,9 +50,9 @@ public class HeadTurnDown : PoseBase
var speed = distance.magnitude / totalTimeSpan.TotalSeconds; var speed = distance.magnitude / totalTimeSpan.TotalSeconds;
LogPrint.Log($"speed:{speed}", PrintLevel.Normal); LogPrint.Log($"speed:{speed}", PrintLevel.Normal);
if (speed > 0.5f) if (speed > 20f)
EventManager.Instance.Dispatch(YogaEventType.Action_SpeedTooFast); //速度语音提示 EventManager.Instance.Dispatch(YogaEventType.Action_SpeedTooFast); //速度语音提示
else if (speed < 0.1f) else if (speed < 8f)
EventManager.Instance.Dispatch(YogaEventType.Action_SpeedTooSlow); //速度语音提示 EventManager.Instance.Dispatch(YogaEventType.Action_SpeedTooSlow); //速度语音提示
} }

View File

@ -21,18 +21,27 @@ public class HeadTurnLeft : PoseBase
public override void ValidationMovement(Vector2 distance, TimeSpan totalTimeSpan, int level) public override void ValidationMovement(Vector2 distance, TimeSpan totalTimeSpan, int level)
{ {
if (totalTimeSpan.TotalMilliseconds / 1000 < 0.05f)
{
LogPrint.Error("TimeSpan too short");
return;
}
var angle = Vector2.SignedAngle(Vector2.left, distance); var angle = Vector2.SignedAngle(Vector2.left, distance);
LogPrint.Log($"Angle:{angle}", PrintLevel.Normal); LogPrint.Log($"Angle:{angle}", PrintLevel.Normal);
if (MathF.Abs(angle) < 10) if (MathF.Abs(angle) < 10)
EventManager.Instance.Dispatch(YogaEventType.Action_Success); //方向不能偏移超过10° EventManager.Instance.Dispatch(YogaEventType.Action_Success); //方向不能偏移超过10°
else else
{
EventManager.Instance.Dispatch(YogaEventType.Action_Fail); EventManager.Instance.Dispatch(YogaEventType.Action_Fail);
return;
}
if (level < 1) if (level < 1)
return; return;
LogPrint.Log($"distance x:{distance.x}, y:{distance.y}, magnitude:{distance.magnitude}", PrintLevel.Normal); LogPrint.Log($"distance x:{distance.x}, y:{distance.y}, magnitude:{distance.magnitude}", PrintLevel.Normal);
if (distance.magnitude > 5f || distance.magnitude < 0.1f) if (distance.magnitude > 80f || distance.magnitude < 20f)
EventManager.Instance.Dispatch(YogaEventType.Action_MoveDistanceNotAccurate); EventManager.Instance.Dispatch(YogaEventType.Action_MoveDistanceNotAccurate);
else else
EventManager.Instance.Dispatch(YogaEventType.Action_MoveDistanceExactly); EventManager.Instance.Dispatch(YogaEventType.Action_MoveDistanceExactly);

View File

@ -21,18 +21,27 @@ public class HeadTurnRight : PoseBase
public override void ValidationMovement(Vector2 distance, TimeSpan totalTimeSpan, int level) public override void ValidationMovement(Vector2 distance, TimeSpan totalTimeSpan, int level)
{ {
if (totalTimeSpan.TotalMilliseconds / 1000 < 0.05f)
{
LogPrint.Error("TimeSpan too short");
return;
}
var angle = Vector2.SignedAngle(Vector2.right, distance); var angle = Vector2.SignedAngle(Vector2.right, distance);
LogPrint.Log($"Angle:{angle}", PrintLevel.Normal); LogPrint.Log($"Angle:{angle}", PrintLevel.Normal);
if (MathF.Abs(angle) < 10) if (MathF.Abs(angle) < 10)
EventManager.Instance.Dispatch(YogaEventType.Action_Success); //方向不能偏移超过10° EventManager.Instance.Dispatch(YogaEventType.Action_Success); //方向不能偏移超过10°
else else
{
EventManager.Instance.Dispatch(YogaEventType.Action_Fail); EventManager.Instance.Dispatch(YogaEventType.Action_Fail);
return;
}
if (level < 1) if (level < 1)
return; return;
LogPrint.Log($"distance x:{distance.x}, y:{distance.y}, magnitude:{distance.magnitude}", PrintLevel.Normal); LogPrint.Log($"distance x:{distance.x}, y:{distance.y}, magnitude:{distance.magnitude}", PrintLevel.Normal);
if (distance.magnitude > 5f || distance.magnitude < 0.1f) if (distance.magnitude > 80f || distance.magnitude < 20f)
EventManager.Instance.Dispatch(YogaEventType.Action_MoveDistanceNotAccurate); EventManager.Instance.Dispatch(YogaEventType.Action_MoveDistanceNotAccurate);
else else
EventManager.Instance.Dispatch(YogaEventType.Action_MoveDistanceExactly); EventManager.Instance.Dispatch(YogaEventType.Action_MoveDistanceExactly);

View File

@ -20,18 +20,26 @@ public class HeadTurnUp : PoseBase
public override void ValidationMovement(Vector2 distance, TimeSpan totalTimeSpan, int level) public override void ValidationMovement(Vector2 distance, TimeSpan totalTimeSpan, int level)
{ {
if (totalTimeSpan.TotalMilliseconds / 1000 < 0.05f)
{
LogPrint.Error("TimeSpan too short");
return;
}
var angle = Vector2.SignedAngle(Vector2.up, distance); var angle = Vector2.SignedAngle(Vector2.up, distance);
LogPrint.Log($"Angle:{angle}", PrintLevel.Normal); LogPrint.Log($"Angle:{angle}", PrintLevel.Normal);
if (MathF.Abs(angle) < 10) if (MathF.Abs(angle) < 10)
EventManager.Instance.Dispatch(YogaEventType.Action_Success); //方向不能偏移超过10° EventManager.Instance.Dispatch(YogaEventType.Action_Success); //方向不能偏移超过10°
else else
{
EventManager.Instance.Dispatch(YogaEventType.Action_Fail); EventManager.Instance.Dispatch(YogaEventType.Action_Fail);
return;
}
if (level < 1) if (level < 1)
return; return;
LogPrint.Log($"distance x:{distance.x}, y:{distance.y}, magnitude:{distance.magnitude}", PrintLevel.Normal); LogPrint.Log($"distance x:{distance.x}, y:{distance.y}, magnitude:{distance.magnitude}", PrintLevel.Normal);
if (distance.magnitude > 5f || distance.magnitude < 0.1f) if (distance.magnitude > 80f || distance.magnitude < 20f)
EventManager.Instance.Dispatch(YogaEventType.Action_MoveDistanceNotAccurate); EventManager.Instance.Dispatch(YogaEventType.Action_MoveDistanceNotAccurate);
else else
EventManager.Instance.Dispatch(YogaEventType.Action_MoveDistanceExactly); EventManager.Instance.Dispatch(YogaEventType.Action_MoveDistanceExactly);

View File

@ -1,6 +1,7 @@
using OpenCVForUnity.CoreModule; using OpenCVForUnity.CoreModule;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using UnityEngine; using UnityEngine;
public abstract class PoseBase public abstract class PoseBase
@ -74,15 +75,23 @@ public abstract class PoseBase
return; return;
var distance = Vector2.zero; var distance = Vector2.zero;
var totalTimeSpan = TimeSpan.Zero; TimeSpan totalTimeSpan = TimeSpan.MinValue;
for (int i = 0; i < points.Count - 1; i++) for (int i = 0; i < points.Count - 1; i++)
{ {
var p1 = points[i].Item2; var p1 = points[i].Item2;
var p2 = points[i + 1].Item2; var p2 = points[i + 1].Item2;
TimeSpan timeSpan = points[i + 1].Item1 - points[i].Item1;
var vector = GetAverageVector(p1, p2, "Nose"); //关键点Nose var vector = GetAverageVector(p1, p2, "Nose"); //关键点Nose
distance += vector; distance += vector;
totalTimeSpan += timeSpan; if (vector.magnitude > 0.1f) //如果矢量长度大于0.1f,说明有运动
{
TimeSpan timeSpan = points[i + 1].Item1 - points[i].Item1;
if (totalTimeSpan == TimeSpan.MinValue)
totalTimeSpan = timeSpan;
else
totalTimeSpan += timeSpan;
}
} }
LogPrint.Log($"distance: {distance}, totalTimeSpan: {totalTimeSpan}", PrintLevel.Normal); LogPrint.Log($"distance: {distance}, totalTimeSpan: {totalTimeSpan}", PrintLevel.Normal);

View File

@ -362,7 +362,7 @@ public class YogaManager : MonoSingleton<YogaManager>
{ {
if (!p.IsValid(points)) //有一个点不符合 返回false if (!p.IsValid(points)) //有一个点不符合 返回false
{ {
LogPrint.Error($"ActionCheckPoints failed, {p} is not valid"); //LogPrint.Log($"ActionCheckPoints failed, {p} is not valid");
return false; return false;
} }
} }

View File

@ -27,14 +27,8 @@ namespace Yoga
var index = PlayerPrefs.GetInt("USBCameraIndex"); var index = PlayerPrefs.GetInt("USBCameraIndex");
if (index >= devices.Count) //数量超出时候改为默认第一个 if (index >= devices.Count) //数量超出时候改为默认第一个
index = 0; index = 0;
for (int i = 0; i < devices.Count; i++)
{
UVCManager.CameraInfo device = devices[i];
picCaptured = device.previewTexture;
if (i == index) //后续可改为IR和RGB条件 picCaptured = devices[index].previewTexture;
break;
}
if (picCaptured == null) if (picCaptured == null)
throw new Exception("No preview Texture found!"); throw new Exception("No preview Texture found!");