Tango Controls

Tango Controls

Какво представлява TANGO?

Това е система за управление на различно оборудване и софтуер.
TANGO в момента поддържа 4 платформи: Linux, Windows NT, Solaris и HP-UX.
Тук ще бъде описана работата с Linux (Ubuntu 18.04)

За какво е нужно?

Оптимизира работата с различно оборудване и софтуер.

  • Не е нужно да се притеснявате как да съхранявате данните в БД, това вече е направено вместо вас.
  • Трябва просто да опишете механизма за опрашване на сензорите.
  • Събира всичките ви кодове в един стандарт.

Къде да намеря?

Не успях да го стартирам от изходния код, използвах готовия образ TangoBox 9.3.
В инструкциите е описано как да се инсталира от пакети.

От какво е съставена?

  • JIVE — служи за преглед и редактиране на базата данни TANGO.
  • POGO — генератор на код за TANGO устройства.
  • Astor — софтуерен мениджър за системата TANGO.

Нас ще ни интересуват само първите две компонента.

Поддържани програмни езици

  • C
  • C++
  • Java
  • JavaScript
  • Python
  • Matlab
  • LabVIEW

Работих с нея на python & c++. Тук в примера ще използваме c++.

Сега да преминем към описанието как да свържем устройството с TANGO и как да работим с него. В пример ще вземем платката GPS neo-6m-0-001:

Tango Controls

Както се вижда на картинката, платката се свързва с ПК чрез UART CP2102. При свързване към ПК се появява устройство /dev/ttyUSB[0-N], обикновено /dev/ttyUSB0.

POGO

Сега да стартираме pogo, и генерираме скелетен код за работа с нашата платка.

pogo

Tango Controls

Вече имах създаден код, ще го създадем наново File->New.

Tango Controls

Получаваме следното:

Tango Controls

Нашето устройство (под устройство в бъдеще ще има предвид софтуерната част) е празно и има две команди за управление: State & Status.

Трябва да го запълните с необходимите атрибути:

Device Property — стойности по подразбиране, които предаваме на устройството за инициализация, за платката GPS трябва да предадем името на платката в системата com="/dev/ttyUSB0" и скоростта на com порта baudrade=9600

Commands — команди за управление на нашето устройство, на които може да зададете аргументи и стойности за връщане.

  • STATE — връща текущото състояние, от States
  • STATUS — връща текущия статус, това е текстово допълнение към STATE
  • GPSArray — връща gps строка под формата на DevVarCharArray

След това се задават атрибутите на устройството, които могат да се четат/пишат в/от него.
Scalar Attributes — прости атрибути (char, string, long и т.н.)
Spectrum Attributes — едномерни масиви
Image Attributes — двумерни масиви

States — състояния, в които се намира нашето устройство.

  • OPEN — устройството е отворено.
  • ЗАТВОРИ — устройството е затворено.
  • НЕУСПЕШНО — грешка.
  • ON — получаваме данни от устройството.
  • ИЗКЛ. — няма данни от устройството.

Пример за добавяне на атрибут gps_string:

Tango Controls

Период на опрашване време в ms, колко често ще се обновява стойността на gps_string. Ако времето за обновление не е зададено, атрибутът ще се обновява само по заявка.

Получено:

Tango Controls

Сега трябва да генерираме код File->Generate

Tango Controls

По подразбиране Makefile не се генерира, при първото използване трябва да се постави отметка, за да бъде създаден. Това е направено, за да не се изтриват направените промени при нова генерация. След като го създадете веднъж и го настроите за вашия проект (да зададете компилационни ключове, допълнителни файлове), можете да забравите за него.

Сега преминаваме директно към програмирането. pogo генерира следното за нас:

Tango Controls

Нас ще ни интересуват NEO6M.cpp & NEO6M.h. Нека разгледаме конструктора на класа като пример:

NEO6M::NEO6M(Tango::DeviceClass *cl, string &s)
 : TANGO_BASE_CLASS(cl, s.c_str())
{
    /*----- ПРОТЕКТИРАНА ЗОНА ID(NEO6M::constructor_1) АКТИВИРАНА НАЧАЛО -----*/
    init_device();

    /*----- ПРОТЕКТИРАНА ЗОНА КРАЙ -----*/    //  NEO6M::constructor_1
}

Какво има тук и какво е основното? В функцията init_device() се заделя памет за нашите атрибути: gps_string & gps_array, но това не е важно. Най-важното тук, това са коментарите:

/*----- PROTECTED REGION ID(NEO6M::constructor_1) ENABLED START -----*/
    .......
/*----- PROTECTED REGION END -----*/    //  NEO6M::constructor_1

Всичко, което се намира вътре в този блок коментар, при последващи прегенерации на кода в pogo няма да бъде изтривано!. Всичко, което не е в блоковете, ще бъде! Това са местата, където можем да програмираме и да правим свои корекции.

Сега какви основни функции съдържа класът 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);

Когато искаме да прочетем стойността на атрибута gps_string, ще бъдат извикани функциите в следния ред: always_executed_hook, read_attr_hardware и read_gps_string. В read_gps_string ще се попълни gps_string със стойност.

void NEO6M::read_gps_string(Tango::Attribute &attr)
{
    DEBUG_STREAM << "NEO6M::read_gps_string(Tango::Attribute &attr) влизане... " <attr_gps_string_read = Tango::string_dup(this->gps.c_str());

    attr.set_value(attr_gps_string_read);

    /*----- ПРОТЕКТИРАНА ЗОНА КРАЙ -----*/    //  NEO6M::read_gps_string
}

Компилация

Влизаме в папката с изходния код и:

, затова потребителите на Windows трябва да инсталират Cygwin или да се справят сами с Visual Studio и библиотеките.

Програмата ще бъде компилирана в папката ~/DeviceServers.

tango-cs@tangobox:~/DeviceServers$ ls
NEO6M

JIVE

jive

Tango Controls

В БД вече има някакви устройства, сега ще създадем нашето Edit->Create Server

Tango Controls

Сега ще опитаме да се свържем с него:

Tango Controls

Нищо няма да се получи, първо трябва да стартираме нашата програма:

sudo .\/NEO6M neo6m -v2

Мога да се свържа с com порта само с права root-а. v — ниво на логване.

Сега можем да се свържем:

Tango Controls

Клиент

Гледането на изображения в графиката определено е приятно, но е нужно нещо по-полезно. Ще напишем клиент, който ще се свързва с устройството и ще извлича показанията от него.

#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);
    }
}

Как да компилираме:

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++

Резултат:

tango-cs@tangobox:~/workspace/c$ ./a.out 
$GPRMC,,V,,,,,,,,,,N*53

$GPRMC,,V,,,,,,,,,,N*53

$GPRMC,,V,,,,,,,,,,N*53

Получихме резултат в отговор на командата, извличане на атрибутите на реда и масива от символи.

Връзки

Написах статията за себе си, защото след известно време започвам да забравям как и какво да правя.

Благодаря за вниманието.

Източник: habr.com

Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри 🔥 Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри | ProHoster