immersivecognition / unity-experiment-framework

UXF - Framework for creating human behaviour experiments in Unity
https://immersivecognition.github.io/unity-experiment-framework/
MIT License
214 stars 41 forks source link

Using UXF while stopping and starting Unity between trials #134

Open A-Ivan opened 2 years ago

A-Ivan commented 2 years ago

In my particular experiment I need to stop/start SteamVR and Unity between each trial, which resets the UXF session each time.

What would be the best way to run a study using UXF to control my experiment (block/trial order, data export, etc. without intervention from the experimenter) in this case? Is there already something in UXF which already takes care of this?

Not sure if this would be the best solution but I'm thinking of creating a csv file which contains the block order currently used, the number of trials in each block, and the block and trial the experiment was last stopped at. This csv file would then need to be read when creating the session in UXF and saved after each trial.

Thank you.

jackbrookes commented 2 years ago

Hi, What is the reason for needing to stop/start SteamVR and Unity between each trial? It seems like it would be much better to temporarily disable the Camera rig then enable it when you need it again with a button press, etc.

A-Ivan commented 2 years ago

Hi Jack.

I am using an HTC Vive Pro with a wireless adapter and vive trackers on the participant during the study. For some reason there are issues with vive correctly keeping track of the trackers and controllers over time and also to not waste so much battery from the wireless HMD (which only lasts a few hours), as the time in VR is much less than the time the participant requires to answer surveys and interview questions, I decided to reset SteamVR and Unity between trials. If I simply turn off the battery from the HMD the controllers or trackers stop working, having to restart trials and deleting this data is more difficult than simply resetting SteamVR and Unity each time.

jackbrookes commented 2 years ago

Hi, I had this exact scenario in one of my studies. I had no problem disconnecting and reconnecting the VR HMD to swap batteries / controllers. Seems like an issue with your setup? With SteamVR 2.0+ you can assign controllers/trackers to specific roles, (left hand, right foot, etc) which they will re-attach to once they reconnect.

If you cannot get around this, you will need to write a more complicated system to start trial 1 on first run, trial 2 on second run, etc.

A-Ivan commented 2 years ago

Interesting. I'm also using 4 base stations, but this should not be the problem.

When you swapped batteries (which would require you to turn off the battery, which is where my problem occurs), did you have any problems with SteamVR 2.0+ recognizing everything again and accepting inputs, specifically the VR controllers?

Sometimes turning off the battery, while having SteamVR and Unity running, would also cause Unity to crash (I'm using the newest version of SteamVR and Unity 2020.3.x) when the battery was reconnected. Did you ever have this problem?

I will do some more tests but if I can't get it to work I may have to create that system to keep track of trials.

JashoBell commented 2 years ago

Hi Jack.

I am using an HTC Vive Pro with a wireless adapter and vive trackers on the participant during the study. For some reason there are issues with vive correctly keeping track of the trackers and controllers over time and also to not waste so much battery from the wireless HMD (which only lasts a few hours), as the time in VR is much less than the time the participant requires to answer surveys and interview questions, I decided to reset SteamVR and Unity between trials. If I simply turn off the battery from the HMD the controllers or trackers stop working, having to restart trials and deleting this data is more difficult than simply resetting SteamVR and Unity each time.

Hi,

By "having trouble keeping track", do you mean the tracking universe seems to drift, or do you mean that reconnecting the controllers/trackers ends up putting them into a different index? I've had trouble with both, and ended up solving them by:

  1. Holding the tracking universe in place with two Vive trackers at known physical locations
  2. Using serial number to assign trackers to specific gameobjects.

I have working scripts for both solutions if they would be helpful, I'm not sure if they'd be plug-and-play for your situation, though.

A-Ivan commented 2 years ago

Hi @JashoBell,

I actually have 3 issues, one of which you mentioned.

The first issue is that the controllers and trackers get put into different indexes. The solution you mentioned to use serial numbers to assign trackers would be really great to have. If you could share this I would really appreciate it. This is an annoying problem that I haven't been able to solve yet, even when assigning the tracker a role in SteamVR and setting that role in the Steam_VR_Behaviour_Pose script (see here for details), this issue still occurs.

The second issue I have is that one of the VR controllers sometimes are not tracked anymore, this might be because of the first issue, maybe the device number got switched with the or with a base station. Solving the first issue might solve this.

The third issue, unrelated to tracking but you may have encountered it is that the HMD randomly goes dark/turns off the display. The HMD is still tracked, as it still moves the virtual camera in Unity and SteamVR can see it, but the display turns off so the user is not able to see anything, so I have to take out the wireless adapter battery and reset SteamVR. The strange thing is that this only occurs when using the wireless adapter, if I connect everything to the computer there is no issue with the display. When I checked online others have also had this problem, so it may be a specific issue with the Vive wireless adapter (this problem does not seem to occur when using the Vive Focus 3 with Wi-Fi streaming, for instance).

Concerning the tracking drift problem you mentioned, did this only occur when having the VR setup/experience continuously running for a specific amount of time? My studies are relatively short but I am looking to running longer ones in the future, so I am wondering if I may have this problem later on.

Thank you.

JashoBell commented 2 years ago

Hi @JashoBell,

I actually have 3 issues, one of which you mentioned.

The first issue is that the controllers and trackers get put into different indexes. The solution you mentioned to use serial numbers to assign trackers would be really great to have. If you could share this I would really appreciate it. This is an annoying problem that I haven't been able to solve yet, even when assigning the tracker a role in SteamVR and setting that role in the Steam_VR_Behaviour_Pose script (see here for details), this issue still occurs.

The second issue I have is that one of the VR controllers sometimes are not tracked anymore, this might be because of the first issue, maybe the device number got switched with the or with a base station. Solving the first issue might solve this.

The third issue, unrelated to tracking but you may have encountered it is that the HMD randomly goes dark/turns off the display. The HMD is still tracked, as it still moves the virtual camera in Unity and SteamVR can see it, but the display turns off so the user is not able to see anything, so I have to take out the wireless adapter battery and reset SteamVR. The strange thing is that this only occurs when using the wireless adapter, if I connect everything to the computer there is no issue with the display. When I checked online others have also had this problem, so it may be a specific issue with the Vive wireless adapter (this problem does not seem to occur when using the Vive Focus 3 with Wi-Fi streaming, for instance).

Concerning the tracking drift problem you mentioned, did this only occur when having the VR setup/experience continuously running for a specific amount of time? My studies are relatively short but I am looking to running longer ones in the future, so I am wondering if I may have this problem later on.

Thank you.

Hi @A-Ivan,

Sure thing! After I responded yesterday I uploaded the script here. I originally found it in another repo that seems to be gone now. I just use this like I would the standard SteamVRTrackedObject with the addition of setting an SN.

1 + 2. I’m not sure, but I think these issues are related. SteamVR behaves strangely when it comes to assigning controllers and trackers to indexes, and it always seems to attempt to fill the “controller” indexes immediately after a controller drops by pulling one of the other connected trackers (seemingly at random) to the controller’s index. Sometimes I feel like it will shuffle the indexes randomly, shortly after your project connects to them for the first time after starting SteamVR. I haven’t run into any issues since using the serial number to assign them to gameobjects directly. One issue I do sometimes have is that the Vive controller’s inputs will occasionally not be responsive, but this only happens

  1. I am not sure about this one, it does sound like a connectivity issue, like a cheaper 10m usb cable extension failing to keep up with the data.

The drift issue happens from the beginning for me. It is primarily a nuisance because I’m doing object interaction/tool-use/motor learning work with an untracked object (a table) and sometimes trackers that have a different universe (infrared LED trackers). Thus, even small misalignment can be immersion-breaking and alter movement characteristics. I am running another study (~30-45m in VR) where precision isn’t as important and it isn’t as noticeable.

If you need to restart Unity between blocks/trials, you may find it helpful to generate the trials using a predetermined order based on participant number, then ask for a start trial/block when you begin the study, delete the earlier trials/blocks and just increment the session each time you need to restart. This is what I'm doing to handle unexpected crashes for my dissertation work. It required a bit of restructuring work outside of that for me but might be a good starting point.

public void ChangeStartingPoint(Session session) 
    {
        int startBlock = Convert.ToInt32(session.participantDetails["startblock"]);
        int startTrial = Convert.ToInt32(session.participantDetails["starttrial"]);
        session.blocks.RemoveAll(x => x.number < startBlock);
        foreach(Block i in session.blocks)
        {
            UXF.Utilities.UXFDebugLog("block " + i.number + " is " + i.settings.GetString("task"));
            if(i.number == 1 & startTrial > 1)
            {
                i.trials.RemoveAll(t => t.numberInBlock < startTrial);
                UXF.Utilities.UXFDebugLog("block " + i.number + " contains " + i.trials.Count);
            }
        }
    }

Hope this was helpful, Josh