-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Description
I have been doing some testing with the existing windows Usbser.sys driver and a WinUSB based driver via a js script. The key problem is that the existing driver drops data. I was able to find some references for this:
- https://community.st.com/t5/stm32-mcus-embedded-software/usb-cdc-packet-loss-at-high-data-rates/td-p/866027
- https://kb.segger.com/CDC#CDC-ACM_issues_on_Windows_10
I have tested with various GCSs using the native driver on both Windows and Ubuntu and with my driver js script. MAVProxy makes this easiest as it gives a average download rate at the end of the log download and the number of retries. The key thing is that the Windows driver is the only one that needs retries. This actually seems to get worse with speed, so as AP goes faster its more likely to drop packets which takes longer overall.
Results
Rover (not sure the exact version) with MAVProxy
- Native: 178.4 kbyte/sec 321 retries
- Custom: 458.3 kbyte/sec 0 retries
Plane (not sure the exact version) with MAVProxy
- Native: 225.6 kbyte/sec 330 retries
- Custom: 315.7 kbyte/sec 0 retries
- Ubuntu: 307.3 kbyte/sec 0 retries
Copter master
MAVProxy:
- Native: 175.1 kbyte/sec 902 retries
- Custom: 455.8 kbyte/sec 0 retries
- Ubuntu: 851.4 kbyte/sec 0 retries
QGC (average speed calculated by manually timing the download):
- Native: 571.77 kbyte/sec
- Custom: 750 kbyte/sec
- Ubuntu: 686.07 kbyte/sec
MissionPlanner (average speed calculated by manually timing the download):
- Native: 640 kbyte/sec
- Custom: 850 kbyte/sec
Rover master
A few different AP loop rates were tested using mission planner only.
50Hz:
- Native: 266 kbyte/sec
- Custom: 266.77 kbyte/sec
100Hz:
- Native: 429 kbyte/sec
- Custom: 589.73 kbyte/sec
200Hz:
- Native: 413 kbyte/sec
- Custom: 619.97 kbyte/sec
400Hz:
- Native: 480 kbyte/sec
- Custom: 769.43 kbyte/sec
Conclusions
We are loosing a fair bit of speed due to the windows driver. This seems mainly due to the dropped data rather than due to a fundamental bottleneck. There is some variation in the number of messages dropped, In this testing it can result in up-to half the effective download rate. With the current AP log download handling there is only a advantage with loop rates over 50Hz, so Rover and Plane would not benefit (Quadplane would).
Custom driver setup
For testing a WinUSB based driver I wrote a little js script to read from the device at its bulk data endpoints and forward that out over TCP which the GCS could connect to. Zadig was used to load the WinUSB driver:
Now instead of a COM port we get a USB device:
You can revert back to the normal driver by right clicking "Uninstall Device" and then checking "Delete the driver software"
The script then looks for a device named "CubeOrange+" and list out the bulk data endpoints. I have not tested other flight controllers, both the name and the endpoints may need to be changed.
The script is here index.js It uses only the USB package.
Path forward
This helper script is not a deployable solution, but it does prove where the issue is. To completely fix we would have to write a custom driver that connects over WinUSB and creates a virtual serial port so the existing GCSs can connect without modification. We would have to work for existing flight controllers, although there is no reason we can't still use the current driver in some cases. I have not tested flashing firmware with the new driver. The zadig overload done not apply to the bootloader driver so firmware flashing does work because it uses the standard driver, so we may not need to get everything working on the new driver.
A alternate method would be to support WinUSB naively in the GCS but then you would need to change driver to suit the GCS you wanted to use. I have not looked into if it would be possible to have a "dual" driver that would for either WinUSB or COM ports (but not both at once).