Программирование на Blockly
Документация по RoboIntellect SDK (RI SDK)
Функциональный RI SDK API исполнительных устройств

PHP

Идем на сайт php.net, выбираем Windows downloads и скачиваем Zip релиз. На момент написания статьи 8.2.1.

Windows

Распаковываем скачанный архив командой

mkdir php-8.2.1 && tar -x -f php-8.2.1-nts-Win32-vs16-x64.zip -C php-8.2.1

Переходим в распакованную директорию

cd 8.2.1

Создайте php.ini для конфигурации из готового шаблона

copy php.ini-development php.ini

Откройте php.ini через текстовый редактор и раскомментируйте следующие строки:

extension_dir = "ext"
extension=ffi
Измените значение переменной short_open_tag=Off на On
Добавьте в переменную окружения PATH путь к папке php-8.2.1.

Подключение RISDK к приложению на PHP

С помощью расширения FFI подключаем распределенную библиотеку risdk, для этого нам в конструкторе cdef нужно указать пути к файлам .so или .dll и .h

Создадим php файл

type nul > shared_client.php

Linux

Идем на сайт php.net и скачиваем оттуда последний релиз. На момент написания статьи 8.2.1.
Скачанный архив можно распаковать командой

tar -xzf php-8.2.1.tar.gz

Переходим в распакованную директорию

cd php-8.2.1

Следующим шагом перед установкой выполняем конфигурацию gcc с указанием расширений которые мы хотим использовать в дальнейшем.
Здесь перечислены часто используемые расширения. Главное расширение, которое обязательно должно быть это FFI (флаг --with-ffi).

./configure --with-openssl --enable-mbstring --with-curl --enable-calendar --enable-bcmath --enable-exif
--enable-gd --enable-ftp --enable-pcntl --enable-sockets --with-sodium --with-zip --with-pear --enable-mysqlnd
--with-pdo-mysql --with-pgsql=/usr/bin/pg_config --with-pdo-pgsql=/usr/bin/pg_config
--with-config-file-scan-dir=/etc/php/8.0 --with-config-file-path=/etc/php/8.0/cli/php.ini --with-zlib --with-ffi

Затем проверяем во сколько потоков может происходить компиляция на вашей машине

nproc

Для более быстрой компиляции вызываем команду make с флагом -j и указываем кол-во потоков сразу после флага. К примеру у вас на машине 12 потоков.

make -j12

Выполняем скрипт установки

sudo make install

После завершения установки проверяем результат командой

  php -v

Создадим php файл

touch shared_client.php

Пример подключения библиотеки, инициализации SDK и создания компонента

Структура проекта

. workspace/
    --- > shared_client.php
    --- > librisdk.h
    --- > librisdk.so/.dll
    --- > libusb-1.0.so/.dll

Подключим библиотеку

Обратите внимание на значение переменной $RELATIVE_PATH. Это относительный путь для поиска библиотеки, если она лежит ниже чем php скрипт.
Например при значении '/..' поиск библиотеки будет выполняться на одну директорию ниже.
При значении '' файлы librisdk.h и librisdk.so должны располагаться в той же директории что и php скрипт.

<?
$RELATIVE_PATH = '';
$headers = file_get_contents(__DIR__ . $RELATIVE_PATH . '/librisdk.h');
// Вырежем лишнии заголовки
$headers = preg_replace(['/#ifdef __cplusplus\s*extern "C" {\s*#endif/i', '/#ifdef __cplusplus\s*}\s*#endif/i'], '', $headers);
$ffi = FFI::cdef($headers, __DIR__ . $RELATIVE_PATH . '/librisdk.so');

print("Success \n");

?>

Для запуска скрипта выполним в терминале следующую команду:

php shared_client.php

Создадим компонент

$logLevel = 2;
$errorText = $ffi->new('char[1000]', 0); // Выделяем память на строку с ошибкой

// Инициализируем SDK
$errCode = $ffi->RI_SDK_InitSDK($logLevel, $errorText);
if ($errCode) {
    // Выведем текст и код ошибки в терминал, при возникновении
    print("RI_SDK_InitSDK errorText:" . FFI::string($errorText) . " errCode: " . $errCode . " \n");
    return $errCode;
}

// Создаем базовый компонент
$descriptor = $ffi->new('int', 0); // Выделяем память на переменную с номером дескриптора
$errCode = $ffi->RI_SDK_CreateBasic(FFI::addr($descriptor), $errorText);
if ($errCode) {
    // Выведем текст и код ошибки в терминал, при возникновении
    print("RI_SDK_CreateBasic errorText:" . FFI::string($errorText). " errCode: " . $errCode . " \n");
    return $errCode;
}

// Выведем полученный дескриптор компонента
print('descriptor: ' . + $descriptor->cdata . " \n");

Запустим скрипт

 php shared_client.php

Результат успешной работы должен выглядеть следующим образом:

descriptor: 1
Success

Пример программы на PHP использующий RI_SDK

Описание

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

Одновременно с движением робота, происходит свечение светодиода. Светодиод горит красным цветом пока сервоприводы приводятся к стартовому положению, после загорается зеленым. Далее светодиоды моргает зеленым при передвижении тела робота и мерцает синим, пока робот кладет/берет кубик.

Структура проекта

. workspace/
    --- > demo.php
    --- > librisdk.h
    --- > librisdk.dll/.so
    --- > CH341DLL.DLL/ CH341DLLA64.DLL
    --- > SLABHIDDevice.dll
    --- > SLABHIDtoSMBus.dll
    --- > libusb-1.0.dll/.so

Реализация

<?
$GLOBALS = ['body_start_pulse' => 1500, // стартовая позиция тела
    'arrowR_start_pulse' => 2000,       // стартовая возиция правой стрелы
    'arrowL_start_pulse' => 1000,       // стартовая позиция левой стрелы
    'claw_start_pulse' => 1000,         // стартовая позиция клешни
    'claw_rotate_start_pulse' => 1500,  // стартовая позиция поворота клешни

    'arrowR_over_cube_position' => -30, // позиция правой стрелы над кубиком
    'arrowL_over_cube_position' => -10,  // позиция левой стрелы над кубиком
    'claw_unclenched_position' => 80,   // позиция открытой клешни
    'arrowR_cube_position' => -75,      // позиция правой стрелы на месте кубика
    'arrowL_cube_position' => 55,       // позиция левой стрелы на месте кубика
];

// структура дескрипторов устройства
class device
{
    public $i2c;        // дескриптор i2c
    public $pwm;        // дескриптор pwm
    public $body;       // дескриптор сервопривода тела
    public $claw;       // дескриптор сервопривода клешни
    public $arrowR;     // дескриптор сервопривода правой стрелы
    public $arrowL;     // дескриптор сервопривода левой стрелы
    public $clawRotate; // дескриптор сервопривода поворота клешни
    public $led;        // дескриптор светодиода

    public function __construct($i2c, $pwm, $body, $claw, $arrowR, $arrowL, $clawRotate, $led)
    {
        $this->i2c = $i2c;
        $this->pwm = $pwm;
        $this->body = $body;
        $this->claw = $claw;
        $this->arrowR = $arrowR;
        $this->arrowL = $arrowL;
        $this->clawRotate = $clawRotate;
        $this->led = $led;
    }
}

// для хранения дескриптоов сервоприводов
class servo
{
    public $descriptor;   // дескриптор сервопривода
    public $startPosition; // стартовая позиция сервопривода

    public function __construct($descriptor, $startPosition)
    {
        $this->descriptor = $descriptor;
        $this->startPosition = $startPosition;
    }
}

// Обратите внимание на значение переменной $RELATIVE_PATH
// Это относительный путь для поиска библиотеки, если она лежит ниже чем php скрипт
// Например при значении '/..' поиск библиотеки будет выполняться на одну директорию ниже
// При значении '' файлы librisdk.h и librisdk.so должны располагаться в той же директории что и php скрипт
$RELATIVE_PATH = '';
$headers = file_get_contents(__DIR__ . $RELATIVE_PATH . '/librisdk.h');
// Вырежем лишнии заголовки
$headers = preg_replace(['/#ifdef __cplusplus\s*extern "C" {\s*#endif/i', '/#ifdef __cplusplus\s*}\s*#endif/i'], '', $headers);
$ffi = FFI::cdef($headers, __DIR__ . $RELATIVE_PATH . '/librisdk.dll');
$errorText = $ffi->new('char[1000]', 0); // Выделяем память на строку с ошибкой. Передается как входной параметр,при возникновении ошибки в эту переменную будет записан текст ошибки

// инициализация структуры устройства
$robohand = new Device($ffi->new('int', 0), $ffi->new('int', 0), $ffi->new('int', 0), $ffi->new('int', 0), $ffi->new('int', 0),
    $ffi->new('int', 0), $ffi->new('int', 0), $ffi->new('int', 0));

// массив дескрипторов сервоприводов
$servos = [
    new servo($robohand->body, $GLOBALS['body_start_pulse']),
    new servo($robohand->claw, $GLOBALS['claw_start_pulse']),
    new servo($robohand->arrowR, $GLOBALS['arrowR_start_pulse']),
    new servo($robohand->arrowL, $GLOBALS['arrowL_start_pulse']),
    new servo($robohand->clawRotate, $GLOBALS['claw_rotate_start_pulse'])
];

$errCode = start($ffi, $servos, $robohand, $errorText);
if ($errCode) {
    print("ErrorText: " . FFI::string($errorText) . " ErrCode: " . $errCode . " \n");

}

// start - запускает демо программу
function start($ffi, $servos, $robohand, $errorText)
{
    $speed = 100;  // скорость в градусах в секунду

    // initDevice - инициализация библиотеки и устройств
    $errCode = initDevice($ffi, $servos, $robohand, $errorText);
    if ($errCode) {
        return $errCode;
    }

    // startPositionAllServo - переводит все сервоприводы в стартовую позицию
    $errCode = startPositionAllServo($ffi, $robohand, $servos, $errorText);
    if ($errCode) {
        return $errCode;
    }

    // Двигаем тело к местонахождению кубика
    $errCode = rotateBody($ffi, $robohand, 45, $speed, $errorText);
    if ($errCode) {
        return $errCode;
    }

    // Берем кубик
    $errCode = get($ffi, $robohand, $speed, $errorText);
    if ($errCode) {
        return $errCode;
    }

    //Двигаем тело к новому местонахождению кубика
    $errCode = rotateBody($ffi, $robohand, -90, $speed, $errorText);
    if ($errCode) {
        return $errCode;
    }

    //Кладем кубик
    $errCode = put($ffi, $robohand, $speed, $errorText);
    if ($errCode) {
        return $errCode;
    }

    // Возвращаем тело в стартовое положение
    $errCode = rotateBody($ffi, $robohand, 45, $speed, $errorText);
    if ($errCode) {
        return $errCode;
    }

    // Уничтожаем компоненты и библиотеку
    $errCode = destruct($ffi, $robohand, $servos, $errorText);
    if ($errCode) {
        return $errCode;
    }

    print("Success \n");

    return 0;
}

// get - берет кубик
function get($ffi, $robohand, $speed, $errorText)
{
    //выполняем мерцание светодиодом,передаем дескриптор светодиода,3 параметра цвета(RGB),продолжительность,кол-во повторений и включаем асинхронный режим работы
    $errCode = $ffi->RI_SDK_exec_RGB_LED_Flicker($robohand->led->cdata, 0, 0, 255, 500, 0, true, $errorText);
    if ($errCode) {
        return $errCode;
    }

    //выполняем поворот на заданный угол,передаем дескриптор стрелы,угол,скорость и асинхронный режим работы
    $errCode = $ffi->RI_SDK_exec_ServoDrive_Turn($robohand->arrowR->cdata, $GLOBALS['arrowR_over_cube_position'], $speed, false, $errorText);
    if ($errCode) {
        return $errCode;
    }

    //выполняем поворот на заданный угол,передаем дескриптор стрелы,угол,скорость и асинхронный режим работы
    $errCode = $ffi->RI_SDK_exec_ServoDrive_Turn($robohand->arrowL->cdata, $GLOBALS['arrowL_over_cube_position'], $speed, false, $errorText);
    if ($errCode) {
        return $errCode;
    }

    //выполняем поворот на заданный угол,передаем дескриптор клешни,угол,скорость и асинхронный режим работы
    $errCode = $ffi->RI_SDK_exec_ServoDrive_Turn($robohand->claw->cdata, $GLOBALS['claw_unclenched_position'], $speed, false, $errorText);
    if ($errCode) {
        return $errCode;
    }

    //выполняем поворот на заданный угол,передаем дескриптор стрелы,угол,скорость и асинхронный режим работы
    $errCode = $ffi->RI_SDK_exec_ServoDrive_Turn($robohand->arrowR->cdata, ($GLOBALS['arrowR_cube_position'] - $GLOBALS['arrowR_over_cube_position']), $speed, false, $errorText);
    if ($errCode) {
        return $errCode;
    }

    //выполняем поворот на заданный угол,передаем дескриптор стрелы,угол,скорость и асинхронный режим работы
    $errCode = $ffi->RI_SDK_exec_ServoDrive_Turn($robohand->arrowL->cdata, ($GLOBALS['arrowL_cube_position'] - $GLOBALS['arrowL_over_cube_position']), $speed, false, $errorText);
    if ($errCode) {
        return $errCode;
    }

    //выполняем поворот на заданный угол,передаем дескриптор клешни,угол,скорость и асинхронный режим работы
    $errCode = $ffi->RI_SDK_exec_ServoDrive_Turn($robohand->claw->cdata, (-1) * $GLOBALS['claw_unclenched_position'], $speed, false, $errorText);
    if ($errCode) {
        return $errCode;
    }

    //выполняем поворот на заданный угол,передаем дескриптор стрелы,угол,скорость и асинхронный режим работы
    $errCode = $ffi->RI_SDK_exec_ServoDrive_Turn($robohand->arrowR->cdata, (-1) * $GLOBALS['arrowR_cube_position'], $speed, false, $errorText);
    if ($errCode) {
        return $errCode;
    }

    //выполняем поворот на заданный угол,передаем дескриптор стрелы,угол,скорость и асинхронный режим работы
    $errCode = $ffi->RI_SDK_exec_ServoDrive_Turn($robohand->arrowL->cdata, (-1) * $GLOBALS['arrowL_cube_position'], $speed, false, $errorText);
    if ($errCode) {
        return $errCode;
    }

    return 0;
}

// rotateBody - вращение тела в указанный угол
function rotateBody($ffi, $robohand, $angle, $speed, $errorText)
{
    //выполняем мигание с заданной частотой,передаем дескриптор светодиода,3 параметра цвета(RGB),частоту,продолжительность и включаем асинхронный режим работы
    $errCode = $ffi->RI_SDK_exec_RGB_LED_FlashingWithFrequency($robohand->led->cdata, 0, 255, 0, 5, 0, true, $errorText);
    if ($errCode) {
        return $errCode;
    }

    //выполняем поворот на заданный угол,передаем дескриптор тела,угол,скорость и асинхронный режим работы
    $errCode = $ffi->RI_SDK_exec_ServoDrive_Turn($robohand->body->cdata, $angle, $speed, false, $errorText);
    if ($errCode) {
        return $errCode;
    }

    //выполняем поворот на заданный угол,передаем дескриптор клешни,угол,скорость и асинхронный режим работы
    $errCode = $ffi->RI_SDK_exec_ServoDrive_Turn($robohand->clawRotate->cdata, 45, $speed, false, $errorText);
    if ($errCode) {
        return $errCode;
    }

    //выполняем поворот на заданный угол,передаем дескриптор клешни,угол,скорость и асинхронный режим работы
    $errCode = $ffi->RI_SDK_exec_ServoDrive_Turn($robohand->clawRotate->cdata, -45, $speed, false, $errorText);
    if ($errCode) {
        return $errCode;
    }

    return 0;
}


// initServos - создает сервоприводы и линкует их
function initServos($ffi, $robohand, $servos, $errorText)
{
    //создаем 5 сервоприводов и линкуем их к пинам 0-4
    for ($i = 0; $i < 5; $i++) {
        // создаем компонент сервопривода с конкретной моделью как исполняемое устройство и получаем дескриптор сервопривода
        $errCode = $ffi->RI_SDK_CreateModelComponent("executor", "servodrive", "mg90s", FFI::addr($servos[$i]->descriptor), $errorText);
        if ($errCode) {
            return $errCode;
        }
        //связываем сервопривод с ШИМ,передаем дескриптор сервопривода и шим
        $errCode = $ffi->RI_SDK_LinkServodriveToController($servos[$i]->descriptor->cdata, $robohand->pwm->cdata, $i, $errorText);
        if ($errCode) {
            return $errCode;
        }
    }

    return 0;
}

// initDevice - инициализация библиотеки и устройств
function initDevice($ffi, $servos, $robohand, $errorText)
{
    $logLevel = 2; // уровень логирования

    // Инициализируем SDK
    $errCode = $ffi->RI_SDK_InitSDK($logLevel, $errorText);
    if ($errCode) {
        return $errCode;
    }

    // создаем компонент ШИМ с конкретной моделью как исполняемое устройство,получаем дескриптор сервопривода
    $errCode = $ffi->RI_SDK_CreateModelComponent("connector", "pwm", "pca9685", FFI::addr($robohand->pwm), $errorText);
    if ($errCode) {
        return $errCode;
    }

   // создаем компонент i2c адатера
    // Здесь осуществлен примитивное определение подключенной модели адаптера
    // Сначала пробуем создать i2c адаптер модели ch341 и связать с ним ШИМ
    $errCode = $ffi->RI_SDK_CreateModelComponent("connector", "i2c_adapter", "ch341", FFI::addr($robohand->i2c), $errorText);
    if ($errCode) {
        return $errCode;
    }

    //связываем i2c адаптер с ШИМ по адресу 0x40
    $errCode = $ffi->RI_SDK_LinkPWMToController($robohand->pwm->cdata, $robohand->i2c->cdata, 0x40, $errorText);
    if ($errCode) {
        // Если не получается то пробуем создать i2c адаптер модели cp2112
        $errCode = $ffi->RI_SDK_CreateModelComponent("connector", "i2c_adapter", "cp2112", FFI::addr($robohand->i2c), $errorText);
        if ($errCode) {
            return $errCode;
        }

        $errCode = $ffi->RI_SDK_LinkPWMToController($robohand->pwm->cdata, $robohand->i2c->cdata, 0x40, $errorText);
        if ($errCode) {
            return $errCode;
        }
    }

    // создаем компонент светодиода с конкретной моделью (ky016) как исполняемое устройство и получаем дескриптор светодиода
    $errCode = $ffi->RI_SDK_CreateModelComponent("executor", "led", "ky016", FFI::addr($robohand->led), $errorText);
    if ($errCode) {
        return $errCode;
    }

    //связываем светодиод адаптер с ШИМ,передаем значения трех пинов к которым подключен светодиод
    $errCode = $ffi->RI_SDK_LinkLedToController($robohand->led->cdata, $robohand->pwm->cdata, 15, 14, 13, $errorText);
    if ($errCode) {
        return $errCode;
    }

    //инициализируем сервоприводы
    $errCode = initServos($ffi, $robohand, $servos, $errorText);
    if ($errCode) {
        return $errCode;
    }

    return 0;
}

// startPositionAllServo - переводит все сервоприводы в стартовую позицию
function startPositionAllServo($ffi, $robohand, $servos, $errorText)
{
//выполняем одиночное свечение светодиодом,передаем дескриптор светодиода,3 параметра цвета(RGB), и включаем асинхронный режим работы
    $errCode = $ffi->RI_SDK_exec_RGB_LED_SinglePulse($robohand->led->cdata, 255, 0, 0, 0, true, $errorText);
    if ($errCode) {
        return $errCode;
    }

    //приводим сервоприводы в стартовое положение
    for ($i = 0; $i < 5; $i++) {
        //выполняем поворот сервопривода в заданный угол,передаем дескриптор сервоприовда,значение угла
        $errCode = $ffi->RI_SDK_exec_ServoDrive_TurnByPulse($servos[$i]->descriptor->cdata, $servos[$i]->startPosition, $errorText);
        if ($errCode) {
            return $errCode;
        }
        sleep(0.5);
    }

    //выполняем одиночное свечение светодиодом,передаем дескриптор светодиода,3 параметра цвета(RGB), и включаем асинхронный режим работы
    $errCode = $ffi->RI_SDK_exec_RGB_LED_SinglePulse($robohand->led->cdata, 0, 255, 0, 0, true, $errorText);
    if ($errCode) {
        return $errCode;
    }
    sleep(0.5);
    return 0;
}

// put - кладет кубик
function put($ffi, $robohand, $speed, $errorText)
{
    //выполняем мерцание светодиодом,передаем дескриптор светодиода,3 параметра цвета(RGB),продолжительность,кол-во повторений и включаем асинхронный режим работы
    $errCode = $ffi->RI_SDK_exec_RGB_LED_Flicker($robohand->led->cdata, 0, 0, 255, 500, 0, true, $errorText);
    if ($errCode) {
        return $errCode;
    }

    //выполняем поворот на заданный угол,передаем дескриптор стрелы,угол,скорость и асинхронный режим работы
    $errCode = $ffi->RI_SDK_exec_ServoDrive_Turn($robohand->arrowR->cdata, $GLOBALS['arrowR_cube_position'], $speed, false, $errorText);
    if ($errCode) {
        return $errCode;
    }

    //выполняем поворот на заданный угол,передаем дескриптор стрелы,угол,скорость и асинхронный режим работы
    $errCode = $ffi->RI_SDK_exec_ServoDrive_Turn($robohand->arrowL->cdata, $GLOBALS['arrowL_cube_position'], $speed, false, $errorText);
    if ($errCode) {
        return $errCode;
    }

    //выполняем поворот на заданный угол,передаем дескриптор клешни,угол,скорость и асинхронный режим работы
    $errCode = $ffi->RI_SDK_exec_ServoDrive_Turn($robohand->claw->cdata, $GLOBALS['claw_unclenched_position'], $speed, false, $errorText);
    if ($errCode) {
        return $errCode;
    }

    //выполняем поворот на заданный угол,передаем дескриптор стрелы,угол,скорость и асинхронный режим работы
    $errCode = $ffi->RI_SDK_exec_ServoDrive_Turn($robohand->arrowR->cdata, (-1) * $GLOBALS['arrowR_cube_position'], $speed, false, $errorText);
    if ($errCode) {
        return $errCode;
    }

    //выполняем поворот на заданный угол,передаем дескриптор стрелы,угол,скорость и асинхронный режим работы
    $errCode = $ffi->RI_SDK_exec_ServoDrive_Turn($robohand->arrowL->cdata, (-1) * $GLOBALS['arrowL_cube_position'], $speed, false, $errorText);
    if ($errCode) {
        return $errCode;
    }

    //выполняем поворот на заданный угол,передаем дескриптор клешни,угол,скорость и асинхронный режим работы
    $errCode = $ffi->RI_SDK_exec_ServoDrive_Turn($robohand->claw->cdata, (-1) * $GLOBALS['claw_unclenched_position'], $speed, false, $errorText);
    if ($errCode) {
        return $errCode;
    }
    return 0;
}

// destructServos - уничтожает сервоприводы
function destructServos($ffi, $servos, $errorText)
{
    //уничтожаем сервоприводы
    for ($i = 0; $i < 5; $i++) {
        $errCode = $ffi->RI_SDK_DestroyComponent($servos[$i]->descriptor->cdata, $errorText);
        if ($errCode) {
            return $errCode;
        }
    }

    return 0;
}

// destruct - уничтожает все компоненты и библиотеку
function destruct($ffi, $robohand, $servos, $errorText)
{
//выполняем одиночное свечение светодиодом,передаем дескриптор светодиода,3 параметра цвета(RGB), и включаем асинхронный режим работы
    $errCode = $ffi->RI_SDK_exec_RGB_LED_SinglePulse($robohand->led->cdata, 255, 0, 0, 0, true, $errorText);
    if ($errCode) {
        return $errCode;
    }

    //уничтожаем сервоприводы
    $errCode = destructServos($ffi, $servos, $errorText);
    if ($errCode) {
        return $errCode;
    }

    //останавливаем свечение светодиода с определенным дескриптором
    $errCode = $ffi->RI_SDK_exec_RGB_LED_Stop($robohand->led->cdata, $errorText);
    if ($errCode) {
        return $errCode;
    }

    //удаляем компонент светодиода по дескриптору
    $errCode = $ffi->RI_SDK_DestroyComponent($robohand->led->cdata, $errorText);
    if ($errCode) {
        return $errCode;
    }

    //сбрасываем все порты на ШИМ
    $errCode = $ffi->RI_SDK_sigmod_PWM_ResetAll($robohand->pwm->cdata, $errorText);
    if ($errCode) {
        return $errCode;
    }

    // удаляем компонент ШИМ
    $errCode = $ffi->RI_SDK_DestroyComponent($robohand->pwm->cdata, $errorText);
    if ($errCode) {
        return $errCode;
    }

    //удаляем компонент i2c
    $errCode = $ffi->RI_SDK_DestroyComponent($robohand->i2c->cdata, $errorText);
    if ($errCode) {
        return $errCode;
    }

    //удаляем sdk со всеми компонентами в реестре компонентов
    $errCode = $ffi->RI_SDK_DestroySDK(true, $errorText);
    if ($errCode) {
        return $errCode;
    }
    return 0;
}


46 просмотров0 комментариев

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

Для участия в обсуждении вы должны быть авторизованным пользователем
Разделы
Программирование на Blockly
Документация по RoboIntellect SDK (RI SDK)
Функциональный RI SDK API исполнительных устройств

Навигация

ВойтиРегистрация