Deze pagina gaat over hetzelfde project, maar uitdrukkelijk over het werkend krijgen ervan in Linux. Dus niet de ontwikkelingen op het gebied van de elektronica zelf, maar het zoeken naar de mogelijkheid om het werkend te krijgen in ArchLinux.
Daarbij bestaat het dashboard uit twee afzonderlijke delen: De Arduino Mega die naar signalen uit de spellen luistert en de Arduino Due die het overgrote deel van de joystickzijde verzorgt. De Fanatec stuurwielbasis hoort er ook bij.
De Arduino Mega en Monocoque
Monocoque is een Linux-alternatief voor het Windows programma SimHub en stuurt telemetrie informatie uit een spel door naar een Arduino, op basis van de configuratie van Monocoque. In mijn geval is dat een Arduino Mega. De Custom-Serial mogelijkheid van dit programma staat het gebruik van zelfbouw-modules toe. Monocoque lijkt op dit moment absoluut niet op SimHub als het om installatie en gebruik gaat, trouwens.
Het installeren vereist handmatig compileren, en vereist meerdere afhankelijkheden, waarvan sommige eveneens handmatige compilatie vereisten, met daarvoor weer elk hun eigen afhankelijkheden. (De zogenaamde “dependency hell”). Dat veel van deze afhankelijkheden in ArchLinux de naam droegen zoals vermeld in de documentatie van Monocoque, was reden om voor ArchLinux te kiezen, naast de VR-ondersteuning.
Ik richt me dan ook niet op het installeren van ervan – door de vele Linux-versies is dat bijna onmogelijk – maar meer op het gebruik. Voor verbinding met een Arduino moet je de configuratie juist instellen. Dit configuratiebestand vind je in:
/home/$user/.config/monocoque/
$user is jouw eigen gebruikersnaam. In deze map vind je het bestand monocoque.config dat er op mijn machine zo uitziet:
configs = (
{
sim = "default";
// one can also specify sim by using the "short-name" for example "ac". also, "acc", "ace", "ams2", "et", "at" and "rf2"
//sim = "ac";
car = "default";
devices = (
{
device = "Serial";
type = "custom";
config = "~/monocoque/conf/custom.lua"
baud = 115200;
devpath = "/dev/ttyACM0";
},
{
device = "Serial";
type = "custom";
config = "~/monocoque/conf/unospeedo.lua"
baud = 115200;
devpath = "/dev/ttyACM1";
});
}
);
sim = default richt zich op een spel dat geen “vertaalbrug” nodig heeft. Voor ETS2 gaat dit op zolang je de “Native Steam” versie gebruikt. Elke Proton-versie betekend dat je in feite de Windows-versie van dit spel gebruikt, waardoor de plek waar Monooque zoekt naar de telemetrie veranderd. OMSI2 vereist dan vermoedelijk ook een andere vermelding. Voor zo ver ik nu weet, ontbreekt de ondersteuning voor OMSI2 nog.
Het type “custom” verwijst naar het gebruik van zelfbouw-modules. Deze functionaliteit lijkt veel op de CustomProtocol of CustomSerial functie van SimHub, die het gebruik van apparatuur die geen kant-en-klare bibliotheek gebruikte mogelijk maakte (denk aan het aansturen van een individuele LED).
config = is een bestand dat je vindt in:
/home/$user/monocoque/conf/
$user is opnieuw jouw eigen gebruikersnaam.
Deze map bevat meerdere configuratiebestanden voor kant-en-klare modules zoals LED-vlaggen en B/C-merk toerentalmeter. Hier breng je ook de configuratiebestanden onder voor je “custom serial” apparaten. De Arduino Mega ziet er bijvoorbeeld aan mijn kant zo uit, in het custom.lua bestand:
Message = simdata.velocity .. ";" .. simdata.gear .. ";" .. simdata.rpm .. ";"
Dit bestand kun je ook vinden op de Github-pagina van het project.
Op dit moment ben ik blij dat dit al werkte en het dashboard er (tot op zekere hoogte) correct op reageerde. Monocoque heeft, voor mij 1 ding gemeen met SimHub: ik begrijp de syntax van de programmeertaal niet. SimHub gebruikt NCalc, Monocoque LUA. Het is me dan ook nog niet gelukt om succesvol meer informatie uit ETS2 te krijgen zonder dat de applicatie stopt door een fout. Wat ook niet lukt, is zorgen dat bij het achteruitrijden de automaat-lampjes op het dashboard juist werken: in Windows is achteruit een negatief getal. In Linux is het 0, /, – en * meen ik zo uit mijn hoofd.
Dat ik mij op ETS2 richt is meer gemak dan een gerichte keuze: omdat dit spel geen vertaalbrug nodig heeft, wil ik daar eerst alles werkend krijgen. Daarna komen de andere spellen aan bod.
Van het in Linux deels werkende dashboard maakte ik een korte video. Het turbine-achtige geluid is dat van de kleine Lenovo die het héél erg warm had…
De Arduino Due in Linux
De joystickzijde van het dashboard is grotendeels een zelfbouw-joystick, met als hart een Arduino Due. Daarop gebruik ik de Heironimus joystick-bibliotheek die een joystick met 87 knoppen en 0 assen creëert. In Windows ziet het onderdeel “Spelbesturingen Instellen” maar 32 knoppen, maar spellen met de juiste ondersteuning “zien” de rest wel.
OMSI2 staat er maar 31 toe per joystick. De rest wees ik daarom toe aan virtuele josticks via Universal Control Remapper die elke virtuele joystick een unieke naam gaf. Dat is belangrijk, want in OMSI kun je van 3 joysticks met dezelfde naam maar 1 exemplaar toevoegen. In Linux kwam ik dan ook op meerdere manieren in de problemen: de kernel heeft een nagenoeg onveranderbare, harde limiet van maximaal 80 knoppen.
Ik zeg nagenoeg, want een kernel-aanpassing kan die limiet verhogen naar 104. Alleen is het bouwen van een aangepaste kernel niet iets dat de gemiddelde Linux-instapper snal zal doen. Het komt erg dicht in de buurt van het passeren van de grens van wat behapbaar is. Ter test probeerde ik het wel, gebruikmakend van dit verzoek tot officieel aanpassen van de kernel en zag meer dan 80 knoppen in KDE’s Spelbesturingen (in “Instellingen”).
Dit creëerde een nieuw probleem. Ergens vindt namelijk een vertaalslag plaats tussen de kernel en het computerspel. Of dit Steam, evdev of SDL is, is mij onbekend, maar ETS2 pikte het in ieder geval niet. Elke knop met een knopnummer groter dan 80 die je probeerde toe te wijzen (of zelfs maar gebruikte), zorgde voor een fatale fout, waarna het spel geforceerd stopte. En dan heb ik het nog niet over OMSI2…
Helaas bestaat er geen Universal Control Remapper voor Linux, AntiMicroX komt er nog het meest bij in de buurt. Dit programma kan alleen knoppen toewijzen aan gamepad-stijl joystick knoppen, geen nummers. Kom je knoppen te kort, moet je een nieuwe virtuele joystick aanmaken, wat gemakkelijk onoverzichtelijk wordt. Je moet van elke knop onthouden aan welke virtuele joystick die gekoppeld is.
Daarom wilde ik de joystick-code op de Due aanpassen zodat ik 3 joystick-apparaten zou creëren. Zo kan OMSI er 1 volledig oppakken en hoef ik er nog maar 2 via AntiMicroX naar virtuele joysticks uit te voeren. De Arduino Due code werd daarom aangepast en creerde 3 joysticks. Maar die zag ik niet in Linux. De Arduino Due bleef zichzelf maar presenteren als 1 apparaat…
USB-Quirks
Om 1 fysiek HID apparaat meerdere virtuele apparaten te laten creëren, bestaat er in Linux de zogenaamde “usb.quirk” regel. Op de Wikipagina van de joystick bibliotheek, wordt hierover een melding gemaakt. Ik was nieuwsgierig of dit ook werkte voor een Due, die niet in de tekst genoemd wordt. Om uit te vinden welke informatie je moet invoeren, gebruik je het commando lsusb. De Arduino Due is gemarkeerd:
:~$ lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 05e3:0610 Genesys Logic, Inc. Hub
Bus 001 Device 003: ID 0582:0159 Roland Corp. DUO-CAPTURE EX
Bus 001 Device 004: ID 1050:0407 Yubico.com Yubikey 4/5 OTP+U2F+CCID
Bus 001 Device 005: ID 04b4:0510 Cypress Semiconductor Corp. HID Keyboard
Bus 001 Device 006: ID 1a7c:0197 Evoluent Evoluent VerticalMouse D
Bus 001 Device 007: ID 2341:003e Arduino SA Due
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 002 Device 002: ID 05e3:0620 Genesys Logic, Inc. GL3523 Hub
De combinatie van nummers en letters achter “ID” slaat op de VID en de PID: Vendor ID en Product ID. Arduino als bedrijf, gebruikt 2341. Deze zal voor veel Arduino’s dus hetzelfde zijn. De Product ID, 003e verteld ons dat het een Arduino Due betreft. Voer lsusb niet uit als de Due verbonden is met de programmeerpoort. Die heeft PID 003d en kun je in Linux niet gebruiken om je joystick mee te laten werken in spellen. Voeg die dus niet toe!
Deze toevoeging is een aanpassing van een opstartregel in
/etc/default/grub
en ziet er als volgt uit. De rest van het document doet niet ter zake en laat ik weg. Ik heb de toevoeging gemarkeerd voor de duidelijkheid:
# If you change this file, run 'update-grub' afterwards to update
# /boot/grub/grub.cfg.
# For full documentation of the options in this file, see:
# info -f grub -n 'Simple configuration'
GRUB_DEFAULT=0
GRUB_TIMEOUT_STYLE=hidden
GRUB_TIMEOUT=0
GRUB_DISTRIBUTOR=`( . /etc/os-release; echo ${NAME:-Ubuntu} ) 2>/dev/null || echo Ubuntu`
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash usbhid.quirks=0x2341:0x003e:0x040"
GRUB_CMDLINE_LINUX=""
Voer hierna “sudo update-grub” uit om deze wijziging in grub op te nemen, anders start je kernel op zonder deze aanpassing. Toen ik dat gedaan had, was het tijd om opnieuw op te starten (en hopen dat ik niet toch iets verkeerd gedaan had). Toen ik jstest-gtk startte, zag ik dat het ook voor de Due werkt:

Het is een bewuste keuze om voor 31 knoppen te kiezen, voor OMSI2. Nu is het een kwestie van de hele Arduino code omzetten: elke knop boven 31 moet worden ondergebracht in een nieuwe joystick, waar het tellen van knoppen opnieuw begint. Voor de eerste joystick lukt dat nog wel redelijk makkelijk, maar daarna moet ik goed opletten en rekenen. De fysieke pin op een Arduino was in de oude situatie namelijk gelinkt aan het joystick-knopnummer dat je manipuleert.
Wordt dus vervolgd.