Report #5 – The Last Push

August 16, 2012

The GSoC period is swiftly coming to its end, with the ‘soft pencils-down’ date already passed. While I’m not yet completely finished with my project I am very close, though, with only some small bits of functionality left to implement and with a quick walk through all the code to sort out the code styling issues and possible memory leaks.

What’s new

Quite some time has passed since the last report and the work has progressed quite a lot in that time. The Gamepad API support in WebKitGTK+ was already complete and pretty polished so the only thing remaining was the implementation of the GNOME Settings Daemon plugin and GNOME System Settings panel. The former’s task would be to recognize supported devices as they are connected and apply to them the correct buttons and axes mappings and previously-stored calibration data. The latter would be used by the users to see if their device is supported and, if the device was well enough supported by the Linux kernel itself, the user could calibrate the device him- or herself.

What changed from the original idea

The most significant change is that originally, I was thinking of giving the users the complete control over the buttons and axes mappings. That would mean that each user would go through an annoying and long process of manually configuring the device. But such processes immediately require the user to understand more about his device and the general gamepad/joystick button and axis layout than it is either required or productive for everyday life. Rather than that the decision was made to spare the user all the hassle around the configuration and rather use preset buttons and axes mappings for specific devices.

This would of course mean that some users might connect a device that the system does not yet recognize as supported. The user could still interact with the device (the system would not block the device’s usage) but could also request that device is awarded the supported status with appropriate mappings assigned to its unique ID. Rather than waiting 6 months for the new release, the data about all the supported devices is stored on the Web and is cached locally and updated whenever a new device is given the supported status and the list of supported devices is expanded. While the Web-located list of supported devices is already working well in the current daemon plugin, the ‘support request’ is, at this moment, only an idea that needs more discussion about approach and implementation.

The internals

The GNOME Settings Daemon plugin was already described in quite some detail. The update of the supported devices list is done when a mismatch in the checksums of the local and Web-located list occurs. The checksums are compared when the daemon starts, and that’s normally when the session begins (at login).  The devices list is written in JSON, so the plugin uses JSON-GLib to parse the list. The device is updated with proper mappings and current calibration through the Linux kernel driver. As much as convenient, these drivers are not quite the holy grail, but more on this later.

The GNOME System Settings panel, as already told, shows the connected devices, their support status, and provides calibration dialog if the device can handle it. The current design is my own, so it’s nothing extra (hopefully in either extreme, good or bad :>), but it has the functionality that it should provide. Here are the two screenshots, first shows the device listing, the second the calibration dialog.

What’s left

The functionality of both the GNOME Settings Daemon plugin and the GNOME System Settings panel is there, all that remains to do in the time left in the GSoC period (three days :>) is to polish the code, document it and start the effort of merging back into the main repositories. The work was done in the mirror repositories I’ve set up on GitHub (the project page has more info on this), with all the work contained in the master branches.

I’ll open two separate bugs for each project in which I’ll upload the merge patches up for review. My mentor Carlos has already volunteered to do some reviewing while the two projects’ maintainers will have a thorough look as well, of course. The design proposal will be updated as well, based on the current panel design. GNOME designers will be invited to have a look, comment on the various approaches and present any design ideas in sketch form.

Hopefully, with a proper design and a couple of devices being supported, the maintainers will give the thumbs-up to enable both the daemon plugin and the control panel in trunk, so they’d make it into GNOME 3.6. If not, there will be enough time to polish both components to near-perfection for the 3.8 release. And talking of polishing things, the device drivers in the Linux kernel need some of that too.

The devices agony

Truth be told, this is partly a rant. And it’s only based on two devices that don’t work properly. I’ve invested into a Wii Remote and a Sony Playstation DualShock3 gamepad to see how they behave with GNOME. They’re both Bluetooth devices, with the DualShock being also connectable through a mini USB cable. Unfortunately, while I’ve had to put quite some effort into connecting the Wiimote, the DualShock stayed reluctant to connect via Bluetooth. But even when connected, the Wiimote wasn’t presented well as a joystick device (the /dev/input/js* file was there, but pretty much useless), neither was the accelerometer propagated as such through GUdev.

The DualShock, when connected through the USB cable, was picked up as a joystick device by the joydev driver, the generic joystick device driver in the kernel. But you’d think it’s quite a special device when it popped out with 27 axes and (if I remember correctly) 18 buttons. A normal gamepad has 6 axes (two of those are the D-pads) and 12 buttons. The DualShock has these neat pressure-sensitive buttons, but the sensor data is exposed as an axis instead of the button value being regulated between 0 and 1 based on that pressure. Also exported as device axes is the accelerometer data, which could (well, should) be exposed as what it is – an accelerometer. There are also a couple of axes that I wasn’t able to locate at all, so I guess that’s sort of a bonus.

While the inability to connect via Bluetooth probably falls under Bluez, it’s obvious DualShock should have a custom driver to handle all its features. There’s a Wiimote-specific driver but I’m not entirely sure of its status in the Linux 3.2 kernel (used when testing), this driver looks OK in Git master, exporting accelerometer data as well, but I haven’t had time yet to test it properly. The Xbox controllers have a specific driver, so they should work in theory but I haven’t tested them really (well, I should buy one first). But it’s the DualShock annoyance that bothers me the most, the device is expensive and advanced as well, but with the current support it turns out to be nothing more than a toy. The device driver wasn’t a planned goal of this GSoC project but it might as well be a late collateral damage.

Conclusion

This blog post has gotten a bit lengthy, so let’s end it. I’ll post another, final report on Sunday just to explain what was left undone and what was actually completed, along with the status of the merge, and where this project could still improve outside of the GSoC scope.

5 Responses to “Report #5 – The Last Push”

  1. Juanjo Marin Says:

    I don’t if you know WiiCan, I think this can help you to support the wiimote https://launchpad.net/wiican

  2. Evandro Says:

    Wow. I had no idea someone was working on this, where were you a few weeks ago?

    I have a DualShock 3 and I wasted many hours on the internet finding a way for it to work well on Linux. The goal was to play Super Meat Boy and Bastion on Linux with a controller.

    The solution I found was to use a program called “xboxdrv”. It creates a virtual joystick device that’s recognized by programs as an Xbox 360 controller, and all the DualShock 3 buttons are mapped appropriately. So with that program I was able to play both games perfectly (using USB only; I have the controller synched to a PS3 so I didn’t want to deal with Bluetooth). Also worth noting is that these particular games only support the Xbox 360 controller, so the driver was very useful.

    Anyway, I hope this helps. You can find xboxdrv here: http://pingus.seul.org/~grumbel/xboxdrv/xboxdrv.html. It’s also packaged in Debian/Ubuntu and available in Arch’s AUR.

    It comes with a configuration file for the Dual Shock 3, and I also had to invert some of the axis for it to work right. Here’s the resulting line once you get the binary and the Dual Shock preset in place:

    xboxdrv -s –axismap -Y1=Y1 –axismap -Y2=Y2 -c playstation3.xboxdrv

  3. Zen Says:

    The PS3 gamepad (Dualshock 3) needs to be paired with the computer (using the USB cable) before it can be used through bluetooth.

    The Wii gamepad needs a driver, I used wminput.

    Those are areas where a Gnome utility would really be useful.

    By the way, joydev is completely deprecated now, and evdev should be used instead. I see no point in supporting joydev these days. Evdev is a superset of the deprecated joydev API.

    evdev has three event types relative to gamepads:
    – EV_KEY (key presses)
    – EV_ABS (absolute position, for example “33 on a range [0-100]”
    – EV_REL (relative movement, for example “+33 on the X axis”

    The Dualshock 3 controller has:
    – 2 analog sticks
    – 2 analog triggers (L2/R2)
    – 10 pressure-sensitive buttons (Up, Down, Left, Right, L1, R1, Triangle, Circle, Cross, Square)
    – 5 standard buttons (Start, Select, “PS”, L3, R3)
    – 1 6-axis accelerometer
    – 1 vibration motor

    * The analog sticks should be handled quite well (ABS_X, ABS_Y, ABS_HAT0X, ABS_HAT0Y).
    * The analog triggers are more complicated, but I guess I would map them on ABS_HAT1Y and ABS_HAT2Y).
    * The standard buttons are easy (BTN_START, BTN_SELECT, BTN_MODE, BTN_THUMBL, BTN_THUMBR).
    * The vibration motor should work just fine with the Force Feedback evdev API
    * The accelerometer should use ABS_RX/RY/RZ for rotation, translation is more problematic since the only logical thing would be to use ABS_X/Y/Z, but it’s already used for the main control, and applications don’t expect an accelerometer there anyway.
    * Last but not least, the pressure-sensitive buttons are a lot more problematic, each button is acting like an absolute axis. Most programs don’t expect to receive absolute axis values for buttons, only a pressed/released information. The good thing would be to send the simple button press information as well as the pressure information as an axis, except that we don’t have any way to do that (I guess that ABS_PRESSURE is a global device attribute and not specific to the event being sent).

    So in the end, I think that:
    – we should have additional axes for accelerometers (ABS_ACCX, ABS_ACCY, ABS_ACCZ, ABS_ACCRX, ABS_ACCRY, ABS_ACCRZ)
    – we should have an extension for pressure-sensitive buttons, maybe something a little similar to multi-touch and/or ABS_PRESSURE.
    – If we don’t have that, then the good thing would be to not export those features and just have the standard buttons and sticks.

    Note that accelerometer support would allow to support the wiimote as well.

    (I think that the current dualshock driver exposes all analog controls, all accelerometer data and all pressure-related buttons as separates absolute axes, and then all buttons as buttons as well, which is a mess if the end app is not aware of it)

  4. Joan Pau Says:

    Maybe you know it already, but in the ROS distribution (a framekork for development in robotics) there is a package to handle the DualShock 3 or SixAxis gamepads I used to overcome the problems with these devices:
    http://www.ros.org/wiki/ps3joy

    It is a sort of user space driver, as the wiki says:
    “Because this package can be used independently of ROS by people wishing to use a PS3 joystick in linux, I am providing a direct link to the driver here. In order to run this python file, you will have to have the following system dependencies installed: python, bluez, python-bluez, joystick, libusb-dev.”

    Clearly it is a temporary solution. Again from the wiki:
    “With maturing support for the PS3 joystick in BlueZ and the Linux kernel, we hope that most people will no longer need this package unless they want to use the gyroscope and accelerometer axes”.

    I do not know if the documentation and code there may be helpful for you, but for sure people in the project will be happy with the improvements in the device support.


  5. […] radical happened since the last report just a few days ago. A couple of you left some comments that I haven’t yet had time to get […]


Leave a comment