
Qué es ?
Este es un sistema para gestionar diversos equipos y software.
TANGO soporta 4 plataformas en este momento: Linux, Windows NT, Solaris y HP-UX.
Aquí se describirá el trabajo con Linux (Ubuntu 18.04)
¿Para qué sirve?
Facilita el trabajo con diversos equipos y software.
- No necesita preocuparse por cómo almacenar datos en la base de datos, ya está hecho por usted.
- Solo necesita describir el mecanismo de sondeo de sensores.
- Reduce todo su código a un único estándar.
¿Dónde conseguirlo?
No pude ejecutarlo desde los fuentes, utilicé la imagen lista TangoBox 9.3 para el trabajo.
La instrucción describe cómo instalar desde paquetes.
¿De qué se compone?
- JIVE — sirve para visualizar y editar la base de datos TANGO.
- POGO — generador de código para servidores de dispositivos TANGO.
- Astor — gestor de software para el sistema TANGO.
Solo nos interesarán los dos primeros componentes.
Lenguajes de programación soportados
- C
- C++
- Java
- JavaScript
- Python
- Matlab
- LabVIEW
He trabajado con ella en python & c++. Aquí se usará c++ como ejemplo.
Ahora pasemos a la descripción de cómo conectar un dispositivo a TANGO y cómo trabajar con él. Se tomará como ejemplo la placa GPS neo-6m-0-001:

Como se puede ver en la imagen, conectamos la placa al PC a través de UART CP2102. Al conectarse al PC, aparece el dispositivo /dev/ttyUSB[0-N], normalmente /dev/ttyUSB0.
POGO
Ahora ejecutemos pogo, y generemos el esqueleto de código para trabajar con nuestra placa.
pogo
Ya había creado el código, lo recrearemos Archivo->Nuevo.

Obtenemos lo siguiente:

Nuestro dispositivo (con dispositivo me refiero a la parte del software) está vacío y tiene dos comandos de control: Estado & Estado.
Necesita ser llenado con los atributos necesarios:
Propiedad del dispositivo — valores predeterminados que pasamos al dispositivo para su inicialización, para la placa GPS es necesario pasar el nombre de la placa en el sistema com="/dev/ttyUSB0" y la velocidad del puerto com baudrade=9600
Comandos — comandos para controlar nuestro dispositivo, se les pueden asignar argumentos y valores de retorno.
- ESTADO — devuelve el estado actual, de Estados
- ESTADO — devuelve el estado actual, es una cadena adicional a ESTADO
- GPSArray — devuelve gps una cadena en forma de DevVarCharArray
A continuación se establecen los atributos del dispositivo que se pueden leer/escribir en él.
Atributos escalares — atributos simples (char, string, long, etc.)
Atributos de espectro — arreglos unidimensionales
Atributos de imagen — arreglos bidimensionales
Estados — estados en los que se encuentra nuestro dispositivo.
- ABIERTO — el dispositivo está abierto.
- CERRADO — el dispositivo está cerrado.
- FALLO — error.
- las vistas materializadas no pueden tener tablas detalle remotas. — recibimos datos del dispositivo.
- APAGADO — no hay datos del dispositivo.
Ejemplo de adición de atributo gps_string:

Periodo de sondeo tiempo en ms, con qué frecuencia se actualizará el valor de gps_string. Si no se establece un tiempo de actualización, el atributo solo se actualizará bajo demanda.
Resultado:

Ahora necesitamos generar el código Archivo->Generar

Por defecto, Makefile no se genera, la primera vez se debe marcar la casilla para crearlo. Esto se hace para que las modificaciones realizadas no se eliminen en la nueva generación. Una vez creado y configurado para su proyecto (escribir las claves de compilación, archivos adicionales), se puede olvidar de él.
Ahora pasamos directamente a la programación. pogo nos ha generado lo siguiente:

Nos interesarán NEO6M.cpp & NEO6M.h. Veamos como ejemplo el constructor de la clase:
NEO6M::NEO6M(Tango::DeviceClass *cl, string &s)
: TANGO_BASE_CLASS(cl, s.c_str())
{
/*----- REGIÓN PROTEGIDA ID(NEO6M::constructor_1) HABILITADA INICIO -----*/
init_device();
/*----- REGIÓN PROTEGIDA FIN -----*/ // NEO6M::constructor_1
}¿Qué hay aquí y qué es lo principal? En la función init_device() se asigna memoria para nuestros atributos: gps_string & gps_array, pero eso no es importante. Lo más importante aquí, son los comentarios:
/*----- PROTECTED REGION ID(NEO6M::constructor_1) ENABLED START -----*/
.......
/*----- PROTECTED REGION END -----*/ // NEO6M::constructor_1Todo lo que esté dentro de este bloque de comentarios no se eliminará ¡durante futuras regeneraciones de código en pogo!. Todo lo que no esté en bloques sí se eliminará. Estos son los lugares donde podemos programar y hacer nuestras modificaciones.
Ahora, ¿cuáles son las funciones principales que contiene la clase 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);Cuando queramos leer el valor del atributo gps_string, se llamarán las funciones en el siguiente orden: always_executed_hook, read_attr_hardware y read_gps_string. En read_gps_string se llenará gps_string con el valor.
void NEO6M::read_gps_string(Tango::Attribute &attr)
{
DEBUG_STREAM << "NEO6M::read_gps_string(Tango::Attribute &attr) entrando... " <attr_gps_string_read = Tango::string_dup(this->gps.c_str());
attr.set_value(attr_gps_string_read);
/*----- REGIÓN PROTEGIDA FIN -----*/ // NEO6M::read_gps_string
}Compilación
Entramos a la carpeta con los fuentes y:
makeEl programa se compilará en la carpeta ~/DeviceServers.
tango-cs@tangobox:~/DeviceServers$ ls
NEO6MJIVE
jive
Ya hay algunos dispositivos en la base de datos, ahora crearemos el nuestro Editar->Crear Servidor

Ahora intentemos conectarnos a él:

No funcionará, primero debemos ejecutar nuestro programa:
sudo ./NEO6M neo6m -v2Conectarse al puerto com solo puedo hacerlo con derechos root-á. v — nivel de registro.
Ahora podemos conectarnos:

Cliente
Mirar las imágenes en el gráfico está bien, pero necesitamos algo más útil. Escribiremos un cliente que se conecte a nuestro dispositivo y obtenga los datos de él.
#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);
}
}Cómo compilar:
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++Resultado:
tango-cs@tangobox:~/workspace/c$ ./a.out
$GPRMC,,V,,,,,,,,,,N*53
$GPRMC,,V,,,,,,,,,,N*53
$GPRMC,,V,,,,,,,,,,N*53Recibimos el resultado en forma de retorno de comando, obtención de atributos de cadena y array de caracteres.
Enlaces
Escribí el artículo para mí, porque después de un tiempo empiezo a olvidar cómo y qué hacer.
Gracias por su atención.
Fuente: habr.com
