
Was ist ?
Dies ist ein System zur Verwaltung verschiedener Hardware- und Softwarekomponenten.
TANGO unterstützt derzeit 4 Plattformen: Linux, Windows NT, Solaris und HP-UX.
Hier wird die Arbeit mit Linux (Ubuntu 18.04) beschrieben.
Wozu dient es?
Es vereinfacht die Arbeit mit verschiedenen Geräten und Software.
- Sie müssen sich keine Gedanken darüber machen, wie die Daten in der Datenbank gespeichert werden, das wurde bereits für Sie erledigt.
- Sie müssen nur den Mechanismus zur Abfrage von Sensoren beschreiben.
- Es reduziert Ihren gesamten Code auf einen Standard.
Woher bekommen?
Ich konnte es aus den Quellcodes nicht starten, habe jedoch ein fertiges TangoBox 9.3-Image verwendet.
In der Anleitung wird beschrieben, wie man es aus Paketen installiert.
Woraus besteht es?
- JIVE − dient zum Anzeigen und Bearbeiten der TANGO-Datenbank.
- POGO − ein Code-Generator für TANGO-Geräteserver.
- Astor − ein Software-Manager für das TANGO-System.
Wir werden uns nur für die ersten beiden Komponenten interessieren.
Unterstützte Programmiersprachen
- C
- C++
- Java
- JavaScript
- Python
- Matlab
- LabVIEW
Ich habe damit in Python und 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 im Bild zu sehen ist, verbinden wir die Platine mit dem PC über UART CP2102. Bei der Verbindung mit dem PC erscheint das Gerät /dev/ttyUSB[0-N], normalerweise /dev/ttyUSB0.
POGO
Jetzt starten wir pogo, und generieren den Code-Skelett zur Nutzung mit unserer Platine.
pogo
Ich hatte bereits Code erstellt, lassen Sie ihn uns neu erstellen Datei->Neu.

Wir erhalten Folgendes:

Unser Gerät (mit dem in Zukunft die Softwarekomponente gemeint ist) ist leer und hat zwei Steuerbefehle: State & Status.
Es muss mit den erforderlichen Attributen ausgefüllt werden:
Geräteeigenschaft — Standardwerte, die wir an das Gerät zur Initialisierung übergeben, für die GPS-Platine muss der Name der Platine im System übergeben werden com="/dev/ttyUSB0" und die Geschwindigkeit des COM-Ports baudrate=9600
Befehle — Steuerbefehle für unser Gerät, die Argumente und Rückgabewerte zugewiesen werden können.
- STATUS — gibt den aktuellen Zustand zurück, von Zustände
- STATUS — gibt den aktuellen Status zurück, dies ist eine String-Ergänzung zu STATUS
- GPSArray — gibt zurück gps String in Form von DevVarCharArray
Als Nächstes werden die Geräteeigenschaften definiert, die von und in das Gerät gelesen/geschrieben werden können.
Skalare Attribute — einfache Attribute (char, string, long usw.)
Spektrum-Attribute — eindimensionale Arrays
Bildattribute — zweidimensionale Arrays
Zustände — der Zustand, in dem sich unser Gerät befindet.
- ÖFFNEN — das Gerät ist offen.
- SCHLIESSEN — Gerät ist geschlossen.
- FEHLER — Fehler.
- EIN — Daten werden vom Gerät empfangen.
- AUS — keine Daten vom Gerät.
Beispiel für das Hinzufügen eines Attributs gps_string:

Abfrageintervall Zeit in ms, wie oft der Wert von gps_string aktualisiert wird. Wenn keine Aktualisierungszeit angegeben wird, wird das Attribut nur auf Anfrage aktualisiert.
Erhalten:

Nun muss der Code generiert werden Datei->Generieren

Standardmäßig wird Makefile nicht generiert. Beim ersten Mal muss das Häkchen gesetzt werden, um es zu erstellen. Dies wurde gemacht, damit die Änderungen beim neuen Generieren nicht gelöscht werden. Wenn es einmal erstellt und an Ihr Projekt angepasst wird (Kompilierungsoptionen, zusätzliche Dateien festlegen), können Sie es vergessen.
Nun kommen wir direkt zum Programmieren. Pogo hat uns Folgendes generiert:

Uns interessieren NEO6M.cpp & NEO6M.h. Lassen Sie uns als 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 gibt es 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 hier, sind die Kommentare:
/*----- PROTECTED REGION ID(NEO6M::constructor_1) ENABLED START -----*/
.......
/*----- PROTECTED REGION END -----*/ // NEO6M::constructor_1Alles, was sich in diesem Kommentarblock befindet, wird bei zukünftigen Code-Neugenerierungen in Pogo nicht gelöscht! Das wird nicht gelöscht!. Alles, was nicht in Block ist, wird gelöscht! Das sind die Stellen, an denen wir programmieren und unsere Änderungen vornehmen können.
Was sind die Hauptfunktionen der 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_string, werden die Funktionen in folgender Reihenfolge aufgerufen: always_executed_hook, read_attr_hardware und read_gps_string. In read_gps_string wird die gps_string-Variable gesetzt.
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
}Kompilierung
Gehen wir in den Quellcode-Ordner und:
makeDas Programm wird im Ordner ~/DeviceServers kompiliert.
tango-cs@tangobox:~/DeviceServers$ ls
NEO6MJIVE
jive
In der Datenbank sind bereits einige Geräte vorhanden, jetzt erstellen wir unser Gerät. Bearbeiten->Server erstellen

Jetzt versuchen wir, eine Verbindung herzustellen:

Es wird nicht funktionieren, zuerst müssen wir unser Programm starten:
sudo ./NEO6M neo6m -v2Eine Verbindung zum COM-Port ist nur mit Rechten möglich root-a. v — Protokollebene.
Jetzt können wir uns verbinden:

Kunde
Es ist zwar schön, die Bilder im Diagramm zu sehen, 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);
}
}So kompilieren Sie:
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++Das Ergebnis:
tango-cs@tangobox:~/workspace/c$ ./a.out
$GPRMC,,V,,,,,,,,,,N*53
$GPRMC,,V,,,,,,,,,,N*53
$GPRMC,,V,,,,,,,,,,N*53Wir haben das Ergebnis im Rückgabewert des Befehls, beim Abrufen von Attributen und dem Zeichenarray erhalten.
Links
Ich habe den Artikel für mich selbst geschrieben, da ich nach einer gewissen Zeit vergesse, wie und was zu tun ist.
Vielen Dank für Ihre Aufmerksamkeit.
Quelle: habr.com
