OSVR / OSVR-Leap-Motion

OSVR Leap Motion plugin
Apache License 2.0
18 stars 14 forks source link

Incorrect analog values #9

Open zachkinstner opened 9 years ago

zachkinstner commented 9 years ago

The analog values being sent through OSVR to Unity are incorrect. The behavior that I see is that all analog channels report the same value. My test Unity client obtains analog values each frame via AnalogInterface.GetState().Value.

Fortunately, there's a good clue. The last value in the device plugin's analog list happens to be a rather distinct/recognizable number (a "palm width" value). It's this value that all analog channels report in Unity.

I can reproduce this, to a certain extent, with AnalogCallback_cpp.exe. In my local build, I have mapped semantic/arms/right/hand/grabStrength to the /controller/left/trigger alias. I would expect to only see that "grabStrength" value in the AnalogCallback_cpp.exe output. However, the output shows all the analog values. I suspect that, somehow, all the analog values are being sent to each channel, and the last value (the "palm width" in this scenario) is the one that gets sent to Unity.

I'm currently using OSVR-Core-Snapshot-v0.2-772-gdf65c03-build155-vs12-32bit and OSVR-Unity-v0.2-122-g2ff3c40-with-core-v0.2-772-gdf65c03-build193. The device plugin sends the list of analog values via osvrDeviceAnalogSetValues().

zachkinstner commented 9 years ago

The behavior is the same if the device plugin sends the analog values individually (in a loop) using osvrDeviceAnalogSetValue().

Within the device plugin, I can confirm the list of analog values is correct via this debugging output.

The analog values were working correctly prior to my latest OSVR upgrade. I was previously using OSVR-Core-Snapshot-v0.2-705-g533991b-build147-vs12-32bit and the corresponding Unity client. My test client was successfully using/testing the analog values by connecting the "grabStrength" value to the scale of the boxes in the scene.

zachkinstner commented 9 years ago

Running some quick tests. The issue occurs in:

This indicates that the issue started between v0.2-705 and v0.2-730. The download page doesn't have any builds available between these two.

I'm testing by dropping a com_osvr_LeapMotion.dll file (taken from either my old 705-based build or the latest 772-based build) into these other OSVR versions, then watching the output of AnalogCallback_cpp.exe. Just mentioning this here, since I'm not 100% sure that this is a valid way to test.

gfrolov commented 9 years ago

@zachkinstner, I was able to partially reproduce the issue that you described. I tested with the plugin as is under the following scenarios

  1. I subscribed AnalogCallback_cpp to /com_osvr_LeapMotion/Controller/analog which resolved to just analog interface for LeapMotion. The plugin was setting all analog values using osvrDeviceAnalogSetValues. Client received all values printed out and they matched the ones that plugin was sending, which is expected
  2. I subscribed AnalogCallback_cpp to /com_osvr_LeapMotion/Controller/analog which resolved to just analog interface for LeapMotion. The plugin was setting only one analog value via osvrDeviceAnalogSetValue and client received correct value for that channel and 0's for the rest of them (expected).
  3. I subscribed to /controller/trigger/left which resolved to /analog/0. The plugin was setting all analog values using osvrDeviceAnalogSetValues. Client received all values despite being subscribed to just one sensor. This is a bug that I fixed now.
  4. I subscribed to /controller/trigger/left which resolved to /analog/0. The plugin was setting one analog value using osvrDeviceAnalogSetValue. Client got the report only for that one sensor as expected.

I did not see the issue with all sensors reporting the same values though. Given that there was a bug that I discovered in scenario 3, I think that was the source of invalid data that you were seeing, so give it a go with an updated OSVR-Core. One thing to note is when you subscribe client to a certain path, you should verify that aliases resolve properly for that path by running osvr_print_tree. For my tests, here is partial output from osvr_print_tree that verified that I was subscribed to one sensor [ AliasElement] /controller/left/trigger -> /com_osvr_LeapMotion/Controller/analog/0

zachkinstner commented 9 years ago

Using OSVR-Core-Snapshot-v0.2-830-g2cde03b-build159-vs12-32bit, and configuring the Leap Motion plugin with this alias...

"/controller/left/trigger": "semantic/arms/left/hand/grabStrength"

...produces AnalogCallback_cpp.exe output like this:

Got report: channel is 0.573693
Got report: channel is 0
Got report: channel is 0
Got report: channel is 1
Got report: channel is 1
Got report: channel is 1
Got report: channel is 0
Got report: channel is 0.578858
Got report: channel is 0
Got report: channel is 0
Got report: channel is 1
Got report: channel is 1
Got report: channel is 1
Got report: channel is 0
Got report: channel is 0.586115
Got report: channel is 0
Got report: channel is 0
Got report: channel is 1
Got report: channel is 1
Got report: channel is 1
Got report: channel is 0
Got report: channel is 0.587469
Got report: channel is 0
Got report: channel is 0
Got report: channel is 1
Got report: channel is 1
Got report: channel is 1
Got report: channel is 0
Got report: channel is 0.489931
Got report: channel is 0
Got report: channel is 0
Got report: channel is 1
Got report: channel is 1
Got report: channel is 1
Got report: channel is 0

For this testing scenario, the fractional values like 0.586114 are are expected for the grabStrength channel, but not the 0 and 1 values.

That said, the issue is resolved within my Unity test scene. It now receives the expected values for each channel, instead of all channels receiving the same value. From the perspective of this Leap Motion plugin work, this was the more important part of the fix.

zachkinstner commented 9 years ago

Note: commit https://github.com/OSVR/OSVR-Leap-Motion/commit/b7c3bb1b32715cc7b76b4cc992e2593ee1560113 fixes an analog issue within the Leap Motion plugin, occurring when when both hands are in use. The output shown in my previous comment is not affected by this code change.