• No results found

B.5 Conclusie

C.3.4 Installatie

Zoals eerder gezegd is er gekozen voor Ubuntu 14.04, dit is een Linux systeem gebaseerd op Debian. Er is gekozen voor de volgende partitie indeling:

mountpoint grote type /boot 200mb ext4 / 60gb ext4 /var 25gb ext4 /swap 10gb swap /tmp 5gb ext4 /home 400gb ext4

In het kort; de boot partitie bevat de kernel en wordt het eerste geinitialiseerd bij boot. in ’/’, de root van het filesystem staat de installatie van het systeem (denk C schijf van windows), de ‘/var’ partitie bevat onder andere logging, de ‘/swap’ partitie legt zichzelf uit, deze partitie wordt gebruikt om te swappen. De ‘/tmp’ partitie is volatile en bevat tijdelijke bestanden, deze wordt elke boot gewist. De ‘/home’ partitie bevat settings en data van de users.

Voor deze opzet is gekozen omdat zo de ‘/boot’ en ‘/’ partities als read-only gemount kunnen worden en zodoende enige robuustheid tegen plotselinge stroomuitval wordt behaald. In linux is een partitie read-only te mounten door de option ‘ro’ toe te voegen en ‘/etc/fstab’.

C.3.5

Configuratie na installatie

Ondanks dat het systeem naar verwachting practisch altijd headless (zonder monitor) gebruikt zal worden is er toch een Desktop versie van Ubuntu geinstalleerd, zodat een grafische omgeving wel beschikbaar is voor het weergeven van status met een scherm. Het blijkt echter dat er voor de grafische kaart van het systeem geen drivers beschikbaar zijn. Dit betekend dat er geen hardware acceleratie beschikbaar is, wat voor de standaard grafische omgeving van Ubuntu (Unity genaamd) wel een vereiste is. Derhalve is besloten om de alternatieve desktopomgeving XFCE te installeren, practisch gezien is het systeem dus hetzelfde als de Xubuntu distributie geworden. XFCE is een grafische interface die zeer weinig frutsels, effecten en dus systeem-eisen heeft. (Dit installeren is niets anders danapt-get install xubuntu-desktop, dan opnieuw uit en inloggen.) Na installatie van deze omgeving is er wel spraken van een snel en responsive systeem.

De volgende stap is zorgen dat we ons niet druk hoeven te maken om de grafische interface, het installeren van een SSH (Secure Shell) daemon zorgt dat ten alle tijden op afstand ingelogd kan worden.

Dit wordt geinstalleerd doorapt-get install openssh-server, dit installeer de SSH server. Hier kan met username en wachtwoord naar verbonden worden (ssh user@[ip/host], beter is echter om inloggen met wachtwoorden uit te zetten en gebruik te maken van SSH certificates. In dit geval is er een bestand wat gebruikt wordt als ‘wachtwoord’, dit is velen malen veiliger, net als bij Tinc. (Handleidingen hiervoor staan op internet, het bestaat uit het maken van een SSH key, vervolgens moet het public deel van deze key op de host worden geplaatst.)

C.3.6

CAN

Deze sectie legt uit hoe het CAN systeem op de huidige IPC van het type iEi DRPC-100 geimplementeerd is. Dit systeem is bij recentere versies vervangen voor een betere computer, zodat het gedoe met deze kernel module niet meer optreedt. De eerste paragraaf zou dan ook overgeslagen kunnen worden.

Library & Kernel module.

De kernel in linux zorgt er voor dat het mogelijk is om met de hardware te interacteren, en verzorgt eveneens de Hardware Abstraction Layer (HAL). Dit zorgt er voor dat het systeems zich hetzelfde gedraagt ongeacht de hardware. Het is good-practice om ten alle tijden een HAL te gebruiken zodat de hardware uitwisselbaar is. In linux moet de communicatie met hardware soms met een kernel module gebeuren, dat is een stukje code wat in de kernel uitgevoerd wordt en wat de interactie met de hardware verzorgt.

De bijgeleverde CAN driver (ieiCANSDK_v1.3.tgz), heeft eveneens een kernel module (p1680.koge- naamd), daarnaast is er een library (libpci_1680.sogenaamd) bijgeleverd die communiceerd met de kernel module. De code van de kernel module vereist enkele wijzigingen om te compileren voor kernel 3.19. Deze wijzigingen zijn nodig omdat deze nieuwere versie van de Kernel anders omgaat met inode strutures en verschillende compilatie fouten opgelost moesten.

In kernel 3.19 is een verandering gemaakt aan de inode structure waardoor kernel driver aangepast moet, p1680.c:

- struct inode *inode = file->f_dentry->d_inode; + struct inode *inode = file->f_path.dentry->d_inode;

Verder moet in de library stdbool.h geinclude worden.

Bij het booten van de machine moet metinsmodde geproduceerde kernel module p1680.ko aan de kernel worden toegevoegd. Het bijgevoegde perl script voegt vervolgens de device node toe aan/dev/, deze is vervangen door een shell script welke deze functionaliteit bevat zodat deze aanrc.local

toegevoegd kan worden. Perl is op dat runlevel nog niet beschikbaar om scripts uit te voeren, bash wel dus het is wenselijk om dit in bash te doen.

Nu de kernel module geladen is en/dev/PCI1680W0aangemaakt is om met de hardware te communi- ceren is kan met behulp van de library in user-land gecommuniceerd worden met de CAN bus.

SocketCAN

Linux heeft een standaard systeem voor CAN, dit zit in de standaard kernel en draagt de naam

SocketCANin feitte is dit een gestandaardiseerde interface - net als een netwerk kaart - voor CAN berichten. Aangezien we onafhankelijk willen werken van de gebruikte hardware is het zeer wenselijk om hier gebruik van te maken. Om dit te bereiken moeten de CAN berichten met behulp van de bijgeleverde library van de hardware doorgestuurd worden naar hetSocketCANsysteem.

Om gebruik te maken vanSocketCANmoeten devcanencanmodules toe aan/etc/moduleszodat deze in de kernel geladen worden bij system boot. Met deze modules kan een virtuele CAN inter- face gemaakt worden die wevcan0noemen. Nu is het zaak om met behulp van de bijgeleverde

libpci_1680.solibrary de berichten uit et lezen en door te sturen naar devcan0interface. De can_unifier

Met behulp van PYTHONis het mogelijk om de library, ondanks dat hij inCgecompileerd is te ge- bruiken door dectypesmodule te gebruiken. Om te interacteren met hetSocketCANsysteem is de

python-canmodule beschikbaar. Na het schrijven van een object wat de library gebruikt om berich- ten te lezen en zenden is er een script geschreven wat optreedt als brug tussen de hardware en het

SocketCANsysteem.

Dit PYTHONscript bevat een klasse, die met behulp van de library de CAN bus aanspreekbaar maakt vanuit PYTHON. Verschillende functionaliteiten zijn beschikbaar in met dit script:

usage: can_unifier.py [-h] [--test] [--baudrate BAUDRATE] [--bridge] [--dump] [--can CAN] [--port PORT]

CAN unifier, makes iEi hardware uniform to the can4linux standard CAN backend in linux. optional arguments:

-h, --help show this help message and exit

--test Does a small selftest between the two can ports of the first card. Respects baudrate.

--baudrate BAUDRATE, -b BAUDRATE

Baudrate to use for the communication. (default 250000)

--bridge Bridge between can4linux and hardware bus. --dump Dump packets on hardware to channel. --can CAN, -c CAN Use this can4linux interface.

--port PORT, -p PORT Use this CAN port on hardware Example usage:

To bridge the first CAN port to the vcan0 can4linux interface: can_unifier.py --bridge --can vcan0 --port 0

can_unifier.py --bridge --can vcan0 --port 0 -b 250000 To dump all messages on port 1 (the second one) to stdout.

can_unifier.py --dump --port 1

One should not use the same port with two different processes. To test sending and receiving at 1M baud:

can_unifier.py --test -b 1000000

This prints when messages are sent, and when they are received. Keeps a counter to verify that no messages are lost, sents 255 messages.

heen en weer stuurt en kijkt of dit succesvol is. Eventuele andere berichten op de bus worden in dit geval genegeerd. De dump mode is enkel om het verkeer op een poort passief te dumpen naar de stdout. Indien de bridge gebruikt wordt worden berichten die op deSocketCANinterface gepushed worden ook ge-echod naar de fysieke CAN bus. Dus hij bridged twee kanten op.

Testing

Omdat de werking van de CAN bus essentieel is voor het dataloggen initieel en later mogelijk ook gebruikt zal worden voor control is van van belang om deze goed te testen. De initiele test zijn gedaan met één enkel apparaat aan de CAN bus (een oude controller van GÖTTING). Dit zijn slechts 100 berichten per seconden is kan derhalve niet gezien worden als extensieve test.

Voor uitgebreidere tests is gebruik gemaakt van het feit dat de IPC twee can poorten heeft. Hierdoor is het mogelijk om op een poort te zenden en op een ander te ontvangen. In figuur C.4 is te zien wat de test opzet was. Er zijn twee virtuele CAN interfaces aangemaakt. Door het bridge script tweemaal uit te voeren wordt elke poort gebridged met zijn virtuele can interface. Omdat er gebruik gemaakt wordt van deSocketCANbackend kunnen de standaard tools uit decan-utilslinux package gebruikt worden. Dit bevatcanbusloadencangen, de eerste is in staat om het gebruik van de BUS weer te geven en de tweede kan gebruikt worden om random berichten te genereren en naar een interface te sturen. Dit laatste is gebruikt om random data opvcan0te zetten, dit wordt vervolgens gebridged naar de hardwareCan 0poort, deze gaat over het draadje waar deze door zowel het GÖTTINGapparaat als de tweede CAN poort ontvangen wordt. Doordat daar ook een bridge draait komt het pakketje uiteindelijk weer terecht opvcan1. Deze virtuele CAN interfaces kunnen met behulp van standaard tools zoals

Wiresharkgeinspecteerd worden.

Bij deze tests zijn er verscheidene contstateringen gedaan:

• De functieCanGetRcvCntreturned soms 127, dit is -1 in een byte, terwijl de library een signed integer zou moeten returnen. Dit is aangenomen als 0 pakketjes in de buffer.

• Dezelfde functie returned soms 137, in dit geval is het uitgelezen pakketje constant hetzelfde, dus dit is impliciet aangenomen als 0 pakketjes in de buffer.

• De functiesCanClearRxBufferenCanClearOverrundoen niets.

• De functie wachtte van origine 10 ms per verzonden bericht, wat de throughput limiteerd tot 100 berichten per seconden, dit is aangepast naar 0.1 ms

• Er is een mogelijkheid dat de library een bericht produceerd waarvan de CAN identifier groter is dan 228, dit zou niet moeten mogen. Als dit optreedt dan blijftCanGetRcvCntfunctie melden dat er een bericht is, welke steeds hetzelfde is. Het heropenen van de interface lost dit probleem op, maar dit is zeer onpractisch, nader onderzoek leidde tot de conclusie dat dit bericht uit de hardware volgt. (Misschien een collision van de berichten op de bus die niet goed afgehandeld wordt?)

De gehele library is van zéér matige code-kwaliteit en bevat zeer veel ‘magic numbers’3. Na enkele aanpassingen en optimalisaties in de library en de PYTHONcode is het wel gelukt om ongeveer 1400 CAN berichten per seconden te verwerken. Omdat er echter gebruik gemaakt moet worden van polling kost dit een significante hoeveelheid CPU gebruik, zo’n 25%. De belasting van de CAN interface zal in realiteit vele malen lager zijn en de verwachting is dat dit geen probleem zal zijn.

can_unifier vcan0 port0 can_unifier vcan1 port1 Can 1

IPC

Go

et

ti

ng

Figuur C.4: De test-setup van de CAN bus, twee instances van het bridge script worden gebruikt en twee virtuele CAN interfaces.

Het uitlezen van de CAN bus is kritiek voor de werking van de INNOVADO, in de toekomst is het mogelijk wenselijk om een IPC te gebruiken waarvan de CAN bus standaard onder- steund is door linux of een deugdelijke driver heeft welke direct gebruik maakt van het

SocketCANframework. Dit bespaard mogelijk instabiliteit door slechte hardware. Update September 2016: Dit advies is doorgevoerd en er wordt nu een andere IPC gebruikt en een PeakCAN kaart als CAN interface.

C.4

Monitoring en logging

Omdat er voor het werk aan het nieuwe localisatie systeem geregeld recordings van data gemaakt moesten worden zijn er enkele programma’s en ‘toolies’ uitgerold om dit te faciliteren. Deze sectie licht enkele van deze tools toe, en hoe / waarom er voor deze gekozen is.

C.4.1

Supervisor

Om bij system-boot meerdere processen te kunnen starten zijn er legio systemen en opties. Wat we willen is een portable configuratie die ons in staat stelt om output van processen te inspecteren en gemakkelijk het herstarten van processen faciliteerd.

• upstart / init.d scripts / crontab @reboot: de eerste twee zijn de standaard methoden om in Debian based systeem processen te starten. Configuratie is tricky en omvat het plaatsen van verschillende shell scripts in de juiste mappen, debuggen van deze is lastig omdat de output ‘zoek’ raakt als deze crashen bij het starten. Output van processen moet met de hand naar een logfile ge-redirect worden en het realtime monitoren van de output is derhalve even lastig. Dit zou op te lossen zijn door elk process in eenscreente draaien maar dit levert een wildgroei aan

Figuur C.5: Screenshot van de webinterface van supervisord zoals deze op Charlie draait.

• Daemontools (http://cr.yp.to/daemontools.html): dit lijkt te doen wat nodig is, echter het live-inspecteren van de output moet gebeuren door de log file te bekijken. Daarnaast lijkt de documentatie enigszins achtergebleven.

• Circus: A Process & Socket Manager (http://circus.readthedocs.org/en/latest/): Deze in PYTHONgeschreven tool lijkt vooral bedoeld voor het managen van (*sgi) processen en even- tuele bijbehorende processen voor webservers. Het is echter vooral ook bedoeld om tussen de processen in te zitten, het voorbeeld wat aangehaald wordt is load balancing via Circus, hierbij managed het dus de socket van de webserver naar de workers / server nodes erachter. Dit is geen functionaliteit die we nodig hebben, daarnaast heeft het een dependency op zeroMQ, wat ook niet nodig is in ons geval.

• Supervisord (http://supervisord.org/, [16]): Een eveneens in PYTHONgeschreven supervi- sor is bekend en wordt door velen aangeraden. Elk proces heeft een simpel configuratiebestand wat specificeerd hoe het process uitgevoerd moet worden. Inspecteren van de output en stoppen en starten kan via de commandline of de eenvoudige webinterace. Daarnaast regelt deze tool logging en rotatie van deze logs.

Initieel werd gebruik gemaakt van de eerste optie waarbij er in verschillendescreensprocessen draaide. Toen er meerdere processen nodig waren was dit echter steeds onhandiger waardoor na een korte vergelijking gekozen is om gerbuik te gaan maken van Supervisord. Een screenshot van de webinterface is te zien in C.5, hierin is in een oogopslag te zien wat de status is van de processen en zijn deze te stoppen / starten of is de output te bekijken.

C.4.2

Loggers

Verschillende tools zijn geschreven om logging mogelijk te maken.

goetting_logger

Vanwege de noodzaak om de data van de wielencoders te verkrijgen zonder dat dit via BODAS moet verlopen is het wenselijk om de logs van GÖTTINGpseudo-realtime uit te kunnen lezen. Hiertoe is degoettin_loggergeschreven welke via het netwerk overtelnetverbind naar de GÖTTINGstuur- computer. De output die via deze verbinding verkregen word is hetzelfde als de logregels die door de

stuurcomputer naar de USB stick geschreven kunnen worden. Het opslaan van de output faciliteerd dus zowel het verkrijgen van de data van de wielencoders als het continue loggen van de performance en output van GÖTTINGwat na fouten een extensieve analyse mogelijk maakt mochten er navigatiefouten optreden.

Dit process is vere van ideaal, de logregels zoals deze worden doorgestuurd door GÖTTINGzijn een ascii formaat, het ‘realtime’ uitlezen van deze viatelnetkost relatief veel CPU belasting. De PYTHON

telnetmodule zal niet bijdrage aan de performance, deze gebruikt een receive buffer van 50 bytes (zie

fill_rawqfunctie intelnetlib.py), na het toevoegen van deze bytes aan de buffer wordt de hele buffer opnieuw geparsed in de hoop om het ‘read until’ karakter te vinden of eentelnetcommand. Gezien een GÖTTINGlogregel rond de 2000 karakters zit wordt er veelvuldig zinloos over de buffer geitereerd.

Naast dat dit script de output logt naar een file maakt deze de output ook beschikbaar op een TCP socket zodat de ruwe log-regels voor andere processen ook beschikbaar is. Onder andere het ‘realtime’- importeren van deze data naar ROS en de omzetting naar joint states geschied via deze TCP verbinding. Er wordt een TCP socket gebruikt op localhost omdat dit een standaard is om verschillende processen makkelijk data te laten uitwisselen, ook is het mogelijk om met commandline tools zoals ‘netcat’ te verbinden naar de socket en de output visueel te inspecteren.

GÖTTING_log_analysis

De stuurcomputer van GÖTTINGlogt in csv bestanden, waarbij elke regel meer dan 300 kolommen bevat. Elke 50 ms wordt er een nieuwe logregel geschreven. Om de wielencoder data beschikbaar te hebben moeten de logregels uit GÖTTINGbeschikbaar zijn. Bijkomend voordeel is dat indien er eenmaal een parser is voor deze gegevens deze ook gebruikt kan worden voor de analyse van de rijperformance van GÖTTINGhetgeen zinvolle informatie verschaft in de werking van het huidige prototype.

Dit stuk PYTHONcode is in staat om een logbestand in te lezen en om te zetten naar handige NumPy arrays waardoor visualisatie van de data gemakkelijk wordt. Deze tool is veelvuldig gebruikt om navigatiefouten bij Vrielink te debuggen en de data van Goetting inzichtelijk te maken.

Dit zelfde stuk code wordt ook benut door de ROS node die de wielencoders omzet naar jointstates.

can_logger

Deze logger slaat alle berichten die via SocketCAN binnenkomen op in een bestand en bied deze ook via een TCP socket aan. Deze logger depend op depython-canmodule. In funtionaliteit is deze practisch hetzelfde als de eerder beschreven goetting_logger. De CAN berichten worden met timestamp en hexadecimaal representatie gelogd en via de TCP socket aangeboden. Dit heeft het grote voordeel dat er eenvoudig met grep en dergelijke gezocht kan worden in de logfiles indien alle logs van een bepaalde ID gezocht worden. Daarnaast kan met een simpele netcat commando gekeken worden of er data ontvangen wordt via CAN.

log_compressor

Dit programma wordt gebruikt om logs te comprimeren, gezien zowel de CAN als GÖTTINGlogs in ascii formaat zijn en erg veel repetitieve data bevatten wordt er veel ruimte gewonnen door compressie. De keuze om de logs pas achteraf te comprimeren in plaats van tijdens het loggen naar een gezipped bestand te schrijven is gemaakt omdat gezipte bestanden corrupt raken indeen deze op een willekeurig moment afgebroken worden. Door te loggen naar een textbestand en deze pas achteraf te comprimeren zijn corrupte bestanden te voorkomen.

Deze data corruptie wordt voorkomen doordat deze log compressor voor elke log de volgende stappen