SteamVR and NoloVR on iOS

edited June 2017 in Developers
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...

iVRy on the App Store:



  • edited June 2017
    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?

  • Yes, both files are in the NOLO drivers folder. (Default to C:\Program Files\LYRobotix\NOLO_driver_for_windows)

    You can install the drivers on you PC without the NOLO hardware if you want to test your implementation.
  • hi,I am the Engineer of NOLO.

    you can find all SDK in

    and my email is

    you can also take the message in github issue.
  • @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?
  • hi
    the best place maybe github or email or other way you would like

  • @hettylool Here is good for me... :)

    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 3) What version of the OSVR SteamVR driver is your modification based on? It looks like a much older (perhaps from last year) version of the driver.
  • @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.
  • 3) You will need to open-source your runtime or provide documentation on your ZeroMQ protocol before you can expect serious driver developers to take on integration work for you.
  • iVRy
    Okey,i have understand your demand, and i will talk to my colleague. 
  • @hettylool Thanks, in "serious" VR implementations, there cannot be any code path which is less than optimal. We do not have spare CPU cycles to waste. Every nanosecond counts... :wink: 
  • iVRy

    hi, my colleague has update the OSVR-driver please check it.
  • edited July 2017
    @hettylool Thank you for the update.

    Are you able to provide documentation on how your runtime talks to ZeroMQ (ie. the protocol)?

    I want to bypass your runtime, it is not efficient design or optimal code.

    Your colleague's code changes are a minor refactor, doesn't really change anything...
  • @iVRy why not optimize their code then implement that in your code? Everyone wins if you are going to do that effort anyway.
  • edited July 2017
    @bigelowed I don't have the code for their runtime. It's the runtime that requires "busy waiting", which is an extremely inefficient programming method that should have died long before DOS did... :/

    I'm looking for the (ZeroMQ) protocol info so that I can re-implement the runtime myself.

    The refactor in the OSVR driver was moving some stuff out of "static globals", which is another programming style that should have died with BASIC. :open_mouth: 
  • @hettylool Maybe I can help whoever is working on the runtime to fix this issue?
  • iVRy

    we will not provide the ZMQ protocol,and we still use our runtime to docking.
    OSVR,Trinus and other all use this runtime.
    it is our rule.and we will perfect and  Long-term maintenance this runtime.
  • @hettylool Understood. What are the chances of getting a callback added to the API so that the client (driver/app/whatever) can be implemented optimally?

  • ok,
    we will add a callback.test and put it tomorrow.
    Do you have any requirements for this callback?
  • @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... :smile: 
  • hi, my colleague, has do it last Thursday.
    please check
  • @hettylool Thanks! What am I checking? The SDK? Unfortunately, I still don't have hardware, and no idea when I will get it...
  • @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 Hardware arrived today, so will start working on this ASAP. Thanks! :smile: 
  • edited July 2017
    @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.

    Here is what you would need to change:

        typedef void(__cdecl *noloData_FuncCallBackNotify)(NoloData _noloData, void* context);
        typedef void(__cdecl *expandMsg_FuncCallBack)(ExpandMsgType expandMsgType, void* context);
        typedef void(__cdecl *funcCallBack)(void* context);

    However, as you probably don't want to break source/binary compatibility with existing apps/drivers, you will need to add these to your SDK:

        typedef void(__cdecl *noloData_FuncCallBackNotifyEx)(NoloData _noloData, void* context);
        typedef void(__cdecl *expandMsg_FuncCallBackEx)(ExpandMsgType expandMsgType, void* context);
        typedef void(__cdecl *funcCallBackEx)(void* context);

        NOLO_API  bool _cdecl disConnect_FunCallBackEx(funcCallBackEx fun, void* context);
        NOLO_API  bool _cdecl connectSuccess_FunCallBackEx(funcCallBackEx fun, void* context);

        NOLO_API  bool _cdecl expandDataNotify_FuncCallBackEx(expandMsg_FuncCallBackEx fun, void* context);
        NOLO_API  bool _cdecl noloDataNotify_FuncCallBackEx(noloData_FuncCallBackNotifyEx fun, void* context);

    The context (which can be NULL) passed to the callback would be the context passed to the function that registers the callback eg.

    class Object
        bool _connected;

        static void connectCallback(void *context)
            Object *that = reinterpret_cast<Object*>(context);
            that->_connected = true;

            _connected = false;
            connectSuccess_FunCallBackEx(connectCallback, this);

  • edited July 2017
    @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.

  • @hettylool Actually I can't use this SDK at all. It does not (in the current 0.7 version on Github) export the noloDataNotify_FuncCallBack(), although it does export expandDataNotify_FuncCallBack().

    Please let me know when you have a working version (ie. DLL matches header files) of the SDK and I will resume my work.


  • 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.
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!