Forum Discussion
vertigo5
11 years agoHonored Guest
Oculus Rift slows down Serial Communication in Unity
Hi Everybody,
I am working on a project which includes Oculus Rift & Arduino on Unity.
I am using simple Serial communication to read values from the Arduino and affect certain parameters in Unity.
Without the Oculus, The scene works fast and I can read values from the Arduino without almost any lag.
The Problem:
When I connect the Oculus, the serial communication is drastically slower, and basically unusable.
I am not very familiar with the inner workings of the Unity/Oculus integration,
so any tips or ideas on how to solve this would be very appreciated!
Thanks,
vertigo5.
I am working on a project which includes Oculus Rift & Arduino on Unity.
I am using simple Serial communication to read values from the Arduino and affect certain parameters in Unity.
Without the Oculus, The scene works fast and I can read values from the Arduino without almost any lag.
The Problem:
When I connect the Oculus, the serial communication is drastically slower, and basically unusable.
I am not very familiar with the inner workings of the Unity/Oculus integration,
so any tips or ideas on how to solve this would be very appreciated!
Thanks,
vertigo5.
9 Replies
Replies have been turned off for this discussion
- vrdavebOculus StaffIt's possible that the USB hub is getting congested. Can you try putting the Arduino on a different hub from the DK1?
- diablosv21Honored GuestSerial communication in Unity is actually pretty annoying, but the Rift shouldn't have any effect on the performance of it. What method are you using to read in your serial data? A few of them don't work very well.
The best solution I've found is to just run a loop in a new thread to read in the serial data asynchronously and use some kind of buffer to use the data in the usual game thread (Update, LateUpdate, etc). - vrdavebOculus StaffGood to hear it's working to get your Arduino data from another thread.
"diablosv21" wrote:
What method are you using to read in your serial data? A few of them don't work very well.
The Rift is a HID device. It should be pretty light on bandwidth. We get its pose from standard axes and use a variety of feature reports to get and set other information. - vertigo5Honored Guest
"diablosv21" wrote:
What method are you using to read in your serial data? A few of them don't work very well.
Currently I am doing everything in Update, boiled down to the essence my code looks something like this:
void Update () {
if (serial.IsOpen) {
try
{
strIn = serial.ReadLine();
// do stuff with data
}
catch (System.Exception) {
}
}
}
"diablosv21" wrote:
The best solution I've found is to just run a loop in a new thread to read in the serial data asynchronously and use some kind of buffer to use the data in the usual game thread (Update, LateUpdate, etc).
Could you please further elaborate on this? I would really like to try this out.
Thanks!
vertigo5 - moltonExplorersomething like this
...
using System.Threading
public void Start()
{
Thread myThread = new Thread(new ThreadStart(ThreadWorker));
mythread.Start();
}
void ThreadWorker
{
//do your work in here, but don't try to access the Unity API in any way
} - diablosv21Honored Guest^^ What molton said.
The method you are using right now is quite problematic. Basically, when you call serial.ReadLine() it will block the thread until it can read a full line of data. This means if your data was only coming through at 20 lines per second your game would be limited to 20 frames per second.
On the flip side, if you data is coming through at higher than 60 lines per second, when V-sync locks your game to 60 frames per second your data will very quickly fall behind, as it's only able to read 60 lines, so the extra lines are processed in the next second.
Lets say your data is coming in at 100 lines per second, you would only get 60 of them in the first second, leaving the other 40 to be read in the next second, so then you only get 20 more of them and it just keeps getting worse.
You might have already discovered that you can't get around this issue by using serial.ReadExisting(), as for some reason it just doesn't work.
So, in the reader thread you create you can basically just put a while loop which constantly calls serial.ReadLine(), and puts the data somewhere it can be accessed in your Update loop. So for example if it is sensor data you might only want to process the last read of data so you could just hold it in a string class variable which you process in the Update method. Just make sure you have a nice way of closing the reader thread when the app closes or you no longer need it. - vertigo5Honored GuestYes it works! Thanks for all the help!! :D
The only thing I'm still not sure about is if I'm closing the Thread correctly.
I ended up using this code, does it make sense?void Update () {
if (strIn.Length >= 6) {
// do stuff with data
}
}
void ThreadWorker ()
{
while(shouldExit == false) {
if (serial.IsOpen) {
try
{
strIn = serial.ReadLine();
}
catch (System.Exception) {
}
}
}
}
void OnApplicationQuit() {
serial.Close();
shouldExit = true;
} - moltonExplorerLooks good I think, I wasn't sure but I found this
http://msdn.microsoft.com/en-us/library/aa645740%28v=vs.71%29.aspxExample 1: Creating, starting, and interacting between threads
This example demonstrates how to create and start a thread, and shows the interaction between two threads running simultaneously within the same process. Note that you don't have to stop or free the thread. This is done automatically by the .NET Framework common language runtime. - diablosv21Honored Guest
"molton" wrote:
Looks good I think, I wasn't sure but I found this
http://msdn.microsoft.com/en-us/library/aa645740%28v=vs.71%29.aspxExample 1: Creating, starting, and interacting between threads
This example demonstrates how to create and start a thread, and shows the interaction between two threads running simultaneously within the same process. Note that you don't have to stop or free the thread. This is done automatically by the .NET Framework common language runtime.
While true, unfortunately it doesn't apply in Unity while using the editor. Because Unity launches your game as part of it's own process it will also keep any threads you started alive after you try to stop your game unless you explicitly close them.
I use OnApplicationQuit as well, works a treat.
Quick Links
- Horizon Developer Support
- Quest User Forums
- Troubleshooting Forum for problems with a game or app
- Quest Support for problems with your device
Other Meta Support
Related Content
- 7 months ago