
Che cos'è ?
È un sistema per la gestione di diverse attrezzature e software.
TANGO supporta attualmente 4 piattaforme: Linux, Windows NT, Solaris e HP-UX.
Qui sarà descritta l'operatività con Linux (Ubuntu 18.04)
A cosa serve?
Semplifica l'utilizzo di diverse attrezzature e software.
- Non devi preoccuparti di come memorizzare i dati nel database, è già stato fatto per te.
- Devi solo descrivere il meccanismo di interrogazione dei sensori.
- Riduce tutto il tuo codice a uno standard unico.
Dove trovarlo?
Non sono riuscito a eseguirlo dagli sorgenti, per lavorarci ho utilizzato l'immagine pronta TangoBox 9.3.
Nelle istruzioni è descritto come installare dai pacchetti.
Da cosa è composta?
- JIVE — serve per visualizzare e modificare il database TANGO.
- POGO — generatore di codice per i server delle attrezzature TANGO.
- Astor — gestore software per il sistema TANGO.
Ci interesseranno solo i primi due componenti.
Linguaggi di programmazione supportati
- C
- C++
- Java
- JavaScript
- Python
- Matlab
- LabVIEW
Ho lavorato con esso in python & c++. Qui come esempio verrà utilizzato c++.
Passiamo ora alla descrizione di come collegare il dispositivo a TANGO e come lavorarci. Come esempio prenderemo la scheda GPS neo-6m-0-001:

Come mostrato nell'immagine, colleghiamo la scheda al PC tramite UART CP2102. Collegando al PC appare il dispositivo /dev/ttyUSB[0-N], di solito /dev/ttyUSB0.
POGO
Ora avviamo pogo, e generiamo il codice scheletro per lavorare con la nostra scheda.
pogo
Avevo già creato il codice, creiamolo di nuovo File->Nuovo.

Otteniamo il seguente:

Il nostro dispositivo (con dispositivo intendiamo in seguito la parte software) è vuoto e ha due comandi di controllo: Stato & Stato.
Deve essere riempito con gli attributi necessari:
Proprietà del dispositivo — valori predefiniti che passiamo al dispositivo per la sua inizializzazione, per la scheda GPS dobbiamo inviare il nome della scheda nel sistema com="/dev/ttyUSB0" e la velocità della porta com baudrate=9600
Comandi — comandi di controllo del nostro dispositivo, a cui si possono assegnare argomenti e valori di ritorno.
- STATO — restituisce lo stato attuale, da Stati
- STATUS — restituisce lo stato corrente, questo è un'aggiunta testuale a STATO
- GPSArray — restituisce gps una stringa sotto forma di DevVarCharArray
Successivamente, vengono definiti gli attributi del dispositivo che possono essere letti/scritti in/da esso.
Attributi scalari — attributi semplici (char, string, long, ecc.)
Attributi Spectrum — array monodimensionali
Attributi Immagine — array bidimensionali
Stati — stati in cui si trova il nostro dispositivo.
- APERTO — dispositivo aperto.
- CHIUDE — dispositivo chiuso.
- FALLIMENTO — errore.
- ON — riceviamo dati dal dispositivo.
- OFF — nessun dato dal dispositivo.
Esempio di aggiunta di un attributo gps_string:

Periodo di polling tempo in ms, quanto spesso verrà aggiornato il valore di gps_string. Se non si specifica il tempo di aggiornamento, l'attributo verrà aggiornato solo su richiesta.
Risultato:

Ora dobbiamo generare il codice File->Genera

Per impostazione predefinita, il Makefile non viene generato; la prima volta è necessario selezionare la casella per crearlo. Questo è fatto affinché le modifiche apportate non vengano eliminate durante una nuova generazione. Creandolo una volta e configurandolo per il proprio progetto (specificare le chiavi di compilazione, file aggiuntivi) si può dimenticare di esso.
Ora passiamo alla programmazione vera e propria. pogo ha generato quanto segue:

Ci interesseranno NEO6M.cpp & NEO6M.h. Consideriamo come esempio il costruttore della classe:
NEO6M::NEO6M(Tango::DeviceClass *cl, string &s)
: TANGO_BASE_CLASS(cl, s.c_str())
{
/*----- REGIONE PROTETTA ID(NEO6M::constructor_1) ABILITATA INIZIO -----*/
init_device();
/*----- REGIONE PROTETTA FINE -----*/ // NEO6M::constructor_1
}Cosa c'è qui e qual è la cosa principale? Nella funzione init_device() viene allocata memoria per i nostri attributi: gps_string & gps_array, ma non è importante. La cosa più importante qui, sono i commenti:
/*----- PROTECTED REGION ID(NEO6M::constructor_1) ENABLED START -----*/
.......
/*----- PROTECTED REGION END -----*/ // NEO6M::constructor_1Tutto ciò che si trova all'interno di questo blocco di commento non verrà rimosso!. Tutto ciò che non è nei blocchi lo sarà! Questi sono i posti dove possiamo programmare e apportare le nostre modifiche.
Ora, quali sono le principali funzioni contenute nella classe 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);Quando vogliamo leggere il valore di un attributo gps_string, verranno chiamate le funzioni nel seguente ordine: always_executed_hook, read_attr_hardware e read_gps_string. In read_gps_string verrà riempita la gps_string con il valore.
void NEO6M::read_gps_string(Tango::Attribute &attr)
{
DEBUG_STREAM << "NEO6M::read_gps_string(Tango::Attribute &attr) entrata... " <attr_gps_string_read = Tango::string_dup(this->gps.c_str());
attr.set_value(attr_gps_string_read);
/*----- REGIONE PROTETTA FINE -----*/ // NEO6M::read_gps_string
}Compilazione
Accediamo alla cartella con i sorgenti e:
makeIl programma verrà compilato nella cartella ~/DeviceServers.
tango-cs@tangobox:~/DeviceServers$ ls
NEO6MJIVE
jive
Nel database sono già presenti alcuni dispositivi, ora creiamo il nostro Modifica->Crea Server

Ora proviamo a connetterci a esso:

Non funzionerà, prima dobbiamo avviare il nostro programma:
sudo ./NEO6M neo6m -v2Per connettermi alla porta com posso farlo solo con i diritti root-a. v — livello di logging.
Ora possiamo connetterci:

Cliente
Guardare le immagini nel grafico è sicuramente bello, ma abbiamo bisogno di qualcosa di più utile. Scriviamo un client che si connetterà al nostro dispositivo e recupererà le letture.
#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);
}
}Come compilare:
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++Risultato:
tango-cs@tangobox:~/workspace/c$ ./a.out
$GPRMC,,V,,,,,,,,,,N*53
$GPRMC,,V,,,,,,,,,,N*53
$GPRMC,,V,,,,,,,,,,N*53Abbiamo ottenuto un risultato come ritorno del comando, ottenimento degli attributi di una stringa e di un array di caratteri.
Link
Ho scritto l'articolo per me stesso, perché dopo un po' di tempo inizio a dimenticare come e cosa fare.
Grazie per l'attenzione.
Fonte: habr.com
