/// <summary>
    /// Coroutine for the welcome text.
    /// Implement your welcome loop here.
    /// </summary>
    /// <returns>Yield instruction</returns>
    public override IEnumerator WelcomeLoop()
    {
        // First flag that we are in the welcome routine
        welcomeDone = false;
        inWelcome   = true;

        welcomeDone = true;

        HudManager.DisplayText("Look to the top right. Instructions will be displayed there.");
        InstructionManager.DisplayText("Hi " + SaveSystem.ActiveUser.name + "! Welcome to the virtual world. \n\n (Press the trigger button to continue...)");
        yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

        InstructionManager.DisplayText("Make sure you are standing on top of the green circle. \n\n (Press the trigger button to continue...)");
        yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

        InstructionManager.DisplayText("Test audio. \n\n (If you can hear the audio, press the trigger button to continue...)");
        audio.loop   = true;
        audio.volume = 0.4f;
        audio.Play();

        yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

        audio.loop = false;
        audio.Stop();
        audio.volume = 1.0f;
        //
        // Hud intro
        InstructionManager.DisplayText("Alright " + SaveSystem.ActiveUser.name + ", let me introduce you to your assistant, the Heads Up Display (HUD)." + "\n\n (Press the trigger)");
        yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

        InstructionManager.DisplayText("Look at the HUD around your left eye. It's saying hi!");
        HudManager.DisplayText("Hi! I'm HUD!" + "\n (Press trigger)");
        yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

        HudManager.DisplayText("I'm here to help!" + "\n (Press trigger)");
        yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

        HudManager.DisplayText("Look at the screen.", 3);


        //
        // Experiment overall intro
        InstructionManager.DisplayText("Alright " + SaveSystem.ActiveUser.name + ", let me explain what we are doing today." + "\n\n (Press the trigger)");
        yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

        InstructionManager.DisplayText("Today, the experiment will require you to reach to the targets in front of you." + "\n\n (Press the trigger)");
        yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

        InstructionManager.DisplayText("You will do 2 sessions, 1st 90 iterations and 2nd 270 iterations " + "\n\n (Press the trigger)");
        yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

        InstructionManager.DisplayText("A 60 sec rest occurs every 35 iterations" + "\n\n (Press the trigger)");
        yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

        // Now that you are done, set the flag to indicate we are done.

        welcomeDone = true;
    }
Esempio n. 2
0
    /// <summary>
    /// Coroutine for the welcome text.
    /// Implement your welcome loop here.
    /// </summary>
    /// <returns>Yield instruction</returns>
    public override IEnumerator WelcomeLoop()
    {
        // First flag that we are in the welcome routine
        welcomeDone = false;
        inWelcome   = true;

        //
        HudManager.DisplayText("Look to the top right.");
        InstructionManager.DisplayText("Hi " + SaveSystem.ActiveUser.name + "! Welcome to the virtual world. \n\n (Press the trigger button to continue...)");
        yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

        InstructionManager.DisplayText("Make sure you are standing on top of the green circle. \n\n (Press the trigger button to continue...)");
        yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

        // Now that you are done, set the flag to indicate we are done.
        welcomeDone = true;
    }
    /// <summary>
    /// Coroutine for the experiment training.
    /// Implement your training loop here.
    /// </summary>
    /// <returns>Yield instruction</returns>
    public override IEnumerator TrainingLoop()
    {
        // First flag that we are in the training routine
        trainingDone = false;
        inTraining   = true;

        // Only run the training loop when requested, for instance some session may require different session.
        if (trainingPerSession[sessionNumber - 1] == 1)
        {
            //
            InstructionManager.DisplayText("This is training. You'll probably want to guide your subject through the task here! \n Press the trigger button to continue...");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            //
            InstructionManager.DisplayText("Like... Punch the Cube!");
            yield return(new WaitForSecondsRealtime(5.0f));

            HudManager.DisplayText("What Cube???", 2.0f);
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            //
            HudManager.DisplayText("On your left, quick!!", 5.0f);
            if (isCubeAvailable != true)
            {
                isCubeAvailable = true;
                cubeGO.SetActive(true);
            }
            yield return(new WaitForSecondsRealtime(5.0f));

            HudManager.DisplayText("And it's gone...", 3.0f);
            isCubeAvailable = false;
            cubeGO.SetActive(false);
            yield return(new WaitForSecondsRealtime(5.0f));

            //
            HudManager.DisplayText("Look to the screen.");
            InstructionManager.DisplayText("It's revolutionary ain't it! \n Press the trigger button to continue...");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.
        }

        // Now that you are done, set the flag to indicate we are done.
        trainingDone = true;
    }
    /// <summary>
    /// Coroutine for the experiment instructions.
    /// Implement your instructions loop here.
    /// </summary>
    /// <returns>Yield instruction</returns>
    public override IEnumerator InstructionsLoop()
    {
        // First flag that we are in the instructions routine
        instructionsDone = false;
        inInstructions   = true;

        //
        InstructionManager.DisplayText("These are the isntructions. You can use other conditions to wait, not only the trigger press! e.g. 10 seconds.");
        HudManager.DisplayText("You can use the HUD too!");
        yield return(new WaitForSecondsRealtime(10.0f)); // Wait for some time.

        //
        HudManager.DisplayText("And get their attention!", 5.0f);
        InstructionManager.DisplayText("It's exciting! \n Press the trigger button to continue...");
        yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

        // Now that you are done, set the flag to indicate we are done.
        instructionsDone = true;
    }
    /// <summary>
    /// Coroutine for the welcome text.
    /// Implement your welcome loop here.
    /// </summary>
    /// <returns>Yield instruction</returns>
    public override IEnumerator WelcomeLoop()
    {
        // First flag that we are in the welcome routine
        welcomeDone = false;
        inWelcome   = true;

        //
        HudManager.DisplayText("Look to the top right.");
        InstructionManager.DisplayText("This is the welcome. Here you can write a welcome for your subject! \n Press the trigger button to continue...");
        yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

        //
        HudManager.ClearText();
        InstructionManager.DisplayText("It's awesome! \n Press the trigger button to continue...");
        yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

        // Now that you are done, set the flag to indicate we are done.
        welcomeDone = true;
    }
    /// <summary>
    /// Coroutine for the experiment instructions.
    /// Implement your instructions loop here.
    /// </summary>
    /// <returns>Yield instruction</returns>
    public override IEnumerator InstructionsLoop()
    {
        // First flag that we are in the instructions routine
        instructionsDone = false;
        inInstructions   = true;

        //Instructions
        if (sessionNumber == 1) // first session
        {
            InstructionManager.DisplayText("Alright, the sphere targets should have spawned for you." + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("In the 1st session, you will need to reach to the spheres using your index finger." + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("If you are ready, let's start training!" + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.
        }
        else if (sessionNumber == 2)                       // second session
        {
            InstructionManager.DisplayText("You've finished the 1st session, well done. Let's start the second session" + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("The sphere targets have been replaced by bottle targets and a bottle has been placed in your hand." + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("In the 2nd session, you will need to match bothe the target locations and orientations ." + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("If you are ready, let's start training!" + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.
        }



        // Now that you are done, set the flag to indicate we are done.
        instructionsDone = true;
    }
    /// <summary>
    /// Coroutine for the experiment training.
    /// Implement your training loop here.
    /// </summary>
    /// <returns>Yield instruction</returns>
    public override IEnumerator TrainingLoop()
    {
        // First flag that we are in the training routine
        trainingDone = false;
        inTraining   = true;


        if (sessionNumber == 1)
        {
            InstructionManager.DisplayText("Let's start training then!" + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.


            //
            // HUD Colours
            InstructionManager.DisplayText("First, let's tell you about the colour of the HUD. It will tell you what you need to do." + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("<Red>: for returning back and adjusting your start position." + "\n\n (Press the trigger)");
            HudManager.DisplayText("I'm red!");
            HudManager.colour = HUDManager.HUDColour.Red;
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("<Orange>: for waiting for the countdown." + "\n\n (Press the trigger)");
            HudManager.DisplayText("I'm orange!");
            HudManager.colour = HUDManager.HUDColour.Orange;
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("<Blue>: for reaching for the target.!" + "\n\n (Press the trigger)");
            HudManager.DisplayText("I'm blue!");
            HudManager.colour = HUDManager.HUDColour.Blue;
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("You need to hold on you reaching position for a while until the HUD says 'Well Done', like" + "\n\n (Press the trigger)");
            HudManager.colour = HUDManager.HUDColour.Red;
            HudManager.DisplayText("Well Done");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            HudManager.ClearText();
            HudManager.colour = HUDManager.HUDColour.Red;

            //
            // Reaching practice
            InstructionManager.DisplayText("Next, the colour of the targets will tell you the status of the target." + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("<Blue>: the target is selected as the next target." + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("<Green>: you have successfully reached the selected one." + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.


            //
            // Explain routine
            InstructionManager.DisplayText("Alright, let's explain the task routine." + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("The task routine is: first keep your start position for 3 seconds, and HUD will tell you when to go." + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("Then reach to the target in <blue> using your index finger." + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("Finally, when you reach, hold on for a while, until you hear 'Return' and HUD says 'Well done'." + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            //
            // Important messages
            InstructionManager.DisplayText("Important!: Keep your final reaching position when you hear 'Hold', like !!! " + "\n\n (Press the trigger to play)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            audio.clip = holdAudioClip;
            audio.Play(0);
            HudManager.DisplayText("Hold on for a while!!");
            InstructionManager.DisplayText("Important!: Keep your final reaching position when you hear 'Hold', like !!! " + "\n\n (Press the trigger to continue)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("Important!: Do not return until HUD says 'Well Done' and you hear 'Return', like !!! " + "\n\n (Press the trigger to play)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            audio.clip = returnAudioClip;
            audio.Play(0);
            HudManager.DisplayText("Well done!!");
            InstructionManager.DisplayText("Important!: Do not return until HUD says 'Well Done' and you hear 'Return', like !!! " + "\n\n (Press the trigger to continue)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            //
            // Have a try
            InstructionManager.DisplayText("Ok, let's have a try of a routine." + "\n\n (Press the trigger)");
            HudManager.ClearText();
            HudManager.colour = HUDManager.HUDColour.Red;
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.


            //
            // Start position
            InstructionManager.DisplayText("First, let's show you the start position." + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            //
            // Start position
            InstructionManager.DisplayText("Your upper arm and elbow should point downards." + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("Try it. The HUD displays: (current upper and fore arm angle/the desired one)");
            //startPosPhoto.SetActive(true);
            //startPosPhoto.transform.Rotate(new Vector3(0.0f, 90.0f, 0.0f), Space.World);
            yield return(new WaitUntil(() => IsReadyToStart()));

            //startPosPhoto.SetActive(false);
            HudManager.ClearText();

            //Start practice
            gridManager.SelectTarget(0);
            InstructionManager.DisplayText("The sphere that you need to reach will turn blue. Don't reach now." + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("You'll have to wait for a three second countdown. Look at the sphere and get ready!" + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            HudManager.colour = HUDManager.HUDColour.Orange;
            HUDCountDown(1);
            yield return(new WaitUntil(() => CountdownDone)); // And wait

            InstructionManager.DisplayText("Reach for it by index finger!!");
            HudManager.DisplayText("Reach for it by index finger!!");
            HudManager.colour = HUDManager.HUDColour.Blue;
            yield return(new WaitUntil(() => IsTaskDone()));

            // Signal the subject that the task is done
            HudManager.DisplayText("Hold on your current position!");
            yield return(new WaitForSecondsRealtime(1.0f));

            audio.clip = returnAudioClip;
            audio.Play();
            HudManager.colour = HUDManager.HUDColour.Red;
            HudManager.DisplayText("Well done (you can return to start position)!");
            // Reset flags
            hasReached   = false;
            taskComplete = false;
            HudManager.DisplayText("You can relax now. Look to the top right.", 3);

            //
            // End
            InstructionManager.DisplayText("Important: Do not return until you hear 'Return' and HUD says 'Well Done' !!! " + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("Otherwise, you look ready to go! Good luck!" + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.
        }
        if (sessionNumber == 2)
        {
            InstructionManager.DisplayText("Let's start training then!" + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            //
            // Reaching practice
            InstructionManager.DisplayText("Everthing is the same except you need to match the orientations." + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("Ok, let's have a try." + "\n\n (Press the trigger)");
            HudManager.ClearText();
            HudManager.colour = HUDManager.HUDColour.Red;
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            //Start practice
            gridManager.SelectTarget(2);
            InstructionManager.DisplayText("The sphere that you need to reach will turn blue. Do not reach now." + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("You'll have to wait for a three second countdown. Look at the sphere and get ready!" + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            HudManager.colour = HUDManager.HUDColour.Orange;
            HUDCountDown(3);
            yield return(new WaitUntil(() => CountdownDone)); // And wait

            InstructionManager.DisplayText("Reach for it!!");
            HudManager.DisplayText("Reach for it!!");
            HudManager.colour = HUDManager.HUDColour.Blue;
            yield return(new WaitUntil(() => IsTaskDone()));

            // Signal the subject that the task is done
            HudManager.DisplayText("Hold on!");
            yield return(new WaitForSecondsRealtime(1.0f));

            HudManager.colour = HUDManager.HUDColour.Red;
            HudManager.DisplayText("Well done (you can return to start position)!");
            // Reset flags
            hasReached   = false;
            taskComplete = false;
            HudManager.DisplayText("You can relax now. Look to the top right.", 3);

            //
            // End
            InstructionManager.DisplayText("Important: Hold your final reaching position until you hear 'Return' and HUD says 'Well Done' !!! " + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("Otherwise, you look ready to go! Good luck!" + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.
        }

        // Now that you are done, set the flag to indicate we are done.
        trainingDone = true;
    }
    /// <summary>
    /// Coroutine for the welcome text.
    /// Implement your welcome loop here.
    /// </summary>
    /// <returns>Yield instruction</returns>
    public override IEnumerator WelcomeLoop()
    {
        // First flag that we are in the welcome routine
        welcomeDone = false;
        inWelcome   = true;
        HudManager.DisplayText("Look to the top right. Instructions will be displayed there.");
        yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

        //HudManager.DisplayText("Look to the top right. Instructions will be displayed there.");
        InstructionManager.DisplayText("Hi " + SaveSystem.ActiveUser.name + "! Welcome to the virtual world. \n\n (Press the trigger button to continue...)");
        yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

        InstructionManager.DisplayText("Make sure you are standing on top of the green circle. \n\n (Press the trigger button to continue...)");
        yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

        InstructionManager.DisplayText("Test audio. \n\n (If you can hear the audio, press the trigger button to continue...)");
        audio.loop   = true;
        audio.volume = 0.4f;
        audio.Play();

        yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

        audio.loop = false;
        audio.Stop();
        audio.volume = 1.0f;
        //
        // Hud intro
        InstructionManager.DisplayText("Alright " + SaveSystem.ActiveUser.name + ", let me introduce you to your assistant, the Heads Up Display (HUD)." + "\n\n (Press the trigger)");
        yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

        InstructionManager.DisplayText("Look at the HUD around your left eye. It's saying hi!");
        HudManager.DisplayText("Hi! I'm HUD!" + "\n (Press trigger)");
        yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

        HudManager.DisplayText("I'm here to help!" + "\n (Press trigger)");
        yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

        HudManager.DisplayText("Look at the screen.", 3);


        //
        // Experiment overall intro
        InstructionManager.DisplayText("Alright " + SaveSystem.ActiveUser.name + ", let me explain what we are doing today." + "\n\n (Press the trigger)");
        yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

        InstructionManager.DisplayText("Today, the experiment will require you to reach to the targets in front of you." + "\n\n (Press the trigger)");
        yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

        InstructionManager.DisplayText("You will do 2 sessions, 1st 90 iterations and 2nd 270 iterations " + "\n\n (Press the trigger)");
        yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

        InstructionManager.DisplayText("A 60 sec rest occurs every 35 iterations" + "\n\n (Press the trigger)");
        yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.



        //
        // Generate the targets

        InstructionManager.DisplayText("First, let's set up the experiment targets for you. \n\n (Press the trigger)");
        yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

        InstructionManager.DisplayText("Extend your arms naturally forward and the desired joint positions will be shown on the HUD. \n\n (Press the trigger)");
        yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

        InstructionManager.DisplayText("HUD Format: SH - Shoulder, EB - Elbow and in the bracket (current joint angle / the desired one)");

        for (int i = 0; i < shoulderDesiredPos.Length; i++)
        {
            for (int j = 0; j < elbowDesiredPos.Length; j++)
            {
                //yield return new WaitUntil(() => IsAtRightPosition(shoulderDesiredPos[i], elbowDesiredPos[j], 2.0f));


                if (i % 2 == 0)
                {
                    yield return(new WaitUntil(() => IsAtRightPosition(shoulderDesiredPos[i], elbowDesiredPos[j], 2.0f)));
                }
                else
                {
                    yield return(new WaitUntil(() => IsAtRightPosition(shoulderDesiredPos[i], elbowDesiredPos[elbowDesiredPos.Length - 1 - j], 2.0f)));
                }

                GameObject[] hand = GameObject.FindGameObjectsWithTag("IndexFingerCollider");
                //Debug.Log(indexFinger[0].transform.position.ToString("F3"));
                Vector3 location = Quaternion.Euler(0, this.worldOrientation, 0) * hand[0].transform.position; // Add the index finger location
                gridManager.AddTargetLocation(location);
            }
        }

        gridManager.AddTargetRotation(new Vector3(0.0f, 0.0f, 0.0f));
        gridManager.AddTargetRotation(new Vector3(45.0f, 0.0f, 0.0f));
        gridManager.AddTargetRotation(new Vector3(-45.0f, 0.0f, 0.0f));


        // Now that you are done, set the flag to indicate we are done.

        welcomeDone = true;
    }
Esempio n. 9
0
    /// <summary>
    /// Coroutine for the experiment training.
    /// Implement your training loop here.
    /// </summary>
    /// <returns>Yield instruction</returns>
    public override IEnumerator TrainingLoop()
    {
        // First flag that we are in the training routine
        trainingDone = false;
        inTraining   = true;

        // Only run the training loop when requested, for instance some session may require different session.
        if (trainingPerSession[sessionNumber - 1] == 1)
        {
            // Hud intro
            InstructionManager.DisplayText("Alright " + SaveSystem.ActiveUser.name + ", let's show you the ropes." + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("Let me introduce you to your assistant, the Heads Up Display (HUD)." + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("Say hi!");
            HudManager.DisplayText("Hi! I'm HUD!" + "\n (Press trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            HudManager.DisplayText("I'm here to help!" + "\n (Press trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            HudManager.DisplayText("Look at the screen.", 3);
            InstructionManager.DisplayText("Let's start training then!" + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            // Type instructions
            if (experimentType == ExperimentType.TypeOne)
            {
                InstructionManager.DisplayText("First, we'll show you the start position." + "\n\n (Press the trigger)");
                yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.
            }
            else if (experimentType == ExperimentType.TypeTwo)
            {
                InstructionManager.DisplayText("First, we'll show how to use the prosthesis." + "\n\n (Press the trigger)");
                yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

                InstructionManager.DisplayText("When the prosthesis is not enabled, the HUD centre will turn yellow." + "\n\n (Press the trigger)");
                HudManager.centreColour = HUDManager.HUDCentreColour.Yellow;
                HudManager.DisplayText("\n <- Like so.");
                yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

                HudManager.ClearText();
                InstructionManager.DisplayText("To activate the prosthesis, press the circle button.");
                yield return(new WaitUntil(() => elbowManager.IsEnabled)); // And wait for the subject to enable it.

                HudManager.DisplayText("\n <- I'll be transparent!");
                InstructionManager.DisplayText("Try moving it around." + "\n\n (Press the trigger)");
                yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

                InstructionManager.DisplayText("Nice! Let's deactivate the prosthesis for now." + "\n\n (Press the trigger)");
                yield return(new WaitUntil(() => !elbowManager.IsEnabled)); // And wait for the subject to disable it.

                InstructionManager.DisplayText("Now, we'll show you the start position." + "\n\n (Press the trigger)");
                yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.
            }

            //
            // Start position
            InstructionManager.DisplayText("Your upper arm should be relaxed pointing downards while your elbow should be bent 90 degrees." + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("Like so:" + "\n Try it.");
            startPosPhoto.SetActive(true);
            yield return(new WaitUntil(() => IsReadyToStart()));

            startPosPhoto.SetActive(false);
            HudManager.ClearText();
            //
            // HUD Colours
            InstructionManager.DisplayText("The colour of the HUD will tell you what you need to do." + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("Red for adjusting your start position." + "\n\n (Press the trigger)");
            HudManager.DisplayText("I'm red!");
            HudManager.colour = HUDManager.HUDColour.Red;
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("Orange for waiting for the countdown." + "\n\n (Press the trigger)");
            HudManager.DisplayText("I'm orange!");
            HudManager.colour = HUDManager.HUDColour.Orange;
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("Blue for reaching for the sphere!" + "\n\n (Press the trigger)");
            HudManager.DisplayText("I'm blue!");
            HudManager.colour = HUDManager.HUDColour.Blue;
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("Green for returning to the start position." + "\n\n (Press the trigger)");
            HudManager.DisplayText("I'm green!");
            HudManager.colour = HUDManager.HUDColour.Green;
            //
            // Practice
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("Now, let's practice reaching for a target!" + "\n\n (Press the trigger)");
            HudManager.ClearText();
            HudManager.colour = HUDManager.HUDColour.Red;
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("The sphere that you need to reach will turn blue." + "\n\n (Press the trigger)");
            gridManager.SelectBall(0);
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("You'll have to wait for a three second countdown. Look at the sphere and get ready!" + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            HudManager.colour = HUDManager.HUDColour.Orange;
            HUDCountDown(3);
            yield return(new WaitUntil(() => CountdownDone)); // And wait

            InstructionManager.DisplayText("Reach for it!!");
            HudManager.DisplayText("Reach for it!!");
            HudManager.colour = HUDManager.HUDColour.Blue;
            yield return(new WaitUntil(() => IsTaskDone()));

            // Signal the subject that the task is done
            HudManager.colour = HUDManager.HUDColour.Green;
            // Reset flags
            hasReached   = false;
            taskComplete = false;
            HudManager.DisplayText("You can relax now.", 3);
            //
            // End
            InstructionManager.DisplayText("Make sure you hold your position until the HUD turns green before moving back to the start position." + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("Otherwise, you look ready to go! Good luck!" + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.
        }

        // Now that you are done, set the flag to indicate we are done.
        trainingDone = true;
    }
Esempio n. 10
0
    /// <summary>
    /// Coroutine for the experiment instructions.
    /// Implement your instructions loop here.
    /// </summary>
    /// <returns>Yield instruction</returns>
    public override IEnumerator InstructionsLoop()
    {
        // First flag that we are in the instructions routine
        instructionsDone = false;
        inInstructions   = true;

        //
        InstructionManager.DisplayText("Alright " + SaveSystem.ActiveUser.name + ", let me explain what we are doing today." + "\n\n (Press the trigger)");
        yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

        InstructionManager.DisplayText("Today you are doing the " + AvatarSystem.AvatarType + " version of the experiment, which means..." + "\n\n (Press the trigger)");
        yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

        // Type instructions
        if (experimentType == ExperimentType.TypeOne)
        {
            InstructionManager.DisplayText("You'll be reaching for a bunch of floating colorful spheres!" + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("You should see 9 spheres arranged in a 3x3 matrix. They should all be reachable, if not, please let me know." + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("You are not allowed to step! So if they are too far away, I'll adjust them." + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("You'll have to touch each sphere a total of " + iterationsPerTarget + " times." + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("The order will be random; however, you'll be shown which one to touch before each reach." + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("You don't need to do anything special, just reach as you normally would, comfortably." + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.
        }
        else if (experimentType == ExperimentType.TypeTwo)
        {
            InstructionManager.DisplayText("You'll be reaching for a single floating colorful sphere while using a smart prosthesis!" + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("You'll have to reach for the sphere a total of " + iterationsPerTarget + " times." + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("At the beginning it might be a bit difficult to reach and you'll need to compensate with your upper body." + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("You should not step though!" + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("However, after each reach, the prosthesis will learn from your movement and adjust itself." + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

            InstructionManager.DisplayText("After a few reachs it should be a piece of cake." + "\n\n (Press the trigger)");
            yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.
        }
        else
        {
            throw new System.Exception("The experiment type is not valid. Place: Instructions");
        }

        InstructionManager.DisplayText("There is no break in this experiment, but if you feel tired or any discomfort let me know immediately and we'll take a break or stop." + "\n\n (Press the trigger)");
        yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

        InstructionManager.DisplayText("Remember you are in VR, so the objects you see are not actually there. So... Don't lean on them!" + "\n\n (Press the trigger)");
        yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

        InstructionManager.DisplayText("Also, objects you can't see may be around you, so don't go running around. You'll have a chance to explore at the end. :)" + "\n\n (Press the trigger)");
        yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

        InstructionManager.DisplayText("If you are ready, let's start training!" + "\n\n (Press the trigger)");
        yield return(WaitForSubjectAcknowledgement()); // And wait for the subject to cycle through them.

        // Now that you are done, set the flag to indicate we are done.
        instructionsDone = true;
    }
    private void FixedUpdate()
    {
        //
        // Tasks performed determinalistically throughout the experiment
        // E.g. data gathering.
        //
        switch (experimentState)
        {
        case ExperimentState.PerformingTask:
            //
            // Gather data while experiment is in progress
            //
            string displayData = "Training time elapsed: " + taskTime.ToString() + " seconds.";
            // Read from all user sensors
            foreach (ISensor sensor in AvatarSystem.GetActiveSensors())
            {
                if (sensor.GetSensorType().Equals(SensorType.EMGWiFi))
                {
                    displayData += "\n" + sensor.GetSensorType().ToString() + " Command:";
                    float[] sensorData = sensor.GetAllProcessedData();
                    foreach (float element in sensorData)
                    {
                        displayData += "\n" + element.ToString();
                    }
                }
                else if (sensor.GetSensorType().Equals(SensorType.VirtualEncoder))
                {
                    displayData += "\n" + sensor.GetSensorType().ToString() + " Command:";
                    float[] sensorData = sensor.GetAllProcessedData();
                    foreach (float element in sensorData)
                    {
                        displayData += "\n" + element.ToString();
                    }
                }
            }


            InstructionManager.DisplayText(displayData);
            //hudManager.DisplayText(logData);

            //
            // Append data to lists
            //
            taskTime += Time.fixedDeltaTime;

            //
            // Raycast debug
            //
            // Vector3 shoulderToElbow = elbowGO.transform.position - residualLimbGO.transform.position;
            // Vector3 shoulderToHand = handGO.transform.position - (residualLimbGO.transform.position - 0.25f * shoulderToElbow);
            // Debug.DrawRay(residualLimbGO.transform.position - 0.2f * shoulderToElbow, shoulderToHand, Color.magenta);

            //
            // Save log and reset flags when successfully compeleted task
            //
            if (IsTaskDone())
            {
                //
                // Perform data management, such as appending data to lists for analysis
                //

                //
                // Save logger for current experiment and change to data analysis
                //
                //ExperimentSystem.GetActiveLogger(1).CloseLog();

                //
                // Clear data management buffers
                //
                experimentState = ExperimentState.AnalizingResults;
                break;
            }

            // Check if requested to end training
            UpdateEnd();

            break;

        default:
            break;
        }
    }
Esempio n. 12
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";
        }
    }
Esempio n. 13
0
    // Update is called once per frame
    void Update()
    {
        switch (experimentState)
        {
        /*
         *************************************************
         *  HelloWorld
         *************************************************
         */
        // Welcome subject to the virtual world.
        case ExperimentState.Welcome:
            if (WaitFlag)
            {
                HudManager.ClearText();
                experimentState = ExperimentState.Initialising;
            }
            else
            {
                HudManager.DisplayText("Welcome!");
            }
            break;

        /*
         *************************************************
         *  InitializingApplication
         *************************************************
         */
        // Perform initialization functions before starting experiment.
        case ExperimentState.Initialising:
            //
            // Perform experiment initialization procedures
            //
            // Enable colliders
            AvatarSystem.EnableAvatarColliders();
            // Initialize arm guide
            guideManager.Initialize(startAngleList[angleNumber - 1], endAngleList[angleNumber - 1], movementTimeList[timeNumber - 1]);
            guideManager.GoToStart();

            //
            // Initialize data logs
            //
            motionLogger.AddNewLogFile(startAngleList[angleNumber - 1] + "_" + endAngleList[angleNumber - 1] + "_" + movementTimeList[timeNumber - 1], iterationNumber, motionDataFormat);

            //
            // 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:
            HudManager.DisplayText(movementTimeList[timeNumber - 1] + " sec. movement.", 2.0f);
            // Skip instructions when repeating sessions
            if (SkipInstructions)
            {
                //hudManager.DisplayText("Move to guide", 2.0f);
                experimentState = ExperimentState.WaitingForStart;
                break;
            }

            //
            // Give instructions
            //

            //
            // Go to waiting for start
            //
            experimentState = ExperimentState.WaitingForStart;
            break;

        /*
         *************************************************
         *  WaitingForStart
         *************************************************
         */
        case ExperimentState.WaitingForStart:

            // Check if pause requested
            UpdatePause();
            switch (waitState)
            {
            // Waiting for subject to grab the object.
            case WaitState.Waiting:
                if (guideManager.StartGuiding())
                {
                    //StopAllCoroutines();
                    HudManager.ClearText();
                    taskTime = 0.0f;
                    HUDCountDown(3);
                    experimentState = ExperimentState.PerformingTask;
                }
                break;

            default:
                break;
            }
            break;

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

        /*
         *************************************************
         *  AnalizingResults
         *************************************************
         */
        case ExperimentState.AnalizingResults:
            HudManager.DisplayText("Rest your arm.", 5.0f);
            // Allow 3 seconds after task end to do calculations
            SetWaitFlag(5.0f);

            //
            // Data analysis and calculations
            //

            //
            // Adaptive system update (when available)
            //

            //
            // Data logging and log management
            //
            motionLogger.CloseLog();

            //
            // Flow managment
            //

            // Rest for some time when required
            if (IsRestTime())
            {
                HudManager.ClearText();
                HudManager.DisplayText("Rest your arm.", 2.0f);
                SetWaitFlag(RestTime);
                experimentState = ExperimentState.Resting;
                break;
            }
            else if (IsEndOfExperiment())
            {
                experimentState = ExperimentState.End;
                break;
            }
            // Check whether the new session condition is met
            else if (IsEndOfSession())
            {
                //
                // Update iterations and flow control
                //
                iterationNumber++;
                timeIterations++;
                totalIterations++;
                // Go to next
                experimentState = ExperimentState.InitializingNext;
                break;
            }
            else
            {
                experimentState = ExperimentState.UpdatingApplication;
            }
            break;

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

                //
                // Update experiment object
                //
                guideManager.GoToStart();

                //
                // Update log requirements
                //
                motionLogger.AddNewLogFile(startAngleList[angleNumber - 1] + "_" + endAngleList[angleNumber - 1] + "_" + movementTimeList[timeNumber - 1], iterationNumber, motionDataFormat);

                //
                // Go to start of next iteration
                //
                HudManager.DisplayText("Move to guide", 2.0f);
                experimentState = ExperimentState.WaitingForStart;
            }
            break;

        /*
         *************************************************
         *  InitializingNext
         *************************************************
         */
        case ExperimentState.InitializingNext:
            if (WaitFlag)
            {
                //
                // Perform session closure procedures
                //

                //
                // Initialize new session variables and flow control
                //
                iterationNumber = 1;
                sessionNumber++;
                // Still doing the angle repetitions for the same time
                if (timeIterations < timeIterationLimit)
                {
                    angleNumber++;
                }
                // Done all the angle repetitions for the given time, reset and go to next time
                else
                {
                    angleNumber    = 1;
                    timeIterations = 1;
                    timeNumber++;
                }

                //
                // Update experiment object
                //
                guideManager.GoToStart();
                //
                // Initialize data logging
                //

                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)
            {
                if (IsEndOfExperiment())
                {
                    experimentState = ExperimentState.End;
                    break;
                }
                // Check whether the new session condition is met
                else if (IsEndOfSession())
                {
                    //
                    // Update iterations and flow control
                    //
                    iterationNumber++;
                    timeIterations++;
                    totalIterations++;
                    // Go to next
                    experimentState = ExperimentState.InitializingNext;
                    break;
                }
                else
                {
                    HudManager.DisplayText("Get ready!", 3.0f);
                    SetWaitFlag(3.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.
            //

            HudManager.DisplayText("Experiment end, thanks!", 5.0f);
            //
            // Return to main menu
            //
            break;

        default:
            break;
        }

        //
        // Update information displayed on monitor
        //
        string experimentInfoText = "Experiment info: \n";

        experimentInfoText += "Iteration: " + iterationNumber + "/" + iterationsPerAngle + ".\n";
        experimentInfoText += "Session: " + sessionNumber + "/" + startAngleList.Count * movementTimeList.Count + ".\n";
        InstructionManager.DisplayText(experimentInfoText);

        //
        // Update information displayed for debugging purposes
        //
        if (debug)
        {
            string debugText = "Debug info: \n";
            debugText += experimentState.ToString() + ".\n";
            if (experimentState == ExperimentState.WaitingForStart)
            {
                debugText += waitState.ToString() + ".\n";
            }
            debugText += "Angle number:" + angleNumber + ".\n";
            debugText += "Time iterations:" + timeIterations + ".\n";
            InstructionManager.DisplayText(debugText + "\n" + experimentInfoText);
        }
    }