URBI - введение в программирование UObject

1. URBI — Введение
2. URBI — архитектура URBI
3. URBI — введение в программирование UObject

Для программирования модулей под Urbi потребуется компилятор:
Microsoft Visual Studio C++ 2008(2005)
Я мучился с попытками компиляции объектов из Visual Studio C++ 6.0, но безрезультатно.
В коде Urbi используются макросы с переменным числом аргументов и ещё разные нюансы, которые, похоже, реализованы только в более современных компиляторах .

Так что придётся остановиться на
Microsoft Visual Studio Express Edition
— бесплатная версия среды разработки для создания приложений под ОС Windows на C#, C++
скачать можно здесь:
www.microsoft.com/express/Downloads/
(выбираем либо инсталяцию через веб для отдельных продуктов, либо, в самом низу, образ диска с полным комплектом).

Скачиваем и устанавливаем urbi SDK 2.1 (windows-x86-vcxx2008):

при установке urbi SDK 2.1 (windows-x86-vcxx2008)
создаётся директория
С:\Program Files\Gostai Engine Runtime\

так же по запросу устанавливается urbiConsole
С:\Program Files\Gostai urbiConsole 2.1\

При установленной VS C++ 2008
добавляется шаблон для создания объектов UObject

Т.е. при создании проекта выбирается
Visual C++ -> uobject


в появившемся поле вводится название объекта
и из шаблона
С:\Program Files\Gostai Engine Runtime\share\templates\Visual Studio\Templates\1033\uobject.cpp
формируется каркас:
#include <urbi/uobject.hh>


class [!output UOBJECT_NAME]: public urbi::UObject
{
  public:
    [!output UOBJECT_NAME](const std::string& str);
    int init();
};


[!output UOBJECT_NAME]::[!output UOBJECT_NAME](const std::string& s)
 : urbi::UObject(s)
{
  UBindFunction([!output UOBJECT_NAME], init);
};

int [!output UOBJECT_NAME]::init()
{
  return 0;
};

UStart([!output UOBJECT_NAME]); 

Т.е. назвав объект, например, MyAdder получим вот такой код:

#include <urbi/uobject.hh>

class MyAdder: public urbi::UObject
{
  public:
    MyAdder(const std::string& str);
    int init();
};


MyAdder::MyAdder(const std::string& s)
 : urbi::UObject(s)
{
  UBindFunction(MyAdder, init);
};

int MyAdder::init()
{
  return 0;
};

UStart(MyAdder); 

Посмотрев свойства проекта можно заметить, что добавляются дополнительные директории для поиска заголовочных файлов и файлов библиотек:

include
С:\Program Files\Gostai Engine Runtime\include

lib
С:\Program Files\Gostai Engine Runtime\bin; С:\Program Files\Gostai Engine Runtime\bin\gostai\engine

так же добавляются дополнительные библиотеки при линковке:
additional
libjpeg4urbi-vc90-d.lib libport-vc90-d.lib libsched-vc90-d.lib libuobject-vc90-d.lib

при отладке запускается:
Debug
С:\Program Files\Gostai Engine Runtime\bin\urbi-launch-d.exe

Добавим тестовый код для суммирования:
#include <urbi/uobject.hh>

class MyAdder: public urbi::UObject
{
  public:
	// класс должен иметь единственный конструктор, принимающий строчку  
    MyAdder(const std::string& str);
 
   // переменная
   urbi::UVar v; 
 
   // методы
   int init();
   double add (double); 
};

// конструктор определяет что доступно из Urbi 
MyAdder::MyAdder(const std::string& s)
 : urbi::UObject(s)  // необходимо
{
  // доступ к переменной
  UBindVar (MyAdder, v); 
 
  // доступ к функции
  UBindFunction (MyAdder, add); 

  UBindFunction(MyAdder, init);
};

int MyAdder::init()
{
  return 0;
};

double 
MyAdder::add (double rhs) 
{ 
  return (v + rhs); 
}

UStart(MyAdder);

При компиляции компилятор ругается на строчку:
return (v + rhs); 

error C2593: operator + is ambiguous

ситуация исправилась только при явном приведении типа:
return ((double)v + rhs); 


При попытке собрать проект получаем ошибку линковки:

LINK: fatal error LNK1104: cannot open file 'libboost_thread-vc90-mt-gd-1_38.lib'
такого файла в каталоге
С:\Program Files\Gostai Engine Runtime\bin\
действительно нет, но есть boost_thread-vc90-mt-gd-1_38.lib
скопировал boost_thread-vc90-mt-gd-1_38.lib в требуемую библиотеку.

следующая ошибка аналогична:
LINK: fatal error LNK1104: cannot open file 'libboost_date_time-vc90-mt-gd-1_38.lib'
скопировал boost_date_time-vc90-mt-gd-1_38.lib
Отлично!
dll-ка успешно слинковалась.

NB при попытке соборать Release-версию выпадают аналогичные ошибки, только теперь библиотеки с суффиксом "-s-" вместо "-gd-"
libboost_thread-vc90-mt-s-1_38.lib
libboost_date_time-vc90-mt-s-1_38.lib


Осталось проверить наш тестовый Urbi-объект.
Для этого нужно:

* Сначала запустить Gostai runtime:
через ярлык в меню пуск, который выполняет команду
«С:\Program Files\Gostai Engine Runtime\bin\urbi.exe» --interactive --port 54000

* загрузка модуля осуществляется программой urbi-launch:
С:\Program Files\Gostai Engine Runtime\bin\urbi-launch.exe -r «C:\Documents and Settings\Myadder.dll»
посмотреть справку можно с флагом (-h)
С:\Program Files\Gostai Engine Runtime\bin\urbi-launch.exe -h


Обратите внимание, что нормально загружаются только Release-версии библиотек.

далее уже в консоли (urbiConsole) создаём объект нашего класса:

=> var adder = MyAdder.new;
#[0002435274] object_423
=> adder.v=6;
#[0002544069] 6
=> adder.add(7);
#[0002551242] 13


Вуаля!

Скачать исходный код примера и готовую dll-ку можно по ссылке:
http://robocraft.ru/files/urbi/MyAdder.zip

выводы:
* класс объекта должен наследоваться от urbi::UObject.
* класс объекта должен иметь единственный конструктор, принимающий в качестве параметра — строку, передавая её в urbi::UObject
* если переменная должна быть доступна из Urbi, то она должна определяться с типом urbi::UVar
* в конструкторе нужно вызвать макрос UBindVar(class-name, variable-name) для каждой переменной UVar и макрос UBindFunction(class-name, function-name) для каждой функции, которые должны быть доступны из Urbi
* вызвать макрос UStart для каждого объекта.

При запуске сервера Urbi объект каждого класса, зарегистрированный с помощью UStart, создаётся с тем же имененм, что и у класса.
Объект класса может быть создан используя метод new.
Для каждого объекта созданного в Urbi создаётся объект объекта С++.

UBindFunction(class-name, function-name)
— даёт доступ к функции из urbiscript
функция может принимать в качестве аргументов/возвращать:
* базовые целочисленные типы и типы с плавающей точкой (int, double, float...)
* const std::string& or const char*.
* urbi::UValue или любые её подтипы (UBinary, UList...).
* std::list или std::vector перечисленных выше типов

UBindFunctions(class-name, function1, function2...)
— можно сразу дать доступ к нескольким функциям

Далее: UObject — пишем Urbi-драйвер для управления сервомашинкой через Arduino
Читать введение в urbiScript — часть 1.

Ссылки:
Документация
Using the Visual C ++ Wizard
Скачать Microsoft Visual Studio Express Edition
  • +1
  • 23 августа 2010, 10:14
  • noonv

Комментарии (4)

RSS свернуть / развернуть
+
0
«При установленной VS C++ 2008
добавляется шаблон для создания объектов UObject»

Ничего такого не произошло. Т.е. VC++ автоматически не обнаружил объект UObjec. Как его добавить ума не приложу.

А что если делать ДЛЛ-ки в Дельфи и пользоваться ими, а не в VC++.
avatar

Alexandr

  • 15 января 2011, 19:13
+
0
можно обойтись и без шаблона, т.к. все нужные параметры проекта перечислены. По поводу делфи ничего подсказать не могу :)
avatar

noonv

  • 15 января 2011, 19:17
+
0
1) Помогите подключить вручную класс UObject. Я очень плохо знаю VC++.
2) Подключил готовую Dll-ку к Urbi. В Gostai Console 2.5 пишу команды, а сервер на них не реагирует, т.е. не пишет таких строчек как
#[0002435274] object_423
#[0002544069] 6


Помогите пожалуйста разобраться в этом.
avatar

Alexandr

  • 15 января 2011, 20:57
+
0
приведённая dll-ка UObject-а собиралась под urbi SDK 2.1 и похоже не будет работать под другими (более новыми) версиями SDK.
avatar

noonv

  • 15 января 2011, 21:06

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.