Raspberry Pi: Anbindung an die Flugelektronik

Was kann das Programm?

Dieses Programm ermöglicht die Anbindung eines Raspberry Pis an die Flugelektronik und erweitert diese dadurch um eine Vielzahl an Funktionen. Der Raspberry Pi lässt sich so als eine universelle Erweiterungsplattform entweder in Form einer Bodenstation, oder direkt als Zusatzmodul, montiert am Kopter, verwenden. Der Raspberry Pi kommuniziert mit der NaviCtrl über die serielle Schnittstelle (UART). Serielle Nachrichten werden durch das Programm erstellt, übertragen, empfangen und ggf. durchgeschleust. Dadurch ist die Nutzung des MikroKopter-Tools nicht eingeschränkt. Der Flug kann weiterhin darüber überwacht und Wegpunkte übertragen werden. Über serielle Befehle ist es möglich ein Kamera-Gimbal und eine Kamera oder auch den gesamten Kopter mit diesem Programm zu steuern. Außerdem kann eine Vielzahl an verschiedener Sensorik und Messinstrumente mit dem Raspberry Pi verbunden werden und die Messwerte über das MikroKopter-Tool ausgegeben werden. Dieses Programm soll jedem der sich mit Raspberry Pis und MikroKoptern beschäftigt den Einstieg erleichtern. Es bietet die Grundlage für die serielle Kommunikation und einige bespielhafte Verwendungsmöglichkeiten und soll daher stets verbessert und erweitert werden.

Was ist der Raspberry Pi?

Ein Raspberry Pi ist ein besonders kostengünstiger Mini-Computer in Kreditkartengröße. Der Rechner besitzt alle üblichen Schnittstellen wie USB, LAN, HDMI und eine Audio-Schnittstelle. Zusätzlich gibt es die Möglichkeit elektronische Bauteile über GPIO-Pins zu verbinden, von denen einige auch die seriellen Bussysteme I2C, SPI und UART unterstützen. Die vielfältigen Einsatzmöglichkeiten haben in den letzten Jahren eine große Community hervorgebracht. Der Raspberry Pi ist außerdem mit einem ‚Camera Serial Interface’, einer seriellen Schnittstelle zur Integration eines Bildsensors ausgestattet. Damit kann eine ebenfalls sehr günstige HD-Kamera verwendet werden. Dieses Programm funktioniert bisher auf dem Raspberry Pi B und Raspberry Pi B+.

Es wurde mit dem Betriebssystem ”Raspbian“ programmiert, dabei handelt es sich um eine abgespeckte Linux Distribution. Eine Übersicht der wichtigsten Konsolenbefehle ist hier dokumentiert: http://goo.gl/mxxO1y

Wie kann ich den Raspberry Pi am Kopter verwenden?

Der Raspberry Pi ist das Herzstück dieser Fernsteuerung. Es handelt sich dabei um einen kleinen Computer mit allen wichtigen Komponenten und Schnittstellen. Verschiedene Betriebssysteme können installiert werden, PiMote wurde jedoch für Raspbian, eine Linux Distribution, konzipiert. Der Raspberry besitzt keinen eigenen Flash Speicher, stattdessen wird das OS auf eine SD Karte installiert. PiMote ist ein Konsole-basiertes C-Programm. Es bietet eine simple grafische Oberfläche zur Kalibrierung des Gamepads und zur Ausgabe der Werte des Gamepads. Ein Monitor kann über HDMI oder einen analogen Videoausgang mit dem Pi verbunden werden. Das Bluetooth Modul wird über die serielle Schnittstelle oder USB mit dem Pi verbunden. Für ein auditives Feedback kann ein Summer mit den entsprechenden GPIO Pins des Pi verbunden werden. Die Spannungsversorgung erfolgt über ein MikroUSB Kabel (5V 0,5A bis 2A), in dieser Beschreibung wird ein modifizierter LiPo-Saver und ein LiPo verwendet.

Schritt-für-Schritt Anleitung

Vorbereitung

Hardware

  • Raspberry Pi B+ (empfohlen) oder Raspberry Pi B
  • Ausreichend große MikroSD-Karte (8 GB empfohlen)
  • Wifi-Dongle (empfohlen: EDIMAX EW-7811UN)
  • LiPo-Saver mit Spannungswandler (12V->5V) und MikroUSB Stecker für die Stromversorgung durch LiPo

  • MKUSB

Software



Schritt 1: Raspberry Pi vorbereiten

Das Betriebssystem auf der Raspberry Pi Seite herunterladen: https://www.raspberrypi.org/downloads/ -> Raspbian

Die Datei entpacken und mit einem entsprechenden Programm auf die MikroSD-Karte schreiben, dazu stehen verschiedene kostenlose Programme zur Verfügung, zum Beispiel:

Windows:

Mac:

Die Programme sind sehr intuitiv, es finden sich aber auch Anleitungen im Internet.

Anschließend die SD-Karte auswerfen und in den Slot des Raspberry Pis einsetzen. Da Wifi erst konfiguriert werden muss sollte der Pi zunächst per Lan an das lokale Netzwerk angeschlossen werden. Die Internetverbindung ist wichtig, da Updates gemacht werden müssen und ggf. der Raspberry Pi über SSH ferngesteuert werden soll. Fehlt nur noch das Netzteil und dann kann es los gehen.

Schritt 2: SSH

Es empfiehlt sich, besonders für unsere Zwecke, den RPI über SSH fernzusteuern, da es zum Einen die Bedienung vereinfacht wenn der RPI am Kopter montiert ist und zum Anderen ohnehin keine grafische Oberfläche verwendet wird. Wer SSH nicht verwenden möchte und stattdessen Monitor und Tastatur direkt am RPI anschließt, kann diesen Schritt überspringen.

SSH ist beim ersten Start des RPI bereits aktiviert und eine IP-Adresse wurde zugewiesen. Diese IP-Adresse muss jetzt ermittelt werden. Dies lässt sich am einfachsten über die Eingabeaufforderung bzw. das Terminal mit dem Befehl ”arp –a“ bewerkstelligen. Alle IP-Adressen im Netzwerk werden damit aufgelistet. Alternativ kann auch externe Software, sogenannte Netzwerk-Scanner eingesetzt werden oder ein Monitor am RPI angeschlossen werden. Die IP Adresse wird bei jedem Start des RPI angezeigt.

Geeignete SSH-Clients:

Windows:

Mac:

  • Hier ist es am einfachsten das Terminal als SSH-Client zu verwenden.
  • Terminal Befehl für SSH: ssh 192.168.X.X –l pi

Default Einstellungen:

Name: pi Passwort: raspberry

Schritt 3: RPI einrichten

Bei dem ersten Start erscheint automatisch das Konfigurationsmenü. Über SSH muss es extra aufgerufen werden: ”sudo raspi-config“

http://gallery3.mikrokopter.de/var/albums/MKBilder/Raspberry-Pi-Anbindung-an-die-Flugelektronik-WIKI/1.png?m=1433855646

Es ist sinnvoll die folgenden Punkte auszuführen/einzustellen:

  • Expand Filesystem: Das Dateisystem wird auf die Größe der SD-Karte eingestellt
  • Change User Password: Passwort ändern
  • Internationalisation Options: Sprache, Zeitzone und Tastaturlayout einstellen

Der RPI ist nun soweit eingerichtet, allerdings sind noch einige Voraussetzungen zu erfüllen, damit das Programm einwandfrei funktioniert.

Schritt 4: Fileserver

Programme werden üblicherweise direkt auf dem RPI programmiert und kompiliert, daher ist sinnvoll die Programmdateien im Netzwerk verfügbar zu machen. So kann auf dem eigenen Computer programmiert werden (zb mit Sublime Text), während die Dateien aber immer auf dem RPI gespeichert werden.

Für einen Fileserver eignet sich das Programm ”Samba“. Es wird auf dem RPI installiert und ist kompatibel mit Windows und Mac. Der Installationsablauf unterscheidet sich jedoch geringfügig:

Windows:

Mac:

Im home Verzeichnis können jetzt über das Netzwerk Ordner und Dateien erstellt, gespeichert oder gelesen werden.

Schritt 5: WLAN

Der empfohlene WLAN Dongle wird automatisch erkannt, keine Treiber müssen installiert werden. Für alle anderen WLAN Sticks bitte bei google erkundigen.

WLAN wird in folgender Datei konfiguriert: ”/etc/network/interfaces“

Diese Konfiguration sollte funktionieren:

http://gallery3.mikrokopter.de/var/albums/MKBilder/Raspberry-Pi-Anbindung-an-die-Flugelektronik-WIKI/2.png?m=1433855653

Falls dennoch Probleme auftreten, bitte eine der unzähligen Anleitungen im Internet zur Rate ziehen.

Schritt 6: Programm kompilieren

Die Programmdateien können auf der MikroKopter-Subversion Seite geladen werden: http://svn.mikrokopter.de/websvn/ -> Projects -> Raspberry Pi

  • PiMoteSwitch (Kamera- oder Koptersteuerung per Gamepad)

  • PiMoteCam (Kamerasteuerung)

  • ExPlat (experimentelle Plattform mit allen beschriebenen Funktionen)

Die Programmdateien sind in C geschrieben und für die Kompilierung in einer Makefile zusammengefasst. Vorgehensweise:

  1. Dateien in einem neuen Ordner im Home-Verzeichnis des RPI speichern
  2. Über die Konsole in dieses Verzeichnis wechseln
  3. Raspbian aktualisieren: ”sudo apt-get update“ und ”sudo apt-get upgrade“
  4. Befehl ”make“ ausführen -> Programm wird kompiliert und erstellt

/!\ Falls es eine Fehlermeldung bzgl. Python.h gibt: sudo apt-get install python-dev ausführen

Anmerkung: Für PiMoteCam und PiMoteSwitch muss in der Datei „File“ zuerst der Pfad angepasst werden.

Das Programm kann jetzt mit dem Befehl ”sudo ./ProgrammName“ oder ”./ProgrammName“ ausgeführt werden. Natürlich wird dabei noch nicht viel passieren, weil Sensorik oder sonstige elektronische Bauteile angeschlossen werden müssen und das Programm entsprechend angepasst werden muss.

Wie funktioniert die serielle Kommunikation?

Innerhalb der MikroKopter-Elektronik wird eine UART-Schaltung mit folgendem Rahmen für die Kommunikation verwendet:

http://gallery3.mikrokopter.de/var/albums/MKBilder/Raspberry-Pi-Anbindung-an-die-Flugelektronik-WIKI/3.png?m=1433855659

Ein Start-Bit, acht Datenbits und 2 Stopp-Bits.

Auf ein Paritätsbit wird verzichtet, da die Fehlerkontrolle durch eine Checksumme gewährleistet wird. Das Senden erfolgt mit einer Bitrate von 57.600 bit/s. Sämtliche Nachrichten sind im ASCII-Format kodiert. Somit ist eine Darstellung von 256 verschiedenen Zeichen möglich. Eine serielle Nachricht ist folgendermaßen aufgebaut:

http://gallery3.mikrokopter.de/var/albums/MKBilder/Raspberry-Pi-Anbindung-an-die-Flugelektronik-WIKI/4.png?m=1433855667

Die Bedeutung der verschiedenen Adressen und IDs ist hier dokumentiert: http://wiki.mikrokopter.de/en/SerialProtocol

Wie funktioniert GPIO

Die Abkürzung steht für ‚General Purpose Input/Output’. Dabei handelt es sich um universell einsetzbare Pins für die Ein- und Ausgabe digitaler Daten. Insgesamt verfügt der Raspberry Pi über 26 GPIO Pins und 14 Pins für die Spannungsversorgung von 5V oder 3,3V. Sensorik kann über diese Pins mit der geeigneten Spannung versorgt und ausgelesen bzw. gesteuert werden.

http://gallery3.mikrokopter.de/var/albums/MKBilder/Raspberry-Pi-Anbindung-an-die-Flugelektronik-WIKI/5.png?m=1433855672

PiMote nutzen

Dieses Programm ermöglicht die Kamera- oder Koptersteuerung per Gamepad am RPI, dieser wird dazu natürlich nicht am Kopter montiert. Externe Bibliotheken sind erforderlich, damit das Programm kompiliert werden kann.

Vorgehensweise:

  1. NCurses installieren: ”sudo apt-get install libncurses5-dev“ -> grafische Oberfläche

  2. PiMoteCam und PiMoteSwitch auf dem RPI speichern und die Datei ”file.c“ in einem Editor öffnen

  3. In den Zeilen 37 und 73 die Pfade anpassen, damit die Konfigurationsdatei ”config.txt“ von dem Programm gefunden wird
  4. Programm kompilieren: in das Verzeichnis mit den Programmdateien wechseln und kompilieren: ”make”
  5. Gamepad und Bluetooth Modul oder WI232 Modul anschließen
  6. Programm starten: ”sudo ./PiMote

Wenn das Programm korrekt startet, wird zunächst die Bezeichnung des angeschlossen Gamepads angezeigt, sofern es erkannt wird, dann folgt eine Aufforderung ein Profil bzw. Layout zu erstellen. Den Funktionen (Nick, Roll, ...) werden jetzt Achsen und Buttons des Gamepads zugewiesen. Das Profil wird anschließend in der Konfigurationsdatei gespeichert und beim nächsten Start wieder geladen.

Bei der Konfiguration von PiMoteSwitch werden zusätzlich zu den Funktionen der Kamera auch noch Buttons und Achsen für die Funktionen des Kopters zugewiesen. Mit einem Button kann dann zwischen der Kopter und der Kamerasteuerung gewechselt werden.

Die Einstellungen für das Programm sind soweit abgeschlossen, jedoch müssen noch einige Einstellungen im MikroKopter-Tool vorgenommen werden. Im Koptertool müssen die seriellen Kanäle den entsprechenden Funktionen zugewiesen werden.

http://gallery3.mikrokopter.de/var/albums/MKBilder/Raspberry-Pi-Anbindung-an-die-Flugelektronik-WIKI/7.png?m=1433862543http://gallery3.mikrokopter.de/var/albums/MKBilder/Raspberry-Pi-Anbindung-an-die-Flugelektronik-WIKI/8.png?m=1433862553http://gallery3.mikrokopter.de/var/albums/MKBilder/Raspberry-Pi-Anbindung-an-die-Flugelektronik-WIKI/9.png?m=1433862559

Die seriellen Kanäle (Ser Ch#) werden den Potis zugewiesen und diese wiederum den Funktionen der Kamerasteuerung. (siehe Bilder) Für die Koptersteuerung wird ein anderer Datensatz verwendet weshalb eine Zuweisung hier nicht nötig ist.

Damit PiMote mit dem Einschalten des RPI automatisch startet, muss der Pfad zum Programm einem Script hinzugefügt werden. Dieses Script wird automatisch ausgeführt, wenn der RPI hochgefahren ist.

  1. Script in einem Editor aufrufen: ”sudo nano /etc/rc.local“
  2. Am Ende des Scrips (vor exit) den Pfad zu PiMote hinzufügen: ”sudo /home/pi/.../PiMote“ (ohne Anführungszeichen)

  3. Script speichern und schließen

Viel Spaß und Erfolg!

http://gallery3.mikrokopter.de/var/albums/MKBilder/Raspberry-Pi-Anbindung-an-die-Flugelektronik-WIKI/6.png?m=1433855682

ExPlat nutzen

Python installieren: Damit die RPI Kamera genutzt werden kann müssen einige Python-Bibliotheken installiert werden: ”sudo apt-get install python-dev”. Dies ist optional, wenn die Kamera jedoch nicht genutzt werden soll, muss das Makefile entsprechend angepasst werden. Wir PiMote muss ExPlat mit ”make” kompiliert werden.

Übersicht der Funktionen

Hauptschleife (main.c)

Alle Funktionen werden bei jedem Neustart zunächst initialisiert. Anschließend beginnt die Hauptschleife. Durch eine Funktion ”timer“ ist es möglich Funktionen in bestimmten Intervallen, in Sekunden (interval_in_sec(#ofseconds)) oder Millisekunden (interval_in_msec(#ofmilliseconds)), aufzurufen.

Serielle Nachricht packen und übertragen (uart.c)

Alle Nachrichten, ob gesendet oder empfangen, werden in folgender Struktur gespeichert und verarbeitet:

typedef struct { u8 c;

  • -> beim Lesen eines eingehenden Streams wird jeder Charakter nacheinander gespeichert und gelesen, dadurch kann der Initialisierungscharakter erkannt werden und die folgenden Charakter als serielle Nachricht gespeichert werden.

u8 collecting;

  • -> 1 o. 0 gibt an ob gerade eine Nachricht erkannt und gespeichert wird.

int count;

  • -> Anzahl der aktuell in einer gespeicherten Nachricht vorhandenen Zeichen.

u8 address;

  • -> Adresse der aktuellen Nachricht

u8 cmdID;

  • -> ID der aktuellen Nachricht

u8 data[1024];

  • -> Der Datensatz zu einem bestimmten Zeitpunkt der Bearbeitung der Nachricht.

u8 collecting_data[1024];

  • -> Der Datensatz zu einem bestimmten Zeitpunkt der Bearbeitung der Nachricht.

u8 txrxdata[1024];

  • -> Der Datensatz zu einem bestimmten Zeitpunkt der Bearbeitung der Nachricht.

u16 position;

  • -> Position des aktuell gelesenen Zeichens eines empfangenen seriellen Streams

u16 dataLength;

  • -> Länge des Datensatzes

u8 position_package;

  • -> Position des aktuell gespeicherten Zeichens einer neuen Nachricht.

u8 position_package_gps;

  • -> nicht relevant

u16 cmdLength;

  • -> Länge eines empfangenen seriellen Streams

u8 readyForTransmit;

  • -> nicht relevant

u8 length_payload;

  • -> Länge einer seriellen Nachricht vom Optical Flow Module

u8 msg_id;

  • -> ID einer Nachricht vom Optical Flow Module

u8 gps_data[30][20];

  • -> nicht relevant

}attribute((packed)) serial_data_struct;

Eine Nachricht übertragen:

  1. Objekt der Struktur erstellen: serial_data_struct struct_name;
  2. Zu übertragenden Datensatz speichern: struct_name.data[0] = ?;
  3. Seriellen Rahmen der Nachricht erstellen: create_serial_frame(Adresse, ID, Länge Datensatz, &struct_name);

  4. Nachricht übertragen: transmit_data(TO_KOPTER, &struct_name);

GPIO Funktionen (gpio.c)

Folgende Makros stehen zur Verfügung um die GPIO Pins zu nutzen:

  1. #define INP_GPIO(g) *(gpio.addr + ((g)/10)) &= ~(7<<(((g)%10)*3)) GPIO Pin als Eingangspin setzen: INP_GPIO(#ofpin)

  2. #define OUT_GPIO(g) *(gpio.addr + ((g)/10)) |= (1<<(((g)%10)*3)) GPIO Pin als Ausgangspin setzen: OUT_GPIO(#ofpin)

  3. #define GPIO_SET *(gpio.addr + 7)

    GPIO Pin Triggern (Ausgang auf HIGH): GPIO_SET = 1 << #ofpin;

  4. #define GPIO_CLR *(gpio.addr + 10)

    GPIO Pin Trigger stoppen (Ausgang auf LOW): GPIO_CLR = 1 << #ofpin;

  5. #define GPIO_READ(g) *(gpio.addr + 13) &= (1<<(g)) GPIO Pin lesen: GPIO_READ(#ofpin);

Im Code wird beispielhaft ein Distanzsensor über GPIO ausgelesen.

Sensordaten im MK-Tool ausgeben (processing.c)

Es ist möglich in einer Funktion GPIO Sensordaten in den Datenstream zum Koptertool einzuspeisen und somit die Daten im Koptertool auszugeben.

Vorgehensweise:

  1. Überprüfen welche Punkte in der Liste für die Sensordatenausgabe im Koptertool nicht verwendet werden (16-19)
  2. In add_sensor_lables() die Beschriftung der Sensoren hinzufügen
  3. In add_sensor_data() die Daten der seriellen Nachricht hinzufügen
  4. Die Funktionen an den richtigen Stellen aufrufen, d.h. nachdem die entsprechende serielle Nachricht empfangen wurde (nach analyze_data_package() in receive_data_from_kopter())

Flugelektronik Daten einlesen und nutzen

Durch die Funktion request_to_kopter() lassen alle Flugdatenparameter erfragen und in analyze_data_package() auslesen und weiterverarbeiten. Einige Beispiele sind im Code vorhanden.

Flugsteuerung

Die Flugsteuerung basiert auf dem gleichen Datensatz wie bei PiMote:

struct str_fc_correction_data {

  • signed char Nick;
  • signed char Roll;
  • signed char Gier;
  • signed char Gas;
  • unsigned char Frame;
  • unsigned char Config;
  • unsigned char free;

}

Die verschiedenen Parameter werden in dieser Struktur gespeichert und durch Aufrufen der Funktion transmit_flight_data() automatisch an den Kopter übertragen. Die richtige Adresse und ID und Länge des Datensatzes wird dort automatisch eingetragen. Als Beispiel für die Flugsteuerung ist im Code eine Flugkorrektur auf Basis der Daten eines Moduls zum Messen des optischen Flusses enthalten. Dabei handelt es sich um ein prototypisches Projekt.

RPI Kamera nutzen (optischer Fluss)

Für das RPI Kamera Modul wurde eine umfangreiche Python Bibliothek geschrieben, durch die sämtliche Funktionen der Kamera verwendet werden können. Das entsprechende Python Script wird, wenn aktiviert, im Code in einem Thread durch eine Funktion aufgerufen. Dadurch kann es parallel zur Hauptschleife laufen. Sämtliche Daten, die durch das Python Script produziert werden, können über eine im physikalischen Speicher gemappte Datei ausgetauscht werden und sind so auch für das C-Hauptprogramm verfügbar. In dem Beispielscript des Programms werden die Daten des optischen Flusses der Kamera gelesen und an das Hauptprogramm übertragen. Weitere Funktionen sind natürlich möglich.

SVN

http://svn.mikrokopter.de/mikrosvn/Projects/RaspberryPi