/// <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 // experimentType = ExperimentType.TypeOne; ExperimentSystem.SetActiveExperimentID("PhotoStage"); // // Create data loggers // // Restart EMG readings foreach (ISensor sensor in AvatarSystem.GetActiveSensors()) { if (sensor.GetSensorType().Equals(SensorType.EMGWiFi)) { UDPSensorManager udpSensor = (UDPSensorManager)sensor; //Debug.Log(wifiSensor.RunThread); udpSensor.StartSensorReading(); //Debug.Log(wifiSensor.RunThread); } } // Set EMG sensor and reference generator as active. // Get prosthesis GameObject prosthesisManagerGO = GameObject.FindGameObjectWithTag("ProsthesisManager"); ConfigurableElbowManager elbowManager = prosthesisManagerGO.GetComponent <ConfigurableElbowManager>(); // Set active sensor and reference generator to EMG. elbowManager.ChangeSensor("VAL_SENSOR_SEMG"); elbowManager.ChangeReferenceGenerator("VAL_REFGEN_EMGPROP"); }
public void AddVIVETracker() { if ((int)selectedDevice > 4) { // Instantiate a new VIVETracker with Player as parent. GameObject playerGO = GameObject.FindGameObjectWithTag("Player"); if (playerGO == null) { throw new Exception("The player GameObject was not found."); } // Load VIVE Tracker prefab. GameObject viveTrackerPrefab = Resources.Load <GameObject>("Trackers/VIVETracker"); if (viveTrackerPrefab == null) { throw new Exception("The requested tracker prefab was not found."); } // Instantiate and with the other SteamVRObjects and set device number GameObject viveTrackerGO = Instantiate(viveTrackerPrefab, viveTrackerPrefab.transform.position, viveTrackerPrefab.transform.rotation, playerGO.transform.GetChild(0).transform); viveTrackerGO.GetComponentInChildren <SteamVR_TrackedObject>().SetDeviceIndex((int)selectedDevice); // Create tracker sensor and add to logger VIVETrackerManager viveTrackerSensor = new VIVETrackerManager(viveTrackerGO.transform); ExperimentSystem.AddSensor(viveTrackerSensor); addExperimentSensorMenu.ReturnToSettingsMenu(); } else { StartCoroutine(DisplayInformationOnLog(3.0f, "Select a valid VIVE Tracker device.")); } }
/// <summary> /// Loads the user data for the given userID. /// </summary> /// <param name="userID">The ID of the user to load the data for.</param> /// <returns>The UserData for the requested user.</returns> public static UserData LoadUserData(string userID) { UserData loadedUserData; // Get the folder for the given user ID string userPath = dataFolder + "/UserData/" + userID; string loadFilePath = userPath + "/userInfo.json"; if (File.Exists(loadFilePath)) { // Load data string userDataAsJson = File.ReadAllText(loadFilePath); loadedUserData = JsonUtility.FromJson <UserData>(userDataAsJson); } else { throw new System.Exception("The file :" + loadFilePath + ", could not be found."); } // Set as active user activeUser = loadedUserData; activeSaveFolder = userPath; // Re-initialize the experiment logger for the new active user. foreach (IExperimentLogger logger in ExperimentSystem.GetActiveLoggers()) { logger.InitializeLog(activeSaveFolder); } isUserAvailable = true; return(loadedUserData); }
/// <summary> /// Initializes the ExperimentSystem and its components. /// Verifies that all components needed for the experiment are available. /// This must be done in Start. /// Extend this method by doing your own implementation, with base.InitExperimentSystem() being called at the start. /// </summary> public override void InitialiseExperimentSystems() { // First run the base initialisation which is needed. base.InitialiseExperimentSystems(); // e.g. make sure that the needed objects have been set. if (cubeGO == null || sphereGO == null) { throw new System.Exception("You need to add the objects in the Unity inspector!"); } // e.g. the update their transform handle and hide the objects cubeTransform = cubeGO.transform; sphereTransform = sphereGO.transform; cubeGO.SetActive(false); sphereGO.SetActive(false); // // Hand tracking sensor for demo // GameObject handGO = GameObject.FindGameObjectWithTag("Hand"); VirtualPositionTracker handTracker = new VirtualPositionTracker(handGO.transform); ExperimentSystem.AddSensor(handTracker); }
AstronautControlPanel() { CommunicationSystem comms = new CommunicationSystem(); ExperimentSystem experiment = new ExperimentSystem(); FlightControlSystem flight = new FlightControlSystem(); LifeSupportSystem lifeSupport = new LifeSupportSystem(); PowerDistributionSystem power = new PowerDistributionSystem(); }
private void InitialiseExperiment() { if (selectedExperiment == 0) { logManager.DisplayInformationOnLog(5, "Please select an experiment from the dropdown menu."); return; } ExperimentSystem.SetActiveExperimentID(experimentList[selectedExperiment]); }
public void OnEnable() { //Debug.Log(Application.persistentDataPath); if (createdUser) { logManager.DisplayInformationOnLog(3.0f, "Created new user with ID " + SaveSystem.ActiveUser.id); createdUser = false; } if (loadedUser) { logManager.DisplayInformationOnLog(3.0f, "Loaded user with ID " + SaveSystem.ActiveUser.id); createdUser = false; } // Display active user name. if (SaveSystem.IsUserAvailable) { activeUserTMP.text = "Active User: \n" + SaveSystem.ActiveUser.name + " " + SaveSystem.ActiveUser.familyName; } // Display available user sensors name. if (AvatarSystem.GetActiveSensors().Count > 0) { sensorTMP.text = "Sensors: \n"; foreach (ISensor sensor in AvatarSystem.GetActiveSensors()) { sensorTMP.text = sensorTMP.text + sensor.GetSensorType().ToString() + "\n"; } } // Display available experiment sensors name. if (ExperimentSystem.GetActiveSensors().Count > 0) { experimentSensorsTMP.text = "Experiment Sensors: \n"; foreach (ISensor sensor in ExperimentSystem.GetActiveSensors()) { experimentSensorsTMP.text = experimentSensorsTMP.text + sensor.GetSensorType().ToString() + "\n"; } } // Conditional menus // Show avatar menu when there is an available user. if (SaveSystem.IsUserAvailable) { avatarOptionsButton.SetActive(true); } // Show sensors menu when there is an available avatar. if (AvatarSystem.IsPlayerAvailable && AvatarSystem.IsAvatarAvaiable) { sensorOptionsButton.SetActive(true); modeSelectionButton.SetActive(true); } }
/// <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 // experimentType = ExperimentType.TypeOne; ExperimentSystem.SetActiveExperimentID("template"); // // Create data loggers // }
private void OnApplicationQuit() { // Check if WiFi sensors are available foreach (ISensor sensor in AvatarSystem.GetActiveSensors()) { if (sensor.GetSensorType().Equals(SensorType.EMGWiFi)) { UDPSensorManager udpSensor = (UDPSensorManager)sensor; udpSensor.StopSensorReading(); } } // // Save and close all logs // ExperimentSystem.CloseAllExperimentLoggers(); }
//private ISensor sensorDebug; public void OnEnable() { // Display available user sensors name. if (AvatarSystem.GetActiveSensors().Count > 0) { userSensorsTMP.text = "User Sensors: \n"; foreach (ISensor sensor in AvatarSystem.GetActiveSensors()) { userSensorsTMP.text = userSensorsTMP.text + sensor.GetSensorType().ToString() + "\n"; } } // Display available experiment sensors name. if (ExperimentSystem.GetActiveSensors().Count > 0) { experimentSensorsTMP.text = "Experiment Sensors: \n"; foreach (ISensor sensor in ExperimentSystem.GetActiveSensors()) { experimentSensorsTMP.text = experimentSensorsTMP.text + sensor.GetSensorType().ToString() + "\n"; } } }
/// <summary> /// Initializes the ExperimentSystem and its components. /// Verifies that all components needed for the experiment are available. /// This must be done in Start. /// Extend this method by doing your own implementation, with base.InitExperimentSystem() being called at the start. /// </summary> public override void InitialiseExperimentSystems() { // Set data format taskDataFormat = ablebodiedDataFormat; // Lefty sign /* * if (SaveSystem.ActiveUser.lefty) * leftySign = -1.0f; */ // Audio audio = GetComponent <AudioSource>(); audio.clip = testAudioClip; #region Modify base // Then run the base initialisation which is needed, with a small modification // // Set the experiment name only when debugging. Take the name from the gameobject + Debug // if (debug) { ExperimentSystem.SetActiveExperimentID(this.gameObject.name + "_Debug"); } // Make sure flow control is initialised sessionNumber = 1; iterationNumber = 1; // // Create the default data loggers // taskDataLogger = new DataStreamLogger("TaskData/" + AvatarSystem.AvatarType.ToString()); ExperimentSystem.AddExperimentLogger(taskDataLogger); taskDataLogger.AddNewLogFile(sessionNumber, iterationNumber, taskDataFormat); // Add file // // Create the performance data loggers // performanceDataLogger = new DataStreamLogger("PerformanceData"); ExperimentSystem.AddExperimentLogger(performanceDataLogger); performanceDataLogger.AddNewLogFile(AvatarSystem.AvatarType.ToString(), sessionNumber, performanceDataFormat); // Add file // Send the player to the experiment centre position TeleportToStartPosition(); #endregion #region Initialize EMG sensors //Initialise Delsys EMG sensor delsysEMG.Init(); delsysEMG.Connect(); #endregion #region Initialize motion sensors // // Add arm motion trackers for able-bodied case. // // Lower limb motion tracker GameObject llMotionTrackerGO = GameObject.FindGameObjectWithTag("ForearmTracker"); lowerArmTracker = new VIVETrackerManager(llMotionTrackerGO.transform); ExperimentSystem.AddSensor(lowerArmTracker); // Upper limb motion tracker GameObject ulMotionTrackerGO = AvatarSystem.AddMotionTracker(); upperArmTracker = new VIVETrackerManager(ulMotionTrackerGO.transform); ExperimentSystem.AddSensor(upperArmTracker); if (!debug) { // Shoulder acromium head tracker GameObject motionTrackerGO1 = AvatarSystem.AddMotionTracker(); shoulderTracker = new VIVETrackerManager(motionTrackerGO1.transform); ExperimentSystem.AddSensor(shoulderTracker); // C7 tracker GameObject motionTrackerGO2 = AvatarSystem.AddMotionTracker(); c7Tracker = new VIVETrackerManager(motionTrackerGO2.transform); ExperimentSystem.AddSensor(c7Tracker); } // // Hand tracking sensor // GameObject handGO = GameObject.FindGameObjectWithTag("Hand"); handTracker = new VirtualPositionTracker(handGO.transform); ExperimentSystem.AddSensor(handTracker); #endregion // // Target ADL poses // poseListManager.AddPose("Rest", restAudioClip); poseListManager.AddPose("Reach Mug", reachMugAudioClip); poseListManager.AddPose("Mug to Mouth", mug2MouthAudioClip); poseListManager.AddPose("Drink with Mug", drinkAudioClip); poseListManager.AddPose("Reach Key", reachKeyAudioClip); poseListManager.AddPose("Turn Key", turnKeyAudioClip); // Start EMG readings delsysEMG.StartAcquisition(); }
/// <summary> /// Initializes the ExperimentSystem and its components. /// Verifies that all components needed for the experiment are available. /// This must be done in Start. /// Extend this method by doing your own implementation, with base.InitExperimentSystem() being called at the start. /// </summary> public override void InitialiseExperimentSystems() { // // Set the experiment type configuration // // Type one if able-bodied subject if (AvatarSystem.AvatarType == AvatarType.AbleBodied) { experimentType = ExperimentType.TypeOne; // Able-bodied experiment type taskDataFormat = ablebodiedDataFormat; performanceDataFormat = ablebodiedPerformanceDataFormat; } // Type two if prosthetic (Adaptive Synergy) else if (AvatarSystem.AvatarType == AvatarType.Transhumeral) { experimentType = ExperimentType.TypeTwo; // Able-bodied experiment type taskDataFormat = prostheticDataFormat; performanceDataFormat = prostheticPerformanceDataFormat; } // Then run the base initialisation which is needed, with a small modification // // Set the experiment name only when debugging. Take the name from the gameobject + Debug // if (debug) { ExperimentSystem.SetActiveExperimentID(this.gameObject.name + "_Debug"); } // Make sure flow control is initialised sessionNumber = 1; iterationNumber = 1; // // Create the default data loggers // taskDataLogger = new DataStreamLogger("TaskData/" + AvatarSystem.AvatarType.ToString()); ExperimentSystem.AddExperimentLogger(taskDataLogger); taskDataLogger.AddNewLogFile(sessionNumber, iterationNumber, taskDataFormat); // Add file // Restart UDP threads foreach (ISensor sensor in AvatarSystem.GetActiveSensors()) { if (sensor is UDPSensorManager udpSensor) { //Debug.Log(wifiSensor.RunThread); udpSensor.StartSensorReading(); //Debug.Log(wifiSensor.RunThread); } } // Send the player to the experiment centre position TeleportToStartPosition(); startPosPhoto.SetActive(false); // // Create the performance data loggers // performanceDataLogger = new DataStreamLogger("PerformanceData"); ExperimentSystem.AddExperimentLogger(performanceDataLogger); performanceDataLogger.AddNewLogFile(AvatarSystem.AvatarType.ToString(), sessionNumber, performanceDataFormat); // Add file if (SaveSystem.ActiveUser.lefty) { leftySign = -1.0f; } // // Iterations configuration // // Set iterations variables for flow control. targetNumber = gridRows * gridColumns; for (int i = 0; i < iterationsPerSession.Count; i++) { iterationsPerSession[i] = targetNumber * iterationsPerTarget; } // Create the list of target indexes and shuffle it. for (int i = 0; i < targetNumber; i++) { for (int j = 0; j < iterationsPerTarget; j++) { targetOrder.Add(i); } } targetOrder.Shuffle(); // // Initialize world positioning // // Get user physiological data. float subjectHeight = SaveSystem.ActiveUser.height; float subjectArmLength = SaveSystem.ActiveUser.upperArmLength + SaveSystem.ActiveUser.forearmLength + (SaveSystem.ActiveUser.handLength / 2); // Set the grid distance from subject gridManager.transform.position = new Vector3((-gridReachMultiplier * subjectArmLength) - 0.1f, gridHeightMultiplier * subjectHeight, 0.0f); // // Add arm motion trackers for able-bodied case. // if (experimentType == ExperimentType.TypeOne) { // Lower limb motion tracker GameObject llMotionTrackerGO = GameObject.FindGameObjectWithTag("ForearmTracker"); lowerArmTracker = new VIVETrackerManager(llMotionTrackerGO.transform); ExperimentSystem.AddSensor(lowerArmTracker); // Upper limb motion tracker GameObject ulMotionTrackerGO = AvatarSystem.AddMotionTracker(); upperArmTracker = new VIVETrackerManager(ulMotionTrackerGO.transform); ExperimentSystem.AddSensor(upperArmTracker); } else if (experimentType == ExperimentType.TypeTwo) { // Get active sensors from avatar system and get the vive tracker being used for the UA foreach (ISensor sensor in AvatarSystem.GetActiveSensors()) { if (sensor is VIVETrackerManager) { upperArmTracker = (VIVETrackerManager)sensor; } } if (upperArmTracker == null) { throw new System.NullReferenceException("The residual limb tracker was not found."); } // Set VIVE tracker and Linear synergy as active. // Get prosthesis prosthesisManagerGO = GameObject.FindGameObjectWithTag("ProsthesisManager"); elbowManager = prosthesisManagerGO.GetComponent <ConfigurableElbowManager>(); // Set the reference generator to linear synergy. elbowManager.ChangeSensor("VAL_SENSOR_VIVETRACKER"); elbowManager.ChangeReferenceGenerator("VAL_REFGEN_LINKINSYN"); // Create the personalisation algorithm object elbowManager.SetSynergy(theta); float[] ditherFrequency = { Mathf.PI / 4, 2 * Mathf.PI / 4 }; float[] observerGain = { 0.3840f, 0.6067f, -0.2273f, -0.8977f, -1.0302f }; float[][] A = new float[2][]; A[0] = new float[2] { 1.3130f, -0.8546f }; A[1] = new float[2] { 1.0f, 0.0f }; float[] B = { 1.0f, 0.0f }; float[] C = { 0.0131f, -0.0131f }; float D = 0.0f; personaliser = new TransCyberHPIPersonalisation(ditherAmplitude, 0, ditherFrequency, observerGain, 1, optimiserGain, 0.1f, A, B, C, D, theta, 0.1f, 3.0f); } if (evaluatorType == EvaluatorType.Compensation) { // Performance evaluation objects evaluator = new UpperBodyCompensationMotionPM(0.5f, 0.5f); shDataBuffer = new List <Vector3>(); c7DataBuffer = new List <Vector3>(); } else if (evaluatorType == EvaluatorType.KinematicEnergy) { throw new System.NotImplementedException("KE method not yet implemented"); } // Debug? if (!debug) { // Shoulder acromium head tracker GameObject motionTrackerGO1 = AvatarSystem.AddMotionTracker(); shoulderTracker = new VIVETrackerManager(motionTrackerGO1.transform); ExperimentSystem.AddSensor(shoulderTracker); // C7 tracker GameObject motionTrackerGO2 = AvatarSystem.AddMotionTracker(); c7Tracker = new VIVETrackerManager(motionTrackerGO2.transform); ExperimentSystem.AddSensor(c7Tracker); } // // Hand tracking sensor // GameObject handGO = GameObject.FindGameObjectWithTag("Hand"); handTracker = new VirtualPositionTracker(handGO.transform); ExperimentSystem.AddSensor(handTracker); // Spawn grid gridManager.SpawnGrid(gridRows, gridColumns, gridSpacing); }
/// <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 configuration // experimentType = ExperimentType.TypeOne; // Able-bodied experiment type if (debug) { ExperimentSystem.SetActiveExperimentID("GridReaching2019"); } // // Iterations configuration // // Make sure flow control is initialised sessionNumber = 1; iterationNumber = 1; // Set iterations variables for flow control. targetNumber = gridRows * gridColumns; iterationsPerSession[sessionNumber] = targetNumber * iterationsPerTarget; maxIterations = iterationsPerSession[sessionNumber] * sessions; // Create the list of target indexes and shuffle it. for (int i = 0; i < targetNumber; i++) { for (int j = 0; j < iterationsPerTarget; j++) { targetOrder.Add(i); } } targetOrder.Shuffle(); // // Initialize world positioning // // Get user physiological data. float subjectHeight = SaveSystem.ActiveUser.height; float subjectArmLength = SaveSystem.ActiveUser.upperArmLength + SaveSystem.ActiveUser.forearmLength + (SaveSystem.ActiveUser.handLength / 2); // Set the grid distance from subject gridManager.transform.position = new Vector3(0.0f, gridHeightMultiplier * subjectHeight, gridReachMultiplier * subjectArmLength); // // Create data loggers // motionLogger = new DataStreamLogger("Motion"); ExperimentSystem.AddExperimentLogger(motionLogger); // // Add arm and body motion trackers. // // Lower limb motion tracker GameObject llMotionTrackerGO = GameObject.FindGameObjectWithTag("ForearmTracker"); lowerArmTracker = new VIVETrackerManager(llMotionTrackerGO.transform); ExperimentSystem.AddSensor(lowerArmTracker); // Upper limb motion tracker GameObject ulMotionTrackerGO = AvatarSystem.AddMotionTracker(); upperArmTracker = new VIVETrackerManager(ulMotionTrackerGO.transform); ExperimentSystem.AddSensor(upperArmTracker); if (!debug) { // Shoulder acromium head tracker GameObject motionTrackerGO1 = AvatarSystem.AddMotionTracker(); VIVETrackerManager shoulderTracker = new VIVETrackerManager(motionTrackerGO1.transform); ExperimentSystem.AddSensor(shoulderTracker); // C7 tracker GameObject motionTrackerGO2 = AvatarSystem.AddMotionTracker(); VIVETrackerManager c7Tracker = new VIVETrackerManager(motionTrackerGO2.transform); ExperimentSystem.AddSensor(c7Tracker); } // // Hand tracking sensor // GameObject handGO = GameObject.FindGameObjectWithTag("Hand"); VirtualPositionTracker handTracker = new VirtualPositionTracker(handGO.transform); ExperimentSystem.AddSensor(handTracker); }
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 logData = taskTime.ToString(); // Read from all user sensors foreach (ISensor sensor in AvatarSystem.GetActiveSensors()) { float[] sensorData = sensor.GetAllProcessedData(); foreach (float element in sensorData) { logData += "," + element.ToString(); } } // Read from all experiment sensors foreach (ISensor sensor in ExperimentSystem.GetActiveSensors()) { float[] sensorData = sensor.GetAllProcessedData(); foreach (float element in sensorData) { logData += "," + element.ToString(); } } // // Append data to lists // taskTime += Time.fixedDeltaTime; // // Log current data // //motionLogger.AppendData(logData); // // 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 // //motionLogger.CloseLog(); // // Clear data management buffers // experimentState = ExperimentState.AnalizingResults; break; } break; default: break; } }
// 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"; } }
/// <summary> /// Initializes the ExperimentSystem and its components. /// Verifies that all components needed for the experiment are available. /// </summary> public override void InitialiseExperimentSystems() { // Check the experiment parameters if (startAngleList.Count <= 0 || endAngleList.Count <= 0 || movementTimeList.Count <= 0) { throw new System.Exception("An experiment configuration list is empty."); } if (startAngleList.Count != endAngleList.Count) { throw new System.Exception("The angle lists do not match in size."); } // // Set the experiment type and ID // if (AvatarSystem.AvatarType == AvatarType.AbleBodied) { // 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; //Debug.Log(wifiSensor.RunThread); udpSensor.StartSensorReading(); //Debug.Log(wifiSensor.RunThread); } } // Set whether emg or synergy based if (EMGAvailable) { experimentType = ExperimentType.TypeTwo; ExperimentSystem.SetActiveExperimentID("EMG_Data"); } else { if (debug) { // DEBUG ONLY experimentType = ExperimentType.TypeTwo; ExperimentSystem.SetActiveExperimentID("EMG_Data"); // DEBUG ONLY } else { throw new System.Exception("An EMG measurement device is required."); } } } else { throw new System.NotImplementedException(); } // // Create data loggers // motionLogger = new DataStreamLogger("Motion"); ExperimentSystem.AddExperimentLogger(motionLogger); // // Check and add experiment sensors // // // Add VIVE Trackers. // if (!debug) { GameObject motionTrackerGO = AvatarSystem.AddMotionTracker(); VIVETrackerManager upperArmTracker = new VIVETrackerManager(motionTrackerGO.transform); ExperimentSystem.AddSensor(upperArmTracker); // Shoulder acromium head tracker GameObject motionTrackerGO1 = AvatarSystem.AddMotionTracker(); VIVETrackerManager shoulderTracker = new VIVETrackerManager(motionTrackerGO1.transform); ExperimentSystem.AddSensor(shoulderTracker); // Set arm guide position tracking guideManager.shoulderLocationTransform = motionTrackerGO1.transform; } }
/// <summary> /// Initializes the ExperimentSystem and its components. /// Verifies that all components needed for the experiment are available. /// This must be done in Start. /// Extend this method by doing your own implementation, with base.InitExperimentSystem() being called at the start. /// </summary> public override void InitialiseExperimentSystems() { // Set data format taskDataFormat = ablebodiedDataFormat; // Lefty sign /* * if (SaveSystem.ActiveUser.lefty) * leftySign = -1.0f; */ // Audio audio = GetComponent <AudioSource>(); audio.clip = testAudioClip; #region Modify base // Then run the base initialisation which is needed, with a small modification // // Set the experiment name only when debugging. Take the name from the gameobject + Debug // if (debug) { ExperimentSystem.SetActiveExperimentID(this.gameObject.name + "_Debug"); } // Make sure flow control is initialised sessionNumber = 1; iterationNumber = 1; // // Create the default data loggers // taskDataLogger = new DataStreamLogger("TaskData/" + AvatarSystem.AvatarType.ToString()); ExperimentSystem.AddExperimentLogger(taskDataLogger); taskDataLogger.AddNewLogFile(sessionNumber, iterationNumber, taskDataFormat); // Add file // Send the player to the experiment centre position TeleportToStartPosition(); #endregion #region Initialize EMG sensors //Initialse Delsys EMG sensor delsysEMG.Init(); delsysEMG.Connect(); delsysEMG.StartAcquisition(); #endregion #region Initialize world positioning // Set the subject physiological data for grid gridManager.ConfigUserData(); gridManager.ConfigGridPositionFactors(gridCloseDistanceFactor, gridMidDistanceFactor, gridFarDistanceFactor, gridHeightFactor); #endregion #region Initialize motion sensors // // Add arm motion trackers for able-bodied case. // // Lower limb motion tracker GameObject llMotionTrackerGO = GameObject.FindGameObjectWithTag("ForearmTracker"); lowerArmTracker = new VIVETrackerManager(llMotionTrackerGO.transform); ExperimentSystem.AddSensor(lowerArmTracker); // Upper limb motion tracker GameObject ulMotionTrackerGO = AvatarSystem.AddMotionTracker(); upperArmTracker = new VIVETrackerManager(ulMotionTrackerGO.transform); ExperimentSystem.AddSensor(upperArmTracker); if (!debug) { // Shoulder acromium head tracker GameObject motionTrackerGO1 = AvatarSystem.AddMotionTracker(); shoulderTracker = new VIVETrackerManager(motionTrackerGO1.transform); ExperimentSystem.AddSensor(shoulderTracker); // C7 tracker GameObject motionTrackerGO2 = AvatarSystem.AddMotionTracker(); c7Tracker = new VIVETrackerManager(motionTrackerGO2.transform); ExperimentSystem.AddSensor(c7Tracker); } // // Hand tracking sensor // GameObject handGO = GameObject.FindGameObjectWithTag("Hand"); handTracker = new VirtualPositionTracker(handGO.transform); ExperimentSystem.AddSensor(handTracker); #endregion }
/// <summary> /// Checks that all the required components have been loaded and starts experiment. /// </summary> public void InitialiseExperiment() { bool EMGAvailable = false; switch (experimentNumber) { case NONE: // Check that a valid experiment has been selected logManager.DisplayInformationOnLog(3.0f, "Please select a valid experiment."); break; // // Jacobian synergy experiment // case JACOBIAN_SYNERGY: // Able-bodied case if (optionNumber == 1 && AvatarSystem.AvatarType == AvatarType.AbleBodied) { KeepOnLoad(); // Load experiment. SteamVR_LoadLevel.Begin("JacobianSynergyExperiment"); } // EMG case else if (optionNumber == 2 && AvatarSystem.AvatarType == AvatarType.Transhumeral) { // Check that an EMG sensor is available EMGAvailable = false; foreach (ISensor sensor in AvatarSystem.GetActiveSensors()) { if (sensor.GetSensorType().Equals(SensorType.EMGWiFi)) { EMGAvailable = true; } else if (sensor.GetSensorType().Equals(SensorType.ThalmicMyo)) { EMGAvailable = true; } } // Load when EMG is available. if (EMGAvailable) { KeepOnLoad(); // Load experiment. //SteamVR_LoadLevel.Begin("JacobianSynergyExperiment"); // Load training SteamVR_LoadLevel.Begin("ProsthesisTraining"); } else { logManager.DisplayInformationOnLog(3.0f, "Please add and configure an EMG sensor."); } } // Synergy case else if ((optionNumber == 3 || optionNumber == 4) && AvatarSystem.AvatarType == AvatarType.Transhumeral) { KeepOnLoad(); // Load experiment. // SteamVR_LoadLevel.Begin("JacobianSynergyExperiment"); GameObject prosthesisManagerGO = GameObject.FindGameObjectWithTag("ProsthesisManager"); ConfigurableElbowManager elbowManager = prosthesisManagerGO.GetComponent <ConfigurableElbowManager>(); if (optionNumber == 3) { // Set VIVE tracker and Jacobian synergy as active. // Get prosthesis prosthesisManagerGO = GameObject.FindGameObjectWithTag("ProsthesisManager"); elbowManager = prosthesisManagerGO.GetComponent <ConfigurableElbowManager>(); // Set the reference generator to jacobian-based. elbowManager.ChangeSensor("VAL_SENSOR_VIVETRACKER"); elbowManager.ChangeReferenceGenerator("VAL_REFGEN_JACOBIANSYN"); } else if (optionNumber == 4) { // Set VIVE tracker and Linear synergy as active. // Get prosthesis prosthesisManagerGO = GameObject.FindGameObjectWithTag("ProsthesisManager"); elbowManager = prosthesisManagerGO.GetComponent <ConfigurableElbowManager>(); // Set the reference generator to linear synergy. elbowManager.ChangeSensor("VAL_SENSOR_VIVETRACKER"); elbowManager.ChangeReferenceGenerator("VAL_REFGEN_LINKINSYN"); } // Load training SteamVR_LoadLevel.Begin("ProsthesisTraining"); // Load experiment. //SteamVR_LoadLevel.Begin("JacobianSynergyExperiment"); } else { logManager.DisplayInformationOnLog(3.0f, "Please configure the " + optionList[optionNumber] + " avatar."); } break; case FEEDBACK2019: // Check that a transradial prosthesis has been set. if (AvatarSystem.AvatarType != AvatarType.Transradial) { logManager.DisplayInformationOnLog(3.0f, "Please configure the Transradial avatar."); } else { // Initialise the prosthesis try { GameObject prosthesisManagerGO = GameObject.FindGameObjectWithTag("ProsthesisManager"); FakeEMGBoniHand prosthesisManager = prosthesisManagerGO.GetComponent <FakeEMGBoniHand>(); prosthesisManager.InitializeProsthesis(); // Set the name from the selected dropdown! ExperimentSystem.SetActiveExperimentID("Feedback2019"); } catch (Exception e) { logManager.DisplayInformationOnLog(10.0f, "Error encountered: " + e.Message); } } break; // // // case EMG_DATA: // Check that an EMG sensor is available EMGAvailable = false; foreach (ISensor sensor in AvatarSystem.GetActiveSensors()) { if (sensor.GetSensorType().Equals(SensorType.EMGWiFi)) { EMGAvailable = true; } } // Load when EMG is available. if (EMGAvailable) { KeepOnLoad(); // Load experiment. SteamVR_LoadLevel.Begin("EMGShoulderData"); } else { logManager.DisplayInformationOnLog(3.0f, "Please add and configure an EMG sensor."); } break; } }