예제 #1
0
    /// <summary>
    /// Handles task data logging which runs on FixedUpdate.
    /// Logs data from sensors registered in the AvatarSystem and ExperimentSystem by default.
    /// Can be exteded to add more data by implementing an override method in the derived class which first adds data
    /// to the logData string (e.g. logData +=  myDataString + ","), and then calls base.HandleTaskDataLogging().
    /// </summary>
    public override void HandleTaskDataLogging()
    {
        // Add your custom data logging here
        // e.g. the magic number!
        logData += targetOrder[iterationNumber - 1] + ",";  // Make sure you always end your custom data with a comma! Using CSV for data logging.

        // Continue with data logging.
        base.HandleTaskDataLogging();

        // Performance evaluation data buffering
        if (!debug)
        {
            if (evaluatorType == EvaluatorType.Compensation)
            {
                Vector3 shPos = new Vector3(shoulderTracker.GetProcessedData("X_Pos"), shoulderTracker.GetProcessedData("Y_Pos"), shoulderTracker.GetProcessedData("Z_Pos"));
                Vector3 c7Pos = new Vector3(c7Tracker.GetProcessedData("X_Pos"), c7Tracker.GetProcessedData("Y_Pos"), c7Tracker.GetProcessedData("Z_Pos"));
                shDataBuffer.Add(shPos);
                c7DataBuffer.Add(c7Pos);
            }
            else if (evaluatorType == EvaluatorType.KinematicEnergy)
            {
                throw new System.NotImplementedException("KE method not yet implemented");
            }
        }
    }
    private bool IsAtRightPosition(float qShoudlerRef, float qElbowRef, float tolerance)
    {
        // Check that upper and lower arms are within the tolerated start position.
        float qShoulder = leftySign * Mathf.Rad2Deg * (upperArmTracker.GetProcessedData(5) + Mathf.PI); // Offsetting to horizontal position being 0.
        float qElbow    = 0;

        HudManager.colour = HUDManager.HUDColour.Orange;
        qElbow            = Mathf.Rad2Deg * (lowerArmTracker.GetProcessedData(5)) - qShoulder; // Offsetting to horizontal position being 0.
                                                                                               // The difference to the start position
        float qSDiff = qShoulder - qShoudlerRef;
        float qEDiff = qElbow - qElbowRef;


        //
        // Update information displayed for debugging purposes
        //


        //InstructionManager.DisplayText(qShoulder.ToString() + "\n" + qElbow.ToString() + "\n");

        if (Mathf.Abs(qSDiff) < tolerance && Mathf.Abs(qEDiff) < tolerance)
        {
            HudManager.colour = HUDManager.HUDColour.Orange;
            return(true);
        }
        // Provide instructions when not there yet
        else
        {
            string helpText = "";
            if (qSDiff < 0 && Mathf.Abs(qSDiff) > tolerance)
            {
                helpText += "SH: up (" + qShoulder.ToString("F0") + "/" + qShoudlerRef.ToString("F0") + ").\n";
            }
            else if (qSDiff > 0 && Mathf.Abs(qSDiff) > tolerance)
            {
                helpText += "SH: down (" + qShoulder.ToString("F0") + "/" + qShoudlerRef.ToString("F0") + ").\n";
            }
            else
            {
                helpText += "SH: ok (" + qShoulder.ToString("F0") + "/" + qShoudlerRef.ToString("F0") + ").\n";
            }


            if (qEDiff < 0 && Mathf.Abs(qEDiff) > tolerance)
            {
                helpText += "EB: up (" + qElbow.ToString("F0") + "/" + qElbowRef.ToString("F0") + ").\n";
            }
            else if (qEDiff > 0 && Mathf.Abs(qEDiff) > tolerance)
            {
                helpText += "EB: down (" + qElbow.ToString("F0") + "/" + qElbowRef.ToString("F0") + ").\n";
            }
            else
            {
                helpText += "EB: ok (" + qElbow.ToString("F0") + "/" + qElbowRef.ToString("F0") + ").\n";
            }
            HudManager.DisplayText(helpText);
            HudManager.colour = HUDManager.HUDColour.Red;


            return(false);
        }
    }
예제 #3
0
    /// <summary>
    /// Checks whether the subject is ready to start performing the task.
    /// </summary>
    /// <returns>True if ready to start.</returns>
    public override bool IsReadyToStart()
    {
        // Check that upper and lower arms are within the tolerated start position.
        float qShoulder = leftySign * Mathf.Rad2Deg * (upperArmTracker.GetProcessedData(5) + Mathf.PI); // Offsetting to horizontal position being 0.
        float qElbow    = 0;

        if (experimentType == ExperimentType.TypeOne)
        {
            qElbow = Mathf.Rad2Deg * (lowerArmTracker.GetProcessedData(5)) - qShoulder; // Offsetting to horizontal position being 0.
        }
        else if (experimentType == ExperimentType.TypeTwo)
        {
            qElbow = -Mathf.Rad2Deg * elbowManager.GetElbowAngle();
        }

        // The difference to the start position
        float qSDiff = qShoulder - startShoulderAngle;
        float qEDiff = qElbow - startElbowAngle;

        //
        // Update information displayed for debugging purposes
        //
        if (debug)
        {
            debugText.text = experimentState.ToString() + "\n";
            if (experimentState == ExperimentState.WaitingForStart)
            {
                debugText.text += waitState.ToString() + "\n";
            }
            debugText.text += qShoulder.ToString() + "\n";
            debugText.text += qElbow.ToString() + "\n";
        }

        // Make sure the user knows the elbow is not enabled.
        if (experimentType == ExperimentType.TypeTwo)
        {
            if (!elbowManager.IsEnabled)
            {
                HudManager.centreColour = HUDManager.HUDCentreColour.Yellow;
            }
            else
            {
                HudManager.centreColour = HUDManager.HUDCentreColour.None;
            }
        }

        if (Mathf.Abs(qSDiff) < startTolerance && Mathf.Abs(qEDiff) < startTolerance)
        {
            HudManager.colour = HUDManager.HUDColour.Orange;
            return(true);
        }
        // Provide instructions when not there yet
        else
        {
            string helpText = "";
            if (qSDiff < 0 && Mathf.Abs(qSDiff) > startTolerance)
            {
                helpText += "UA: ++.\n";
            }
            else if (qSDiff > 0 && Mathf.Abs(qSDiff) > startTolerance)
            {
                helpText += "UA: --.\n";
            }

            if (qEDiff < 0 && Mathf.Abs(qEDiff) > startTolerance)
            {
                helpText += "LA: ++.\n";
            }
            else if (qEDiff > 0 && Mathf.Abs(qEDiff) > startTolerance)
            {
                helpText += "LA: --.\n";
            }

            HudManager.DisplayText(helpText);
            HudManager.colour = HUDManager.HUDColour.Red;
            return(false);
        }
    }
예제 #4
0
    // Update is called once per frame
    void Update()
    {
        switch (experimentState)
        {
        /*
         *************************************************
         *  HelloWorld
         *************************************************
         */
        // Welcome subject to the virtual world.
        case ExperimentState.Welcome:
            if (WaitFlag)
            {
                if (debug)
                {
                    TeleportToStartPosition();
                }
                HudManager.ClearText();
                experimentState = ExperimentState.Initialising;
            }
            else
            {
                HudManager.DisplayText("Welcome!");
                InstructionManager.DisplayText("Hello world!");
            }
            break;

        /*
         *************************************************
         *  InitializingApplication
         *************************************************
         */
        // Perform initialization functions before starting experiment.
        case ExperimentState.Initialising:
            //
            // Perform experiment initialization procedures
            //

            //
            // Initialize data logs
            //

            //
            // Go to training
            //
            experimentState = ExperimentState.Training;
            break;

        /*
         *************************************************
         *  Practice
         *************************************************
         */
        // Perform initialization functions before starting experiment.
        case ExperimentState.Training:
            //
            // Guide subject through training
            //

            //
            // Go to instructions
            //
            experimentState = ExperimentState.Instructions;
            break;

        /*
         *************************************************
         *  GivingInstructions
         *************************************************
         */
        case ExperimentState.Instructions:
            // Skip instructions when repeating sessions
            if (SkipInstructions)
            {
                HudManager.DisplayText("Move to start", 2.0f);
                // Turn targets clear
                experimentState = ExperimentState.WaitingForStart;
                break;
            }

            //
            // Give instructions
            //

            //
            // Go to waiting for start
            //
            HudManager.DisplayText("Move to start", 2.0f);
            // Turn targets clear
            experimentState = ExperimentState.WaitingForStart;

            break;

        /*
         *************************************************
         *  WaitingForStart
         *************************************************
         */
        case ExperimentState.WaitingForStart:
            // Show status to subject
            infoText = GetInfoText();
            InstructionManager.DisplayText(infoText);

            // Check if pause requested
            UpdatePause();
            switch (waitState)
            {
            // Waiting for subject to get to start position.
            case WaitState.Waiting:
                if (IsReadyToStart())
                {
                    startEnable = true;
                    // Select target
                    gridManager.SelectBall(iterationNumber - 1);
                    waitState = WaitState.Countdown;
                }
                break;

            // HUD countdown for reaching action.
            case WaitState.Countdown:
                // If all is good and haven't started counting, start.
                if (startEnable && !counting && !CountdownDone)
                {
                    // Manage countdown
                    HudManager.ClearText();
                    StopHUDCountDown();
                    counting = true;
                    HUDCountDown(3);
                }
                // If all is good and the countdownDone flag is raised, switch to reaching.
                else if (CountdownDone)
                {
                    // Reset flags
                    startEnable   = false;
                    counting      = false;
                    countdownDone = false;
                    // Continue
                    experimentState = ExperimentState.PerformingTask;
                    waitState       = WaitState.Waiting;
                    break;
                }
                // If hand goes out of target reset countdown and wait for position
                else if (!IsReadyToStart() && !CountdownDone)
                {
                    StopHUDCountDown();
                    startEnable   = false;
                    counting      = false;
                    countdownDone = false;
                    // Clear ball
                    gridManager.ResetBallSelection();
                    // Indicate to move back
                    HudManager.DisplayText("Move to start", 2.0f);
                    waitState = WaitState.Waiting;
                    break;
                }
                break;

            default:
                break;
            }
            break;

        /*
         *************************************************
         *  PerformingTask
         *************************************************
         */
        case ExperimentState.PerformingTask:
            // Task performance is handled deterministically in FixedUpdate.
            break;

        /*
         *************************************************
         *  AnalizingResults
         *************************************************
         */
        case ExperimentState.AnalizingResults:
            // Allow 3 seconds after task end to do calculations
            SetWaitFlag(3.0f);

            //
            // Data analysis and calculations
            //

            //
            // System update
            //

            //
            // Data logging
            //

            //
            // Flow managment
            //
            // Rest for some time when required
            if (IsRestTime())
            {
                SetWaitFlag(RestTime);
                experimentState = ExperimentState.Resting;
            }
            // Check whether the new session condition is met
            else if (IsEndOfSession())
            {
                experimentState = ExperimentState.InitializingNext;
            }
            // Check whether the experiment end condition is met
            else if (IsEndOfExperiment())
            {
                experimentState = ExperimentState.End;
            }
            else
            {
                experimentState = ExperimentState.UpdatingApplication;
            }
            break;

        /*
         *************************************************
         *  UpdatingApplication
         *************************************************
         */
        case ExperimentState.UpdatingApplication:
            if (WaitFlag)
            {
                //
                // Update iterations and flow control
                //
                iterationNumber++;
                completedIterations++;

                //
                // Update log requirements
                //

                //
                //
                // Go to start of next iteration
                experimentState = ExperimentState.WaitingForStart;
            }
            break;

        /*
         *************************************************
         *  InitializingNext
         *************************************************
         */
        case ExperimentState.InitializingNext:
            //
            // Perform session closure procedures
            //

            //
            // Initialize new session variables and flow control
            //
            iterationNumber = 1;
            sessionNumber++;
            skipInstructions = true;

            //
            // Initialize data logging
            //
            ExperimentSystem.GetActiveLogger(1).AddNewLogFile(sessionNumber, iterationNumber, "Data format");

            experimentState = ExperimentState.Initialising;     // Initialize next session
            break;

        /*
         *************************************************
         *  Resting
         *************************************************
         */
        case ExperimentState.Resting:
            //
            // Check for session change or end request from experimenter
            //
            if (UpdateNext())
            {
                ConfigureNextSession();
                break;
            }
            else if (UpdateEnd())
            {
                EndExperiment();
                break;
            }
            //
            // Restart after flag is set by wait coroutine
            //
            if (WaitFlag)
            {
                HudManager.DisplayText("Get ready to restart!", 3.0f);
                SetWaitFlag(5.0f);
                experimentState = ExperimentState.UpdatingApplication;
                break;
            }
            break;

        /*
         *************************************************
         *  Paused
         *************************************************
         */
        case ExperimentState.Paused:
            //
            // Check for session change or end request from experimenter
            //
            UpdatePause();
            if (UpdateNext())
            {
                ConfigureNextSession();
                break;
            }
            else if (UpdateEnd())
            {
                EndExperiment();
                break;
            }
            break;

        /*
         *************************************************
         *  End
         *************************************************
         */
        case ExperimentState.End:
        //
        // Update log data and close logs.
        //

        //
        // Return to main menu
        //
        default:
            break;
        }

        //
        // Update information displayed on monitor
        //

        //
        // Update information displayed for debugging purposes
        //
        if (debug)
        {
            debugText.text = experimentState.ToString() + "\n";
            if (experimentState == ExperimentState.WaitingForStart)
            {
                debugText.text += waitState.ToString() + "\n";
            }
            float qShoulder = Mathf.Rad2Deg * (upperArmTracker.GetProcessedData(5) + Mathf.PI);  // Offsetting to horizontal position being 0.
            float qElbow    = Mathf.Rad2Deg * (lowerArmTracker.GetProcessedData(5)) - qShoulder; // Offsetting to horizontal position being 0.
            debugText.text += qShoulder.ToString() + "\n";
            debugText.text += qElbow.ToString() + "\n";
        }
    }