SteamVR and NoloVR on iOS

I am the author of the iOS SteamVR HMD software, iVRy. I have been trying for weeks to make contact with this company so that I can add native NoloVR support to my software, with no luck. Is this company still in business? Does anyone have any idea how to get them to respond? The best I've got is some kind of "we'll get back to you" via the Facebook page, but no actual contact from the company itself. I have many users of my software asking for NoloVR tracking support, but without getting the hardware and some kind of SDK, it's obviously impossible...

Comments

Gonna have to do this without input from NoloVR (or hardware!). I don't want to ship Nolo DLLs with my SteamVR driver (it's a lot of bloat for a small number of users). So, are the libzmq.dll and noloRuntime.dll files installed anywhere on a NoloVR end-user's system?

@hettylool Thanks for making contact. Apparently a dev kit has been sent out to me, so I'm going to put this on hold until I get that. I've had a look at your changes to the OSVR driver and I do have some questions about that. Where is the best place to ask you those questions?

1) Why do you use "busy waiting" in your thread that reads from the NoloVR hardware? Is there no method available in your runtime to get callbacks or notifications when new position data is available?2) What are you trying to achieve with your "double click menu button" code? A "recenter" type operation?

@hettylool I'm going to quote your reply here, as I believe this is the place to have this conversation, not via email or on an issue tracker for a source code repository.

"1.Currently, there is no calllbacks method,but you can get all data from the method like "get_Nolo_LeftControllerData" in your thread.maybe callbacks is the best way,and we will add it in the future.2.we want to add some method belong us,we want double system to reset headset marker's yaw.double click menu to turn around in steamVR.3.yes,We started doing OSVR this last year,we also think this is a old version.and Next step,we want OSVR doing this things by OSVR,not us.thank you for your suppot"

@hettylool 1) This is a fundamental design flaw in your solution. Effectively you are tying up 1 core of the CPU permanently with "busy waiting". At the very least you should be sleeping on that thread (using the minimum possible time to take a position sample from the hardware).

Are you able to provide documentation on how your runtime talks to ZeroMQ (ie. the protocol)? It seems a better solution (for high performance PC applications) would be to eliminate your runtime and talk directly to the hardware.

I am not happy to put any code into my driver which will degrade its performance, so we need to find a way around this (1) design flaw.

@hettylool Thanks! No requirements, other than that it is called at the soonest moment when new position data is available. This will allow the app/driver to keep an optimal code path (ie. no polling/waiting necessary).

@hettylool The biggest goal in VR is to keep the latency to the *absolute* minimum. The only way to achieve this is if *every* part of the motion->photon path is optimal. We need to keep the entire motion->photon path to less than 20ms. We don't want to wait even 1 nanosecond from when the tracking hardware has resolved a position to when it passes it to the driver/app, as there are *many* steps that need to come after this...

@hettylool Ok, I looked at the SDK, and it seems that the callbacks added should be sufficient, thanks. I cannot test anything at this stage, so we'll have to wait until the hardware arrives with me. I spoke with the person doing the FB page and they told me they haven't received tracking information from the courier yet. I'm not sure how long these things take, but by my understanding the hardware was sent 2 weeks (or more) ago.

@hettylool A big design problem with the SDK is how callbacks are done (in general). The standard way that callbacks are done in modern software is to use the following pattern:

typedef void(*callbackFn)(void* context);

void registerCallback(callbackFn callback, void *context);

This allows the code being called back to provide a pointer (for example to a C++ object) so that there isn't a need for global variables (which are generally a *very bad* idea in modern code). If you had done this in the SDK, you would have been able to avoid the scenario you have at the moment of global flag variables in the OSVR driver.

So, in order for the SDK to be usable in professional, production code written outside of Nolo, you will need to add this functionality to the SDK.

@hettylool Another issue with the SDK is that it isn't easy to remove link-time dependencies on the SDK. For instance, I won't make a special driver version for NoloVR, but instead, at run-time I will check for the presence of NoloVR libraries and load them if they're present. I don't want to ship Nolo libraries with my product (as most users won't have NoloVR), nor use hard-coded paths to the libraries.

At the moment, I will develop test versions of my driver using a hard-coded path for the NoloVR DLLs. I won't ship a product like this, nor will I introduce dependencies or 'bloat' to my driver (and I suspect neither will any other serious VR developers).

So, (easiest) the Nolo installer writes a value to the registry containing the path to the NoloVR DLLs. The driver/app queries the registry, finds the path of the driver and then loads it. Afterwards it can do detection checks to determine if Nolo hardware is actually attached.

In any case, this will be better for you, as you really only want 1 copy of a Nolo DLL on the system (the copy the user installed with the driver). You don't want to be in the situation where you have each app having a different version of the Nolo DLL, none of which match the version installed with the (latest version of) the driver.

I went ahead and integrated the SDK into my driver without the callback functions, as I wanted to see the hardware in action (and not in the box!).

In the first test version of the driver, I'm reading the Nolo data whenever I get a motion update from the HMD sensors, and then "fusing" the Nolo position data with the headset's rotational data. This works well, but obviously isn't optimal, as the timing of the headset sensor data is not matched to the sample frequency of the Nolo hardware.

So that I can continue work on the integration, I've implemented a simulator for the HMD data callback. In the simulator the driver reads the NoloVR hardware at 100Hz, and calls the callback with data. This is just for testing, the release version of the driver that has Nolo support will check for the presence of the noloDataNotify_FuncCallBack() export and fall back to the first method above if it's not available.

I've put all of the NoloVR integration into a C++ class that hides all of the details of the Nolo SDK, and will scan the user's hard drives for the location of the Nolo libraries (for now) and load them dynamically. I will probably need to do a USB device check to see if the Nolo hardware is attached so that I can avoid looking for the libraries on a system that doesn't have NoloVR.

I expect that I will release the new version of the iVRy driver with NoloVR support in the next few days, and will update it with new versions of the Nolo SDK when they become available. It seems that the driver will need to maintain (at least until Nolo reaches 1.0) backwards compatibility with earlier SDK versions, to give users the option to choose whichever NoloVR driver version works for them.