
Was ist ?
Dies ist ein System zur Steuerung verschiedener Hardware und Software.
TANGO unterstützt derzeit 4 Plattformen: Linux, Windows NT, Solaris und HP-UX.
Hier wird die Arbeit mit Linux (Ubuntu 18.04) beschrieben.
Wozu ist es nötig?
Es erleichtert die Arbeit mit verschiedenen Geräten und Software.
- Sie müssen sich keine Gedanken darüber machen, wie Daten in der Datenbank gespeichert werden, das wurde bereits für Sie erledigt.
- Sie müssen nur den Mechanismus zur Abfrage der Sensoren beschreiben.
- Es vereinfacht Ihren gesamten Code auf einen Standard.
Woher bekommt man das?
Ich konnte es aus dem Quellcode nicht starten, für die Arbeit habe ich das fertige Image TangoBox 9.3 verwendet.
In der Anleitung wird beschrieben, wie man es aus Paketen installiert.
Woraus besteht es?
- JIVE — dient zur Anzeige und Bearbeitung der TANGO-Datenbank.
- POGO — ein Code-Generator für TANGO-Geräteserver.
- Astor — ein Software-Manager für das TANGO-System.
Uns werden nur die ersten beiden Komponenten interessieren.
Unterstützte Programmiersprachen
- C
- C++
- Java
- JavaScript
- Python
- Matlab
- LabVIEW
Ich habe damit in Python & C++ gearbeitet. Hier wird als Beispiel C++ verwendet.
Jetzt kommen wir zur Beschreibung, wie man ein Gerät mit TANGO verbindet und damit arbeitet. Als Beispiel wird das Board GPS neo-6m-0-001:

Wie auf dem Bild zu sehen, schließen wir das Board über UART CP2102 an den PC an. Beim Anschluss an den PC erscheint das Gerät /dev/ttyUSB[0-N], normalerweise /dev/ttyUSB0.
POGO
Jetzt starten wir pogo, und wir generieren das Skelett des Codes für die Arbeit mit unserem Board.
pogo
Ich hatte bereits einen Code erstellt, lassen Sie uns ihn neu erstellen. File->Neu.

Wir erhalten folgendes:

Unser Gerät (mit Gerät ist hier die Softwarekomponente gemeint) ist leer und hat zwei Steuerbefehle: State & Status.
Es muss mit den notwendigen Attributen gefüllt werden:
Device Property — Standardwerte, die wir an das Gerät zur Initialisierung übergeben, für das GPS-Board muss der Name des Boards im System übergeben werden com="/dev/ttyUSB0" und die Geschwindigkeit des COM-Ports baudrade=9600
Commands — Steuerbefehle für unser Gerät, die Argumente und Rückgabewerte definieren können.
- STATE — gibt den aktuellen Zustand zurück, aus States
- STATUS — gibt den aktuellen Status zurück, dies ist eine string Ergänzung zu STATE
- GPSArray — gibt zurück gps einen String in Form von DevVarCharArray
Anschließend werden die Geräteeigenschaften festgelegt, die gelesen/geschrieben werden können.
Scalar Attributes — einfache Attribute (char, string, long usw.)
Spectrum Attributes — eindimensionale Arrays
Image Attributes — zweidimensionale Arrays
States — Zustände, in denen sich unser Gerät befindet.
- OPEN — das Gerät ist geöffnet.
- CLOSE — das Gerät ist geschlossen.
- FAILT — ein Fehler.
- AN — Wir empfangen Daten vom Gerät.
- AUS — Es liegen keine Daten vom Gerät vor.
Beispiel für das Hinzufügen eines Attributs gps_string:

Abfragezeitraum Zeit in ms, wie oft der Wert von gps_string aktualisiert wird. Wenn die Aktualisierungszeit nicht festgelegt wird, wird das Attribut nur auf Anfrage aktualisiert.
Es hat geklappt:

Jetzt müssen wir den Code generieren Datei->Generieren

Standardmäßig wird kein Makefile generiert. Beim ersten Mal muss das Häkchen gesetzt werden, um es zu erstellen. Das wurde gemacht, damit die vorgenommenen Änderungen bei einer neuen Generierung nicht gelöscht werden. Nachdem wir es einmal erstellt und an unser Projekt angepasst haben (Kompilierungsschlüssel, zusätzliche Dateien), können wir es vergessen.
Jetzt kommen wir direkt zum Programmieren. Pogo hat uns Folgendes generiert:

Wir werden uns für NEO6M.cpp & NEO6M.h interessieren. Lassen Sie uns zum Beispiel den Konstruktor der Klasse betrachten:
NEO6M::NEO6M(Tango::DeviceClass *cl, string &s)
: TANGO_BASE_CLASS(cl, s.c_str())
{
/*----- PROTECTED REGION ID(NEO6M::constructor_1) ENABLED START -----*/
init_device();
/*----- PROTECTED REGION END -----*/ // NEO6M::constructor_1
}Was ist hier und was ist das Wichtigste? In der Funktion init_device() wird Speicher für unsere Attribute reserviert: gps_string & gps_array, aber das ist nicht wichtig. Das Wichtigste hiersind die Kommentare:
/*----- PROTECTED REGION ID(NEO6M::constructor_1) ENABLED START -----*/
.......
/*----- PROTECTED REGION END -----*/ // NEO6M::constructor_1Alles, was sich innerhalb dieses Kommentarblocks befindet, wird bei nachfolgenden Code-Regenerierungen in Pogo nicht gelöscht!. Alles, was nicht in Blöcken ist, wird gelöscht! Das sind die Stellen, an denen wir programmieren und unsere Änderungen vornehmen können.
Jetzt, welche Hauptfunktionen enthält die Klasse NEO6M:
void always_executed_hook();
void read_attr_hardware(vector &attr_list);
void read_gps_string(Tango::Attribute &attr);
void read_gps_array(Tango::Attribute &attr);Wenn wir den Wert eines Attributs lesen möchten, gps_stringwerden die Funktionen in folgender Reihenfolge aufgerufen: always_executed_hook, read_attr_hardware und read_gps_string. In read_gps_string wird gps_string mit dem Wert gefüllt.
void NEO6M::read_gps_string(Tango::Attribute &attr)
{
DEBUG_STREAM << "NEO6M::read_gps_string(Tango::Attribute &attr) entering... " <attr_gps_string_read = Tango::string_dup(this->gps.c_str());
attr.set_value(attr_gps_string_read);
/*----- PROTECTED REGION END -----*/ // NEO6M::read_gps_string
}Kompilation
Gehen Sie in den Quellcode-Ordner und:
makeDas Programm wird im Ordner ~/DeviceServers kompiliert.
tango-cs@tangobox:~/DeviceServers$ ls
NEO6MJIVE
jive
In der Datenbank gibt es bereits einige Geräte, nun erstellen wir unser eigenes. Bearbeiten->Server erstellen

Jetzt versuchen wir, eine Verbindung herzustellen:

Es wird nichts funktionieren, zuerst müssen wir unser Programm starten:
sudo ./NEO6M neo6m -v2Ich kann nur mit Rechten zu dem COM-Port verbinden root-a. v — Protokollierungsstufe.
Jetzt können wir uns verbinden:

den Kunden zurückzuführen sind, nicht verfügbar ist.
Im Diagramm ist es natürlich gut, die Bilder zu betrachten, aber wir brauchen etwas Nützlicheres. Lassen Sie uns einen Client schreiben, der sich mit unserem Gerät verbindet und die Messwerte abruft.
#include <tango.h>
using namespace Tango;
int main(int argc, char **argv) {
try {
//
// create a connection to a TANGO device
//
DeviceProxy *device = new DeviceProxy("NEO6M/neo6m/1");
//
// Ping the device
//
device->ping();
//
// Execute a command on the device and extract the reply as a string
//
vector<Tango::DevUChar> gps_array;
DeviceData cmd_reply;
cmd_reply = device->command_inout("GPSArray");
cmd_reply >> gps_array;
for (int i = 0; i < gps_array.size(); i++) {
printf("%c", gps_array[i]);
}
puts("");
//
// Read a device attribute (string data type)
//
string spr;
DeviceAttribute att_reply;
att_reply = device->read_attribute("gps_string");
att_reply >> spr;
cout << spr << endl;
vector<Tango::DevUChar> spr2;
DeviceAttribute att_reply2;
att_reply2 = device->read_attribute("gps_array");
att_reply2.extract_read(spr2);
for (int i = 0; i < spr2.size(); i++) {
printf("%c", spr2[i]);
}
puts("");
} catch (DevFailed &e) {
Except::print_exception(e);
exit(-1);
}
}Wie man kompiliert:
g++ gps.cpp -I/usr/local/include/tango -I/usr/local/include -I/usr/local/include -std=c++0x -Dlinux -L/usr/local/lib -ltango -lomniDynamic4 -lCOS4 -lomniORB4 -lomnithread -llog4tango -lzmq -ldl -lpthread -lstdc++Ergebnis:
tango-cs@tangobox:~/workspace/c$ ./a.out
$GPRMC,,V,,,,,,,,,,N*53
$GPRMC,,V,,,,,,,,,,N*53
$GPRMC,,V,,,,,,,,,,N*53Wir haben das Ergebnis in Form einer Rückgabe des Befehls zum Abrufen von Attributen der Zeichenkette und des Zeichenarrays erhalten.
Links
Ich habe den Artikel für mich selbst geschrieben, weil ich nach einiger Zeit zu vergessen beginne, wie und was zu tun ist.
Danke für Ihre Aufmerksamkeit.
Quelle: habr.com
