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

Decrease mixer period for USB Joystick mode, increase report rate #831

Merged
merged 2 commits into from
Oct 1, 2021

Conversation

CapnBry
Copy link
Contributor

@CapnBry CapnBry commented Sep 28, 2021

Many people use USB HID Joystick mode for connection to a simulator, and when they do, it is likely they disable both the Internal and External modules to do so. However, when there is no module enabled on boot, the mixer period is adjusted to 50ms (limited to 25ms by the MIN/MAX_REFRESH_RATE). When an external module is enabled, the Joystick latency is greatly reduced even though the external module is not needed for the connection.

This PR

  • Addresses the issue of dropping to MIN_REFRESH_RATE if no module is enabled
  • Adds a new mixer rate (2ms) for joystick mode if no module is enabled
  • Lowers the report interval for the USB HID joystick

Details

Using usblag I measured the latency from electrically shorting a switch in the handset to the time that switch changes in the USB HID report 1000x. The handset was a Taranis Q X7 ACCST. The results may shock you. (lower is better, come on you know that!)
USB report latency

  • Red: the report latency if booted into a model profile with no internal/external module selected. The bug here is that enablePulsesExternalModule will set the external mixer period to 50ms, preventing the default period (4ms) from being used. This creates a 25ms mixer schedule, with 10ms HID reporting interval.
  • Yellow: report latency if a model profile is selected with an external module, even if that profile is switched away from. This correctly sets the interval to 0 when leaving the profile, which results in a 4ms mixer schedule with 10ms HID reporting interval.
  • Blue: Decreasing the USB report interval to 4ms, along with a 4ms mixer schedule results in some pretty good numbers
  • Green: Adding a new 2ms mixer schedule for if no module (internal or external) is enabled but joystick mode is active, along with a 1ms report interval. Implemented in this PR
Color Mixer (ms) HID Interval (ms) Average (ms) Std Dev (ms) Max (ms)
Red 25 10 19.2 7.9 37.4
Orange 4 10 14.8 3.4 22.5
Blue 4 4 5.9 1.9 10.4
none 2 2 3.8 1.6 7.2
Green 2 1 3.2 1.5 6.1

Note that the 2/2 is pretty close to 2/1 and is therefore an acceptable substitute, but not included in the scatter plot. 1ms report intervals works fine even with an external module connected, so I do not see any reason to not use 1ms reporting, especially since the use case for USB HID Joystick is usually exclusive of any other handset activity so I think we should allow for the best performance.

The jitter is the real killer in this scenario. Imagine a variable latency in a control link of 0-40ms. People would lose their minds! 🤯

Further work

If no other module is enabled, then mixer sync could be enabled using the USB's USBD_HID_DataIn to capture the time, then just adjust the mixer schedule as it would normally do with another external module. I'm not sure how necessary this is because the results are already quite good for not adding much code at all and the sync would only remove 1.5ms of jitter and up to 1.2 ms of average latency.

Thanks

This came out of a conversation with Hyper at a race this weekend where he remarked that he could tell the difference in latency between having a Ghost module plugged in and active when using the simulator. I was shocked to see 40Hz update rate when I started profiling my connection. Kudos to his keen reflexes for picking up on the problem.

Also adds a 2ms mixer period if internal and external modules are stopped
but joystick mode is active
@qdrk
Copy link

qdrk commented Sep 29, 2021

Nice, I literally just shoot a tutorial 2 days ago on how to "overclock" it to 500hz. It's definitely gonna be better if this can be fixed from the firmware side.

I also wrote a web based tool that calculates the refresh rate that might come in handy when testing: https://dronesitter.com/radio-tester

@qdrk
Copy link

qdrk commented Sep 29, 2021

I'm not very familiar with OpenTX code base, just wonder if it's possible to do 1ms or lower mixer loop. Is it capped by processing power or noise?

@@ -21,7 +21,8 @@
#ifndef _MIXER_SCHEDULER_H_
#define _MIXER_SCHEDULER_H_

#define MIXER_SCHEDULER_DEFAULT_PERIOD_US 4000u // 4ms
#define MIXER_SCHEDULER_DEFAULT_PERIOD_US 4000u // 4ms
#define MIXER_SCHEDULER_JOYSTICK_PERIOD_US 2000u // 2ms
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens when this is 1000u :)

@CapnBry
Copy link
Contributor Author

CapnBry commented Sep 29, 2021

Stop asking, it doesn't go below 1750us 😛. Also, you can't run a simulator at 1000fps anyway.

@pfeerick
Copy link
Member

pfeerick commented Sep 29, 2021

I was gonna say... c'mon... seriously... I don't think anyone would actually subjectively feel any difference between 1 and 2ms, or anything much below ~13ms for that matter - this is the frame rate considered to be the sweet spot, above it you'll start noticing lag, but probably can't quite discern it until it gets up to 20ms, but below which there is no gain.

i.e. one standard of sorts is

300ms  < game is unplayable
150ms  < game play degraded 
100ms  < player performance affected
50ms   > target performance
13ms   > lower detectable limit

@CapnBry
Copy link
Contributor Author

CapnBry commented Sep 30, 2021

I'm not sure any racing drone pilot would agree with that standard that 50ms aka 20Hz is "target performance" 😀 50Hz Crossfire vs 150Hz Crossfire is a crazy different feel, so I'd insist on a 150Hz/6.67ms max latency (which is what this PR provides). I will agree that 2ms mixer + 1ms report may be a little overkill, but the hardware can do it so why not provide the best performance that can be delivered? If it was mixer synced at 4ms and 4ms reports that would probably be the ideal performance to latency solution, or 2ms/2ms if more headroom is needed over the 2ms/1ms of the PR.

Mixer 4ms with a 10ms report with a max recorded latency of 22ms is just unacceptable when the hardware is just sitting idle to do it.

@pfeerick
Copy link
Member

lol... there will always be exceptions to the rule, and that was industry standard gameplay metrics... so may not be 100% transferable... but it is research backed with the key point being 13ms latencies being the lowest detectable limits, which is backed by hand-eye co-ordination and reaction speed studies. And since 50Hz (20ms) is nearly double the detectable threshold, and 150Hz (6.67ms) is nearly half of it... of course it will feel different. The real question there would be is it any different to 100Hz (10ms) - to which I suspect the answer will be no.

Having said that, of course, if the hardware allows it, why not make full use of it! :) I'll play with this tonight, but don't see any issue with this... however I may leave it to Raphael to review, as I try not play with the guts of the code too much! 😁

@qdrk
Copy link

qdrk commented Sep 30, 2021

Stop asking, it doesn't go below 1750us 😛. Also, you can't run a simulator at 1000fps anyway.

Just curious what's the bottleneck here 😄 , since a simple arduino/teensy sketch can do 2kHz easily. Sim can run at 700-800fps though, that means two frames might get the same sample, not to mention a higher scheduling rate can reduce latency variations that can occur by unsynchronized polling between sim and radio.

@akfpv
Copy link

akfpv commented Sep 30, 2021

lol... there will always be exceptions to the rule, and that was industry standard gameplay metrics... so may not be 100% transferable... but it is research backed with the key point being 13ms latencies being the lowest detectable limits, which is backed by hand-eye co-ordination and reaction speed studies. And since 50Hz (20ms) is nearly double the detectable threshold, and 150Hz (6.67ms) is nearly half of it... of course it will feel different. The real question there would be is it any different to 100Hz (10ms) - to which I suspect the answer will be no.

Having said that, of course, if the hardware allows it, why not make full use of it! :) I'll play with this tonight, but don't see any issue with this... however I may leave it to Raphael to review, as I try not play with the guts of the code too much! 😁

Drone racing, especially in sims where there are much less external factors affecting the flight (wind, tune, propwash, other quads, etc.), is very different from say first person shooter games. Reaction doesn't matter much in drone racing, instead fast pilots rely more on timing the moves. This is where the frame period matters a lot, as it adds up to the move response - if you fly a drone at 60mph and make fast sharp stick deflections from one side to the other (slalom) then a shorter frame period would feel more responsive. Faster refresh rate also means lower standard deviation between physical stick deflection and drone reaction (less variable latency). So, the statement "13ms being the lowest scientifically proven detectable limit" only applies to scenarios where you need to react to a sudden change, which isn't a common case in drone racing - track layout is static and the race line is planned ahead, gates/flags don't randomly pop up in your view. Hope this makes sense.

@pfeerick
Copy link
Member

pfeerick commented Sep 30, 2021

Hope this makes sense.

Perfectly so! Thank you... I wasn't thinking about pre-emptive movements, so yes, I can see where the sub 13ms latencies could start to be a problem / would be noticeable.

@obeny
Copy link

obeny commented Sep 30, 2021

Hi, I've built 2.5-rc2 with this change and tried it out. Difference is significant. Quad in simulator feels sharper and more connected to the sticks. If somebody wants to test-drive the change, here is my bin file for TX16S.
https://github.com/obeny/copter_resources/tree/master/edgetx/2.5-rc2-20210930_mixer_latency

Copy link
Member

@raphaelcoeffic raphaelcoeffic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thx! I like it like that!

Copy link
Member

@pfeerick pfeerick left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh boy... NV14 is so much smoother on Liftoff :)

@pfeerick pfeerick merged commit a04a56c into EdgeTX:main Oct 1, 2021
@pfeerick pfeerick added this to the 2.6 milestone Nov 28, 2021
@pfeerick pfeerick added the enhancement ✨ New feature or request label Nov 28, 2021
@pfeerick pfeerick modified the milestones: 2.6, 2.5 Nov 28, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement ✨ New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants