As I've been posting about previously, I've been working on a hidapi patch to get device enumeration working correctly for Bluetooth HID devices on Linux. After about two months, and thanks to the great support and feedback of Alan Ott (the hidapi maintainer), the patch landed in mainstream hidapi yesterday.
How does this benefit the MoveOnPC project? It now allows us to use the PS Move Motion Controller under Linux via Bluetooth and without having to resort to source-code-level hacks. For most users, this will just be a transparent improvement.
In other news, I've been working with Benjamin yesterday on getting his OpenCV code working on Linux, and while it worked, the LED writing did cause a noticeable pause every 4 seconds. Fixing this by using my experimental "multithreading" branch did help, but we had to increase the delay for the initial calibration blinking. I hope to look into possibilities to improve this for Bluetooth devices on Linux, so that we get the same write performance as on OS X and Windows.
Posts mit dem Label linux werden angezeigt. Alle Posts anzeigen
Posts mit dem Label linux werden angezeigt. Alle Posts anzeigen
Mittwoch, 18. Juli 2012
Samstag, 2. Juni 2012
Multi-threaded LED writing
Today I've experimented a bit with using multi-threading in Linux to write LED status updates. On Linux, setting LEDs actually blocks the process - depending on the controller - for 30 ms up to 500 ms in some cases. I'm not yet sure if there is a way to make this faster (in Mac OS X on the same hardware, updating LEDs is no problem, but maybe OS X does not wait for an acknowledgement when sending out the set LEDs packet).
You can find the multi-threading branch in the multithreaded branch on Github. Now that we have the nice test_read_performance tool, we can compare the results with the previous results from the OS X installation (same hardware):
-- PS Move API Sensor Reading Performance Test --
Testing STATIC READ performance (non-changing LED setting)
1000 reads in 13043 ms = 76.669478 reads/sec (144x seq jump = 14.40 %)
1000 reads in 12563 ms = 79.598822 reads/sec (100x seq jump = 10.00 %)
1000 reads in 12451 ms = 80.314834 reads/sec (88x seq jump = 8.80 %)
=====
Mean over 3 rounds: 78.861043 reads/sec
Testing SMART READ performance (rate-limited LED setting)
1000 reads in 20073 ms = 49.818164 reads/sec (177x seq jump = 17.70 %)
1000 reads in 20113 ms = 49.719087 reads/sec (196x seq jump = 19.60 %)
1000 reads in 19858 ms = 50.357539 reads/sec (190x seq jump = 19.00 %)
=====
Mean over 3 rounds: 49.964930 reads/sec
Testing BAD READ performance (continous LED setting)
1000 reads in 26187 ms = 38.186887 reads/sec (310x seq jump = 31.00 %)
1000 reads in 25985 ms = 38.483741 reads/sec (306x seq jump = 30.60 %)
1000 reads in 26784 ms = 37.335723 reads/sec (343x seq jump = 34.30 %)
=====
Mean over 3 rounds: 38.002116 reads/sec
Testing RAW READ performance (no LED setting)
1000 reads in 12612 ms = 79.289565 reads/sec (101x seq jump = 10.10 %)
1000 reads in 12639 ms = 79.120184 reads/sec (109x seq jump = 10.90 %)
1000 reads in 12576 ms = 79.516539 reads/sec (107x seq jump = 10.70 %)
=====
Mean over 3 rounds: 79.308762 reads/sec
Still not as good as on OS X, but a good starting point. Without multi-threading on Linux, the results are much worse when the LEDs are updated often:
-- PS Move API Sensor Reading Performance Test --
Testing STATIC READ performance (non-changing LED setting)
1000 reads in 12890 ms = 77.579519 reads/sec (125x seq jump = 12.50 %)
1000 reads in 12660 ms = 78.988942 reads/sec (104x seq jump = 10.40 %)
1000 reads in 12650 ms = 79.051383 reads/sec (108x seq jump = 10.80 %)
=====
Mean over 3 rounds: 78.539948 reads/sec
Testing SMART READ performance (rate-limited LED setting)
1000 reads in 14596 ms = 68.511921 reads/sec (161x seq jump = 16.10 %)
1000 reads in 14315 ms = 69.856794 reads/sec (143x seq jump = 14.30 %)
1000 reads in 14224 ms = 70.303712 reads/sec (139x seq jump = 13.90 %)
=====
Mean over 3 rounds: 69.557475 reads/sec
Testing BAD READ performance (continous LED setting)
1000 reads in 41132 ms = 24.311971 reads/sec (69x seq jump = 6.90 %)
1000 reads in 41014 ms = 24.381918 reads/sec (70x seq jump = 7.00 %)
1000 reads in 41153 ms = 24.299565 reads/sec (76x seq jump = 7.60 %)
=====
Mean over 3 rounds: 24.331151 reads/sec
Testing RAW READ performance (no LED setting)
1000 reads in 12683 ms = 78.845699 reads/sec (114x seq jump = 11.40 %)
1000 reads in 12723 ms = 78.597815 reads/sec (114x seq jump = 11.40 %)
1000 reads in 12640 ms = 79.113924 reads/sec (107x seq jump = 10.70 %)
=====
Mean over 3 rounds: 78.852478 reads/sec
Interestingly, the multi-threaded variant is worse in the SMART READ test (the rate-limited LED update variant). Not sure why this is the case - maybe it's some threading overhead. For some of my older PS Move controllers that I have here, it's even worse - seems like some controllers are faster to respond than others. I wonder if there's a difference in the firmware or if it's different hardware (the faster controllers is the one that I bought more recently).
You can find the multi-threading branch in the multithreaded branch on Github. Now that we have the nice test_read_performance tool, we can compare the results with the previous results from the OS X installation (same hardware):
-- PS Move API Sensor Reading Performance Test --
Testing STATIC READ performance (non-changing LED setting)
1000 reads in 13043 ms = 76.669478 reads/sec (144x seq jump = 14.40 %)
1000 reads in 12563 ms = 79.598822 reads/sec (100x seq jump = 10.00 %)
1000 reads in 12451 ms = 80.314834 reads/sec (88x seq jump = 8.80 %)
=====
Mean over 3 rounds: 78.861043 reads/sec
Testing SMART READ performance (rate-limited LED setting)
1000 reads in 20073 ms = 49.818164 reads/sec (177x seq jump = 17.70 %)
1000 reads in 20113 ms = 49.719087 reads/sec (196x seq jump = 19.60 %)
1000 reads in 19858 ms = 50.357539 reads/sec (190x seq jump = 19.00 %)
=====
Mean over 3 rounds: 49.964930 reads/sec
Testing BAD READ performance (continous LED setting)
1000 reads in 26187 ms = 38.186887 reads/sec (310x seq jump = 31.00 %)
1000 reads in 25985 ms = 38.483741 reads/sec (306x seq jump = 30.60 %)
1000 reads in 26784 ms = 37.335723 reads/sec (343x seq jump = 34.30 %)
=====
Mean over 3 rounds: 38.002116 reads/sec
Testing RAW READ performance (no LED setting)
1000 reads in 12612 ms = 79.289565 reads/sec (101x seq jump = 10.10 %)
1000 reads in 12639 ms = 79.120184 reads/sec (109x seq jump = 10.90 %)
1000 reads in 12576 ms = 79.516539 reads/sec (107x seq jump = 10.70 %)
=====
Mean over 3 rounds: 79.308762 reads/sec
Still not as good as on OS X, but a good starting point. Without multi-threading on Linux, the results are much worse when the LEDs are updated often:
-- PS Move API Sensor Reading Performance Test --
Testing STATIC READ performance (non-changing LED setting)
1000 reads in 12890 ms = 77.579519 reads/sec (125x seq jump = 12.50 %)
1000 reads in 12660 ms = 78.988942 reads/sec (104x seq jump = 10.40 %)
1000 reads in 12650 ms = 79.051383 reads/sec (108x seq jump = 10.80 %)
=====
Mean over 3 rounds: 78.539948 reads/sec
Testing SMART READ performance (rate-limited LED setting)
1000 reads in 14596 ms = 68.511921 reads/sec (161x seq jump = 16.10 %)
1000 reads in 14315 ms = 69.856794 reads/sec (143x seq jump = 14.30 %)
1000 reads in 14224 ms = 70.303712 reads/sec (139x seq jump = 13.90 %)
=====
Mean over 3 rounds: 69.557475 reads/sec
Testing BAD READ performance (continous LED setting)
1000 reads in 41132 ms = 24.311971 reads/sec (69x seq jump = 6.90 %)
1000 reads in 41014 ms = 24.381918 reads/sec (70x seq jump = 7.00 %)
1000 reads in 41153 ms = 24.299565 reads/sec (76x seq jump = 7.60 %)
=====
Mean over 3 rounds: 24.331151 reads/sec
Testing RAW READ performance (no LED setting)
1000 reads in 12683 ms = 78.845699 reads/sec (114x seq jump = 11.40 %)
1000 reads in 12723 ms = 78.597815 reads/sec (114x seq jump = 11.40 %)
1000 reads in 12640 ms = 79.113924 reads/sec (107x seq jump = 10.70 %)
=====
Mean over 3 rounds: 78.852478 reads/sec
Interestingly, the multi-threaded variant is worse in the SMART READ test (the rate-limited LED update variant). Not sure why this is the case - maybe it's some threading overhead. For some of my older PS Move controllers that I have here, it's even worse - seems like some controllers are faster to respond than others. I wonder if there's a difference in the firmware or if it's different hardware (the faster controllers is the one that I bought more recently).
Freitag, 1. Juni 2012
Bluetooth on Linux: Fixing hidapi's HID enumeration
One obvious goal of the PS Move API is to be cross-platform. On Linux right now, we can get the controller working via USB with no problems, but Bluetooth devices are not found via hidapi's hid_enumerate() method. One could work around this by opening the /dev/hidraw[0-9]* devices directly, and picking one. However this is kludgy and would require another special-case. The reason why the hid_enumerate() method does not work on Linux is because it always tries to find the USB device for a given hidraw device (even if the hidraw device is a Bluetooth one) and returns the VID/PID from there (this works fine for USB devices, but in case of Bluetooth devices what is returned is the VID/PID of the Bluetooth host adapter, which is not what we are interested in).
As a workaround, I've now implemented a better detection mechanism based on the sysfs path of the hidraw file. For Bluetooth devices, the path could look like this:
For USB devices, it could look like this:
/sys/devices/pci0000:00/0000:00:06.1/usb2/2-2/2-2.1/2-2.1:1.0/0003:054C:03D5.0008/hidraw/hidraw6
In the case of the PS Move Motion Controller, the vendor ID is 0x054c and the product ID is 0x03d5. I've highlighted the occurence of these IDs in boldface above. Given that the hidapi already determines the sysfs path of the hidraw device, it's easy to write a function that extracts the IDs from the path. I've done so now in a patch against hidapi: commit 8ba92edb519 in thp/hidapi.
In order to get it merged into hidapi upstream, I've created pull request #62 at the signal11/hidapi repository on Github. Let's see if I have to rework/improve the patch or if it will be accepted.
After the patch has been merged (you can merge it locally or clone from my hidapi repo), connecting to the PS Move on Linux will become even easier. The only part remaining then is figuring out the permission problems on the hidraw devices (we could probably fix this with some udev rules) and getting Bluez' bluetoothd to reliably accept connections from new PS Move controllers.
As a workaround, I've now implemented a better detection mechanism based on the sysfs path of the hidraw file. For Bluetooth devices, the path could look like this:
/sys/devices/pci0000:00/0000:00:06.0/usb4/4-1/4-1.1/4-1.1:1.0/bluetooth/hci0/hci0:12/0005:054C:03D5.0007/hidraw/hidraw5
For USB devices, it could look like this:
/sys/devices/pci0000:00/0000:00:06.1/usb2/2-2/2-2.1/2-2.1:1.0/0003:054C:03D5.0008/hidraw/hidraw6
In the case of the PS Move Motion Controller, the vendor ID is 0x054c and the product ID is 0x03d5. I've highlighted the occurence of these IDs in boldface above. Given that the hidapi already determines the sysfs path of the hidraw device, it's easy to write a function that extracts the IDs from the path. I've done so now in a patch against hidapi: commit 8ba92edb519 in thp/hidapi.
In order to get it merged into hidapi upstream, I've created pull request #62 at the signal11/hidapi repository on Github. Let's see if I have to rework/improve the patch or if it will be accepted.
After the patch has been merged (you can merge it locally or clone from my hidapi repo), connecting to the PS Move on Linux will become even easier. The only part remaining then is figuring out the permission problems on the hidraw devices (we could probably fix this with some udev rules) and getting Bluez' bluetoothd to reliably accept connections from new PS Move controllers.
Abonnieren
Posts (Atom)