Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auto-Repeat Intervall -> doesn't return to zero? #108

Closed
AndunHH opened this issue Jun 30, 2024 · 10 comments
Closed

Auto-Repeat Intervall -> doesn't return to zero? #108

AndunHH opened this issue Jun 30, 2024 · 10 comments

Comments

@AndunHH
Copy link

AndunHH commented Jun 30, 2024

Here is an issue from the DIY spacemouse again.

I found the problem, that in FreeCAD the model is stop moving, when the spacemouse is off-centered hold still.
A quick and dirty solution is toggle the last digit with every reported event, which actually works.

But I read through the docs and issues here and found #87 with all referenced issues.

When I start the spacenav daemon, open a new model in freecad and don't touch the mouse: the model stays still.
When I use the mouse: the model moves.
When I let go of the mouse: The model still moves, because the auto-repeat seems to repeat the last input. Even though the mouse is actually reporting zero values. (I can debug the sent values in our DIY approach and we use a proper deadzone filtering)

Is it possible that the deadzone detection in the auto-repeat mechanism is buggy with the consequence, that the mouse is not returning to zero, but is always auto-repeating the last non-zero values?
Do I need to configure more dead-zone values in the config file to get the correct behavior?

I'm using:

  • libspnav lasted git version from June, 3 2024
  • spacenavd Release 1.3
  • spnavcg didn't compile, due to the same issue as in #43, therefore I created the /etc/spnavrc file with the only line uncommented repeat-intervall = 250

For completeness, here to output of the log file

Spacenav daemon v1.3
reading config file: /etc/spnavrc
found usb device [256f:c631]: "3Dconnexion SpaceMouse Pro Wireless (cabled)" (/dev/input/event19) 
adding device (id: 0).
device name: 3Dconnexion SpaceMouse Pro Wireless (cabled)
  Number of axes: 6 (6a 0r)
Device 256f:c631 reports 24 buttons before disjointed button remapping
  Number of buttons: 15 (evdev offset: 256)
  Axis 0 value range: -342 - 350 (fuzz: 0)
  Axis 1 value range: -342 - 350 (fuzz: 0)
  Axis 2 value range: -342 - 350 (fuzz: 0)
  Axis 3 value range: -342 - 350 (fuzz: 0)
  Axis 4 value range: -342 - 350 (fuzz: 0)
  Axis 5 value range: -342 - 350 (fuzz: 0)
using device: 3Dconnexion SpaceMouse Pro Wireless (cabled) (/dev/input/event19)
  device flags: swap y-z invert y-z
trying to open X11 display ":1"
   XAUTHORITY=/run/user/1000/gdm/Xauthority
Using XSendEvent to send key events
adding dev event for device: /dev/input/event19
read error: No such device
removing device: 3Dconnexion SpaceMouse Pro Wireless (cabled) (id: 0 path: /dev/input/event19)
removing pending device event of: /dev/input/event19
failed to turn LED off
found usb device [256f:c631]: "3Dconnexion SpaceMouse Pro Wireless (cabled)" (/dev/input/event19) 
adding device (id: 1).
device name: 3Dconnexion SpaceMouse Pro Wireless (cabled)
  Number of axes: 6 (6a 0r)
Device 256f:c631 reports 24 buttons before disjointed button remapping
  Number of buttons: 15 (evdev offset: 256)
  Axis 0 value range: -342 - 350 (fuzz: 0)
  Axis 1 value range: -342 - 350 (fuzz: 0)
  Axis 2 value range: -342 - 350 (fuzz: 0)
  Axis 3 value range: -342 - 350 (fuzz: 0)
  Axis 4 value range: -342 - 350 (fuzz: 0)
  Axis 5 value range: -342 - 350 (fuzz: 0)
using device: 3Dconnexion SpaceMouse Pro Wireless (cabled) (/dev/input/event19)
  device flags: swap y-z invert y-z
adding dev event for device: /dev/input/event19
AndunHH added a commit to AndunHH/spacemouse that referenced this issue Jun 30, 2024
Zero values are only reported every HIDUPDATERATESLOW_MS

As a linux users I have some troubles with not repeated rotations, when the values don't change, see FreeSpacenav/spacenavd#108. Therefore I introduced a small jiggling on the last bit.
@jtsiomb
Copy link
Contributor

jtsiomb commented Jun 30, 2024

When I let go of the mouse: The model still moves, because the auto-repeat seems to repeat the last input. Even though the mouse is actually reporting zero values.

How do you know the mouse is reporting zero values?

uncommented repeat-intervall = 250

Interval is spelled with a single 'L'.

Is it possible that the deadzone detection in the auto-repeat mechanism is buggy with the consequence, that the mouse is not returning to zero, but is always auto-repeating the last non-zero values?

It's possible, but I don't think so. When motion input is received it's zeroed out if it's within the deadzone threshold before any further processing, and auto-repeat checks if the previous event is out of deadzone by making sure it's not all zeroes otherwise the daemon sleeps indefinitely waiting for new input.

See:

@jtsiomb
Copy link
Contributor

jtsiomb commented Jun 30, 2024

spnavcg didn't compile, due to the same issue as in #43

You need to install Qt 5. That bug report (FreeSpacenav/spnavcfg#43) is about making it build with Qt 6, which is possible but takes some hacking of the build process. spnavcfg is a Qt5 application for now, Qt6 is unsupported.

@AndunHH
Copy link
Author

AndunHH commented Jun 30, 2024

Thanks for your usefull feedback again!

How do you know the mouse is reporting zero values?

As we write the arduino code by ourself, I can see, that 0x0000 is send to the USB API within the arduino.

You need to install Qt 5

Thanks for the good hint. I got it working and the gui for the configuration was brilliant for debugging, as I can see the resulting values for the axis, that are handled on the PC. Here, I found that my values didn't return to zero, but to 6 !?
Your suggestion above (really sending zeros?) was right, but the cause is in my HID descriptor, that I copied from another project. The spacenavd log shows to culprit: Axis 0 value range: -342 - 350

    0x16, 0xA2, 0xFE,    // Logical Minimum (-350) (0xFEAA in little-endian)  

The comment is just wrong... 0xFEAA is -342!? argh!

I corrected our HID descriptor to a symmetric range from -350 to +350 and the values return to zero. Yeah

The spnavcfg shows the values from -500 to +500? Do I assume correctly, that they are just mapped from the logical min to logical max from the HID descriptor or is there more magic?

The auto-repeat is finally stopping after 1s with zero values. Great!
I'm figuring out, why it takes so long in between our to programs.
Regarding https://github.com/FreeSpacenav/spacenavd/blob/master/src/spnavd.c#L225

Is every value repeated regardless if there is new data sent?

How are new, but equal data treated?
Is there a place where they are thrown away?

I'm asking, because when I'm activating auto-repeat now, the usual motion is faster than necessary, even if the same data is sent every 10 ms from my device.

@jtsiomb
Copy link
Contributor

jtsiomb commented Jul 1, 2024

The spnavcfg shows the values from -500 to +500? Do I assume correctly, that they are just mapped from the logical min to logical max from the HID descriptor or is there more magic?

The values are whatever the device sends, multiplied by sensitivity, both global and per-axis.

Is every value repeated regardless if there is new data sent?

How are new, but equal data treated?

If the last motion event had any non-zero values (after deadzone clamping), it is repeated roughly as often as the repeat interval specifies. If a new motion event arrives, it gets immediately sent out, and becomes the new "last motion event" to be repeated after the repeat interval elapses again.

Is there a place where they are thrown away?

The daemon sends out all inputs as they arrive, but libspnav provides a function to discard all pending events of a given type (spnav_remove_events), so at any given point you can process only the most recent one if more than one are queued. This function is used by the "cube" and "fly" examples, but not by "simple" or the spnavcfg gui.

Btw I'm closing this issue as it's not really a spacenavd bug, but feel free to continue asking questions here if you need more details.

@jtsiomb jtsiomb closed this as completed Jul 1, 2024
@AndunHH
Copy link
Author

AndunHH commented Jul 1, 2024

Thanks again for the good answer and your absolutely right, that the "issue" is not a bug.

I got hold off an old, used SpaceNavigator and observed the behavior and noticed two main things:

The SpaceNavigator is reporting translations (report id 1) and rotations (report id 2) every 8 ms, if there are non-zero values. Before stopping to transmit this value, if return to zero, the zeroes are sent three times ... I will try to imitate this behavior with our DIY approach and check if spacenavd responds to our imitation as to the real mouse.

Another interesting part in the HID Descriptor (full report below, if other persons are interested)
The translation data are reported as:
0x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)

In our inherited code fragment (maybe from a SpaceMouse Pro ... i doubt that in the meantime):
0x81, 0x02, // Input (variable,absolute)

I tried both versions and observed different behavior in FreeCad and the spnavcfg. Is there a different handling for those different input definitions in spacenavd or do I need to read the USB specifications to get the meaning from this? ;)

DEVICE DESCRIPTOR
    bLength: 18
    bDescriptorType: 0x01 (DEVICE)
    bcdUSB: 0x0200
    bDeviceClass: Device (0x00)
    bDeviceSubClass: 0
    bDeviceProtocol: 0 (Use class code info from Interface Descriptors)
    bMaxPacketSize0: 8
    idVendor: Logitech, Inc. (0x046d)
    idProduct: 3Dconnexion Space Navigator 3D Mouse (0xc626)
    bcdDevice: 0x0435
    iManufacturer: 1
    iProduct: 2
    iSerialNumber: 0
    bNumConfigurations: 1

HID Report, when the SpaceNavigator is plugged in

0x05, 0x01,        // Usage Page (Generic Desktop Ctrls)
0x09, 0x08,        // Usage (Multi-axis Controller)
0xA1, 0x01,        // Collection (Application)
0xA1, 0x00,        //   Collection (Physical)
0x85, 0x01,        //     Report ID (1)
0x16, 0xA2, 0xFE,  //     Logical Minimum (-350)
0x26, 0x5E, 0x01,  //     Logical Maximum (350)
0x36, 0x88, 0xFA,  //     Physical Minimum (-1400)
0x46, 0x78, 0x05,  //     Physical Maximum (1400)
0x55, 0x0C,        //     Unit Exponent (-4)
0x65, 0x11,        //     Unit (System: SI Linear, Length: Centimeter)
0x09, 0x30,        //     Usage (X)
0x09, 0x31,        //     Usage (Y)
0x09, 0x32,        //     Usage (Z)
0x75, 0x10,        //     Report Size (16)
0x95, 0x03,        //     Report Count (3)
0x81, 0x06,        //     Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              //   End Collection
0xA1, 0x00,        //   Collection (Physical)
0x85, 0x02,        //     Report ID (2)
0x09, 0x33,        //     Usage (Rx)
0x09, 0x34,        //     Usage (Ry)
0x09, 0x35,        //     Usage (Rz)
0x75, 0x10,        //     Report Size (16)
0x95, 0x03,        //     Report Count (3)
0x81, 0x06,        //     Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              //   End Collection
0xA1, 0x02,        //   Collection (Logical)
0x85, 0x03,        //     Report ID (3)
0x05, 0x01,        //     Usage Page (Generic Desktop Ctrls)
0x05, 0x09,        //     Usage Page (Button)
0x19, 0x01,        //     Usage Minimum (0x01)
0x29, 0x02,        //     Usage Maximum (0x02)
0x15, 0x00,        //     Logical Minimum (0)
0x25, 0x01,        //     Logical Maximum (1)
0x35, 0x00,        //     Physical Minimum (0)
0x45, 0x01,        //     Physical Maximum (1)
0x75, 0x01,        //     Report Size (1)
0x95, 0x02,        //     Report Count (2)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x0E,        //     Report Count (14)
0x81, 0x03,        //     Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              //   End Collection
0xA1, 0x02,        //   Collection (Logical)
0x85, 0x04,        //     Report ID (4)
0x05, 0x08,        //     Usage Page (LEDs)
0x09, 0x4B,        //     Usage (Generic Indicator)
0x15, 0x00,        //     Logical Minimum (0)
0x25, 0x01,        //     Logical Maximum (1)
0x95, 0x01,        //     Report Count (1)
0x75, 0x01,        //     Report Size (1)
0x91, 0x02,        //     Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x95, 0x01,        //     Report Count (1)
0x75, 0x07,        //     Report Size (7)
0x91, 0x03,        //     Output (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              //   End Collection
0x06, 0x00, 0xFF,  //   Usage Page (Vendor Defined 0xFF00)
0x09, 0x01,        //   Usage (0x01)
0xA1, 0x02,        //   Collection (Logical)
0x15, 0x80,        //     Logical Minimum (-128)
0x25, 0x7F,        //     Logical Maximum (127)
0x75, 0x08,        //     Report Size (8)
0x09, 0x3A,        //     Usage (0x3A)
0xA1, 0x02,        //     Collection (Logical)
0x85, 0x05,        //       Report ID (5)
0x09, 0x20,        //       Usage (0x20)
0x95, 0x01,        //       Report Count (1)
0xB1, 0x02,        //       Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              //     End Collection
0xA1, 0x02,        //     Collection (Logical)
0x85, 0x06,        //       Report ID (6)
0x09, 0x21,        //       Usage (0x21)
0x95, 0x01,        //       Report Count (1)
0xB1, 0x02,        //       Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              //     End Collection
0xA1, 0x02,        //     Collection (Logical)
0x85, 0x07,        //       Report ID (7)
0x09, 0x22,        //       Usage (0x22)
0x95, 0x01,        //       Report Count (1)
0xB1, 0x02,        //       Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              //     End Collection
0xA1, 0x02,        //     Collection (Logical)
0x85, 0x08,        //       Report ID (8)
0x09, 0x23,        //       Usage (0x23)
0x95, 0x07,        //       Report Count (7)
0xB1, 0x02,        //       Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              //     End Collection
0xA1, 0x02,        //     Collection (Logical)
0x85, 0x09,        //       Report ID (9)
0x09, 0x24,        //       Usage (0x24)
0x95, 0x07,        //       Report Count (7)
0xB1, 0x02,        //       Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              //     End Collection
0xA1, 0x02,        //     Collection (Logical)
0x85, 0x0A,        //       Report ID (10)
0x09, 0x25,        //       Usage (0x25)
0x95, 0x07,        //       Report Count (7)
0xB1, 0x02,        //       Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              //     End Collection
0xA1, 0x02,        //     Collection (Logical)
0x85, 0x0B,        //       Report ID (11)
0x09, 0x26,        //       Usage (0x26)
0x95, 0x01,        //       Report Count (1)
0xB1, 0x02,        //       Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              //     End Collection
0xA1, 0x02,        //     Collection (Logical)
0x85, 0x13,        //       Report ID (19)
0x09, 0x2E,        //       Usage (0x2E)
0x95, 0x01,        //       Report Count (1)
0xB1, 0x02,        //       Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              //     End Collection
0xC0,              //   End Collection
0xC0,              // End Collection

@jtsiomb
Copy link
Contributor

jtsiomb commented Jul 1, 2024

Another interesting part in the HID Descriptor (full report below, if other persons are interested) The translation data are reported as:
0x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)

In our inherited code fragment (maybe from a SpaceMouse Pro ... i doubt that in the meantime):
0x81, 0x02, // Input (variable,absolute)

I tried both versions and observed different behavior in FreeCad and the spnavcfg. Is there a different handling for those different input definitions in spacenavd

Indeed there is, and this relates back to one of your previous questions. I did not remember this but if the device sends absolute events, the value goes through a remapping function that brings it to the range [-500, 500] before further processing and sensitivity adjustment. See: https://github.com/FreeSpacenav/spacenavd/blob/master/src/dev_usb_linux.c#L294

I probably did this to normalize the values reported by different devices, but I have no recollection about how the specific range was chosen.

When I wrote the first version of spacenavd, I only had a space navigator, and the first version of spacenavd only worked with "relative" inputs because that was what the space navigator emitted. I'm saying "relative" in quotes because they weren't really relative, they were just reported as such, but the values were always absolute displacements per axis. 3Dconnexion probably realized at some stage that reporting them as "relative" is incorrect, and changed to absolute in newer devices. Specifically the commit which added EV_ABS handling in spacenavd came from a bug report of a "space pilot" user (commit df57ada).

I'm pretty sure all modern 3Dconnexion devices report absolute axis usage.

Edit: you've seen this before, but here's the hid descriptor of a spacemouse wireless: https://pastebin.com/GD5mEKW6

@AndunHH
Copy link
Author

AndunHH commented Jul 2, 2024

Ah, yes. The remapping to +/- 500 explains my observations.

I have implemented a state machine which sends the data every 8 ms, with three zero packages at the end of non-zero data.

I staying with the absolute reporting as inherited and suggested, because there seems no benefit in changing this.

I still have the problem, that under FreeCAD the parts stays still, when only equal non-zero data are sent.
I'm not sure if the borrowed SpaceNavigator shows the same phanomenon, as it values are toggling/jiggling (even observed with wireshark).
Are there some defaults for which devices the auto-repeat is implemented "automatically"? I can't find such a definition in dev.c?

And second, I played around with the auto-repeat interval in spnavcfg and observed the mechanism working in general. The shorter the time duration, the higher the effect, as the packages get sent more often. Interestingly - maybe even a bug? - If I raise auto-repeat from 250 to 500, even higher to 800, to 900 I observe weaking response. But if i set it to the maximum=1000 the behavior is the same as with 0 or off. Is this intended? Otherwise you could just limit the value in spnavcfg to be less than 1000.
I also reproduced the behavior by directly changing /etc/spnavrc.

@AndunHH
Copy link
Author

AndunHH commented Jul 4, 2024

I found the problem, that in FreeCAD the model is stop moving, when the spacemouse is off-centered hold still.

My final conclusion to this is as follows:
The original Space Navigator reports it's data as relative positions. The original Space Navigator is very sensitive and is jiggling a lot i.e. the same value is only send repeatedly very for some milli-seconds.

My emulated "SpaceMouse Pro Wireless (cabled)" (or at least our inherited) hid report descriptor reports absolute values
Our emulation is very sturdy and if you hold it in position, the same value are easily calculate for a second.

When using spacenavd and the simple example, cube or even in FreeCAD:

  • Relative reports are evaluated with every event, even if they are the same as before.
  • Absolute reports are only evaluated, if they differ from the previous report. This is merely visible with the SpaceNavigator, but is very annoying for our emulation, as it is reporting same values very often. I didn't figured out, if this dropping of events is done by spacenavd or linux itself...

Solution: Change our emulated mouse to Relative Positions, even if this is not "up to date". But it avoids the necessity to jiggle the values.

AndunHH added a commit to AndunHH/spacemouse that referenced this issue Jul 4, 2024
Changed from absolute to relative values to avoid the need for jiggling the values. This is needed because equal absolute inputs are ignored in linux. Check the discussion in spacenavd for more informations:

FreeSpacenav/spacenavd#108 (comment)
@jtsiomb
Copy link
Contributor

jtsiomb commented Jul 4, 2024

You lost me with your last two messages. I clearly don't understand something about what you're observing here. It might be me, but I don't find your description about what happens when you fiddle with the repeat interval clear at all.

As I said previously, the intended behaviour when the repeat interval is enabled, is that even if the device stops sending events entirely when motionless out of deadzone, spacenavd repeats the last motion event roughly every X milliseconds. I can't understand from your description if what you're observing is something different, and what that is.

Are there some defaults for which devices the auto-repeat is implemented "automatically"?

No, auto-repeat is always off by default at the moment. It might be a good idea to change that for some devices.

But if i set it to the maximum=1000 the behavior is the same as with 0 or off.

If that's true, that might be a bug. The intended behaviour when repeat interval is set to 1000, is to send motion events every second. I don't think that's a very useful setting, but that's what it's supposed to do. Also there is no maximum, you can set it in the config file to whatever interval you want.

The original Space Navigator reports it's data as relative positions.

To be clear, it delcares its reports as relative, but they're not. It's still sending absolute positions.

As for the differences in handling of absolute and relative HID reports, if there is a difference it must be in the kernel, aside from the remapping I mentioned there's nothing else spacenavd does differently between the two.

@AndunHH
Copy link
Author

AndunHH commented Jul 6, 2024

Sry, for my unclear explanations. My main problem was, that auto-repeat is neither the cause, nor the solution for my problem. But I didn't knew that ...

As we found out in our last posts, I struggled with the (probable) kernel behavior of hiding data, if the (declared as) absolute value doesn't change. (Which is common in our emulated mouse)

In search for a solution, I activated auto-repeat with an intervall of e.g. 250 ms and observed:

  • The mouse is sending (abs) data on it's own (but they are hidden, because not changing).
  • Auto-repeat is also repeating this values
  • If I move the mouse a little bit, the new values and the repeated old value are more often actually transmitted to the programm and not hidden by the kernel. Many data sent, but very shaky, because old an new values are mixed.
  • If I increased the auto-repeat intervall up to 999 ms, the behavior got better (=more stable, less shaking movements).
  • If I set the auto-repeat interval to 1s the observed behavior is again very agitating, shaking, as small values were. Therefore I was suggesting, that this might be a bug.

Conclusion:
As my mouse is reporting the non-zero alues always, I don't need auto-repeat anymore! I just didn't knew that. I turned it off now and changed our code to declare the data as "relative".
I can't say for sure, if there really is a bug at auto-repeat interval = 1000. Sorry for making such a fuss about it.

Thank you very much for the good answers and links which led me in the right direction, to solve my problem.

AndunHH added a commit to AndunHH/spacemouse that referenced this issue Jul 7, 2024
Based on the reverse engineered SpaceNavigator, see SpaceNavigator.md, this commit introduces a little state machine, which sends new data over the usb interface with a constant rate every 8 ms. This is not to be configured by every user and therefore not in the config_sample.h. If no data is to sent, the zero data are sent three times before stopping the transmissions.

* Introduced debounced keyState for key evaluation
* Changed the HID descriptor to a symmetric logical range of +/- 350. It has been -342 to +350, despite the comment saying it to be -350 all the time. 0xFEA2 = 350, not 0xFEAA. ?!
* Changed HID report from absolute to relative values to avoid the need for jiggling the values. This is needed because equal absolute inputs are ignored in linux. Check the discussion in spacenavd for more informations:
FreeSpacenav/spacenavd#108 (comment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants