(WS13-01) Scuderia

Aus Verteilte Systeme - Wiki
Wechseln zu: Navigation, Suche

Ein Telemetrie-System für das Rennteam Scuderia Mensa der Hochschule RheinMain, Standort Rüsselsheim

Teilnehmer

Name Email-Adresse Rolle(n) im Projekt
Christian Arlt Christian.Arlt@student.hs-rm.de
Olga Dedi olga@dedi.de Projektleiterin
Torben Grünewald torben.gruenewald@web.de
Andreas Werner hs@andy89.org Rüsselsheim-Kontakt

Inhaltsverzeichnis

Einleitung

Kontext

Im Rahmen eines Wahlprojektes soll ein Telemetrie-System für das Rennteam, Scuderia Mensa, der Hochschule RheinMain entwickelt werden. Mit Hilfe des Telemetrie-Systems soll es möglich sein, einzelne Sensoren des Autos während der Fahrt in Echtzeit überwachen zu können.

Odedi001 (Diskussion) 14:56, 26. Feb. 2014 (CET)

Problemstellung

Im Rahmen eines Wahlprojektes soll ein Telemetrie-System für das Rennteam, Scuderia Mensa, der Hochschule RheinMain entwickelt werden. Mit Hilfe des Telemetrie-Systems soll es möglich sein, einzelne Sensoren des Autos während der Fahrt in Echtzeit überwachen zu können. Während sich die Echtzeitüberwachung nur auf ausgewählte Sensoren bezieht, sollen alle anfallenden Daten, zur späteren Auswertung, auf einem Datenträger aufgezeichnet werden. Die Übertragung der Daten soll über Funk erfolgen, wobei die Wahl des Übertragungsmediums vom Zustand des Fahrzeugs (stehend oder fahrend) abhängen soll.

Odedi001 (Diskussion) 14:56, 26. Feb. 2014 (CET)

Grundlagen

CAN

Da in diesem Projekt nicht direkt mit dem CAN-Contoller gearbeitet wird, wird auf die Eigenschaften des CAN-Buses nicht weiter eingegangenen. Fokus in diesem Projekt ist die verwendete Linux CAN Socket Schnittstelle.

Die CAN Socket Schnittstelle erweitert die Berkeley Socket API um die Fähigkeit mit einem CAN-Bus Netzwerk zu kommunizieren. Ziel der Linux CAN Schnittstelle ist es, einen Standard zu schaffen mit denen alle gängigen CAN Controller angesprochen werden können. Zusätzlich besteht die Möglichkeit weitere Protokollschichten hinzuzufügen, beispielsweise TCP ähnliche Schichten.

Öffnen eines Sockets

Ein CAN-Socket wird mithilfe von socket(2) geöffnet.

 s = socket(PF_CAN, SOCK_RAW, CAN_RAW);

Bei CAN gibt es folgende Protokolle:

  • SOCK_RAW: CAN Frame werden vom Controller weitergeleitet.
  • SOCK_DGRAM: Broadcast Manager (BCM) Packete werden automatisch in CAN Frames Fragmentiert.

Nach dem Erstellen des Socket muss er durch bind(2) mit einem Interface verbunden werden. Es besteht auch die Möglichkeit von allen Interfaces zu empfangen. Weiter ist es möglich CAN-Daten aller Interfaces zu erhalten. Hierfür wird der index auf den Wert 0 gesetzt.

 struct sockaddr_can {
  sa_family_t can_family;
  int         can_ifindex;
  union {
   /* transport protocol class address info (e.g. ISOTP) */
   struct { canid_t rx_id, tx_id; } tp;
   /* reserved for future CAN protocols address information */
  } can_addr;
 };

Beispiel binding:

 int s;
 struct sockaddr_can addr;
 struct ifreq ifr;
 
 s = socket(PF_CAN, SOCK_RAW, CAN_RAW);
 
 strcpy(ifr.ifr_name, "can0" );
 ioctl(s, SIOCGIFINDEX, &ifr);
 
 addr.can_family = AF_CAN;
 addr.can_ifindex = ifr.ifr_ifindex;
 
 bind(s, (struct sockaddr *)&addr, sizeof(addr));


Aufbau eines RAW CAN Frames

Ein CAN-Frame besteht aus der can_id, der Länge und den bis zu 64 Bit an Daten. Die Error-Frames werden als CAN-Frame übertagen und in der ID kodiert. Der Dateninhalt ist bei einem Error-Frame leer.

 struct can_frame {
   canid_t can_id;  /* 32 bit CAN_ID + EFF/RTR/ERR flags */
   __u8    can_dlc; /* data length code: 0 .. 8 */
   __u8    data[8] __attribute__((aligned(8)));
 };

Empfang von CAN Nachrichten

Der Empfang kann über die Funktionen read(2) oder recv(2) erfolgen. Falls von allen CAN-Interfaces gelesen werden soll muss recvmsg(2) verwendet werden.

Senden von CAN Nachrichten

Das Senden kann über die Funktionen write(2) oder send(2) erfolgen. Falls von allen CAN-Interfaces gelesen werden soll muss sendto(2) verwendet werden.

Filtern von CAN Nachrichten

Es können beliebig viele Filter pro Socket gesetzt werden.

Ein Filter hat folgen Felder:

 struct can_filter {
   canid_t can_id;
   canid_t can_mask;
 };

Wenn die Bedienung

 <received_can_id> & mask == can_id & mask

erfüllt ist, wird die Message weitergeleitet.

Beispiel:

 struct can_filter rfilter[2];
 
 rfilter[0].can_id   = 0x123;
 rfilter[0].can_mask = CAN_SFF_MASK;
 rfilter[1].can_id   = 0x200;
 rfilter[1].can_mask = 0x700;
 
 setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter));

CAN Open

Allgemein

CAN Open ist ein Kommunikationsstandard für den CAN Feldbus. Der Kommunikationsstandard definiert die Layer 3 bis 7 des ISO OSI Models. CAN Open definiert die Einrichtung und Echtzeitkommunikation über CAN. Weiter definiert der Standard zusätzlich Mechanismen für die Synchronisation zwischen einzelnen Geräten. Alle Informationen werden der Anwendung als Service Objekte präsentiert. Ein Service Objekt bietet spezifizierte Funktionen an.

Geräte Aufbau

600

CAN Open ist in folgende Strukturen unterteilt:

  • Communication - Dieses Objekt ist für die Kommunikation mit den unterliegenden Netzwerk Struktur verantwortlich.
  • Object Dictionary - Das Object Dictionary ist eine Sammlung von Datenelementen die einen direkten Einfluss auf die Kommunikationsobjekte, Applikationsobjekte und ihre Zustände haben.
  • Application - Diese Objekte stellen die Verbindung zu eigentlichen Applikation her.

Der Inhalt der einzelenen Strukturen werden in jeweils separaten Device Profiles definiert. ((Quelle: DS-301: [[1]]))

The Object Dictionary

Einer der wichtigsten Teile einer CANOpen Pofilbeschreibung ist die Object Dictionary Beschreibung. In dieser Beschreibung sind alle Objekte aufgelistet, welche über das Netzwerk erreichbar sind. Jedes Objekt ist über eine eindeutige 16-Bit ID ansprechbar.

Index (hex) Object
0000 not used
0001-001F Static Data Types
0020-003F Complex Data Types
0040-005F Manufacturer Specific Complex Data Types
0060-007F Device Profile Specific Static Data Types
0080-009F Device Profile Specific Complex Data Types
00A0-0FFF Reserved for further use
1000-1FFF Communication Profile Area
2000-5FFF Manufacturer Specific Profile Area
6000-9FFF Standardized Device Profile Area
A000-FFFF Reserved for further use


Communication Objects (COBs)

In CAN Open werden folgende Nachrichtentypen unterschieden:

  • Service data object (SDO): Werden verwendet um Objekte einer bestimmten ID zu ändern(Peer-to-Peer).
  • Process data object (PDO): Werden verwendet um Objekte ohne Bezugnahme einer ID zu ändern(vergleichbar mit Broadcasts).
  • Emergency (EMCY): Nachrichten um vor einem kritischen Ereignis zu wahren. Diese Nachrichten können auftreten ohne eine explizite Anforderung.
  • Network Management (NMT): Werden zum Anlegen eines Objektes verwendet.
  • Layer Setting Service (LSS): Werden verwendet um IDs zu vergeben und verschiedene Einstellungen(wie z.B. Baudrate) zu verändern.

Die Nachrichtentypen werden anhand von CAN Message IDs unterschieden:

COB Type Bits 8 - 11 of COB-ID CAN ID Range
NMT 0000 0
SYNC 0001 128 (0x80)
Time Stamp 0010 256 (0x100)
Emergency 0001 129-250(0x81-0xff)
PDO1 - Transmit 0011 385-511 (0x181-0x1ff)
PDO1 - Receive 0100 513-639 (0x201-0x27f)
PDO2 - Transmit 0101 641-767 (0x281-0x2ff)
PDO2 - Receive 0110 769-895 (0x301-0x37f)
PDO3 - Transmit 0111 897-1023 (0x381-0x3ff)
PDO3 - Receive 1000 1025-1151 (0x401-0x47f)
PDO4 - Transmit 1001 1153-1279 (0x481-0x4ff)
PDO4 - Receive 1010 1281-1407 (0x501-0x57f)
SDO - Transmit 1011 1409-1535 (0x581-0x5ff)
SDO - Receive 1100 1537-1663 (0x601-0x67f)
Error control (node guarding) 1110 1793-1919 (0x701-0x77f)

CANOpen Stadien

550

Initialisation Status

Im Initialisation Status wird das Gerät initialisiert. Nach der Initialisierung wechselt der Status automatisch auf Pre-Operational.

550

Die Initialisierung wird in 3 Stadien unterteilt:

  • Reset Application: Setzen aller Parameter des herstellerspezifischen Profilbereichs und des standardisierten Geräteprofilbereichs auf vordefinierte Power-On Werte.
  • Reset Communication: Setzen aller Parameter der Kommunikationsobjekte auf vordefinierte Power-On Werte.
  • Initialising: Starten aller Gerätdienste und Wechseln in den Pre-Operational Status.

Pre-Operational Status

Im Pre-Operational Status ist es möglich Peer-to-Peer Kommunikation zu betreiben(Senden von Nachrichten über SDOs). Das Senden von PODs ist in diesem Status nicht erlaubt.

Es ist möglich mit dem Senden des Start_Remote_Node den Status in den Operational zu wechseln.

Operational Status

In diesem Status ist es möglich mit allen Kommunikationsobjekten zu arbeiten(PODs und SDOs). Beim Betreten dieses Status werden alle PDO Objekte nach der Beschreibung im Object Dictionary erzeugt.

Stopped Status

In diesem Modus muss alle Kommunikation bis auf node guarding und heartbeat eingestellt werden. Das Verwalten der Anwendungen ist in den einzelnen Geräte Profilen definiert.

Stadien und Communication Objects

INITIALISING PRE-OPERATIONAL OPERATIONAL STOPPED
PDO X
SDO X X
Synchronisation Object X X
Time Stamp Object X X
Emergency Object X X
Boot-Up Object X
Network Management Objects X X X

Process data object(PDO)

Die Process data object werden zur Kommunikation verwendet. Hierbei wird das Publisher/Subscriber Pattern verwendet.

Transmission Modes

Es gibt zwei Transmission Modes:

  • Synchronous Transmission
  • Asynchronous Transmission

Synchrone PDOs werden immer in einem genau definierten Zeitfenster übertragen. Dieses Zeitfenster wird durch das SYNC Object angeben. Dieses wird zyklisch von einer zentralen Stelle übermittelt(häufig vom Master).

Es gibt zwei Arten von Synchronen PDOs. Zum Einen Objekte die nicht periodisch wiederholt werden, sondern immer nur dann übermittelt werden, wenn ein SYNC Event aufgetretten ist und zum Anderen periodische Objekte die immer bei einem SYNC Evnet gesendet werden.

Weiter gibt es die Asynchronen PDOs, diese werden komplett unabhängig vom SYNC Event übertragen.

Producer/Consumers

Es gibt zwei Arten von Kommunikationsteilnehmern: Producer und Consumer.

Producer senden PDOs und Consumer sind die Empfänger dieser.

Websockets

Websocket ist ein 2011 als RFC 6455 von der IETF verabschiedetes Protokoll, das eine bidirektionale Kommunikation über TCP ermöglicht.

Um die Vorzüge des Websocket-Protokolls zu verdeutlichen, ist es wichtig einen Blick darauf zu werfen wie die Kommunikation zwischen Webbrowser und Server funktioniert und welche Technologien sonst zur Kommunikation eingesetzt wurden.

Standard HTTP

Bei der normalen HTTP Kommunikation stellt der Client eine Anfrage nach einer Webseite an den Server und bekommt diese als Antwort vom Server zurück.

HTTP-Request.png


Polling

Ein HTTP-Request kann zusammen mit der Webseite auch ein Javascript liefern, das vom Client ausgeführt wird und beispielsweise den Client dazu veranlasst in regelmäßigen Abständen neue Daten vom Server anzufordern. In diesem Fall muss die Webseite nicht erneut geladen werden, da sie vom Javascript anhand der neuen Daten aktualisiert wird. Während Daten vom Server geladen werden, kann der Benutzer trotzdem noch mit der Webseite interagieren. Diese Art der Kommunikation ist asynchron und in der Webentwicklung zusammen mit XML in dem Konzept AJAX verankert.

Polling.png


Long Polling

Wie bereits erleutert fragt der Client bei Polling in regelmäßigen Abständen beim Server Daten an. Wenn allerdings noch keine Daten verfügbar sind, erhält der Client eine leere Antwort und versucht es mit einem erneuten Request. Durch die häufigen Requests entsteht ein sehr hoher Overhead, der sich mit Hilfe von Long Polling reduzieren lässt. Dabei schickt der Client wie zuvor eine Anfrage, jedoch antwortet der Server nicht sofort, sondern erst wenn neue Daten verfügbar sind. Dies reduziert die ständigen Anfragen, jedoch wird dadurch die Latenzzeit stark erhöht.

Long Polling.png


Websocket

Das Websocket Protokoll ermöglicht es nun eine beständige TCP-Verbindung zu öffnen über die Client und Server bidirektional kommunizieren können. Der Overhead der ständigen Anfragen wird dadurch nahezu vollständig reduziert und zusätzlich wird der Client über ein Event über eingehende Daten informiert.

Websocket.png


Um Abwärtskompatibilität zu gewährleisten, wird die Verbindung über einen Handshake aufgebaut, der auf dem HTTP-Protokoll basiert. Dabei schickt der Client einen HTTP-Upgrade-Request an den Server und fordert diesen dazu auf, auf das Websocket Protokoll zu wechseln. Wenn der Server das Protokoll beherrscht kann er auf das Protokoll wechseln und bestätigt dies dem Client ebenfalls über den Upgrade-Header. Ein Beispiel-Handshake könnte so aussehen:

Request Headers

Cache-Control:no-cache
Connection:Upgrade
Cookie:PHPSESSID=666gonnovktmas3ok32353r322; x-autozoom=100f
Host:scuderia.cs.hs-rm.de:4243
Origin:http://scuderia.cs.hs-rm.de
Pragma:no-cache
Sec-WebSocket-Extensions:permessage-deflate; client_max_window_bits, x-webkit-deflate-frame
Sec-WebSocket-Key:DIidfJe1WcwyAtrkLONryg==
Sec-WebSocket-Version:13
Upgrade:websocket
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36

Response Headers

Connection:Upgrade
Sec-WebSocket-Accept:fg3w3wPYJ+qJiot5GU1zIRG52sM=
Server:libwebsock/1.0.7
Upgrade:websocket

Es ist möglich sowohl Strings, als auch Binärdaten über das Websocket Protokoll zu übertragen, dabei beschreibt der Header um welche Art von Daten und es sich handelt und deren Länge.


Header

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 +-+-+-+-+-------+-+-------------+-------------------------------+
 |F|R|R|R| opcode|M| Payload len |    Extended payload length    |
 |I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
 |N|V|V|V|       |S|             |   (if payload len==126/127)   |
 | |1|2|3|       |K|             |                               |
 +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
 |     Extended payload length continued, if payload len == 127  |
 + - - - - - - - - - - - - - - - +-------------------------------+
 |                               |Masking-key, if MASK set to 1  |
 +-------------------------------+-------------------------------+
 | Masking-key (continued)       |          Payload Data         |
 +-------------------------------- - - - - - - - - - - - - - - - +
 :                     Payload Data continued ...                :
 + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
 |                     Payload Data continued ...                |
 +---------------------------------------------------------------+


Clientseitig wird die API von der W3C standardisiert und findet immer mehr Unterstützung in modernen Browsern.

Odedi001 (Diskussion) 14:57, 26. Feb. 2014 (CET)

Analyse

Requirements

Grafischer Client

Die Bedienung des Telemetrie-Systems, so wie Darstellung der Sensordaten soll über eine grafische Benutzeroberfläche erfolgen.

Einstellung der Filter

Der grafische Client soll die Möglichkeit haben seine Sensorauswahl an das Fahrzeug zu übertragen, so dass nur tatsächlich angefordete Daten übermittelt werden und somit die benötigte Bandbreite reduziert wird.

Download aller Daten

Vorgabe des Auftraggebers

Die gesamten Daten sollen über die GUI vom Board heruntergeladen werden können.

Da die Micro-SD vom Gehäuse des Boards verhüllt wird, soll es möglich sein die aufgezeichneten Daten über die bereitgestelte GUI herunter zu laden.

Upload von Daten

Die heruntergeladenen Daten sollen in eine Datenbank importiert werden können.

Da die Daten als CSV heruntergeladen werden, können sie ohne großen Umstand in jede beliebige SQL-Datenbank importiert werden.

Einfache Bedienbarkeit

Vorgabe des Auftraggebers

Der Client soll einfach zu bedienen sein und ein breites Spektrum von Geräten unterstützen.

Um nicht nur unterschiedliche PC-Systeme zu unterstützen, sondern auch mobilen Geräten es zu ermöglichen den Dienst nutzen zu können, jedoch trotzdem nur eine Implementierung zu haben, bietet sich ein webbasierter Client an. Für die grafische Darstellung der Messdaten kann eine bereits existierende Plotting-Library verwendet werden. Die Plotting-Library sollte Javascript basiert sein, da somit das rechenintensive Rendering clientseitig erledig werden kann.

Verteilen der Daten

Die gemessenen Werte sollen an alle verbundenen Clients verteilt werden.

Kommunikation mit dem fahrenden Auto

Vorgabe des Auftraggebers

Während der Fahrt soll es ebenfalls möglich sein mit dem Fahrzeug zu kommunizieren. Da das Auto sehr hohe Geschwindigkeiten erreichen kann, soll hier für Mobilfunk als Übertragungsmedium genutzt werden.

Aufgrund des NATs des Mobilfunks, kann der lokale Webserver für den Dienst nicht verwendet werden. Das Board muss als Client die Verbindung zu einem Gateway aufbauen über welchen die Daten dann an die Web-Clients verteilt werden.

Livestream der aktuellen Daten

Vorgabe des Auftraggebers Das Fahrzeug soll während der Fahrt überwacht werden und die gemessenen Daten als Livestream an die Clients geschickt werden. Dabei werden die aktuellen Sensordaten in Echtzeit auf der grafischen Oberfläche geplottet.

Stabile Verbindung

Vorgabe des Auftraggebers

Die Verbindung soll während der Fahrt stabil bleiben. Bei Verbindungsabbrüchen muss sich das Gerät eigenstänig neu in das Mobilfunk einwählen und die Verbindung zum Gateway wieder herstellen können.

Kommunikation mit stehendem Fahrzeug

Bei stillstand des Fahrzeugs soll es ebenfalls möglich sein mit diesem zu kommunizieren.

Upload aller Daten auf eine zentrale Stelle

Alle gemessenen Daten sollen an einer zentralen Stelle gesammelt werden können. Die heruntergeladenen Daten sollen an einen zentralen Ort hochgeladen werden können, um alle gesammelten Daten auswerten zu können.

Livestream der aktuellen Daten

Auch bei Stillstand des Autos soll ein Livestream der aktuellen Messwerte möglich sein. Hierfür soll WLAN als Übertragungsmedium dienen, um eine höhere Bandbreite mit einfachem Zugang nutzen zu können.

Daten loggen

Alle gemessenen Werte sollen geloggt werden, dabei dürfen maximal Daten im Zeitraum von einer Sekunde verloren gehen.

Datenträger

Vorgabe des Auftraggebers

Die geloggten Daten sollen auf einem externen Datenträger gespeichert werden um sie auch später analysieren zu können. Der Datenträger soll von außen zugreiffbar sein.

Zentrales Ablegen der Daten

Alle gemessenen Werte sollen gemeinsam abgelegt werden. Das Ergebnis soll eine einzelne Log-Datei sein, die alle Daten beider CAN-Busse enthält.

Erfassen von Messgrößen

Alle Messwerte werden über den CAN Bus entgegen genommen.

Ordnen der Daten

Die entgegen genommen Daten sollen entsprechend ihrer zeitlichen Abfolge geordnet sein. Jedes Frame soll beim Eingehen mit einem Zeitstempel versehen werden, wodurch der zeitliche Verlauf beim Plotten dargestellt werden kann.

Erkennen von Verlusten

Da durch einen reinen Zeitstempel noch kein Datenverlust erkannt werden kan, soll jedes eingehende Frame mit einer Sequenznummer versehen werden. Damit können verlorene Frames durch Lücken in der Nummerierung erkannt werden und die größe des Datenverlustet innerhalb des Systems bestimmt werden.

Konfiguration

Die Zuordnung der Messgrößen muss konfigurierbar sein um Felxibilität bei der Vergabe der CANId zu bewahren.

Robustheit des Systems

Automatischer Restart

Vorgabe des Auftraggebers

Das System soll sich selbst überwachen und bei einem "hängenbleiben" selbstständig neustarten. Damit wird gewährleistet, dass nur für eine festgelegte Maximalzeit (Zeit bis zum Neustart des Systems) keine Daten aufgezeichnet werden.

Hardware

Robuste Hardware

Vorgabe des Auftraggebers

Die Hardware muss robust gegen ESD- und EMV-Einflüsse sein.

Einfache Ersetzbarkeit

Vorgabe des Auftraggebers

Die Hardware soll einfach austauschbar sein.

Gewicht

Vorgabe des Auftraggebers

Der gesamte Aufbau darf eine Gewicht von 500g nicht überschreiten.

Data Mining

Upload von Daten

Es soll möglich sein ein lokales Backup (die heruntergeladenen Log_Datein) in eine Datenbank hochzuladen um die gemessenen Werte für Data-Mining-Zwecke nutzen zu können.


Odedi001 (Diskussion) 14:58, 26. Feb. 2014 (CET)

Problemberreiche

Problemberreich Einstellung der Filter Download aller Daten Upload von Daten Einfache Bedienbarkeit Kommunikation mit dem fahrenden Auto Kommunikation mit dem stehendem Fahrzeug Stabile Verbindung Livestream der aktuellen Daten Upload aller Daten auf eine zentrale Stelle Daten loggen Ordnen der Daten Erkennen von Verlusten Konfiguration Robustheit des Systems Hardware Data Mining
Hardware x x x x
Robustheit des Systems x
Ordnen der Daten und Erkennen von Verlusten x x
Konfigurierbarkeit x
Daten loggen x x
Darstellung der Sensordaten x x
Kommunikation mit dem Fahrzeug und die daraus folgende eingeschränkte Datenübertragungsrate und Datenpufferung x x x
Download der Logdaten x x x

Odedi001 (Diskussion) 14:59, 26. Feb. 2014 (CET)

Hardware

Die Auswahl des Boards entstand durch die Empfehlung des betreuenden Professors, aufgrund von positiven Erfahrungen in anderen Projekten. Dabei handelt es sich um das Board Artila Matrix-522 (Datenblatt). Mit ca. 440g liegt es unterhalb der gewünschten Grenze von 500g. Es verfügt über zwei CAN-Ports womit beide CAN-Busse des Fahrzeugs angeschlossen werden können. Desweiteren verfügt es über zwei RS-232-Ports, zwei Ethernet-Ports, zwei USB-Ports und einen Micro-SD-Karten-Slot. Es ist mit einem 400MHz ARM9-Prozessor und 64 MB SDRAM, sowie 128 MB NAND Flash und 2 MB Data Flash ausgestattet. Ausgeliefert wird das Board mit einem 2.6.29 Linux Kernel, womit das Gerät eine solide Grundlage bietet.

Für die Übertragung über Mobilfunk eignet sich ein Industriegerät, das in der Lage ist mit der maximalen Sendeleistung von 2W zu senden und die Möglichkeit bietet eine externe Antenne anzuschließen. Eine Vorauswahl ergab vier favorisierte Module und zwei Antennentypen.

Odedi001 (Diskussion) 14:59, 26. Feb. 2014 (CET)

Funkmodule

LyconSys 4G2LTE

Pro:

  • GPRS/UMTS/HSPA/LTE Unterstützung
  • RX-Diversity
  • USB Anschluss
  • Linux 2.6 Unterstützung

contra:

  • Sehr geringe Auswahl an Antennen für GSM 800 und LTE(mögliche Verluste durch zu hohen Frequenzabstand)


LyconSys 3GPLUS4

Pro:

  • GPRS/UMTS/HSPA Unterstützung
  • USB Anschluss
  • Linux 2.6 Unterstützung

Contra:

  • keinLTE
  • keine RX-Diversity


Erco & Gener GenPro 30e

Pro:

  • GPRS/UMTS/HSPA Unterstützung
  • Linux ?.? Unterstützung
  • USB Anschluss
  • IP31

Conta:

  • Kein LTE
  • keine RX-Diversity

Erco & Gener GenPro 40e

Pro:

  • GPRS/UMTS/HSPA/LTE Unterstützung
  • Linux ?.? Unterstützung
  • RX-Diversity
  • USB Anschluss
  • IP31

Conta:

  • Sehr geringe Auswahl an Antennen für GSM 800 und LTE(mögliche Verluste durch zu hohen Frequenzabstand)

Antennen

WAO-GUL0D-2B050-SMAM0 Pro:

  • Kein Gegengewicht nötig

Negativ:

  • Nur 2dbm Gewinn


WAO-GUL0F-2D250-SMAM0

Pro:

  • Nur 6dbm Gewinn

Negativ:

  • Gegengewicht nötig


WLAN

Industrie Module:

Pro:

  • Sendeleistung/Hohe Reichweite
  • Industriestandart

Corntra

  • Groß
  • Schwer

Consumer Gerät:

Pro:

  • Geringe Anschaffungskosten
  • Klein

Contra:

  • Geringere Sendeleistung
  • Kein Industriestandart

Robustheit des Systems

Sollte das System sich aufhängen, ist es nicht möglich es während der Fahrt neuzustarten. Aus diesem Grund soll das System ein Aufhängen selbstständig erkennen. Dies soll durch einen Überwachungsprozess geschehen, der in regelmäßigen Abständen eine Rückmeldung von allen beteiligten Komponenten erwartet. Meldet sich auch nur eine der beteiligten Komponenten nach der maximal tollerierten Zeit nicht zurück, soll das System mit Hilfe von Watchdog neugestartet werden.

Odedi001 (Diskussion) 15:00, 26. Feb. 2014 (CET)

Ordnen der Daten und Erkennen von Verlusten

Um sicher zu gehen, dass die Daten beim Client auch in der richtigen Reihenfolge angezeigt werden müssen sie beim Eintreffen geordnet werden und da für das Plotten auch der zeitliche Abstand zwischen zwei Werten wichtig ist, eignet sich hier ein Zeitstempel.

Anhand des Zeitstempels lassen sich verlorene Daten allerdings nicht erkennen, da zwischen zwei eingehenden Nachrichten beliebig viel Zeit vergehen kann. Um den Verlusst erkennen zu können, werden alle eingehenden Nachrichten mit einer Sequenznummer versehen, sodass anhand von Lücken in der Nummerierung Datenverlusst erkannt werden kann.

Odedi001 (Diskussion) 15:00, 26. Feb. 2014 (CET)

Konfigurierbarkeit

Um den eingehenden Daten Informationen entnehmen zu können, müssen diese ihren entsprechnenden Messgrößen zugeordnet werden können. Die Zuordnung geschieht über das DBC-Format (DBC "data base CAN"). Diese Beschreibungsdatei wird bereits im Vorfeld angelegt und eignet sich an dieser Stelle auch, um das Telemetrie-System anhand eines beliebigen DBC-Files zu konfigurieren.

Odedi001 (Diskussion) 15:00, 26. Feb. 2014 (CET)

Daten loggen

Über den Client ist es möglich einzelne Sensoren zu betrachten, jedoch sollen alle erfassten Daten auf einem externen Datenträger geloggt werden. Die gewählte Hardware verfügt über einen Micro-SD-Karten-Slot. Somit eigenet sich hier eine SD-Karte als Datenträger, da diese leicht und einfach zu ersetzen ist.

Das schreiben auf die SD-Karte sollte vorzugsweise blockweise erfolgen, jedoch ist dies durch die Anforderung, dass maximal eine Sekunde an Daten verloren gehen dürfe, nicht möglich. Aus der Anforderung ergibt sich, dass die Daten maximal im Sekundentakt geschrieben werden müssen.

Odedi001 (Diskussion) 15:00, 26. Feb. 2014 (CET)

Darstellung der Sensordaten

Der grafische Client soll als Webapplikation laufen. Um das ressourcenschwache Board zu entlasten, soll das Plotten des Graphen über Javascript auf Clientseite verlagert werden, dafür soll eine fertige Plotting-Library verwendet werden. Bei einer Vorabanalyse haben sich zwei Favorieten heraus kristalliesiert, die im folgenden Abschnitt mit ihren Vor- und Nachteilen näher erläutert werden.


Google Charts Plotting-Library

Google Charts ist eine von Google entwickelte Plotting-Library, die eine Vielzahl unterschiedlicher Graphentypen bereitstellt und auch den Umgang mit großen Datenmengen ermöglicht. Die Library ist hervorragend dokumentiert und bietet mit zahlreichen Beispielen einen schnellen einstieg.

Googles Lizenzbedingungen erlauben zwar die freie Nutzung der Library, jedoch nur im reinen Onlinebtrieb, offline stehen die Quellen der Library nicht zur Verfügung.


HighCharts Plotting-Library

HighCharts ist ebenfalls eine sehr umfangreiche Plotting-Library, die zusätzlich zu der Vielzahl unterschiedlicher Graphentypen, auch eine extra Teil-Library (HighStock) für zeitbasierte Graphen bereitstellt. HighCharts ist gut dokumentiert und bietet mit zahlreichen Beispielen einen schnellen einstieg.

HighCharts wurde unter der Creative Commons (CC BY-NC 3.0) veröffentlicht und erlaubt somit eine Nicht-Kommerzielle Nutzung.


Odedi001 (Diskussion) 15:01, 26. Feb. 2014 (CET)

Kommunikation mit dem Fahrzeug und die daraus folgende eingeschränkte Datenübertragungsrate und Datenpufferung

Die Kommunikation mit dem fahren Fahrzeug soll über Mobilfunk verlaufen, wodurch die Datenübertragungsrate stark eingeschränkt wird. Das erfordert, die zu übertragende Datenmenge so klein wie möglich zu halten.

Der effektivste Weg dazu führt über eine semantische Kompression, indem nur tatsächlich benötigte Daten übertragen werden. Ein vom Benutzer konfigurierter Filter kann den Datenstrom auf die tatsächlich benötigten Daten begrenzen. Der Filter entspricht dabei der Vereinigung der Filter jedes einzelnen Clients. Damit verfügt der zwischengeschaltete Gateway über exakt die Datenmenge, die alle Clients gemeinsam brauchen. Ein Client kann dann seine benötigten Daten vom Gateway anfordern.

Die einfachste Möglichkeit dazu bietet Polling. Dabei werden in regelmäßigen Abständen Daten vom Server angefordert, wobei jedes Mal ein kompletter HTTP-Request gesendet wird. Polling ist nicht nur einfach zu implementieren sondern auch eine verbreitete Methode, die von allen Geräten und Browsern unterstütz wird.

Ausgehend davon, dass auch die Clients über Mobilfunk mit dem Gateway kommunizieren, sollte auch auf diesem Übertragungsweg versucht werden die Datenrate so weit es geht zu reduzieren.

Eine Alternative bieten hier Websockets. Dabei wird eine Socketverbindung zwischen Browser und Server aufgebaut, die über die gesamte Zeit offen bleibt. Nach einem einmaligen Verbindungsaufbau können also reinen Daten in beide Richtungen fließen ohne erneute Requests senden zu müssen. Ein weiterer Vorteil ist, dass der Client automatisch benachrichtigt wird sobald neue Daten verfügbar sind. Das ist effizienter als das aktive "nachfragen" und hat den positiven Nebeneffekt, dass die Daten in vergleichsweise der selben Geschwindigkeit reinkommen wie auf dem Gateway, anstatt stoßweise, wie sie es bei Polling tun würden.


Websockets ist eine neue Technologie und somit noch nicht so weit verbreitet, besonders auf Clientseite wird es noch nicht von allen Browsern unterstützt. Bei der Entscheidung für Websockets würde man den Nutzer auf aktuelle Browserversionen einschränken.

Websocketunterstützung in Browsern

In beiden Fällen müssen die Daten seitens des Gateways zwischengepuffert werden. Damit der lesende Prozess nicht blockiert während Daten an den Client gesendet werden, eignet sich hier die Implementierung eines Wechselpuffers. Dabei wird der Puffer, aus dem gelesen wird, mit dem Puffer, in den eingehende Daten geschrieben werden, getauscht. Der lesende und schreibende Prozess müssen in unterschiedlichen Threads laufen, somit ist es möglich, dass gleichzeitig gelesen und geschrieben werden kann, ohne zu blockieren. Für die Kommunikation mit dem stehenden Fahrzeug gilt die Beschränkung der Datenübertragungsrate nicht. Beide bereits beschriebnen Techniken kommen in Frage, jedoch sollte an dieser Stele die selbe Technologie verwendet werden wie bei der Kommunikation mit dem fahrenden Auto.

Neben dem Ziel, die übetragene Datenmenge so gering wie möglich zu halten, ist es wichtig, eine Strategie zu entwickeln, die eine mangelhafte Übertragungsrate(komprimierte Datenrate > Übertragungsrate) kompensiert. Da die Daten zeitnah zu deren Entstehung beobachtet werden sollen, ist eine Pufferung nicht sinnvoll. Die einzige Möglichkeit, die Datenrate zu verringern, besteht in dem Verwerfen von Daten. Der Benutzer kann dazu eine Prioritätenliste festlegen, nach der die Daten bei Bedarf verworfen werden. Sinkt also die Übetragungsrate unter die komprimierte Datenrate, so werden die unwichtigsten Daten verworfen.


Odedi001 (Diskussion) 15:01, 26. Feb. 2014 (CET)

Download der Logdaten

Alle eingehenden Daten werden auf der SD-Karte geloggt, welche jedoch nur schwer zugänglich ist. Deswegen sollen alle aufgezeichneten Logs über eine nahe Verbindung heruntergeladen werden können. Es besteht die Möglichkeit die Logdateien über eine SSH-Verbindung herunter zu laden, jedoch würde das Grundkentnisse im Umgang mit Linux vorraussetzen. Die Alternative besteht darin den Download über den lokalen Webserver anzubieten. Dabei konvertiert eine CGI, die Logs für den Download in das CSV-Format.

Odedi001 (Diskussion) 15:03, 26. Feb. 2014 (CET)

Designentscheidungen

Hardware

Funkmodule

Da die Erco & Gener GenPro Geräte beide den Vorteil haben das sie Spritzwasser geschützt sind war die Wahl des Gerätes sehr einfach. Weiter sind sie durch ihr Metallgehäuse von Haus aus Stroßresistenter. Die LTE Geräte sind aufgrund der geringen Auswahl an Antennen für GSM 800 bis LTE gestrichen worden.

Anntene

Da die Antenne auf der Außenhaut installiert werden muss, musste eine Antenne benutzt werden die kein physikalisches Gegengewicht benötigt.

WLAN

Da ein weiteres Industriemodule zu Schwer wäre und auch keine hohe Reichweite benötigt wird. Wurde hier ein Consumer Gerät ausgewählt. Zusätzlich wurde ein Gerät ausgewählt das ohne Problem unter einer kleinen Klappe passt und somit auch an der Außenhaut installiert werden kann.

Robustheit des Systems

Für das Problem der Robustheit des Systems ergab die Analyse nur eine mögliche Lösung. Diese Lösung ist zwar simpel, jedoch im Rahmen der Anforderung ausreichend.

Odedi001 (Diskussion) 15:03, 26. Feb. 2014 (CET)

Ordnen der Daten und Erkennen von Verlusten

Die für dieses Problem vorgestellten Läsungen müssen beide umgesetzt werden, da jede für sich nicht vollständig die Anforderungen erfüllt. Zwar wäre es möglich allein über die Sequenznummer sowohl die Daten ihrem eintreffen nach zu ordnen, als auch Verluste zu erkennen, jedoch fehlt dabei die zeitliche Skalierung die für eine korrekte Darstellung nötig ist.

Odedi001 (Diskussion) 15:03, 26. Feb. 2014 (CET)

Konfigurierbarkeit

Für das Problem der Konfigurierbarkeit ergab die Analyse nur eine sinnvolle Lösung. Da die Zuordnung der Messgrößen vom Team der Scuderia Mensa sowieso im DBC-Format angefertig wird, ist naheliegend anhand dieser DBC-Datei auch das Telemetrie-System zu konfigurieren.

Odedi001 (Diskussion) 15:04, 26. Feb. 2014 (CET)

Daten loggen

Gewicht und Größe sind zwei wichtige Anforderungen seitens des Auftraggebers. Eine µSD-Karte bietet bei geringer Größe und Gewicht, eine hohe Speicherkapazität und ist wenn nötig leicht zu ersetzten. Somit ist hierfür eine Micro-SD-Karte die beste Wahl.

Odedi001 (Diskussion) 15:04, 26. Feb. 2014 (CET)

Darstellung der Sensordaten

Um den Zugang zum Client und die Bedienbarkeit zu vereinfachen, soll der Client als webbasierte Applikation angeboten werden. Die grafische Aufbereitung der Messdaten soll über die Javascript-Library HighCharts geschehen, da auch bei bloßer WLAN-Verbindung, ohne Zugang zum Internet es möglich sein soll Sensoren zu überwachen.

Odedi001 (Diskussion) 15:04, 26. Feb. 2014 (CET)

Kommunikation mit dem Fahrzeug und die daraus folgenden eingeschränkte Datenübertragungsrate und Datenpufferung

Um die Datenrate gering zu halten, soll eine semantische Kompression erfolgen, so dass durch einen Filter nur tatsächlich benötigte Daten verschickt werden. Der Client kommuniziert dann über Websockets mit dem Server. Dies gilt sowohl für die lokale Variante, als auch für die Kommunikation über Mobilfunk.

Websockets werden zwar nicht von allen Browsern unterstütz, jedoch unterstützen sowohl Firefox für Desktop-PCs als auch für das Andriod Smartphone Websockets (ein verbreitetes Beispiel neben vielen anderen). Beide Browser können kostenlos heruntergeladen werden, so dass mit wenig Aufwand die Webapplikation genutz werden kann.

Zum effizienteren Senden und Empfangen der Daten wird die beschriebene Methode des Wechselpuffers genutzt. Bei zu geringer Übertragungsrate werden Daten nach einer vom Benutzer festgelegten Prioritätenliste verworfen.

Odedi001 (Diskussion) 15:04, 26. Feb. 2014 (CET)

Download der Logdaten

Da nicht davon ausgegangen werden kann, dass der Endnutzer über Linuxkentnisse besitzt, sollen die Logdaten über eine Weboberfläche im CSV-Format heruntergeladen werden können.

Odedi001 (Diskussion) 15:05, 26. Feb. 2014 (CET)

Design

Grobdesign

Grobdesign.png


Bevor im einzelnen auf die beteiligten Module eingegangen wird, soll erstmal ein Überblick über das gesamte System verschafft werden. Die einzelnen Module können räumlich in drei Gruppen eingeteilt werden. Der IO Daemon, Logging-Distributor Daemon, GatewayCommunicator, Websocket Daemon und die CGI-Anwendungen laufen auf dem Matrix-Board, das im Fahrzeug verbaut werden soll und die gemessenen Daten über eine Funkverbindung verteilt, der Client, der, auf einem beliebigen System, im Webbrowser des Benutzer ausgeführt wird und der Gateway, ein aus dem Internet erreichbarer Server, der als Kommunikationsbrücke, über eine GSM-Verbindgung, zum Fahrzeug dient.

Das Matrix-Board wird an zwei CAN-Bussysteme angeschlossen. Die Daten beider CAN-Ports werden vereinigt über einen UNIX-Socket an den Logging-Distributor Daemon gesendet, wo die CAN-Frames einerseits auf die SD-Karte geloggt werden und andererseits die in ihnen enthaltenen Sensordaten, sowohl über WLAN, als auch über GSM, versendet werden können. Die Kommunikation über WLAN übernimmt der Websocket Daemon, dafür bezieht der Client zuerst die Sensorkonfiguration über ein CGI, das auf dem lokalen Webserver des Boards läuft. Die Auswahl des Clients wird über einen Websocket an den Websocket Daemon geschickt, welcher dann die angeforderten Sensordaten an den Client streamt.

Der Weg über die GSM-Verbindung muss über den Gateway als Brücke erfolgen, da das Matrix-Board auf diesem Weg nicht von außen erreichbar ist. Der GatewayCommunicator muss sich als Client mit dem Gateway verbinden. Über ein, eigens dafür konzipiertes, Protokoll können Sensorkonfiguration und Daten übertragen werden. Wie auch bei der Verbindung über WLAN, trifft der Nutzer eine Vorauswahl, nach welcher Sensordaten an den Gateway gesendet werden. Die am Client antreffenden Daten werden dem Benutzer als Graph dargestellt.


Odedi001 (Diskussion) 15:06, 26. Feb. 2014 (CET)


Komponentendiagramm

Scuderia telemetrie feindesign.svg

Hardware

Scuderia telemetrie hartware.svg

Wie bereits beschrieben wird in diesem Projekt das Matrix 522 Board verwendet. Dieses besteht aus folgende Komponenten:

  • Atmel AT91SAM9G20: Hauptprozessor des Boardes. An diesem Hauptprozessor ist neben des DDRAM Speicher alle Komponenten. Der Kern des Prozessor bildet ein ARM926Ej-STM Kern. Weiter besitzt der Prozessor on Cipe Peripherie auf die nicht weiter eingegangen wird.
  • M41T81 Real Time Chip: Dies ist Real Time Chip der über I2C angebunden ist und an eine Batterie angeschlossen ist um die Aktuelle Uhrzeit trotz Stromausfall zu gewährleisten.
  • 2 x PCA9539 GPIO Expannder: Diese sind auch über I2C angebunden werden aber in diesem Projekt nicht verwendet.
  • ST Micro NAND01GW3B2CN6: Ein 128 MB Großer NAND Speicher auf dem die Anwendung und das Linux Kernel installiert ist.
  • Ethernet Schnittstelle: Eine Ethernet Schnittelle wird über die Prozessor eigene On-Chip Peripherie zu Verfügung gestellt. Es gibt noch eine weitere Ethernet Schnittstelle die über einen DM9000 Chip zu Verfügung gestellt wird.
  • SD: Weite ist über einen Micro SD Karten über Steckplatz an den Prozessor angeschlossen.
  • UART: Weiter werden drei RS232 Schnittstelle vom Prozessor angeboten. Dieses werden nur für Debug Zwecke verwendet.
  • USB: Über USB werden zwei Geräte angeschlossen:
    • WLAN Transiver Ralink RT5370
    • GSM Modem: Hier wird das Industrie Gerät von Erco & Gender GenPro 30e verwendet. Dieses Modem verwendet internen ein Sierra MC8790
  • 2 x SJA1000 CAN Contoller: Weiter werden SJA1000 CAN Contoller über SPI angeschlossen. Jeder CAN Contoller hat hierbei seinen eigenen Interrupt Pin am Hauptprozessor.

IO-Schicht

Scuderia telemetrie iod.svg

Die IO Schicht besteht aus drei Komponenten:

  • Linux CAN mit zwei CAN Interfaces
  • CANOpen Daemon
  • Input/Output Daemon(IOD)

Linux CAN

Wie bereits beschrieben wird in diesem Projekt Linux CAN als Schnittelle verwendet um auf die CAN-Interfaces zuzugreifen. Um die Empfangszeit genauer zu bestimmen wird die Option SO_TIMESTAMP für die Socket Verbindung aktiviert.


CANOpen Daemon

Der CANOpen Daemon verwendet das CANFestival Framework und die Linux CAN Schnittelle um CANOpen Nachrichten zu verarbeiten. In der Initialisierungsphase von CANFestival wird das komplette CANOpen Dictionary gescannt und für jeden Eintrag, wenn es möglich ist ein Callback registriert.

Bei einer Änderung wird dieser Callback aufgerufen. Dieser Callback sendet dann eine IOD-Nachricht an den Input/Output Daemon(IOD).

Input/Output Daemon(IOD)

Der Input/Output Daemon(IOD) hat die Aufgabe alle Nachrichten des CAN-Interfaces entgegen zu nehmen, zu bündeln und an den Logging-Distributor Daemon(LDD) weiterzuleiten. Die CAN Interfaces werden über die Linux CAN Socket Schnittstelle abgerufen. Weiter ist es möglich über einen UNIX Socket einen CANOpen Daemon anzubinden, der Mithilfe des CANFestival Framework CANOpen Nachrichten dekodieren kann.

Scuderia telemetrie iod-seq.svg

Als erstes wird die Verbindung zu den verschieden Sockets hergestellt. Die Verarbeitung eines Socket unterscheidet sich hierbei nur in den Nachrichten Typen.

Es wird in folgenden Typen unterschieden:

  • CANopen: Eine Nachricht vom CANOpen Daemon hierbei handelt es sich bereits um eine IOD Nachricht ohne Sequenznummer. Die Interface ID wird hierbei nicht gesetzt.
  • Generic CAN: Eine einfache CAN Nachricht sie besteht aus der COB ID, der Länge und den bis zu 64 Bit großen Nutzdaten, diese werden alle kopiert in eine IOD Nachricht kopiert. Zusätzlich wird von der Socket Schnittelle die Empfangszeit mitgeliefert.

Nach dem Kopieren einer Nachricht wird die Sequenznummer, Interface ID und falls die Zeit nicht gesetzt ist die aktuelle System Zeit gesetzt.

Nach dem Erstellen der Nachricht wird die Nachricht über einen UNIX Socket an den LDD weitergeleitet.

libsm - Shared Library

Scuderia telemetrie libsm.svg Die Libsm besteht aus folgenden Komponenten:

  • AT Parser
  • Daemon
  • Config Parser
  • PM Client
  • LDD Client

AT Parser

Der AT Parser stellt die Verbindung zum GSM Modem her. Über das Modem können Informationen über Verbindung wie Rauschabstand, verwendetes Band, etc. abgerufen werden.

Daemon

Die Daemon Funktion wandelt einen normalen Prozess in einen Daemon um. Ein Daemon ist ein Systemprozess der ohne Benutzereingaben arbeitet. Dieser wird häufig beim Systemstart gestartet.

Config-Parser

Der Config-Parser ist dafür zuständig, CAN- und CAN-Open Konfigurationen einzulesen, in eine Datenstruktur für die weitere Benutzung zu bringen und bereitzustellen. Wird der Parser aufgerufen, so greift dieser intern auf den richtigen Parser für die gegebene Konfigurationsdatei (CAN oder CAN-Open) zu. Da von mehreren Prozessen auf die Konfiguration zugegriffen werden soll, wird diese in einem Shared Memory Segment hinterlegt werden. Diese Shared Memory Segmente werden durch den SHM-Trustee verwaltet.

ParserDesign.svg

PM client

Der PM CLient stellet die Verbindung zum Prozessmonitor Daemon her und übermittelt alle n-Sekunden einen Status an den Daemon.

LDD Client

Der LDD Client stellt die Verbindung zum LDD her. Über diese Funktionen ist es möglich CAN IDs anzufordern und einzelne Sensor Werte zu empfangen.

Logging-Distributor Daemon

Aufgabe des Logging-Distributor Daemons ist es, Datenpakete des IO-Daemons entgegen zu nehmen und weiter zu verarbeiten, d.h. einzelne Sensorwerte aus dem Datenfeld, gemäß der von der libsm zur Verfügung gestellten Konfiguration, herauszulesen und diese anschließend an verschiedene Abnehmer weiter zu verteilen. Um unnötige Berechnungen zu vermeiden, wird ein Filter angelegt um CAN-IDs auszusortieren.

Komponentendiagramm

Ldd-komp.svg

Sequenzdiagramm Ldd-seq.svg

Aufbereiten der Daten

Das CAN Data Field besteht aus 0 bis maximal 8 Datenbytes. Innerhalb dieser Bytes können 1 bis 64 Sensordaten vorliegen, welche widerum folgende Konfigurationen haben können:

Startbit
Bitbreite
Datentyp: double, float, integer
Endianess
Signed
Scale
Offset

Daten loggen

Um die Dateigröße der Logdaten und die benötigte Datenrate beim Schreiben selbst möglichst gering zu halten, werden alle vom IO-Daemon eingehenden "io-data" Nachrichten als Binärstream auf die SD Karte geschrieben. Als Dateisystem wird hierbei EXT4 mit aktiver Journaling-Option verwendet, da ein kontrolliertes Herunterfahren des Systems nicht vorgesehen ist, die Integrität mit beispielsweise einem FAT nicht gegeben wäre und ein kompletter Datenverlust wahrscheinlicher werden würde. Da von seitens des Kunden ein Datenverlust von ~1 Sekunde erlaubt wurde, werden die anfallenden Daten in einen Buffer zwischengelagert und periodisch jede Sekunde auf den Datenträger geschrieben. Dies hat den Vorteil, dass die Daten in kleinen Burst-Perioden in größerer Menge geschrieben werden und sich somit der Funktions-Overhead beim Schreiben möglichst gering hält. Nachteilig ist jedoch, dass sich ein kontrolliertes Schreiben in Blockgröße schwierig gestaltet, da nicht immer Daten in diesem Umfang anliegen, es also zwangsweise zu Schreibvorgängen kommen würde, in welchen nur Teilblöcke beschrieben werden würden. Zusätzlich stellt sich die Frage, ob solche Optimierungen überhaupt von Vorteil sind, da auf seitens des Controllers auf der SD Karte selbst schon Optimierungen ablaufen(Wearlevel etc.), welche von aussen her nicht beeinflusst werden können.

Verteilen der Daten

Als Abnehmer gibt es zwei Clients- den GateWayCommunicator und den lokalen Webserver.

Aus Sicht des LDD gibt es keinen Unterschied zwischen den Clients, da sie beide über einen gemeinsamen IPC Socket mit dem LDD kommunizieren und von diesem Daten bekommen, bzw. Filter Konfigurationen verschicken können.

Log CGIs

Da die SD-Karte innerhalb des Gehäuses des Matrix-Boards eingetzt wird, gibt es keine schnelle und komfortable Lösung diese zu entnehmen um an die Logdaten zu kommen. Als Lösung wird ein benutzerfreundliches Extrahieren über ein CGI-Skript angeboten, welches dem Nutzer den Download einer .csv ermöglicht, damit dieser die Daten zur Weiterverarbeitung mit einer Vielzahl an Programmen nutzen kann.

Der Nutzer ruft hierfür ein vorgeschaltetes CGI-Skript zur Logverwaltung auf, welches ihm eine Liste an vorhandenen Logdaten zur Verfügung stellt, um diese einzeln als csv herunterzuladen (optional mit Echtzeit-Zeitstempeln oder bei 0 beginnend) bzw. den kompletten Satz an Logs zu löschen.

Konvertieren in csv

Das Konvertieren der Logdaten in eine csv geschieht analog zur Konvertierung der Sensordaten im LDD, nur mit dem Unterschied, dass der Binärstream über die SD-Karte kommt anstelle des IO-Daemons und auch nicht konfigurierte CAN-IDs ausgegeben werden. Die csv hat folgendes Format: TIME[ss:us],CANPORT,CANID,SUBID,VALUE, UNIT; sollte eine undefinierte Nachricht hereinkommen, so werden die Felder ab SUBID zur benachrichtigung genutzt. (Anm.: Für künftige Versionen sollte hier vielleicht noch der Inhalt des Datenfeldes ausgegeben werden).

DBCConfig Fast-CGI

Das DBCConfig Fast-CGI soll auf eine durch den Logging-Distributor geparste Sensorkonfiguration zugreifen und diese dem Client als JSON-Objekt zurückliefern. Da es sich hier im ein CGI handelt kommunizieren DBCConfig und Client über das HTTP Protokoll. Genutzt wird das DBCConfig Fast-CGI zur Übermittlung der Konfiguration an den WLAN Client.

Komponentendiagramm


DBCConfig.fcgi.png


Sequenzdiagramm


Vor dem Eintritt in die Fast-CGI-Loop wird auf die bereits geparste Sensorkonfiguration zugegriffen. Ab diesem Zeitpunkt ist es möglich HTTP-Requests vom Client anzunehmen, worauf die in einer Liste abgelegte Konfiguration gelesen und in einen JSON-String umgewandelt wird, der als Antwort an den Client geschickt wird.

DBCConfig.fcgi - Design.png


Odedi001 (Diskussion) 15:06, 26. Feb. 2014 (CET)

Websocket Daemon

Der Websocket Daemon (WSD) verteilt Sensordaten, die er vom Logging-Distributor Daemon (LDD) bekommt, über WLAN an einen Client.


Schnittstellen

WSD - Interface.png

Komponentendiagramm

WSD - Komponentendiagramm.png


Sequenzdiagramm


Die Aufgabe des Websocket Daemons ist es Sensordaten zwischen dem Client und dem Fahrzeug über WLAN zu übermitteln. Dabei laufen das Empfangen der Sensordaten, das Senden an den Client und das Verwalten der einzelnen Clients jeweils in getrennten Threads ab. Durch den Aufruf eines Callbacks, der zuvor registriert werden muss, ist es möglich Daten vom LDD zu empfangen. Diese Daten werden dann in einem separaten Thread an die entsprechenden Clients gesendet. Um das gegenseitige Blockieren des sendenden und empfangenen Threads zu reduzieren arbeiten diese mit einem Wechselpuffer. Damit der sendende Thread wissen kann welcher Client welche Daten bekommt und um dem LDD mitteilen zu können, welche Daten er überhaupt senden muss, werden in einem weiteren Thread die Einzelanfragen aller Clients verwaltet und zu einer gemeinsamen Anfrage vereinigt, die an den LDD weitergegeben wird.

WSD - Design (1).png


Odedi001 (Diskussion) 15:07, 26. Feb. 2014 (CET)

Gateway Communicator

Der Gateway Communicator(GC) kommuniziert über eine Mobilfunkverbindung mit dem Gateway und ist somit das Bindeglied zwischen Logging Distributor Daemon(LDD) und Gateway(GW). Fallen im LDD neue Daten an, ist es Aufgabe des GC diese Daten entgegenzunehmen und zwischenzuspeichern bis sie an das Gateway gesendet wurden. Zudem nimmt er Benutzerkonfigurationen seitens des Gateway entgegen. Der GC hat zudem den Datenstrom zum Gateway hin zu kontrollieren, sodass trotz Schwankungen in der Übertragungsrate ein konstanter Datenfluss gewährleistet ist, der Werte zeitnah zur Enstehung übeträgt. Das wird erreicht, indem zum einen die zu sendende Datenmenge mittels semantischer Komprimierung durch eine Filterliste (nur angeforderte Daten werden gesendet) minimiert wird. Zum anderen hinterlegt der Benutzer eine Liste, die die Prioräten der einzelnen Daten festlegt. Sinkt nun die Übertragungsrate unter die Rate der zu sendenden Daten, so werden niederprioren Daten verworfen. So erhält der Nutzer immer die maximal sendbare Datenmenge, die die wichtigsten Daten enthalten.

Protokoll zur Kommunikation mit dem Gateway

Zur Kommunikation zwischen dem Matrixboard und dem Scuderia Gateway wurde eine Kommunikation auf Basis des Request-Response Prinzips auf einer TCP/IP Verbindung gewählt. Gründe hierfür waren eine einfachere Kontrolle des Ablaufes und das Erkennen von Verbindungsabbrüchen gegenüber einer Verbindung über UDP.

Nach dem Verbingungsaufbau wird dem Gateway zuerst als Initalhandshake eine vorher definiertes Magicbyte geschickt. Anschließend werden die aktuellen DBC Konfigurationsdateien des Matrixboardes verschickt, damit auf seiten des Gateways dem Nutzer eine Sensorauswahlsliste bereitgestellt werden kann. Von nun an läuft die Hauptkommunikationsloop, in welcher der Gateway auf weitere Nachrichten des gatewayCommunicators mit Requests seinerseits Antworten kann(bsp. ein erneutes Versenden der DBC Files), oder ihm Filterauswahlkonfigurationen seiner Nutzer überliefert, damit nun Sensordaten verschickt werden, sobald diese aufgezeichnet werden.

Verhalten und Befehle Seitens des Matrix-Boardes

CMD:    {MAGIC | CFGDATA | BIGDATA}
________________________________________________________________

CFGDATA: {CFGDAT, SIZE, TXTDATA, SIZE, TXTDATA}                 // ACK | ERR | FILTERCFG   // sends cfg files to gateway
    CFGDAT: 0xCD                                                //  Identifier
    SIZE: {UINT_32}                                             //  Number of bytes to be sent
    TXTDATA: {CHAR, {TXTDATA | NIL}}                            //  single char of cfg file

BIGDATA: {BD, N, SENSORDATA}                                    // ACK | ERR
    BD: 0xBD                                                    //  Identifier
    N: {UINT_32}                                                //  Number of Sensordata
    SENSORDATA: {ID, SUBID, SEQ, INTEFACEID TIME, VALUE,        //
      {SENSORDATA | NIL}}                                       //  Torben data struct
        TIME: {SEC, USEC}                                       //  
            SEC: {INT_32}                                       //
            USEC: {UINT_32}                                     //
        ID: {UINT_32}                                           //
        SUBID: {UINT_8}                                         //
        SEQ: {UINT_32}                                          //
        INTERFACEID: {UINT_8}                                   //
        VALUE: {DOUBLE}                                         //
    
MAGIC:  { MGCNR}                                                // ACK | ERR | FILTERCFG Acts as Ping
    MGCNR: 0x13
NIL: {}

Verhalten und Befehle Seitens des Gateways

REPLY {ACK | ERR | FILTERCFG | NOFILTER}
_______________________________________________________________

ACK: {ACKID}                                                // Acknowledges success
	ACKID: 0xAC
NOFILTER: 0x0F
ERR: 0xEE                                                       // ERROR
FILTERCFG: {FLTRCFG, N, FILTER}                                 // For changing filter configuration
    FLTRCFG: 0xFC                                               // Identifier
    N: {UINT_32}                                                // Number of filters to be configured
    FILTER: { FID, FSID, {FILTER | NIL}}                        // Filter Setting
        FID: {UINT_32}                                          // filter id
        FSID: {INT_8}
    
NIL: {}

Sequenzdiagramm

Protokoll - Sequenzdiagramm.png

Ablauf der Kommunikation zwischen GatewayCommunicator und Gateway

Kommunikation GC-GW.svg

Gateway

Der Gateway dient bei einer Verbindung über GSM als Kommunikationsbrücke zwischen Client und Matrix-Board. Insgesamt verfügt der Gateway über drei Schnittstellen, einen TCP/IP-Socket zur Kommunikation mit dem Matrix-Board und zwei Schnittstellen zur Kommunikation mit dem Client. Hier hat der Client die Möglichkeit sich über einen HTTP-Request mit einem PHP-Script zu verbinden, mit dessen Hilfe er die Prioritätenlisten an das Matrix-Board übertragen kann. Die Sensordaten bekommt der Client dann über den Websocket.

Schnittstellen

Gateway - Interface.png

Komponentendiagramm

Gateway - Komponentendiagramm.png


Kommunikation mit dem Board und dem Browser

Die Aufgabe des Gateways ist es Sensordaten vom Fahrzeug zu empfangen und an den Client weiter zu leiten. Dafür kommuniziert er mit seinem Gegenstück, dem GatewayCommunicator, über ein dafür konzipiertes Protokoll. Nach einem erfolgreichen Verbinden ist der Gateway in der Lage DBC-Dateien zu empfangen, aus denen er, für die Darstellung über ein PHP-Script, eine Sensorkonfiguration als JSON-Objekt erstellt. Anhand dieser Sensorkonfiguration können Clients eine Auswahl der zu beobachteten Sensoren wählen, die als Prioritätenliste vom PHP-Script an den Gateway übertragen werden. Diese Prioritätenliste wird an den GatewayCommunicator gesendet, anhand welcher dieser Daten an den Gateway übermittelt. Jeder Client sendet über den Websocket auch eine persönliche Sensorauswahl und wird wie bereits beim WSD mit seiner Auswahl im Websocket-Thread verwaltet. Eingehende Sensordaten werden vom Matrix-Thread entgegen genommen und vom Send-Thread wieder über den Websocket, anhand der Auswahl der einzelnen Clients an diese verteilt. Um das gegenseitige Blockieren des sendenden und empfangenen Threads zu reduzieren arbeiten diese mit einem Wechselpuffer.


Gateway - Design.png

PHP-Script

Das PHP-Script dient als Schnittstelle zwischen Client und Gateway um die Prioritätenliste zu übertragen. Dafür wird die vom Gateway erzeugte Konfigurationsdatei eingelesen. Sie enthält die Sensorkonfiguration als JSON-String und kann durch das Script in ein Objekt umgewandelt werden. Anhand dieses JSON-Objektes werden dem Benutzer alle verfügbaren Sensoren als Tabelle dargestellt. Die vom Benutzer ausgewählten Sensoren werden über HTTP-POST wieder an das PHP-Script geschickt. Falls eine Prioritätenliste bereits existiert, wurde sie serialisiert und in eine Datei in /tmp/ abgelegt. Diese Liste wird vom Script wieder deserialisiert, die Sensorauswahl des Benutzers wird hinzugefügt und die aktualisierte Liste wird erneut in die Datei geschrieben.

Über ein GET-Request kann die aktualisierte Liste nun an den Gateway übertragen werden. Dabei verbindet sich das Script über einen IPC-Socket zum Gateway und überträgt die Prioritätenliste als Binärdaten zum Gateway.


PHP-Script - Sequenzdiagramm.png


Odedi001 (Diskussion) 15:07, 26. Feb. 2014 (CET)

Client

Beim Client muss man zwischen der WLAN und der GSM Variante unterscheiden. Weil der auf dem Matrix-Board laufende Webserver kein PHP unterstützt, soll die WLAN Variante komplett Javascript basierend sein.


WLAN-Client

Der WLAN-Client bezieht die Sensorkonfiguration über ein CGI, welche er dem Benutzer als Formular anbietet. Er arbeitet ab diesem Zeitpunkt autark vom Webserver, so müssen die Daten nicht zwischen verschiedenen Scripten transportiert werden. Der Client sendet die Auswahl über den Websocket direkt zum WSD und überlässt diesem die Vereinigung aller Clientanfragen zu einer gemeinsamen Anfrage. Die daraufhin eintreffenden Daten werden mit Hilfe der HighCharts-Library als Graph dargestellt.


Client WLAN - Komponentendiagramm.png


GSM-Client

Der Webserver des Gateways verfügt über die Möglichkeit PHP-Scripte auszuführen, so dass die Sensorkonfiguration von einem PHP-Script erhalten wird. An dieser Stelle wird der Komfort einer serverseitigen Scriptsprache ausgenutzt und die Vereinigung der Auswahl aller Clients durch das PHP-Script erledigt und an den Gateway übertragen. Die persöhnliche Auswahl jedes Clients wird dabei in einer PHP-Session abgelegt, auf die wieder zugegriffen werden kann, um über den Websocket die persönliche Auswahl an den Gateway zu übertragen. Wie auch beim WLAN-Client werden die Sensordaten mit Hilfe der HighCharts-Library dargestellt.


Client GSM - Komponentendiagramm.png


Odedi001 (Diskussion) 15:07, 26. Feb. 2014 (CET)

Prozessüberwachung

Die Prozessüberwachung hat die Aufgabe alle Daemon zu überwachen. Beim Systemstart werden hierbei alle Daemon beim Prozessüberwachungs Daemon registriert. Alle Daemon senden hierbei in einem festgelegten Zyklus eine Status Nachricht. Der Prozessüberwachungs Daemon empfängt diese Nachrichten und Werte diese im doppelten Zyklus alle Nachrichten aus. Falls sich ein Daemon nicht gemeldet hat wird diesem Daemon noch einmal verziehen. Falls er dann im nächsten Zyklus sich nicht gemeldet hat wird das Board mit Hilfe des Watchdogs neu gestartet.

Implementierung

In diesem Kapitel wird auf die Implementierung in diesem Projekt eingegangen.

Als Toolchain wurde der GCC des Herstellers des Matrix 522 verwendet. Weiter wurde aus den GNU Toolchain Autoconf, Libtool und Automake verwendet.

IO-Schicht

Änderung im SJA1000 Treiber

Um die Zeit so früh wie möglich aufzuzeichnen, wurde die RX Funktion des SJA1000 Treiber angepasst. Diese Funktion wird von dem Interrupt Service Routine aufgerufen um ein Paket zu empfangen. Der Socket Buffer enthält hierfür bereits einen Timestamp.(skbuff). Dieser kann Mithilfe von der Option SO_TIMESTAMP und recvmsg(2) ausgelesen werden.

 static void sja1000_rx(struct net_device *dev)
 {
  ...
  /* ------- Time Patch ------- */
  {
    skb->tstamp = ktime_get_real();
  }
  /* ------- Time Patch ------- */
  ...
 }

Input/Output Daemon(IOD)

Der Input/Output Daemon(IOD) wurde mit Hilfe von select(2) implementiert. Dies hat den Vorteil das der IOD keine Threads besitzt und somit wenige Prozesswechsel durchgeführt werden muss.

Als erstes werden alle IO Verbindung initialisiert, danach wird der IPC Socket erzeugt. Standardmäßig wird nur ein Gerneric CAN Interface ausgelesen. Mithilfe von Argumenten können ein weiteres Gerneric CAN angebunden werden. Weiter ist es möglich den canopend IPC angebudnen werden.

Für jeden Input gibt es einen speziellen Reader. Es gibt folgende Reader:

  • Gerneric CAN Reader
  • CANOpen IPC Reader

Für die Gerneric CAN werden pro Interface eine separate Reader Instanz angelegt. Für den CANOpen Reader wird nur eine Instanz angelegt.

Alle Inputs werden hierbei über ein Select verwaltetet. Wenn eine Nachricht eingeht wird diese zu den passenden Reader umgeleitet dieser sendet sie dann über ipc raus.

Falls Werte fehlen werden diese von den Readern gesetzt(Zeit, Seqnenznummer, etc).

Gerneric CAN Reader

Der Generic CAN Reader liest RAW CAN Frames von genau einem CAN Interface. Der Socket wurde hierbei so konfiguriert das er alle CAN Frame des Busses empfängt. Dieser liest mit Hilfe von recvmsg neben dem CAN Frame noch den Timestamp des Socket Frames aus.

CANOpen IPC Reader

Der CANOpen IPC Reader setzt die Sequenznummer und sendet die IOD Message an den LDD unverändert weiter.

CANOpen Daemon(canopend)

Der CANOpen Daemon besteht aus 3 Komponenten:

  • IOD IPC
  • CANFestival
  • CANOpen Dictionary

IOD IPC

In der Initialisierungsphase von CANFestival wird das komplett CANOpen DIctionary gescannt und für jeden Eintrag wenn es möglich ist ein Callback registriere. Diese Callbacks erstellen einen IOD Messages. Anhand des CANOpen Dictionary wird die Type eines Frame erfasst und in ein Double umgewandelt da dieses der größte Einheit von CANOpen Dictionary. Dieses Double wird dann in die IOD Struktur umgewandelt.

CANFestival

An der CANFestival Libary wurden keine änderungen gemacht. Sie besitzt bereits ein Linux CAN Interface und konnte direkt übernommen werden.

CANOpen Dictionary

Das CANOpen Dictionary musste erstellt und eingestellt werden. Danach würde dieses Mithilfe eines Python Scriptes von CANFestival erzeugt.

libsm - shared Library

Config-Parser

Der Config-Parser wandelt Konfigurationsdateien für CAN oder CAN-Open in eine interne Datenstruktur um und hinterlegt diese in einem shared memory Segment, sodass alle Prozesse darauf zugreifen können. Für jede Konfiguration werden zwei shared memory Segmente angelegt, in einem wird die Konfiguration selbst gespeichert, in dem anderen Größe des Datensegmentes und Adresse des Datensegmentes beim Anlegen desselben. Diese Adresse wird benötigt, um im Datensegment gespeicherte Pointer beim Einbinden an anderen Adressen zu dereferenzieren.

Alle shared memory Segmente werden vom shmTrustee erstellt, verwaltet und gelöscht. So stellt der shmTrustee auch eine Funktion zum Allokieren von Speicher im shared memory Segment bereit. Sämtlicher Speicher wird durch den shmTrustee auf 32 bit alligned angelegt.

Eine bereits geparste Konfiguration kann von jedem Prozess mit einem einfachen Funktionsaufruf in den privaten Speicherbereich eingebungen und benutzt werden.

Logging Distributor Daemon

Verarbeiten der io-data Nachrichten

Bei Systemstart wird der ausgehende IPC Socket erstellt, anschließend die Sensorkonfigurationen unter Zuhilfenahme der libsm geladen und CAN-ID Filter in Form von boost::unordered_maps angelegt und als "nicht-aktiv" initialisiert. Sollte dies erfolgreich sein, verbindet er sich mit dem IPC des IO-Daemons. Sollte nun ein Pfad für die Log gesetzt sein, so wird ein CString generiert, bestehend aus angegebenem Pfad und der aktuellen Uhrzeit des Systems. Zusätzlich werden Vorbereitungen für das Loggen getroffen. Von nun an befindet sich der ldd in seinem Arbeitsloop, in welchem er Nachrichten vom io-daemon abruft und verarbeitet.

Aktivitätsdiagramm

Ldd act - ldd act.svg

Filter

Um unötigen Verkehr auf den ausgehenden IPC Socket zu verhindern werden unangeforderte CAN-IDs vor Verarbeitung herausgefiltert. Intern wird hierfür eine lokale Klasse "filterStates" genutzt:

 class filterStates {
         uint8_t active;
         uint8_t can[2];
 }

Jede CAN-ID/CAN-Port Kombination bekommt eine eigene Instanz in einer boost::unordered_map angelegt, welche bei Systemstart als nicht aktiv markiert ist. Ein Filter ist aktiv, wenn er von mindestens einem der Clients (lokaler Webserver, gatewayCommunicator) angefordert wird und bekommt von dortan seine Sensorwerte extrahiert und auf den LDD-IPC gelegt.

Extrahieren einzelner Sensorwerte

Um einzelne Sensordaten auslesen zu können, müssen deren Datenbits zuerst isoliert werden. Gearbeitet wird hierbei auf einem uint64_t. Das Isolieren geschieht über eine "1er" Bitmaske der Bitbreite und einer bitwise "and" Verknüpfung. Anschließend werden die Bits an den Anfang des Datensatzes verschoben.

Double und Float Werte können nun direkt übernommen werden, da diese durch IEEE754 in ihrer Interpretation spezifiziert sind.

Bei Integer werten muss nun die Endianess betrachtet werden und im Falle von Big Endian die ByteOrder umgestellt werden. Anschließend gilt es die Signedness auszuwerten und im positiven Falle, bei einer negativen Zahl die führenden Bits der Operationsvariable aufzufüllen.

Auf den nummerischen Wert des Sensors wird abschließend erst die Skalierung und dann der Offset draufgerechnet.

Loggen der Daten

Da ein Datensatz zu jeder Sekunde geloggt werden soll, bietet es sich an einen eigenen Thread für diese Arbeit zu starten. Dies hat zur Folge, dass es notwendig ist die Daten zwischen zu speichern. Hierfür wurde ein Doppel Puffer gewählt, welcher durch die Nutzung eines Mutexes einen wechselseitigen Auschluss beim Wechsel der Puffer garantiert.

CGI Prozesse und Logverwaltung

Um dem Nutzer eine rudimentäre Verwaltung der Logdaten zu ermöglichen, wird über ein CGI Prozess eine html Seite erstellt, auf welcher die aktuell vorhandenen Logdateien gelistet und per Radiobutton zur Auswahl gestellt werden. Eine Liste der Dateien wird durch Iterieren über das Logverzeichnis unter der Nutzung von opendir() und readdir() erstellt, wobei hierfür als Value der Radiobuttons die Entdeckungsreihenfolge genutzt wird. Beim Absenden der html-Form wird dieser Index per "get" als Argument einem weiteren cgi Prozess übergeben, welcher sich der Funktionen des LLDs und der libsm bedient um analog zur Arbeitsweise des LDDs einen Binärstrom an IO-Data anhand der Konfigurationsdateien aufspaltet und die einzelnen Sensorwerte, in diesem Fall über den stdout Stream, dem Nutzer als CSV zur Verfügung stellt. Der Prozess sendet dem LDD ein UserSignal2, damit dieser das aktive Loggen pausiert und damit auch die zuletzt aufgezeichnete Logdatei beziehbar macht. Sobald der Download abgeschlossen ist, wird dem LDD ein erneutes UserSignal2 gesendet und dieser kann das Loggen fortsetzen. Neben den bisher erläuterten CGIs gibt es noch einen zusätzlichen Prozess, welcher den kompletten Bestand an Logdaten löscht. Dies geschieht in der aktuellen Version über ein eher unschicklichen system() Aufruf.

DBCConfig Fast-CGI

Um das JSON-Objekt erzeugen zu können, greift das DBCConfig-Fast-CGI auf das vom Logging-Distributor erstellte Shared Memory Segment zu, in welchem die Konfiguration der verwendeten DBC-Datei als Liste vorliegt. Das Shared Memory Segment wird beim Start des Fast-CGIs in den eigenen Adressraum eingebunden und beim Beenden wieder aus diesem entfernt, so dass bei einem HTTP-Request lediglich der Zugriff auf das bereits eingebundene Shared Memory Segment erfolgen muss. Dies geschieht mit dem Aufruf der Funktion send_config. Dabei durchläuft sie die gesamte Liste und erstellt daraus ein JSON-Objekt, welches als "Content-type: application/json" an den Browser zurückgeliefert wird.


DBCConfig.fcgi - Sequenzdiagramm.png

Odedi001 (Diskussion) 15:08, 26. Feb. 2014 (CET)

Websocket Daemon

Zur Kommunication über Websockets wurde die Library libwebsock verwendet.

Zuerst muss der Client die Sensorkonfiguration vom DBCConfig Fast-CGI beziehen und anhand dieser eine Auswahl treffen, welche Sensoren er beobachten möchte. Die Kommunikation zwischen Client und WSD läuft über die Websocket-Schnittstelle. Ein Client kann seine Sensorauswahl über den Socket an den WSD schicken und erwartet darauf einen Stream an Sensordaten passend zu seiner Auswahl. Jeder verbundene Client wird vom WSD zusammen mit der zugehörigen Sensorauswahl in einer Liste gespeichert. Um die Last auf dem IPC-Socket, welcher als Kommunikationsschnittstelle zwischen WSD und LDD dient, zu entlasten, soll der WSD die Senrsorauswahl aller verbundenen Clients zu einer gemeinsamen Liste vereinigen und an den LDD übertragen. Die vereinigte Sensorauswahl dient im LDD als Filter, so dass dieser nur tatsächlich benötigte Daten sendet.

Das Senden und Empfangen der Daten laufen im WSD in verschiedenen Threads ab und arbeiten mit einem Wechselpuffer. Dabei wird zwischen einem aktiven und einem inaktiven Puffer unterschieden. In den inaktiven Puffer werden durch den Aufruf eines zovor registrierten Callbacks Daten geschrieben. Parallel dazu werden in einem anderen Thread der aktive und inaktive Puffer getauscht. Der zuvor inaktive Puffer wird damit zum aktiven Puffer aus dem nun Daten an den die Clients gesendet werden. Da der Webclient ein JSON-Objekt erwartet, muss zuvor aus den binären Sensordaten ein JSON-String erzeugt werden, wobei nicht jeder Client alle Daten erhält sondern nur Daten nach seiner eigenen Auswahl. Wie zuvor erwähnt, wird jeder Client zusammen mit seiner Auswahl in einer Liste festgehalten. Diese Liste wird durchlaufen und entsprechend der Auswahl ein JSON-String für den Client erzeugt, der wenn Daten vorhanden waren, über den Websocket an den Client geschickt wird.

Bei Verbindungsabbruch zu einem Client, wird dieser aus der Liste entfernt und eine aktualisierte Liste der Gesamtauswahl an den LDD übermittelt.


WSD - Sequenzdiagramm (1).png


Odedi001 (Diskussion) 15:08, 26. Feb. 2014 (CET)

Gateway Communicator

Der Gateway Communicator besteht im Wesentlichen aus zwei Threads, die gemeinsam auf einen Wechselpuffer zugreifen und einem Filter mit integrierter Prioritätenliste.

GC Impl.svg

Der receive-Thread liest dauerhaft blockierend aus dem Socket des LDD. Treffen Daten ein, so wird geprüft, ob sie im Filter vorhanden sind, also vom Nutzer angefragt wurden. Zudem prüft der Filter, ob die Priorität der Daten hoch genug ist, um bei aktueller Übertragungsrate gesendet werden zu können.

Der Filter ist als combined hashmap implementiert, die als key CAN-ID und Sub-ID enthält und als value die Priorität dieser Messgröße. Ein Schwellwert, der vom send-Thread gewählt wird, legt fest, wieviele Prioritäten mit der aktuellen Übertragungsrate gesendet werden können.

Überlebt ein Datenpaket den Filter, so wird er in den Wechselpuffer geschrieben. Jeder Thread kann immer nur auf den eigenen der beiden Puffer im Wechselpuffer zugreifen, sodass keiner der beiden Threads auf eine Zugriffsberechtigung warten muss.

Der send-Thread wechselt die beiden Puffer im Wechselpuffer und schreibt dann alle Daten aus dem eigenen Puffer in Form des beschriebenen Kommunikationsprotokolls auf den Socket des Gateway. Sobald alle Daten geschrieben sind, wird der Puffer wieder gewechselt.

Nach jedem wechseln des Puffers, wird dessen Auslastung geprüft. Anhand dieser Auslastung wird der Schwellwert der Prioritätenliste berechnet. Die Wahl dieses Algorithmus ist eine Abwägung zwischen Anpassungsfähigkeit und Konstanz des Prioritätenfilters. Ist die Änderungsrate des Schwellwertes sehr klein, so wird bei relativ konstanter Übertragungsrate ein Schwellwert gefunden, der nur geringfügig schwankt. Ist allerdings die Übertragungsrate großen Schwankungen unterzogen, so dauert es zu lange, einen passenden Schwellwert zu finden. Wird eine große Änderungsrate gewählt, so wird bei Änderung der Übertragungsrate zwar schnell ein Wert nahe des Optimums gefunden, allerdings pendelt der Schwellwert stark um dieses Optimum. Hier wurde sich für eine Abstufung der Änderungsrate entschieden. Ist der Puffer sehr voll oder sehr lehr, so kann die Prioritätenliste stark skaliert werden, ist der Füllstand des Puffers nahe dem gewünschten Wert (1/2), so wird der Schwellwert nur um eine Messgröße verändert.

PrioAlg.svg

Gateway

Zur Kommunikation über Websockets wurde die Library libwebsock verwendet

Nach dem Erstellen der erforderlichen Sockets ist der Gateway bereit Verbindungen zum Matrix-Board aufzunehmen. Dies geschieht über das Modul GatewayCommunicator seitens des Matrix-Boards. Gateway und GatewayCommunicator kommunizieren über das zuvor definierte Protokoll miteinander. So wird zum Einleiten der Kommunikationsschleife als erstes das Magic-Byte erwartet, womit sich das Matrix-Board als Kommunikationspartner ausweist. Erst wenn das erfolgt ist, wird zur Bearbeitung ein neuer Thread erzeugt. Zusätzlich werden auch noch drei weitere Threads erzeugt, ein Thread in welchem die über dem Websocket verbundenen Clients abgehandelt werden, ein Thread in dem die eingehenden Verbindungen des PHP-Scriptes abgearbeitet werden und ein Thread, der einzig für das Senden der Sensordaten an den Client über den Websocket verantwortlich ist.

Nach beginn der Kommunikationsschleife, schickt der GatewayCommunicator beide DBC-Dateien an den Gateway. Diese werden empfangen und als Datei in /tmp/ geschrieben. Jetzt können mit Hilfe von libsm die DBC-Dateien geparst werden. Die erstellte Liste wird in ein JSON-String umgewandelt und in einer Datei ebenfalls in /tmp/ abgelegt. Diese Datei kann vom PHP-Script eingelesen werden, um die Konfiguration als JSON-Objekt zu erhalten und als Auswahltabelle dem Client darzustellen.

Das PHP-Script kommuniziert mit dem entsprechenden Thread über einen IPC-Socket. Nachdem die Verbindung aufgenommen wurde, wird ein weiterer Thread erzeugt, der die eingehende Prioritätenliste vom Socket liest und diese in einer lokalen Pioritätenliste speichert. Das Flag has_changed, wird darauf folgend auf TRUE gesetzt und kennzeichnet für den Matrix-Thread eine Änderung der Liste.

Solange der GatewayCommunicator noch keine Prioritätenliste vom Gateway erhalten hat, fragt er nach dieser. Sobald eine Liste seitens des Gateways existiert oder die bestehende Liste aktualisiert wurde, wird diese an den GatewayCommunicator geschickt und das Flag has_changed auf FALSE gesetzt, um zu kennzeichnen, dass der GatewayCommunicator über die aktuelle Version verfügt. Entsprechend der Prioritätenliste und der aktuellen Verbindungsqualität werden Daten an den Gateway übertragen. So können bei schlechter Verbindung weniger Daten als angefordert übertragen werden, jedoch nie mehr unterschiedliche Sensoren, als durch die Prioritätenliste festgelegt.

Um die Daten vom Gateway zu erhalten verbindet sich der Client über einen Websocket zum Gateway und schickt diesem seine persönliche Sensorauswahl. Jeder verbundene Client wird zusammen mit seiner Sensorauswahl in einer Liste geführt. Vom GatewayCommunicator eingehende Daten werden in einen Puffer geschrieben, bis der sendende Thread bereit ist die Daten an die Clients raus zu schicken. Dabei arbeiten der lesende und der sendende Thread mit einem Wechselpuffer. Gelesene Daten werden in den inaktiven Puffer geschrieben, der sendende Thread sendet aus dem aktiven Puffer. Vor dem Senden tauscht der sendende Thread den aktiven mit dem inaktiven Puffer, so dass die bis dahin gelesenen Daten, als JSON-String, an die Clients gesendet werden, dabei erhält jeder Client nur Daten nach seiner persönlichen Auswahl.


Gateway - Sequenzdiagramm.svg


Odedi001 (Diskussion) 15:09, 26. Feb. 2014 (CET)

Client

Die clientseitige Implementierung besteht aus drei Javascript Dateien. Zuerst wird die Sensorkonfiguration als Formular dargestellt, über welches der Benutzer seine Auswahl treffen kann. Wurde eine Auswahl getroffen, wird ein Websocket erstellt und mit dem Gateway verbunden. Die zuvor ausgewählten Sensoren, werden an den Gateway übertragen und es wird auf eintreffende Sensordaten gewartet. Die ersten Daten werden dazu genutzt, einen Graphen mit Hilfer der HighCharts Library zu erzeugen, alle weiteren Daten werden über die HighCharts-API dem Graphen hinzugefügt und der Graph aktualisiert.


Client - Sequenzduagramm.png

Odedi001 (Diskussion) 15:17, 26. Feb. 2014 (CET)

Prozessüberwachung

Wie bereits Beschreiben überwacht der Prozessüberwachung Daemon alle andren Damon. Die Kommunikation zwischen den Daemonen erfolgt über einen UNIX IPC Socket.

Watchdog

Als Watchdog wurde in diesem Projekt der Watchdog des AT91SAM9G20 Verwendet. Dieser wurde über das Watchdog Interfaces des Linux Kernel angesprochen.

Als erstes wird der Watchdog initialisiert.

 ret = ioctl(wdt_fd , WDIOC_SETTIMEOUT , 10);

Bei jedem Überprüfungszyklus wird der Watchdog reset, falls ein Deamon nicht mehr reagiert wird der Watchdog nicht mehr registriert.

 int dummy;
 int ret;
 ret = ioctl(wdt_fd, WDIOC_KEEPALIVE, &dummy);

Statische Eigenschaften

libsm

Lines of Code Funktionen
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
C                               14            235            486           2537
-------------------------------------------------------------------------------
SUM:                            14            235            486           2537
-------------------------------------------------------------------------------
-----------------------------------------------------
Language                     files          functions
-----------------------------------------------------
C                                14                57
-----------------------------------------------------
SUM:                             14                57
-----------------------------------------------------

Input/Output Deamon

Lines of Code Funktionen
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
C                                6            115            470           1133
-------------------------------------------------------------------------------
SUM:                             6            115            470           1133
-------------------------------------------------------------------------------
-----------------------------------------------------
Language                     files          functions
-----------------------------------------------------
C                                8                 41
-----------------------------------------------------
SUM:                             8                 41
-----------------------------------------------------

LoggingDistributorDaemon

Lines of Code Funktionen
  -------------------------------------------------------------------------------
  Language                     files          blank        comment           code
  -------------------------------------------------------------------------------
  C++                              8            227            392           1313
  -------------------------------------------------------------------------------
  SUM:                             8            227            392           1313
  -------------------------------------------------------------------------------
-----------------------------------------------------
Language                     files          functions
-----------------------------------------------------
C++                              8                 37
-----------------------------------------------------
SUM:                             8                 37
-----------------------------------------------------

GatewayCommunicator

Lines of Code Funktionen
  -------------------------------------------------------------------------------
  Language                     files          blank        comment           code
  -------------------------------------------------------------------------------
  C++                              3            174            147           1130
  -------------------------------------------------------------------------------
  SUM:                             3            174            147           1130
  -------------------------------------------------------------------------------
-----------------------------------------------------
Language                     files          functions
-----------------------------------------------------
C++                              3                 24
-----------------------------------------------------
SUM:                             3                 24
-----------------------------------------------------

Odedi001 (Diskussion) 15:09, 26. Feb. 2014 (CET)

DBCConfig Fast-CGI

Lines of Code Funktionen
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
C++                              1             20             10             93
HTML                             2              3              3             62
-------------------------------------------------------------------------------
SUM:                             3             23             13            155
-------------------------------------------------------------------------------
-----------------------------------------------------
Language                     files          functions
-----------------------------------------------------
C++                              1                  2
HTML                             2                  0
-----------------------------------------------------
SUM:                             3                  2
-----------------------------------------------------

Odedi001 (Diskussion) 15:09, 26. Feb. 2014 (CET)

Websocket Daemon

Lines of Code Funktionen
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
C                                2            149            267            678
-------------------------------------------------------------------------------
SUM:                             2            149            267            678
-------------------------------------------------------------------------------
-----------------------------------------------------
Language                     files          functions
-----------------------------------------------------
C                                2                 23
-----------------------------------------------------
SUM:                             2                 23
-----------------------------------------------------

Odedi001 (Diskussion) 15:10, 26. Feb. 2014 (CET)

Gateway

Lines of Code Funktionen
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
C                                4            289            372           1159
PHP                              3             68             65            440
-------------------------------------------------------------------------------
SUM:                             7            357            437           1599
-------------------------------------------------------------------------------
----------------------------------------------------
Language                     files         functions
----------------------------------------------------
C                                7                34
PHP                              3                 8
----------------------------------------------------
SUM:                            12                42
----------------------------------------------------

Odedi001 (Diskussion) 15:09, 26. Feb. 2014 (CET)

Client

Lines of Code Funktionen
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
Javascript                       3             82            140            515
-------------------------------------------------------------------------------
SUM:                             3             82            140            515
-------------------------------------------------------------------------------
-----------------------------------------------------
Language                     files          functions
-----------------------------------------------------
Javascript                       3                  7
-----------------------------------------------------
SUM:                             3                  7
-----------------------------------------------------

Tests und Evaluation

Betrachtete Größen

IO-Daemon: CAN in, Generic-CAN in, CANopen in, soll io-data out, ist io-data out

LDD: io-data in, logged io-data, Sensor out, Verlust durch Buffer overflow

lddc: Sensoren in, Filterkonfigurationen out

gatewayCommunicator: Anzahl GW_ERR responses

Art der Tests

  1. iod
    1. Abgleich der Anzahl eingehender CAN-Nachrichten mit der vom Betriebssystem gemessenen.
  2. ldd
    1. Abgleich der Sensorwertberechnung mit denen des Vector-Tools.
    2. Datendurchsatztest mit aktiver Log.
    3. Datendurchsatztest mit deaktivierter Log.
  3. configparser
    1. Funktionstest mit vorhandenen DBC und CSV Konfigurationsdateien.
  4. gatewayCommunicator
    1. Labortest des Prioritätenfilters durch Simulation einer schlechten Verbindung.
  5. Gateway
    1. Test der Anzeigeperformance/Kompatibilität von Mobilgeräten.
  6. Lokaler Webserver
    1. Test der Anzeigeperformance/Kompatibilität von Mobilgeräten.
  7. Systemtest unter Nachstellung von Realbedingungen, geschehen durch Betrieb des Systems während einer 1-stündigen Autofahrt über eine Distanz von 48,73km, bei wechselhaften Wetterbedingungen und einer Geschwindigkeit im Bereich von 0km/h - 157,87km/h.

Ergebnisse

  1. iod
    1. Erfolgreich eine gleich gemeldete Anzahl an eingehenden Nachrichten erhalten.
  2. ldd
    1. Geteste Stichprobe an CAN-Frames stimmten mit denen des Vector-Tools überein.
    2. Ab einer gewissen Anzahl an ausgewählten Sensoren gibt es eine Differenz zwischen iod-out und ldd-in.
    3. Vor Einbau der lld-seitigen Filter gab es eine Differenz zwischen iod-out und ldd-in. Nach Einbau gab es vorhersehbar erneuten Verlust bei einer quantitativ großen Anzahl an gesetzten Filtern.
  3. configparser
    1. Funktioniert.
  4. gatewayCommunicator
    1. Prioritätenliste funktioniert. Naturgemäß gibt es dennoch einen Verlust bei einer zu geringen Übertragungsbandbreite.
  5. Gateway
    1. Desktopsysteme konnten eine überschaubare Anzahl an Sensoren Anzeigen können (10), Mobilgeräte wurden erfolgreich mit der Anzeige von drei Sensoren getestet.
  6. Lokaler Webserver
    1. Desktopsysteme konnten eine überschaubare Anzahl an Sensoren Anzeigen können (10), Mobilgeräte wurden erfolgreich mit der Anzeige von drei Sensoren getestet.
  7. Clients
    1. Während der gesamten Zeit wurden mit drei unterschiedlichen Geräten (Laptop (i7), Tablet (iPad4), Smartphone (Nexus4)) Sensoren beobachtet, dabei hatte das Laptop sechs, und die beiden mobilen Geräte jeweils 2 Sensoren ausgewählt. Ingesamt wurden jedoch 156 Sensoren an den Gateway übertragen.
    2. Die Darstellung auf dem Latop lief flüssig, auf den mobilen Geräten, wäre eine etwas flüssigere Darstellung zwar wünschenswert, bewegte sich jedoch noch im annehmbaren Rahmen.
    3. Beim Verbindungsverlust blieb der Graph stehen und lief nach einem Neuverbinden wie erwartet wieder weiter, mit der entsprechenden Lücke im Graphen, du der Zeit, als keine Verbindung zum Fahrzeug bestand.

Bewertung des Systems

Im getesteten Umfeldstellte sich die GSM-Verbindung besser heraus, als erwartet. Durch fehlende Analyse kann keine obere Gränze angegeben werden, jedoch konnte bei einem Anwendungsfall von 20 - 30 Sensoren kein Ausfall oder Datenvelust festgestellt werden.

Die Darstellung der Sensordaten auf Nutzerendgeräten könnte performanter und die Benutzeroberfläche noch komfortabler sein.

Projektmanagement

Aufgabenbereiche

Arbeitspakete

Arbeitspaket Hauptverantwortlicher
Projektmanagement Olga Dedi
Rüsselsheim-Kontakt Andreas Werner
Toolchain + IO + Hardware Andreas Werner
Aufbereitung der Daten Torben Grünewald
Verteilen der Daten Christian Arlt
Gateway + Webserver + Clients Olga Dedi

Modulimplementierung

Modul implementiert durch Bemerkung
IO-Schicht Andreas Werner
libsm - AT Andreas Werner
libsm - Daemon Andreas Werner
PM Client Andreas Werner
libsm - LDD Client Andreas Werner unterstützt durch Christian Arlt
libsm - Config Parser Torben Grünewald
Logging-Distributor Daemon Christian Arlt
Log CGIs Christian Arlt
DBCConfig Fast-CGI Olga Dedi
Websocket Daemon Olga Dedi LDD Client initialisierung durch Andreas Werner
Gateway Communicator Torben Grünewald, Andreas Werner erste Version, Protokoll und weitere Beratung durch Christian Arlt
Gateway Olga Dedi
Client Olga Dedi
Prozessüberwachung Andreas Werner

Projektplan

Zeitplan vergeich.png


Gantt Diagramm

Scuderia zeit.png


Meilenstein 1

UC001

Name/ID: CAN lesen/UC001

Ziel: CAN-Nachricht von CAN-Bus lesen.

Beteiligte Akteure: OS, CAN-Bus

Verwendete Anwendungsfälle:

Auslöser: Aktivität auf CAN-Bus

Vorbedingungen: CAN-Bus muss angeschlossen sein.

Nachbedingung: (Ergebnis)

Erfolg: CAN-Nachricht wurde vom OS gelesen

Misserfolg: CAN-Nachricht wurde nicht gelesen

Arbeitspaket Aufwandsschätzung Verantwortlicher
Vector Tool Analysen + Wiedergeben alter Nachrichten 10 SWS Torben
Test-Treiber Tool schreiben von trace auf CAN-Interface 20 SWS Olga
Implementierung Generic CAN Treiber lesen 20 SWS Andreas
UC002

Name/ID: CAN-Daten verfügbar machen/UC002

Ziel: Anweder bekommt Rohdaten.

Beteiligte Akteure: Anwender

Verwendete Anwendungsfälle:

Auslöser: Anwender will CAN-Daten anschauen.

Vorbedingungen: CAN-Daten liegen vor.

Nachbedingung (Ergebnis)

Erfolg: Anwender bekommt Daten zur verfügung gestellt

Misserfolg: Anwender bekommt keine Daten

Arbeitspaket Aufwandsschätzung Verantwortlicher
Erste CGI Version erstellen und CAN Daten weiterleiten 20 SWS Christian

Meilenstein 2

UC003

Name/ID: CANopen verarbeiten/UC003

Ziel: CANopen Nachrichten lesen und verarbiten

Beteiligte Akteure: OS, CAN-Bus

Verwendete Anwendungsfälle:

Auslöser: Aktivität auf CAN-Bus

Vorbedingungen: CAN-Bus muss angeschlossen sein.

Nachbedingung (Ergebnis)

Erfolg: CANopen wurde aufgeschlüsselt

Misserfolg: Keine Daten

Arbeitspaket Aufwandsschätzung Verantwortlicher
In CANopen Standard einarbeiten und Dokumentieren. 10h Andreas
CANopen in IO-Daemon implementieren. (CAN-Festival) 30h Andreas
UC004

Name/ID: Sensorkonfiguration lesen/UC004

Ziel: Lesen der Sensorkofiguration um CAN-Frames Messgrößen zuordnen zu können.

Beteiligte Akteure: OS

Verwendete Anwendungsfälle:

Auslöser: Systemstart

Vorbedingungen: Konfigurationsdatei vorhanden.

Nachbedingung (Ergebnis)

Erfolg: CAN-Frames wurden Messgrößen zugeordnet.

Misserfolg: Messgrößen konnten nicht zugeordnet werden.

Arbeitspaket Aufwandsschätzung Verantwortlicher
Konfigurationsformat festlegen. 10h Torben
Konfiguration (DBC) einlesen und parsen. RDD Datenbanken anlegen. 30h Torben
UC005

Name/ID: Daten verarbeiten/UC005

Ziel: Eingehende Daten splitten

Beteiligte Akteure: Modul: LoggingDistributorDaemon.

Verwendete Anwendungsfälle:

Auslöser: Systemstart

Vorbedingungen: Konfiguration erfolgreich eingelesen.

Nachbedingung (Ergebnis)

Erfolg: Daten nach Konf. gesplittet.

Misserfolg: Daten nicht gesplittet.

Arbeitspaket Aufwandsschätzung Verantwortlicher
Implementierung des Datensplittens und Daten in RRD einpflegen. 30h Christian
Vorbereiten zum loggen. 10h Christian
UC006

Name/ID: Gefilterte Daten verteilen/UC006

Ziel: Gefilterte Datenmenge an den Client schicken.

Beteiligte Akteure: Modul: LoggingDistributorDaemon, Webserver, Client

Verwendete Anwendungsfälle:

Auslöser: Clientanfrage

Vorbedingungen: Daten gesplittet und Webserver läuft.

Nachbedingung (Ergebnis)

Erfolg: Client bekommt gefilterte Daten

Misserfolg: Client bekommt keine Daten.

Arbeitspaket Aufwandsschätzung Verantwortlicher
Filter (mit RRD) implementieren und Clientoberfläche erstellen. 40h Olga

Meilenstein 3

UC007

Name/ID: Überwachungprozess/UC007

Ziel: Hängende Prozesse erkennen und Fehlerbehandlung

Beteiligte Akteure: CANOpenD, IOD, LLD, Webserver

Verwendete Anwendungsfälle:

Auslöser: -

Vorbedingungen: -

Nachbedingung (Ergebnis)

Erfolg: Hängende Prozesse werdenden ernannt und entsprechend neu gestartet

Misserfolg: Hängende Prozesse werdenden nicht ernannt

ID Vorgang Aufwandsschätzung Verantwortlicher
UC007.1 Überwachungprozess erstellen 20h Andreas
UC008

Name/ID: Integration von externer Hardware/UC008

Ziel: Integration des Mobilfunkgerät + Fehlerbehandlung

Beteiligte Akteure: Mobilfunkgerät

Verwendete Anwendungsfälle:

Auslöser: -

Vorbedingungen: -

Nachbedingung (Ergebnis)

Erfolg: Mobilfunkgerät baut Verbindung auf. Erkennt Verbindungsabbruch und startet die Verbindung neu

Misserfolg: Kein Telemetrie möglich!

ID Vorgang Aufwandsschätzung Verantwortlicher
UC008.1 Integration des Mobilfunkgerät 20h Andreas
UC009

Name/ID: Logging/UC009

Ziel: Logging

Beteiligte Akteure: LDD, SD-Karte

Verwendete Anwendungsfälle:

Auslöser: -

Vorbedingungen: -

Nachbedingung (Ergebnis)

Erfolg: Daten werden geloggt

Misserfolg: Kein Datenlogging


ID Vorgang Aufwandsschätzung Verantwortlicher
UC009.1 Logging 20h Christan
UC010

Name/ID: Gatewaykommunikation/UC010

Ziel: Kommunikation mit dem Gateway

Beteiligte Akteure: Gateway, Mobielfunk, LDD

Verwendete Anwendungsfälle:

Auslöser: -

Vorbedingungen: -

Nachbedingung (Ergebnis)

Erfolg: Verbindungaufbau, Überwachung der Verbindung(Heartbead), Daten gefiltert senden(Signalstärken abhäng)

Misserfolg: Kein Verbindung

ID Vorgang Aufwandsschätzung Verantwortlicher
UC010.1 Definition eines Protokolls 10h Christan
UC010.2 Implementierung der Kommunikation mit dem Gateway 10h Christan
UC011

Name/ID: SOS-Datenstruktur entwerfen und Daten in SOS schreiben/UC011

Ziel: Erstellung einer Datenstruktur für das die Umwandlung in SOS-XML-Format. Daten in SOS-XML überführen und an SOS übergeben

Beteiligte Akteure: Gateway, LDD, SOS-Server

Verwendete Anwendungsfälle:

Auslöser: -

Vorbedingungen: -

Nachbedingung (Ergebnis)

Erfolg: Einpflegen der Daten in SOS

Misserfolg: Keine Kommunikation

ID Vorgang Aufwandsschätzung Verantwortlicher
UC011.1 Definition einer Datenstruktur 10h Torben
UC011.2 Umwandlung der Datenstruktur/Schreiben der Daten 10h Torben
UC013

Name/ID: Kommunikation mit dem Matrixboard/UC013

Ziel: Verbindungsanfrage des Matrixboard entgegen nehmen und Filterkonfiguration senden

Beteiligte Akteure: Gateway, LDD

Verwendete Anwendungsfälle:

Auslöser: -

Vorbedingungen: -

Nachbedingung (Ergebnis)

Erfolg: Verbindung zum Martixboard herstellen und Filterkonfiguration versendet

Misserfolg: Keine Kommunikation mit dem Board


ID Vorgang Aufwandsschätzung Verantwortlicher
UC013.1 Verbindungsaufbau 10h Olga
UC013.2 Konfigurationen vom Benutzer bekommen/zusammenfassen und senden 20h Olga
UC013.3 Daten empfangen 10h Olga

Meilenstein 4

UC014

Name/ID: Websockets/UC014

Ziel: Umstellung auf Websockets durch IPC

Beteiligte Akteure: Gateway, Webserver

Verwendete Anwendungsfälle:

Auslöser: -

Vorbedingungen: -

Nachbedingung (Ergebnis)

Erfolg: Übertraung der Daten über Websockets

Misserfolg: Keine Datenübertraung

ID Vorgang Aufwandsschätzung Verantwortlicher
UC014.1 Implementierung der Websocket Gateway Cleint/Server 20h Olga
UC014.2 Implementierung der Websocket Lokalen Webserver Client/Server 20h Olga
UC015

Name/ID: Konvertierung der Logdaten/UC015

Ziel: Laden Logdaten und Konvertieren in CSV Datei über den lokalen Webserver

Beteiligte Akteure: Webserver

Verwendete Anwendungsfälle:

Auslöser: -

Vorbedingungen: -

Nachbedingung (Ergebnis)

Erfolg: Laden Logdaten und Konvertieren in CSV Datei über den lokalen Webservers

Misserfolg: Keine Konvertierung

ID Vorgang Aufwandsschätzung Verantwortlicher
UC015.1 Implementirung eines CGI's zum Download einer CSV 10h Christian
UC016

Name/ID: Zeiterfassung durch Kernel/UC016

Ziel: Zeiterfassung durch ISR

Beteiligte Akteure: Webserver

Verwendete Anwendungsfälle:

Auslöser: -

Vorbedingungen: -

Nachbedingung (Ergebnis)

Erfolg: Zeiterfassung der CAN Daten so führ wie möglich(ISR)

Misserfolg: Keine genaue Zeiterfassung.

ID Vorgang Aufwandsschätzung Verantwortlicher
UC016.1 Implementirung der Erfassung im ISR 40h Andreas
UC017

Name/ID: LDD IPC/UC017

Ziel: Umstellung der Kommunikation vom LDD zum Gateway und Webserver auf IPC

Beteiligte Akteure: Webserver, LDD, Gateway Kommunikator

Verwendete Anwendungsfälle:

Auslöser: -

Vorbedingungen: -

Nachbedingung (Ergebnis)

Erfolg: IPC Kommunikation zum Webserver

Misserfolg: Keine Kommunikation mit Außen


ID Vorgang Aufwandsschätzung Verantwortlicher
UC017.1 Entwicklung einer Alternative zu Redis/RRD 20h Christian
UC017.2 Implementirung eines Filters im LDD 10h Christian
UC017.3 Umstellung des Gateway Kommunikator 20h Torben
UC017.4 Implementirung des IPC 20h Andreas, Christian

Meilenstein 5

Testes

Dokumentation

Projektverlauf

Während dem Projektverlauf hat sich das Team mit verschiedenen Ansätzen auseinandergesetzt und diese auch zum Teil implementiert und ist dabei auf technische oder konzeptionelle Hindernisse gestoßen. So war der erste Ansatz anstelle des IPC-Sockets eine Datenbank zu verwenden. Hier sollte das RRDtool, eine Round-Robin-Datenbank, zum einsatz kommen, die neben der Datenhaltung auch Möglichkeit hat Messwerte über einen angegebenen Zeitraum zu mitteln. Auch wenn die Möglichkeit viele Werte zusammen zu fassen und somit Bandbreite bei der Übertragung zu reduzieren damit gegeben war, stellte sich das Aufnehemen der Werte in die Datenbank als sehr unperformant dar und führte dadurch zu einem enormen Datenverlust.

Um nicht zu stark vom gewählten Design abzuweichen entschied sich das Team für den Einsatz von Redis, einer In-Memory-Datenbank. Doch obwohl alle durch den Hersteller empohlenen Performance-Maßnahmen eingehalten wurde, reichte das nicht aus, so dass es immer noch bei einem erheblichen Datenverlust bliebt.

Komplexe Datenbanksysteme schienen an dieser Stelle der falsche Einsatz zu sein, weswegen sich das Team auf eine reine C/C++ Buffer-Implementierung in einem Shared Memory Segment beschränken wollte, jedoch aufgrund des Voranschreitens der Zeit, sich schlussendlich auf die einfacher zu implmentierender Variante der IPC-Socket-Kommunikation beschränkt hat.

Da in den ersten Varianten die Daten in einer Datenbank vorlagen, setzte das Team für die Kommunikation über WLAN die weitaus verbreitetere Methode des Pollings ein. So hatte das Fast-CGI, welches in der Endversion nur noch die Sensorkonfiguration bereitstellt auch Anfragen nach Sensordaten vom Client entgegen genommen und diese aus der Datenbank an den Client gesendet.

Auch der Gateway wurde aus Zeitgründen zusätzlicher Funktionalität beschnitten. So war es ursprünglich angedacht einen SOS-Service anzubinden. Dabei wurde bei einer Vorauswahl die SOS-Implementierung istSOS gewählt. Bei der Integration in das System sind Kompatibilitätsprobleme mit einer Pythonlibrary aufgetreten, deren Auflösung den Fortschritt des Projektes verzögert hätte. Da noch essentiellere Probleme offen waren, wurde diese angedachte Zusatzfunktionalität gestrichen.

Designentwicklung

Design1.png Design2.png Design3.png Design4.png


Aktuelles Design

Scuderia telemetrie feindesign.svg

Zeitbillanz

Gesamtbilanz

Arbeitspaket Olga [Std] Andreas [Std] Christian [Std] Torben [Std] Gesamt [Std]
Analyse & Design 37,75 56,00 62,17 30,75
Aufbereitung der Daten 4,00 12,00 95,47 116,25
Dokumentation 50,75 19,5 9 37,5
Gateway + Webserver + Clients 294,62 12,00 65,00 80,25
Projektmanagement 59,98 45,48 66,48 53,75
Rüsselsheim 24,25 63,33 32,75 26,50
Toolchain + IO + Hardware 34,48 272,89 7,75 1,75
Verteilen der Daten 0 44,00 99,25 7,75
Vorlesung 18,00 16,50 21,00 20,50
Gesamt 523,83 541,70 458,87 375,00 1.899,40
Verfügbar 450 450 450 450 1800

Zeitbilanz pro Meilenstein

Meilenstein 1

Meilenstein1.png

Meilenstein 2

Meilenstein2.png

Meilenstein 3

Meilenstein3.png

Meilenstein 4

Meilenstein4.png


Odedi001 (Diskussion) 15:10, 26. Feb. 2014 (CET)

Zusammenfassung und Ausblick

Das Projekt wurde über viele Umwege und Sackgassen im Endeffekt erfolgreich Abgeschlossen. Die anfangs gesetzten Ziele konnten dabei zu größten Teilen erreicht werden. Durch iterative Implementierung und der Wahl relativ kleiner Meilensteine wurde das Risiko einer Fehlentscheidung in Design und Implementierung entschärft. Trotzdem ist durch fehlende Tests vor Verwendung von Fremdsoftware viel Zeit verloren gegangen.

Reflektion des Projektmanagements

Das Projektmanagement ist in den größten Teilen erfolgreich verlaufen, wobei es natürlich trotzdem Verbesserungspotenzial gibt. Zu den wichtigsten Erkenntnissen gehört, dass mit den schwierigsten/kritischen Aufgaben angefangen werden sollte. Zudem wurden benutzte Architekturen und Technologien, sowie Fremdsoftware zu schlecht auf Brauchbarkeit evaluiert. Dazu zählt auch das vorherige und generell häufige Testen. Die benutzte Hardware hat stark beschränkte Ressourcen, somit sind Performance-Aspekte von Anfang an zu beachten. In Sachen Zeitmanagement, sollte darauf geachtet werden, einen Lösungsweg rechtzeitig zu verwerfen, bevor zu viel Zeit investiert wird. Auch das gesamt gegebene Zeitbudget wurde deutlich überschritten. Um dem entgegenzuwirken, sollten die Ziele rechtzeitig darauf angepasst werden.

Ausblick auf die Zukunft des Projektes

Für zukünftigen Arbeiten an diesem Projekt gibt es zahlreiche Ansätze und Verbesserungsmöglichkeiten.

Verbesserungsmöglichkeiten:

  • WLAN-Stick als Access-Point verwenden, anstatt auf externen Access-Point zu verbinden.
  • Upload von Konfigurationsfiles über die Weboberfläche.
  • Konfiguration des Ausgabeformats der CSV-Logdateien.
  • Ausweiten des Filters im LDD auf sub-IDs anstatt nur CAN-IDs.
  • Verbessern des Algorithmus zum Festlegen der Prioritätsschwelle.
  • Kommunikationsprotokoll optimieren, sodass Datenframes erst auf seiten des Gateways extrahiert werden, sofern es bei aktueller Filtereinstellung an Bandbreite sparen würde.

Ausblick:

  • Telecontrolling
  • Erfassen weiterer Daten (Position, Beschleunigung, Video).

Quellen

http://oss.oetiker.ch/rrdtool/

http://redis.io/

http://www.opengeospatial.org/standards/sos

http://istgeo.ist.supsi.ch/software/istsos/

http://stackoverflow.com/questions/11077857/what-are-long-polling-websockets-server-sent-events-sse-and-comet

http://caniuse.com/websockets

https://tools.ietf.org/html/rfc6455

https://github.com/payden/libwebsock

http://www-csr.bessy.de/control/Hard/fieldbus/CAN/CiA/Bessy/DS301.pdf