É un sistema para xestionar varios hardware e software.
Actualmente TANGO admite 4 plataformas: Linux, Windows NT, Solaris e HP-UX.
Aquí describiremos o traballo con Linux (Ubuntu 18.04)
Para que serve?
Simplifica o traballo con varios equipos e software.
Non necesitas pensar en como almacenar datos na base de datos, xa está feito por ti.
Só é necesario describir o mecanismo de sondaxe dos sensores.
Non puiden inicialo desde o código fonte; usei unha imaxe preparada de TangoBox 9.3 para funcionar.
As instrucións describen como instalar desde paquetes.
En que consiste?
JIVE — úsase para ver e editar a base de datos TANGO.
POGO — xerador de código para servidores de dispositivos TANGO.
Astor — xestor de programas para o sistema TANGO.
Estaremos interesados só nos dous primeiros compoñentes.
Linguaxes de programación soportadas
C
C ++
Java
JavaScript
Pitão
matlab
LabVIEW
Traballei con el en python e c++. Aquí usarase C++ como exemplo.
Agora imos pasar a unha descrición de como conectar o dispositivo a TANGO e como traballar con el. A taxa tomarase como exemplo GPS neo-6m-0-001:
Como podes ver na imaxe, conectamos a placa ao PC mediante UART CP2102. Cando está conectado a un PC, aparece o dispositivo /dev/ttyUSB[0-N], normalmente /dev/ttyUSB0.
POGO
Agora imos lanzar pogo, e xerar código esqueleto para traballar co noso taboleiro.
pogo
Xa creei o código, creémolo de novo Ficheiro->Novo.
Obtemos o seguinte:
O noso dispositivo (no futuro, por dispositivo queremos dicir a parte de software) está baleiro e ten dous comandos de control: estado & Estado.
Debe cubrirse cos atributos necesarios:
Propiedade do dispositivo — valores predeterminados que transferimos ao dispositivo para inicializalo; para a placa GPS, cómpre transferir o nome da tarxeta no sistema com="/dev/ttyUSB0" e velocidade do porto com Baudrade = 9600
comandos — comandos para controlar o noso dispositivo; pódense dar argumentos e un valor de retorno.
ESTADO - devolve o estado actual, de Unidos
ESTADO - devolve o estado actual, este é o complemento da cadea ESTADO
GPSArray - devolve GPS cadea no formulario DevVarCharArray
A continuación, configure os atributos do dispositivo que se poden ler/escribir para/desde el. Atributos escalares - atributos simples (char, string, long, etc.) Atributos do espectro -Matrices unidimensionales Atributos da imaxe -Matrices bidimensionais
Unidos — o estado no que se atopa o noso dispositivo.
aBERTO - o dispositivo está aberto.
Pechar - o dispositivo está pechado.
FALLO - erro.
ON — recibir datos do dispositivo.
OFF - non hai datos do dispositivo.
Exemplo de engadir un atributo cadea_gps:
Período de votación tempo en ms, con que frecuencia se actualizará o valor gps_string. Se non se especifica o tempo de actualización, o atributo só se actualizará previa solicitude.
Acontecido:
Agora cómpre xerar o código Ficheiro->Xerar
Por defecto, o Makefile non se xera; a primeira vez que cómpre marcar a caixa para crealo. Isto faise para que os cambios realizados nel non se eliminen durante unha nova xeración. Creado unha vez e configurado para o seu proxecto (rexistrar claves de compilación, ficheiros adicionais), pode esquecerse del.
Agora imos pasar á programación. pogo con xerou o seguinte para nós:
Estaremos interesados en NEO6M.cpp e NEO6M.h. Poñamos un exemplo dun construtor de clases:
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
}
Que hai e que é importante aquí? A función init_device() asigna memoria para os nosos atributos: cadea_gps & matriz_gps, pero non é importante. O máis importante aquí, estes son os comentarios:
/*----- PROTECTED REGION ID(NEO6M::constructor_1) ENABLED START -----*/
.......
/*----- PROTECTED REGION END -----*/ // NEO6M::constructor_1
Todo o que estea dentro deste bloque de comentarios non se incluirá en pogo durante as rexeneracións de código posteriores Irse!. Todo o que non estea en bloques será! Estes son os lugares onde podemos programar e facer as nosas propias edicións.
Agora cales son as principais funcións que contén a clase? NEO6M:
Cando queremos ler o valor do atributo cadea_gps, as funcións convocaranse pola seguinte orde: gancho_sempre_executado, read_attr_hardware и read_gps_string. Read_gps_string encherá gps_string co valor.
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
}
Recompilación
Vaia ao cartafol de orixe e:
make
O programa compilarase no cartafol ~/DeviceServers.
tango-cs@tangobox:~/DeviceServers$ ls
NEO6M
JIVE
jive
Xa hai algúns dispositivos na base de datos, agora imos crear o noso Editar->Crear servidor
Agora imos tentar conectar con el:
Nada funcionará, primeiro necesitamos executar o noso programa:
sudo ./NEO6M neo6m -v2
Só podo conectarme ao porto de comunicación con dereitos raíz-A. v - Nivel de rexistro.
Agora podemos conectarnos:
Cliente
En gráficos, mirar imaxes é certamente bo, pero necesitas algo máis útil. Escribamos un cliente que se conectará ao noso dispositivo e fagamos lecturas del.
#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);
}
}