public AngleBasedHandModel createRandomFromSavedMorph() { TrainingUnit first = PostureDataHandler.instance.getRand(); TrainingUnit second; do { second = PostureDataHandler.instance.getRand(); }while(first.posture == second.posture); AngleBasedHandModel temp1 = first.hand; AngleBasedHandModel temp2 = second.hand; AngleBasedHandModel result = new AngleBasedHandModel(); for (int i = 0; i < result.fingers.Length; i++) { result.fingers [i] = AngleBasedFingerModel.Lerp(temp1.fingers[i], temp2.fingers[i], ((float)i) / ((float)result.fingers.Length)); } //Debug.Log ("First: "+first.posture+", Second: "+second.posture); temp1 = PostureDataHandler.instance.getRand().hand; result.thumb = temp1.thumb; return(result); }
public float euclidianDistance(AngleBasedHandModel other) { float result = Mathf.Pow(euclidianDistanceFingers(other), 2.0f); //TODO: make usefull as soon as i need return(Mathf.Sqrt(result)); }
public AngleBasedHandModel createRandomRandom() { AngleBasedHandModel result = new AngleBasedHandModel(); float random = Mathf.Pow(Random.value, 2.0f); result.fingers[(int)AngleBasedHandModel.FingerName.index].mcp = Quaternion.Euler(Random.Range(XMCP_min, XMCP_max), random * abduct_index, 0); result.fingers[(int)AngleBasedHandModel.FingerName.middle].mcp = Quaternion.Euler(Random.Range(XMCP_min, XMCP_max), 0, 0); result.fingers[(int)AngleBasedHandModel.FingerName.ring].mcp = Quaternion.Euler(Random.Range(XMCP_min, XMCP_max), random * abduct_ring, 0); result.fingers[(int)AngleBasedHandModel.FingerName.pinky].mcp = Quaternion.Euler(Random.Range(XMCP_min, XMCP_max), random * abduct_pinky, 0); for (int i = 0; i < result.fingers.Length; i++) { AngleBasedFingerModel finger = result.fingers[i]; random = Random.value; finger.jointAngles[(int)AngleBasedFingerModel.Fingerjoints.DIP] = DIP_min + random * (DIP_max - DIP_min); finger.jointAngles[(int)AngleBasedFingerModel.Fingerjoints.PIP] = PIP_min + random * (PIP_max - PIP_min); } random = Random.value; result.thumb.tmc = Quaternion.Lerp(PostureDataHandler.instance.getRand().hand.thumb.tmc, Quaternion.Euler(Random.Range(XTMC_min, XTMC_max), Random.Range(YTMC_min, YTMC_max), Random.Range(ZTMC_min, ZTMC_max)), 0.5f); result.thumb.jointAngles[(int)AngleBasedThumbModel.Fingerjoints.IP] = IP_min + random * (IP_max - IP_min); result.thumb.jointAngles[(int)AngleBasedThumbModel.Fingerjoints.MP] = MP_min + random * (MP_max - MP_min); result.rotation = Quaternion.identity; result.position = Vector3.zero; return(result); }
public static float[] getRRP(AngleBasedHandModel otherHand) { float[] result = new float[otherHand.fingers.Length + 1]; for (int i = 0; i < result.Length; i++) { result[i] = float.PositiveInfinity; } if (instance.idleStates == null) { Debug.LogError("Idle states not initialized?"); return(result); } else { foreach (TrainingUnit tu in instance.idleStates) { // if (result > otherHand.euclidianDistanceFingers(tu.hand)) // result = otherHand.euclidianDistanceFingers(tu.hand); for (int i = 0; i < otherHand.fingers.Length; i++) { if (result[i] > otherHand.fingers[i].euclidianDistance(tu.hand.fingers[i])) { result[i] = otherHand.fingers[i].euclidianDistance(tu.hand.fingers[i]); } } if (result[otherHand.fingers.Length] > otherHand.thumb.euclidianDistance(tu.hand.thumb)) { result[otherHand.fingers.Length] = otherHand.thumb.euclidianDistance(tu.hand.thumb); } } } return(result); }
public void showRandHand() { AngleBasedHandModel result = createRandom(); output.visualizeHand(result); Debug.Log("Comfort+Discomfort: " + (Discomfort.getDiscomfortAngled(result) + Comfort.getRRPComponent(result))); }
static void debug(AngleBasedHandModel otherHand) { string debug = "Abduction: " + getAbductionComponent(otherHand); debug += "Hyper: " + getHyperExtensionComponent(otherHand); debug += "Inter: " + getInterFingerComponent(otherHand); Debug.Log(debug); }
public TrainingUnit.Posture detectPosture(AngleBasedHandModel hand) { KNNThread thread = new KNNThread(hand, this); newestThread = new Thread(new ThreadStart(thread.threadJob)); newestThread.Start(); return(result); }
public static float getDiscomfortAngled(AngleBasedHandModel otherHand) { float result = 0.0f; result += getAbductionComponent(otherHand) * yaxisFac; result += getHyperExtensionComponent(otherHand) * hyperFac; result += getInterFingerComponent(otherHand) * interFac; return(result); }
public void visualizeHand(AngleBasedHandModel currentHand) { if (observedHand != currentHand) { observedHand = currentHand; } visualizeHand(); }
public float euclidianDistanceFingers(AngleBasedHandModel other) { float result = Mathf.Pow(thumb.euclidianDistance(other.thumb), 2.0f); for (int i = 0; i < fingers.Length; i++) { result += Mathf.Pow(fingers [i].euclidianDistance(other.fingers [i]), 2); } return(Mathf.Sqrt(result)); }
public List <ThreadedKNN.poseCompareObject> getCompareList(AngleBasedHandModel hand) { List <ThreadedKNN.poseCompareObject> result = new List <ThreadedKNN.poseCompareObject> (); foreach (TrainingUnit tu in trainingData) { result.Add(tu.compare(hand)); } return(result); }
// Use this for initialization void Start() { if (UserStudyData.instance.right) { outH.transform.localScale = new Vector3(-outH.transform.localScale.x, outH.transform.localScale.y, outH.transform.localScale.z); } comfortable = PostureDataHandler.instance.getSublist(TrainingUnit.Posture.idle)[Random.Range(0, PostureDataHandler.instance.getSublist(TrainingUnit.Posture.idle).Count)].hand; outH.visualizeHand(comfortable); StartCoroutine(getNewRandomHand()); }
public AngleBasedHandModel createRandomProcedural() { AngleBasedHandModel result = new AngleBasedHandModel(); FingerState[] fingers = new FingerState[result.fingers.Length]; for (int i = 0; i < fingers.Length; i++) { fingers [i] = (FingerState)Random.Range(0, System.Enum.GetNames(typeof(FingerState)).Length); } //abduction float random = Mathf.Pow(Random.value, 2.0f); float[] abductions = { random *abduct_index, 0, random *abduct_ring, random *abduct_pinky }; for (int i = 0; i < result.fingers.Length; i++) { float xmcp = 0; if (fingers [i] == FingerState.ForwardFist || fingers [i] == FingerState.Flat) { xmcp = 0; } if (fingers [i] == FingerState.Fist) { xmcp = XMCP_max; } if (fingers [i] == FingerState.HyperExtended) { xmcp = XMCP_min; } result.fingers [i].mcp = Quaternion.Euler(xmcp, abductions[i], 0); AngleBasedFingerModel finger = result.fingers[i]; if (fingers [i] == FingerState.HyperExtended || fingers [i] == FingerState.Flat) { finger.jointAngles [(int)AngleBasedFingerModel.Fingerjoints.DIP] = DIP_min; finger.jointAngles [(int)AngleBasedFingerModel.Fingerjoints.PIP] = PIP_min; } if (fingers [i] == FingerState.Fist || fingers [i] == FingerState.ForwardFist) { finger.jointAngles [(int)AngleBasedFingerModel.Fingerjoints.DIP] = DIP_max; finger.jointAngles [(int)AngleBasedFingerModel.Fingerjoints.PIP] = PIP_max; } } ThumbState thumb = (ThumbState)Random.Range(0, System.Enum.GetNames(typeof(ThumbState)).Length); result.thumb = PostureDataHandler.instance.getRand().hand.thumb; result.rotation = Quaternion.identity; result.position = Vector3.zero; result = AngleBasedHandModel.Lerp(result, PostureDataHandler.instance.getRand(TrainingUnit.Posture.idle).hand, 0.2f); return(result); }
// Update is called once per frame void Update() { AngleBasedHandModel currentHand = currentList[index].hand; if (Input.GetButton("Fire2") && observedHand.gameObject.activeInHierarchy) { currentHand = observedHand.hand; Debug.Log("Observing"); } outputHand.visualizeHand(currentHand); }
public void saveCurrentAs(TrainingUnit.Posture posture) { if (gameObject.activeInHierarchy) { PostureDataHandler.instance.addTrainigData(new TrainingUnit(posture, hand)); hand = new AngleBasedHandModel(); } else { Debug.LogError("Tried to save hand, eventhough not active!"); } }
public static string getRRPCSV(AngleBasedHandModel otherHand, string endl) { string result = ""; float[] fingers = getRRP(otherHand); foreach (float finger in fingers) { result += finger + endl; } return(result); }
//Definitely Discomfort public static float getHyperExtensionComponent(AngleBasedHandModel otherHand) { float result = .0f; foreach (AngleBasedFingerModel finger in otherHand.fingers) { if (((Quaternion)finger.mcp).eulerAngles.x > 300) { result += 360 - ((Quaternion)finger.mcp).eulerAngles.x; } } return(result); }
//obsolete public static float getInterFingerComponent(AngleBasedHandModel otherHand) { float result = .0f; for (int i = 0; i < otherHand.fingers.Length - 1; i++) { result += Mathf.Abs(otherHand.fingers[i].getTotalBending() - otherHand.fingers[i + 1].getTotalBending()); } result += (ringBonus - 1) * Mathf.Abs((otherHand.fingers[(int)AngleBasedHandModel.FingerName.middle].getTotalBending() - otherHand.fingers[(int)AngleBasedHandModel.FingerName.ring].getTotalBending()) - (otherHand.fingers[(int)AngleBasedHandModel.FingerName.ring].getTotalBending() - otherHand.fingers[(int)AngleBasedHandModel.FingerName.pinky].getTotalBending())); return(result); }
public AngleBasedHandModel createRandomFromSaved() { AngleBasedHandModel temp; AngleBasedHandModel result = new AngleBasedHandModel(); for (int i = 0; i < result.fingers.Length; i++) { temp = PostureDataHandler.instance.getRand().hand; result.fingers [i] = temp.fingers [i]; } temp = PostureDataHandler.instance.getRand().hand; result.thumb = temp.thumb; return(result); }
public static AngleBasedHandModel Lerp(AngleBasedHandModel first, AngleBasedHandModel second, float t) { AngleBasedHandModel result = new AngleBasedHandModel(); t = Mathf.Clamp(t, 0, 1); result.rotation = Quaternion.Lerp(first.rotation, second.rotation, t); result.position = Vector3.Lerp(first.position, second.position, t); for (int i = 0; i < result.fingers.Length; i++) { result.fingers [i] = AngleBasedFingerModel.Lerp(first.fingers [i], second.fingers [i], t); } result.thumb = AngleBasedThumbModel.Lerp(first.thumb, second.thumb, t); return(result); }
public static float[] getAbduction(AngleBasedHandModel otherHand) { float[] result = new float[otherHand.fingers.Length]; for (int i = 0; i < otherHand.fingers.Length; i++) { float temp = ((Quaternion)otherHand.fingers[i].mcp).eulerAngles.y; if (temp > 180) { temp = 360 - temp; } result[i] = temp; } return(result); }
public static float[] getHyperExtension(AngleBasedHandModel otherHand) { float[] result = new float[otherHand.fingers.Length]; for (int i = 0; i < otherHand.fingers.Length; i++) { if (((Quaternion)otherHand.fingers[i].mcp).eulerAngles.x > 300) { result[i] = 360 - ((Quaternion)otherHand.fingers[i].mcp).eulerAngles.x; } else { result[i] = 0; } } return(result); }
//TODO: refine this: split up in comfort/discomfort public static float getAbductionComponent(AngleBasedHandModel otherHand) { float result = .0f; foreach (AngleBasedFingerModel finger in otherHand.fingers) { float temp = ((Quaternion)finger.mcp).eulerAngles.y; if (temp > 180) { temp = 360 - temp; } result += temp; } return(result); }
public static float[] getInterFinger(AngleBasedHandModel otherHand) { float[] result = new float[otherHand.fingers.Length]; float[] interFingerAngle = new float[otherHand.fingers.Length - 1]; for (int i = 0; i < interFingerAngle.Length; i++) { interFingerAngle[i] = otherHand.fingers[i].getTotalBending() - otherHand.fingers[i + 1].getTotalBending(); } result[0] = Mathf.Abs(interFingerAngle[0]); result[1] = Mathf.Abs(interFingerAngle[1] - interFingerAngle[0]); result[2] = Mathf.Abs(interFingerAngle[2] - interFingerAngle[1]); result[3] = Mathf.Abs(interFingerAngle[2]); return(result); }
public static float getMinDistanceToPosture(TrainingUnit.Posture posture, AngleBasedHandModel hand) { if (comparePosture != posture || compareData == null || compareData.Count == 0) { comparePosture = posture; reload(); } float result = float.PositiveInfinity; foreach (TrainingUnit tu in compareData) { if (result > hand.euclidianDistanceFingers(tu.hand)) { result = hand.euclidianDistanceFingers(tu.hand); } } return(result); }
// Use this for initialization void Start() { remaining = UserStudyData.instance.evaluations; fileName = PostureDataHandler.instance.filePath + "ComfortEvaluationData" + UserStudyData.instance.fileEnding; string fileHeader = "Name" + endl + "Rating" + endl + "Discomfort" + endl + "Comfort" + endl + "InterDis" + endl + "AbductionDis" + endl + "HyperDis" + endl + Discomfort.getInterFingerCSVHeader(endl) + Discomfort.getAbductionCSVHeader(endl) + Discomfort.getHyperExtensionCSVHeader(endl) + Comfort.getRRPCSVHeader(endl) + AngleBasedHandModel.getCSVHeader(endl, "RandomHand"); if (!File.Exists(fileName)) { File.AppendAllText(fileName, fileHeader + Environment.NewLine); } else { StreamReader read = new StreamReader(fileName); string oldHeader = read.ReadLine(); read.Close(); if (!oldHeader.Equals(fileHeader)) { Debug.Log("Fileheader not matching. Creating new file."); File.Delete(fileName); File.AppendAllText(fileName, fileHeader + Environment.NewLine); } } reset(); if (UserStudyData.instance.right) { outputHand.transform.localScale = new Vector3(-outputHand.transform.localScale.x, outputHand.transform.localScale.y, outputHand.transform.localScale.z); } }
public static float getRRPComponent(AngleBasedHandModel otherHand) { float result = float.PositiveInfinity; if (instance.idleStates == null) { Debug.LogError("Idle states not initialized?"); return(-1); } else { foreach (TrainingUnit tu in instance.idleStates) { if (result > otherHand.euclidianDistanceFingers(tu.hand)) { result = otherHand.euclidianDistanceFingers(tu.hand); } } } return(result); }
IEnumerator getNewRandomHand() { generating = true; targetdiscomfort = UnityEngine.Random.Range(50, 1000); int counter = 0; Debug.Log(targetdiscomfort); do { targethand = randHand.createRandom(); outputHand.visualizeHand(targethand); yield return(new WaitForEndOfFrame()); counter++; if (counter > 200) { counter = 0; targetdiscomfort = UnityEngine.Random.Range(50, 1000); Debug.Log(targetdiscomfort); } }while (Discomfort.getDiscomfortAngled(targethand) + Comfort.getRRPComponent(targethand) < targetdiscomfort || Discomfort.getDiscomfortAngled(targethand) + Comfort.getRRPComponent(targethand) > targetdiscomfort + 100); generating = false; }
public ThreadedKNN.poseCompareObject compare(AngleBasedHandModel otherHand) { return(new ThreadedKNN.poseCompareObject(hand.euclidianDistanceFingers(otherHand), posture)); }
public float distance; //distance to current hand posture, used to sort Training Units public TrainingUnit(Posture _posture, AngleBasedHandModel _hand) { posture = _posture; hand = _hand; }