blog · git · desktop · images · contact & privacy · gopher


Logitech DFP: Auto-Kalibrierung mit udev

Gestriger Ausflug in die alten NFS2-Zeiten hat mich daran erinnert, dass ich mir -- noch zu Windows-Zeiten -- ja mal für viel Geld ein Logitech Driving Force Pro samt dazu passender Simulation gekauft habe: GTR2. Das war jetzt lange Zeit in der Kiste verstaut und stand so rum. Wirklich ausprobiert hatte ich es unter Linux aber noch nie.

Eigentlich ist es ziemlich simpel. Erschwert wurde das Vorhaben lediglich dadurch, dass bei Arch die "joystick utilities" nicht mitinstalliert werden und auch nicht im regulären Repository sind. Aus wundersamen Gründen hab ich dann eine halbe Ewigkeit gebraucht, bis ich gemerkt hab, dass die im AUR zu finden sind. Von da an war es nicht mehr weit.

Zumindest, was den "legacy mode" des Devices angeht. Und abgesehen von Force Feedback.

Die Sache ist nämlich: Um abwärtskompatibel zu sein, befindet sich das Steuerrad (wie auch das G25 von Logitech -- die beiden sind sich ohnehin sehr ähnlich) nach dem ersten Einstecken in besagtem legacy mode. Hier erscheinen dann beide Pedale als eine Achse, das Lenkrad ist auf 200 Grad beschränkt und so weiter.

Spitzfindige Leute haben schon herausgefunden, was man prinzipiell tun muss, oder sind noch auf dem Weg zum fertigen Code. Bis in den Kernel haben es diese Ändernungen aber noch nicht geschafft. Deswegen werde ich das auch erstmal ein paar Tage zurückstellen, bis mehr Motivation da ist. ;) Es tut nämlich auch so schon ziemlich gut.

Stöpselt man das Device ans USB, gibt es sich (im legacy mode) zu erkennen:

$ lsusb
Bus 002 Device 024: ID 046d:c294 Logitech, Inc. Driving Force

Man beachte, dass kein "Pro" hinten dran steht. Genau das und die Device-ID "c294" statt "c298" signalisieren den legacy mode.

Es ist aber schon die nötige Device-Node erstellt und alle passenden Kernel-Module geladen, insbesondere joydev:

$ ls -al /dev/input
...
crw-r-----  1 root root 13, 69 2009-07-26 17:07 event5
crw-r--r--  1 root root 13,  0 2009-07-26 17:07 js0
...
$ lsmod | grep joydev
joydev                 10432  0

Schaut man jetzt einmal nach, was das Ding so von sich gibt ...

$ od < /dev/input/js0
0000000 044642 000740 000000 000201 044642 000740 000000 000601
0000020 044642 000740 000000 001201 044642 000740 000000 001601
0000040 044642 000740 000000 002201 044642 000740 000000 002601
...

... so merkt man schnell, dass es eine enorm große Deadzone nahe der Mittelstellung gibt -- womit man das Ding eigentlich wegschmeißen könnte, gäbe es nicht die joystick utilities (Link zur Bauanleitung im AUR siehe oben).

Was fehlt, ist eine saubere Kalibrierung:

$ jscal -c /dev/input/js0

Hat man das gemacht, kann man sich das Ergebnis erst noch einmal mit "od" anschauen, aber auch die Zahlenwerte wegspeichern:

$ jscal -p /dev/input/js0

Denn wenn man den USB-Stecker herauszieht, ist die Kalibrierung verloren. Prinzipiell könnte man einfach jedesmal von Hand oder in einem Skript "jscal" mit den obigen Werten von "jscal -p ..." neu aufrufen:

$ jscal -s 4,1,0,516,...

Ich bin aber faul. :) Die Gelegenheit habe ich also genutzt, um mir mal udev-Regeln anzusehen. Damit kann man schön automatisch ein Skript triggern, wenn das Lenkrad eingestöpselt wird:

ACTION=="add", BUS=="usb", KERNEL=="js?", \
    SYSFS{idVendor}=="046d", \
    SYSFS{idProduct}=="c294", \
    SYMLINK+="logi_dfp", \
    RUN+="/usr/bin/dfp-cali.sh"

Anhand der Vendor- und Product-ID wird das Gerät genau identifiziert, die passenden Werte stehen oben in der Ausgabe von "lsusb". Weiterhin soll die Regel nur reagieren, wenn am USB-Bus ein Gerät hinzugefügt wird und wenn dieses im Kernel "js?", also zum Beispiel "js0", heißt. Dann wird das Skript aufgerufen, aber vorher noch ein Symlink namens "logi_dfp" angelegt -- damit kann immer genau dieses Lenkrad eindeutig angesprochen und somit von eventuellen weiteren Joysticks unterschieden werden. Übrigens fliegt dieser Symlink automatisch wieder raus, wenn man den Stecker zieht. In besagtem Skript wird dann einfach "jscal -s ..." für "/dev/logi_dfp" ausgeführt und bei Bedarf noch ein paar Messages ins Syslog.

Überwachen kann man die Aktivitäten von udev übrigens hiermit:

$ udevadm monitor --udev

Daraus wird dann auch ersichtlich, wieso es nicht reicht, nur auf Vendor- und Product-ID zu reagieren: udev triggert nicht nur ein einziges Event, wenn man das Ding einstöpselt und das Kalibrierungs-Skript darf erst dann laufen, wenn "/dev/input/js?" da ist.

Mehr Informationen zum Schreiben von udev-Regeln gibt es unter anderem hier:

Meine udev-Akrobatik und das Skript hab ich mal in ein Arch-Paket gestopft (erscheint mir irgendwie allzu sehr spezifisch, um das ins AUR zu stellen...).

So, was stellen wir jetzt mit dem ganzen Kram an? Na klar, zuerst mal NFS2 ausprobieren. ;) Aber irgendwie ist das Lenkrad dafür ein bisschen zu overpowered. Richtig ausnutzen kann man es aber mit GTR2, was erstaunlich sauber mit Wine läuft. Man muss lediglich im ersten Bildschirm blind den "Optionen"-Knopf treffen, da dieser Screen nicht lesbar ist. Auch sollte die Windows-Version auf Win98 gesetzt sein, denn mit XP oder höher verweigert Wine hier den Dienst. Das Spiel läuft hier auch in 1920x1200 noch flüssig und der Alt-F11-Hotkey von Xfce kann wunderbar genutzt werden, um in den Fullscreen-Mode und zurück zu schalten.

Wäre es nicht so unverschämt groß, hätte ich mir auch VDrift schon angesehen. Will sagen, das tue ich ganz bestimmt noch, aber die Daten müssen erstmal durch meine kleine Leitung reintröpfeln. Das dauert noch.

Fehlt noch Force Feedback und der "extended mode".