Skip to content

Commit

Permalink
Minimalbeispiel für Simulink-Echtzeitschnittstelle ohne ROS
Browse files Browse the repository at this point in the history
  • Loading branch information
SchapplM committed Mar 28, 2020
1 parent b8657f7 commit c2247ab
Show file tree
Hide file tree
Showing 21 changed files with 2,436 additions and 0 deletions.
143 changes: 143 additions & 0 deletions README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,147 @@ Vorausgesetzte Hardware:
Vorgehensweise:
* Modell `NI9144_NI9401_example.mdl`. Ansonsten alle Schritte wie oben.
## Echtzeit-Schnittstelle für Anwendungen
Die Schnittstelle erlaubt die Kommunikation von Nicht-Echtzeit-Anwendungen mit Echtzeit-Simulink-Modellen. Die Besonderheit ist, dass die Schnittstelle nicht direkt in Simulink implementiert ist, sondern als externe Abhängigkeit (Programmbibiliothek) hinzugefügt wird. Dadurch wird in Simulink nur ein relativ allgemeiner Block eingefügt und die Programmierung erfolgt in der eingebundenen Bibliothek.
Eine derartige Schnittstelle ist notwendig, wenn das Simulink-Modell über externe Eingabe parametriert oder gesteuert werden soll oder wenn Daten aus Quellen eingefügt werden, die nicht echtzeitfähig anzubinden sind.
Die genaue technische Dokumentation ist der [Bachelorarbeit von Lucas Jürgens](#quellen) zu entnehmen. Die Schnittstelle ist bisher in folgenden Projekten zum Einsatz gekommen: [SoftPro](#quellen).
### Minimal-Beispiel für Anwendungsschnittstelle
Das Minimalbeispiel zeigt ohne Abhängigkeiten zu anderen Programmbibliotheken wie ROS die Funktionsweise der Schnittstelle. Damit ist auch erkennbar, ob die Schnittstelle prinzipiell auf dem Rechner funktioniert.
Das Beispiel kann für einfache Projekte als Vorlage genommen werden (z.B. wenn nur ein zusätzliches Modul mit dem Simulink-Modell kommunizieren soll).
Für komplexere Projekte ist das [ROS-Beispiel](#apint_rosbsp) als Vorlage besser geeignet.
Das Beispiel schickt Dummy-Daten vom Simulink-Modell zur Anwendungs-Seite und zurück.
Ordner: `appinterface_minexample`
Dateistruktur mit kurzer Erklärung:
```
appint_minex_extmode.mdl - Simulink-Modell
appint_minex_extmode_open.m - Initialisierungsskript zum Öffnen des Simulink-Modells

rt_interface/ - Ordner für Echtzeit-Schnittstelle (im Simulink-Modell)
ros_rt_core/ - Ordner mit Definitionen auf Simulink-Seite
bus_SL_IN.m, bus_SL_OUT.m - Definition der Ein- und Ausgaben im Simulink-Modells
SL_func.h - Gleiche Definition für die Anwendungsschnittstelle
SL_func_dummy.cpp - Platzhalter-Code für Anwendungsschnittstelle (nur Deklaration, kein Inhalt)
build/ - Temporärer Ordner zum Kompilieren
generate_block.m - Kompiliert die S-Function für den Simulink-Block der Anwendungsschnittstelle
load_buses.m - Bus-Definition in Matlab-Workspace laden
Makefile - Wird zum Kompilieren benutzt

sl_interface/ - Ordner für Simulink-Schnittstelle (der Anwendung)
CMakeLists.txt - Zum Kompilieren mit cmake
src/
SL_func.h - Identische Datei wie in rt_interface/ros_rt_core
node.cpp - Code für Anwendungsschnittstelle
assert.h - Zusätzliche Abhängigkeit
test_interface.cpp - Programm zum Testen der Schnittstelle ohne das Simulink-Modell starten zu müssen
lib/ - Hierhin wird die Programmbibliothek erstellt, die die Echtzeit-Kommunikation durchführt
build/ - Temporärer Ordner zum Kompilieren
```
Zuerst: Abhängigkeiten für die Kompilierung des Modells installieren:
```bash
sudo apt-get install cmake g++
```

Dann werden die Abhängigkeiten des Simulink-Modells, das Modell selbst und die Programmbibliothek der Anwendungsschnittstelle kompiliert:

#### Einrichtung des Simulink-Modells

Kompilierung des Echtzeit-Interface zum Einbinden als S-Function. Das erstellt rt_interface/build/libros_sl_interface.so. Ausführung des folgenden Befehls (und aller weiterer .sh-Befehle) im Linux-Terminal:

```bash
./build_dep_simulink.sh
```

Erstellung des Simulink-Blocks für die S-Function.

* Pfade initialisieren: `appint_minex_extmode_open.m` (in Matlab)
* Block kompilieren: `rt_interface/generate_block.m` (in Matlab).
Das erzeugt rt_interface/build/rt_interface.mexa64.
* Das neue Simulink-Fenster ("untitled") mit dem generierten Block wieder schließen
* Bei Änderung der Schnittstelle: Ersetzen des bestehenden Blocks in Simulink damit.

Kompilierung des Simulink-Modells:

* Simulink-Modell appint_minex_extmode.mdl öffnen und Pfade laden: `appint_minex_extmode_open.m` (In Matlab)
* Klick auf Build (Strg+B) im Simulink-Modell. Das erzeugt die ausführbare Datei appint_minex_extmode (ohne Endung)


Diese Schritte müssen nur einmal gemacht werden und bei jeder Änderung der Schnittstelle (Ein- und Ausgangssignale) wiederholt werden.

#### Einrichten der Anwendungs-Schnittstelle

Kompilierung der Anwendungs-Schnittstelle. Das erstellt im Ordner sl_interface die Ordner die Schnittstelle in lib/libros_sl_interface.so.

```bash
./build.sh
```

#### Programm auf Zielrechner kopieren

Es wird angenommen: Dass die Anwendung und das Simulink-Modell auf einem zweiten Rechner (Echtzeitrechner) laufen. Die Dateien libros_sl_interface.so (Anwendungsschnittstelle) und appint_minex_extmode (Echtzeit-Modell) müssen auf den Rechner kopiert werden. Das geht am bequemsten per SCP. Der Name des Rechners muss in dem Skript angepasst werden.

```bash
./sync.sh
```

#### Programm auf Zielrechner starten

Konsole auf dem Zielrechner öffnen (am besten per SSH). Wenn das Modell längere Zeit läuft, sollte man noch `screen` benutzen, damit das Programm bei Schließen der SSH-Sitzung nicht abstürzt.
Programmbibliothek-Suchpfad ergänzen. Es muss der Ordner eingetragen werden, in dem die Datei libros_sl_interface.so liegt. Dieser Pfad wird im Skript sync.sh eingestellt.

```bash
export LD_LIBRARY_PATH=/home/ec/app_interface
```

Simulink-Modell mit integrierter Anwendungsschnittstelle starten:
```bash
./appint_minex_extmode
```

Wenn alles funktioniert, erscheint folgende Ausgabe in der Konsole:

```
$ ./appint_minex_extmode
Sample-Time: 0.001000
Creating ROS-Node Thread!
Set task prio to 98
Counter 100. Mdl Output: q1: 0.200000, q2: 1.130497; sl_state: 42
```

#### Verbindung mit External Mode aufnehmen

Die Verbindung erfolgt, wie in den vorherigen Beispielen beschrieben.
Bei Erfolg sind die eingestellten Zeitverläufe in den Scopes sichtbar und die Signale werden als mat-Datei im Ordner results gespeichert.

#### Testen auf einem einzigen PC

Zum reinen Testen der Funktionalität braucht man nicht unbedingt den Echtzeitrechner.Grundsätzlich werden die gleichen Befehle ausgeführt, wie oben beschrieben.
* Der Befehl `export LD_LIBRARY_PATH` muss auf dem eigenen Rechner ausgeführt werden mit dem Pfad zur so-Datei.
* Das Modell wird dann genauso mit `./appint_minex_extmode` gestartet.
* In Simulink muss unter Model Configuration Parameters -> Code Generation -> Interface die Adresse "'127.0.0.1' 0 17725" eingetragen werden (ohne Anführungszeichen).

Beim Start des Modells werden folgende Meldungen auftreten:

```
mlockall() failed: Cannot allocate memory
Setting SCHED_FIFO with priority 98 failed: Operation not permitted
Loop 18713. TOO LATE (2). Threadtime 38945.046582780 s, starttime 38945.047197471 s, diff 614691 ns
Loop 106159. OVERRUN (23). Threadtime 39032.493582780 s, endtime 39032.493663656 s, diff -85870 ns
```

Ursache dafür ist, dass kein Echtzeit-Betriebssystem verwendet wird, bzw. der aktuelle Benutzer keine Berechtigung hat, Echtzeit-Eigenschaften zu verändern.

### ROS-Beispiel für Anwendungsschnittstelle <a name="apint_rosbsp"></a>

# Quellen <a name="quellen"></a>

* Bachelorarbeit von Lucas Jürgens. Durchgeführt 2017 am Institut für Regelungstechnik, Leibniz Universität Hannover. Betreuer: Moritz Schappler. Titel der Arbeit: "Implementation and Evaluation of a Prosthesis Control Unit on a mobile ARM-based Computing Platform"
* Projekt SoftPro. Gefördert durch EU Forschungsrahmenprogramm 2020. Bearbeitung am Institut für Regelungstechnik (LUH) 2016-2018 u.a. durch Johannes Kühn, Moritz Schappler (bezogen auf Echtzeit-Regelung). Ziel: Entwicklung einer intelligenten Unterarm-Prothese.
2 changes: 2 additions & 0 deletions appinterface_minexample/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
appint_minex_extmode
results
Loading

0 comments on commit c2247ab

Please sign in to comment.