
Co to jest ?
Jest to system służący do zarządzania różnorodnym sprzętem i oprogramowaniem.
TANGO поддерживает 4 платформы на данный момент: Linux, Windows NT, Solaris и HP-UX.
Здесь будет описана работа с Linux(Ubuntu 18.04)
Po co to jest?
Ułatwia pracę z różnorodnym sprzętem i oprogramowaniem.
- Nie musisz się zastanawiać, jak przechowywać dane w bazie danych, bo zrobimy to za Ciebie.
- Wystarczy opisać mechanizm sondowania czujników.
- Konsoliduje cały kod w jeden standard.
Skąd je wziąć?
Ponieważ nie mogłem uruchomić go z kodu źródłowego, wykorzystałem gotowy obraz TangoBox 9.3.
Instrukcja opisuje sposób montażu z torebek.
Z czego się składa?
- JIVE — służy do przeglądania i edycji bazy danych TANGO.
- POGO — generator kodu dla serwerów urządzeń TANGO.
- Astor — kierownik ds. oprogramowania systemu TANGO.
Nas będą interesować tylko dwa pierwsze komponenty.
Obsługiwane języki programowania
- C
- C + +
- Java
- JAVASCRIPT
- Python
- matlab
- LabVIEW
Pracowałem z nią nad Pythonem i C++. W tym przykładzie wykorzystamy język C++.
Teraz przejdziemy do opisu jak podłączyć urządzenie do TANGO i jak z nim pracować. Tablica będzie brana jako przykład GPS neo-6m-0-001:

Jak widać na zdjęciu, płytkę podłączamy do komputera poprzez UART CP2102. Po podłączeniu do komputera pojawia się urządzenie /dev/ttyUSB[0-N], zwykle /dev/ttyUSB0.
POGO
Teraz uruchommy pogoi generujemy szkielet kodu do pracy z naszą płytką.
pogo
Mam już utworzony kod, stwórzmy go jeszcze raz Plik->Nowy.

Otrzymujemy co następuje:

Nasze urządzenie (dalej przez urządzenie będziemy rozumieć część programową) jest puste i posiada dwa polecenia sterujące: Miasto & Status.
Musi zostać wypełniony wymaganymi atrybutami:
Właściwość urządzenia — wartości domyślne, które przekazujemy urządzeniu w celu jego inicjalizacji, w przypadku płytki GPS należy przekazać nazwę płytki w systemie com="/dev/ttyUSB0" i prędkość portu COM prędkość transmisji=9600
Polecenia — polecenia sterujące naszym urządzeniem, można ustawić argumenty i zwrócić dla nich wartość.
- STAN - zwraca aktualny stan, od Zjednoczone
- STATUS - zwraca aktualny status, jest to ciąg uzupełniający do STAN
- Tablica GPS - zwraca GPS linia w formie Tablica cech DevVarCharArray
Następnie określa się atrybuty urządzenia, które można z niego odczytać i zapisać.
Atrybuty skalarne — proste atrybuty (char, string, long, itd.)
Atrybuty widma — tablice jednowymiarowe
Atrybuty obrazu - tablice dwuwymiarowe
Zjednoczone — stan, w którym znajduje się nasze urządzenie.
- OPEN — urządzenie jest otwarte.
- ZAMKNIJ — urządzenie jest zamknięte.
- NIEPOWODZENIE - błąd.
- ON — otrzymujemy dane z urządzenia.
- OFF - brak danych z urządzenia.
Przykład dodania atrybutu ciąg_gps:

Okres odpytywania czas w ms, jak często wartość gps_string będzie aktualizowana. Jeśli czas aktualizacji nie zostanie określony, atrybut zostanie zaktualizowany tylko na żądanie.
Stało się:

Teraz musimy wygenerować kod Plik->Generuj

Domyślnie plik Makefile nie jest generowany. Za pierwszym razem musisz zaznaczyć pole wyboru, aby go utworzyć. Robi się tak, aby wprowadzone zmiany nie zostały usunięte podczas nowej generacji. Jeśli raz je utworzysz i skonfigurujesz dla swojego projektu (zarejestrujesz klucze kompilacji, dodatkowe pliki), możesz o nich zapomnieć.
Przejdźmy teraz bezpośrednio do programowania. Pogo wygenerowało dla nas następujące dane:

Będziemy interesować się plikami NEO6M.cpp i NEO6M.h. Przyjrzyjmy się przykładowi konstruktora klasy:
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
}Co tu jest i co jest tu najważniejsze? W funkcji init_device() pamięć jest przydzielana dla naszych atrybutów: ciąg_gps & tablica_gps, ale to nie ma znaczenia. Najważniejsza rzecz tutaj, oto komentarze:
/*----- PROTECTED REGION ID(NEO6M::constructor_1) ENABLED START -----*/
.......
/*----- PROTECTED REGION END -----*/ // NEO6M::constructor_1Wszystko, co znajduje się wewnątrz bloku komentarza, nie zostanie uwzględnione w kolejnych regeneracjach kodu w pogo. oddalić się!. Wszystko co nie jest w blokach będzie! To miejsca, w których możemy programować i wprowadzać własne zmiany.
Jakie są główne funkcje tej klasy? NEO6M:
void always_executed_hook();
void read_attr_hardware(vector<long> &attr_list);
void read_gps_string(Tango::Attribute &attr);
void read_gps_array(Tango::Attribute &attr);Kiedy chcemy odczytać wartość atrybutu ciąg_gps, funkcje będą wywoływane w następującej kolejności: zawsze_wykonywany_hak, przeczytaj_atrybut_sprzętu и odczyt_ciągu_gps. W read_gps_string parametr gps_string zostanie wypełniony wartością.
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
}Kompilacja
Wchodzimy do folderu ze źródłami i:
makeProgram zostanie skompilowany w folderze ~/DeviceServers.
tango-cs@tangobox:~/DeviceServers$ ls
NEO6MJIVE
jive
W bazie danych jest już kilka urządzeń, teraz utwórzmy nasze Edytuj->Utwórz serwer

Teraz spróbujmy się z nim połączyć:

Nic nie zadziała, najpierw musimy uruchomić nasz program:
sudo ./NEO6M neo6m -v2Mogę połączyć się tylko z portem COM z uprawnieniami korzeń-a v — poziom rejestrowania.
Teraz możemy się połączyć:

Klient
W grafice oglądanie obrazków jest oczywiście przydatne, ale potrzeba czegoś bardziej użytecznego. Napiszmy klienta, który połączy się z naszym urządzeniem i będzie pobierał z niego odczyty.
#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);
}
}Jak skompilować:
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++Wynik:
tango-cs@tangobox:~/workspace/c$ ./a.out
$GPRMC,,V,,,,,,,,,,N*53
$GPRMC,,V,,,,,,,,,,N*53
$GPRMC,,V,,,,,,,,,,N*53Wynik otrzymaliśmy jako polecenie return przyjmujące atrybuty ciągu i tablicę znaków.
referencje
Napisałem ten artykuł dla siebie, bo po jakimś czasie zaczynam zapominać, jak i co mam robić.
Dziękuję za uwagę.
Źródło: www.habr.com
