È un sistema per la gestione di vari hardware e software.
TANGO attualmente supporta 4 piattaforme: Linux, Windows NT, Solaris e HP-UX.
Qui descriveremo il lavoro con Linux (Ubuntu 18.04)
Perché sei nuovo?
Semplifica il lavoro con varie apparecchiature e software.
Non devi pensare a come archiviare i dati nel database, lo hanno già fatto per te.
È solo necessario descrivere il meccanismo per il polling dei sensori.
Non sono riuscito a lanciarlo dal codice sorgente; per funzionare ho utilizzato un'immagine già pronta di TangoBox 9.3.
Le istruzioni descrivono come eseguire l'installazione dai pacchetti.
In cosa consiste?
JIVE — utilizzato per visualizzare e modificare il database TANGO.
POGO — generatore di codice per server di dispositivi TANGO.
Astor — responsabile del programma per il sistema TANGO.
Saremo interessati solo ai primi due componenti.
Linguaggi di programmazione supportati
C
C++
Java
JavaScript
Python
Matlab
LabVIEW
Ci ho lavorato in Python e C++. Qui verrà utilizzato il C++ come esempio.
Passiamo ora alla descrizione di come collegare il dispositivo a TANGO e come lavorare con esso. La tassa sarà presa come esempio GPS neo-6m-0-001:
Come puoi vedere nell'immagine, colleghiamo la scheda al PC tramite UART CP2102. Quando è collegato a un PC, viene visualizzato il dispositivo /dev/ttyUSB[0-N], solitamente /dev/ttyUSB0.
POGO
Ora lanciamo pogoe generare codice scheletro per lavorare con la nostra scheda.
pogo
Ho già creato il codice, creiamolo di nuovo File->Nuovo.
Otteniamo quanto segue:
Il nostro dispositivo (in futuro per dispositivo intendiamo la parte software) è vuoto e dispone di due comandi di controllo: Regione / Stato & Stato dei servizi.
Deve essere compilato con gli attributi necessari:
Proprietà del dispositivo — valori di default che trasferiamo al dispositivo per inizializzarlo; per la scheda GPS è necessario trasferire il nome della scheda nel sistema com="/dev/ttyUSB0" e la velocità della porta com baudrade=9600
Comandi — comandi per controllare il nostro dispositivo; ad essi possono essere forniti argomenti e un valore di ritorno.
STATO - restituisce lo stato corrente, da stati
STATUS - restituisce lo stato corrente, questo è il complemento della stringa STATO
GPSArray - ritorna GPS stringa nel modulo DevVarCharArray
Successivamente, impostare gli attributi del dispositivo che possono essere letti/scritti su/da esso. Attributi scalari — attributi semplici (char, string, long, ecc.) Attributi dello spettro - array unidimensionali Attributi immagine - array bidimensionali
stati — lo stato in cui si trova il nostro dispositivo.
APERTO — il dispositivo è aperto.
CHIUDI - il dispositivo è chiuso.
FALLIMENTO - errore.
ON — ricevere dati dal dispositivo.
OFF — nessun dato dal dispositivo.
Esempio di aggiunta di un attributo stringa_gps:
Periodo di polling tempo in ms, la frequenza con cui verrà aggiornato il valore gps_string. Se l'ora di aggiornamento non è specificata, l'attributo verrà aggiornato solo su richiesta.
Si è scoperto:
Ora devi generare il codice File->Genera
Per impostazione predefinita, il Makefile non viene generato; la prima volta è necessario selezionare la casella per crearlo. Questo viene fatto in modo che le modifiche apportate non vengano cancellate durante una nuova generazione. Dopo averlo creato una volta e averlo configurato per il tuo progetto (chiavi di compilazione del registro, file aggiuntivi), puoi dimenticartene.
Passiamo ora alla programmazione. pogo con ha generato quanto segue per noi:
Saremo interessati a NEO6M.cpp e NEO6M.h. Prendiamo un esempio di costruttore di classi:
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
}
Cosa c'è e cosa è importante qui? La funzione init_device() alloca memoria per i nostri attributi: stringa_gps & gps_array, ma non è importante. La cosa più importante qui, questi i commenti:
/*----- PROTECTED REGION ID(NEO6M::constructor_1) ENABLED START -----*/
.......
/*----- PROTECTED REGION END -----*/ // NEO6M::constructor_1
Tutto ciò che si trova all'interno di questo blocco commenti non verrà incluso nel pogo durante le successive rigenerazioni del codice vai via!. Tutto ciò che non è in blocchi lo sarà! Questi sono i luoghi in cui possiamo programmare e apportare le nostre modifiche.
Ora quali sono le funzioni principali contenute nella classe? NEO6M:
Quando vogliamo leggere il valore dell'attributo stringa_gps, le funzioni verranno richiamate nel seguente ordine: sempre_eseguito_hook, read_attr_hardware и leggi_stringa_gps. Read_gps_string riempirà gps_string con il valore.
void NEO6M::read_gps_string(Tango::Attribute &attr)
{
DEBUG_STREAM << "NEO6M::read_gps_string(Tango::Attribute &attr) entering... " << endl;
/*----- PROTECTED REGION ID(NEO6M::read_gps_string) ENABLED START -----*/
// Set the attribute value
*this->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
}
compilazione
Vai alla cartella di origine e:
make
Il programma verrà compilato nella cartella ~/DeviceServers.
tango-cs@tangobox:~/DeviceServers$ ls
NEO6M
JIVE
jive
Ci sono già alcuni dispositivi nel database, ora creiamo il nostro Modifica->Crea server
Ora proviamo a connetterci ad esso:
Niente funzionerà, prima dobbiamo eseguire il nostro programma:
sudo ./NEO6M neo6m -v2
Posso connettermi solo alla porta COM con diritti radices. v — livello di registrazione.
Ora possiamo connetterci:
Cliente
Nella grafica guardare le immagini va sicuramente bene, ma serve qualcosa di più utile. Scriviamo un client che si connetterà al nostro dispositivo e ne prenderà 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);
}
}