private void KeepOnLoad() { // Keep player and avatar objects GameObject playerGO = GameObject.FindGameObjectWithTag("Player"); GameObject avatarGO = GameObject.FindGameObjectWithTag("Avatar"); if (playerGO == null || avatarGO == null) { MonitorManager.DisplayText("The user or avatar has not been loaded."); throw new System.Exception("The player or avatar has not been loaded."); } DontDestroyOnLoad(playerGO); DontDestroyOnLoad(avatarGO); }
// Update is called once per frame protected override void Update() { switch (experimentState) { /* ************************************************* * HelloWorld ************************************************* */ // Welcome subject to the virtual world. case ExperimentState.Welcome: if (debug) { LoadDebugAvatar(); InitialiseExperimentSystems(); InitializeUI(); } MonitorManager.DisplayText("Instructions:\n" + instructionsText); experimentState = ExperimentState.Initialising; 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: // // Go to waiting for start // HudManager.DisplayText("Loading...", 2.0f); // Turn targets clear experimentState = ExperimentState.WaitingForStart; break; /* ************************************************* * WaitingForStart ************************************************* */ case ExperimentState.WaitingForStart: // Check if pause requested UpdatePause(); switch (waitState) { // Waiting for subject to get to start position. case WaitState.Waiting: SetWaitFlag(3.0f); waitState = WaitState.Countdown; break; case WaitState.Countdown: if (WaitFlag) { // Enable training camera TrainingCamera.enabled = true; experimentState = ExperimentState.PerformingTask; } 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 // // // 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. // EndExperiment(); break; // // Return to main menu // default: break; } // // Update information displayed on monitor // // // Update information displayed for debugging purposes // // // Update HUD state // if (elbowManager.IsEnabled) { trainingHudManager.colour = HUDManager.HUDColour.Blue; } else { trainingHudManager.colour = HUDManager.HUDColour.Red; } }
/// <summary> /// Initializes the ExperimentSystem and its components. /// Verifies that all components needed for the experiment are available. /// </summary> public override void InitialiseExperimentSystems() { // // Set the experiment type and ID // if (AvatarSystem.AvatarType == AvatarType.AbleBodied) { experimentType = ExperimentType.TypeOne; MonitorManager.DisplayText("Wrong avatar used. Please use a Transhumeral avatar."); throw new System.Exception("Able-bodied avatar not suitable for prosthesis training."); } else if (AvatarSystem.AvatarType == AvatarType.Transhumeral) { // Check if EMG is available bool EMGAvailable = false; foreach (ISensor sensor in AvatarSystem.GetActiveSensors()) { if (sensor.GetSensorType().Equals(SensorType.EMGWiFi)) { EMGAvailable = true; UDPSensorManager udpSensor = (UDPSensorManager)sensor; udpSensor.StartSensorReading(); } else if (sensor.GetSensorType().Equals(SensorType.ThalmicMyo)) { EMGAvailable = true; } } // Set whether emg or synergy based if (EMGAvailable) { experimentType = ExperimentType.TypeTwo; instructionsText = emgInstructions; // Set EMG sensor and reference generator as active. // Get prosthesis GameObject prosthesisManagerGO = GameObject.FindGameObjectWithTag("ProsthesisManager"); elbowManager = prosthesisManagerGO.GetComponent <ConfigurableElbowManager>(); // Set active sensor and reference generator to EMG. //elbowManager.ChangeSensor("VAL_SENSOR_SEMG"); elbowManager.ChangeSensor("VAL_SENSOR_THALMYO"); elbowManager.ChangeReferenceGenerator("VAL_REFGEN_EMGPROP"); } else { experimentType = ExperimentType.TypeThree; instructionsText = synergyInstructions; // Set VIVE tracker and Jacobian synergy as active. // Get prosthesis GameObject prosthesisManagerGO = GameObject.FindGameObjectWithTag("ProsthesisManager"); elbowManager = prosthesisManagerGO.GetComponent <ConfigurableElbowManager>(); if (elbowManager.GetInterfaceType() == ReferenceGeneratorType.JacobianSynergy) { // Set the reference generator to jacobian-based. elbowManager.ChangeSensor("VAL_SENSOR_VIVETRACKER"); elbowManager.ChangeReferenceGenerator("VAL_REFGEN_JACOBIANSYN"); } else if (elbowManager.GetInterfaceType() == ReferenceGeneratorType.LinearKinematicSynergy) { // Set the reference generator to linear synergy. elbowManager.ChangeSensor("VAL_SENSOR_VIVETRACKER"); elbowManager.ChangeReferenceGenerator("VAL_REFGEN_LINKINSYN"); } else { throw new System.Exception("The prosthesis interface available is not supported."); } } if (!debug) { // Find the residual limb and change the follower residualLimbGO = GameObject.FindGameObjectWithTag("ResidualLimbAvatar"); limbFollower = residualLimbGO.GetComponent <LimbFollower>(); limbFollower.enabled = false; angleFollower = residualLimbGO.AddComponent <AngleFollower>(); angleFollower.fixedTransform = fixedProsthesisPosition; } } else { throw new System.NotImplementedException(); } // Get Raycast Debug info // handGO = GameObject.FindGameObjectWithTag("Hand"); // elbowGO = GameObject.FindGameObjectWithTag("Elbow_Upper"); // residualLimbGO = GameObject.FindGameObjectWithTag("ResidualLimbAvatar"); }