Abbreviations VR – Virtual Reality MMORPG – Massively Multiplayer Online Role-Playing Game MOBA – Massively Online Battle Arena IR – Infrared WBS – Work Breakdown Structure RAG – Red Amber Green FPS – Frames per Second IPP – Performance Primitive HCI – Human Computer Interaction UI – User Interface LMRS – Leap Motion Rehabilitation System XML – Extensible Mark-up Language WPF – Windows Presentation Foundation Table of Figures
{ // ... } // Raise hand if (hand.Direction.Pitch < -2.5 * avgPitch && repsPerformed < repsRequired && !raisePromptGiven) { // ... } Listing – Exercise 2 – Wrist Flexion & Extension Key Metric Conditional The third and final exercise (Three Jaw Chuck Pinch) uses the exact same logic as the first exercise (Fist Clench) and will therefore not be covered. The only notable difference between them is the number of fingers being checked for at each stage of the exercise. Since the third exercise uses the thumb, index finger and middle finger, we check for 3 fingers instead of 5 followed by 1 instead of 0. After the data from the Leap Motion has been collected and used to progress the exercises, the last remaining task for the current loop iteration is to update the 3d hand model. The 3D hand model used in the LMRS is powered by version 3.5 of XNA and uses data from the Leap Motion to animate the bones of the model. Before animating the hand however, we must first calculate two key vectors, the angles between which will then be used to animate the hand model by setting the joints equal to these angles. The first of these two vectors covers the distance between the centre of the palm and the base of the finger in question; the second of the two vectors covers the distance from the base of the finger to the finger tip, these can be seen in Figure 38. Figure – Vectors used for calculation However, before we can even calculate these two vectors, we must first calculate the base of the finger itself as this data is not readily accessible via the Leap Motion SDK, however, the Leap developers do provide a means to calculate this in the SDK documentation . These three vectors (finger base, palm to base and base to tip) along with the resulting angle data are
11.1: Appendix 1: Clinician User Scenario Test Case Test ID Description Expected Outcome Actual Outcome Pass/ Fail Test Date Comment(s) 0 Login with junk credentials Enter false username and/or password System should show a failed login prompt Failed login prompt shown PASS 18/04/14 1 Login with valid credentials Enter valid username and password System should login successfully successful PASS 18/04/14 2 Able to view patient user exercise results Select “View Patient Results” menu option. Toggle between patients, exercises and dates System should allow graphs of various types, reflecting changes in patient, exercise and dates Data is shown but crashes if no session data is available/also no guard against duplicate sessions FAIL 18/04/14 Added checks for empty session data and attempts to make duplicate sessions under same data now ignored. PASS after retesting 3 Leaving fields in “Register New Patient” screen empty Leave any field in the “Register New Patient” screen blank and click “Register” System should show a prompt asking the user to fill in the empty field Prompt shown PASS 18/04/14 4 Register a duplicate patient Enter the details for an already registered patient user in System should show a prompt informing the user that such a patient is Prompt shown PASS 18/04/14
the “Register New Patient” screen and click “Register” already registered 5 Able to register new patient user Enter the details for a new patient user in the “Register New Patient” screen and click “Register” System should show a prompt confirming successful addition Prompt shown, new patient found in XML data store PASS 18/04/14 6 Unable to remove patient user Enter the username of a non-existent patient in the search field of the “Remove Existing Patient” screen and click “Search” System should show a prompt requesting the user to enter a valid patient username Prompt shown PASS 18/04/14 7 Able to remove existing patient user Select “Register New Patient”, enter new patient credentials and click “Register” System should show a prompt confirming successful addition Prompt shown, patient removed from XML data store PASS/FAIL 18/04/14 Empty remaining patient XML element causing results screen crash. 8 Log out Click “Log Out” System should show a prompt, click OK at which point Prompt shown PASS 18/04/14
progress logically, with instructions and timing updated update and respond 3 Progress loss prompt shown when leaving while exercise in progress While performing an exercise, click the “Back” button System should show a prompt, informing of data loss and requiring user confirmation to continue No prompt shown FAIL 19/04/14 Prompt added 4 Can view exercise results from exercise page When exercises have been completed, the “Continue” button should be enabled, click it The “View Results” screen should be shown. The chart should respond to changes in exercise type, start/end date and chart type. Crash if any exercises have no data recorded against them FAIL 19/04/14 Added guard against empty sessions 5 Can view exercise results from main menu From the main menu, select the “View Results” option The “View Results” screen should be shown. The chart should respond to changes in exercise type, start/end date and chart type. Same as above FAIL 19/04/14
// Update xna hand //updateHandModelExercise2(frameData); } #endregion // Demo exercise 3 - Three jaw chuck pinch #region ex3 if (currentExercise == 3 && repsPerformed < repsRequired) { // Give exercise brief if (!exerciseDescGiven) { updateExerciseDescription("Exercise 3 of 3: Jaw. " + "\n1) Form a closed fist. \n2) Relax hand. \n\nThe timer will start automatically"); exerciseDescGiven = true; game.ResetCameraArcAndRoll(); } // A sufficient delta in the vector between finger-tip and palm signals // the user has begun to moving their hand, start the timer if ((hand.Fingers.Frontmost.TipPosition - hand.PalmPosition).Magnitude < 0.9 * avgMag && !timer.IsRunning) { restartTimer(); } // Exercise part 0 - Form a fist if (hand.Fingers.Count == 3 && !clenchPromptGiven) { // Present time for this rep if (timer.IsRunning) { repTimes[repsPerformed] = timer.ElapsedMilliseconds; updateRepInfo("Rep " + (repsPerformed + 1) + " of 5 complete. \nTime: " + repTimes[repsPerformed] / 1000.0 + " seconds."); // New best rep time? if (repTimes[repsPerformed] < bestRepTime) { bestRepTime = repTimes[repsPerformed]; updateBestRepInfo("Best rep time: \nRep " + (repsPerformed + 1) + " of 5: \n" + bestRepTime / 1000.0 + "seconds."); } ++repsPerformed; restartTimer(); }