!!! ИНФОРМАЦИЯ
RISDK - библиотека Robo Intellect Software Development Kit
exec - группа исполнителей
RServoDrive - подгруппа сервоприводов вращения
RotateByPulse - название метода вращения сервопривода по импульсу
Сигнатура функции:
- Golang DLL
RI_SDK_exec_RServoDrive_RotateByPulse(descriptor, pulse, errorText):errorCode
- Golang gRPC
RI_SDK_Exec_RServoDrive_RotateByPulse(descriptor, pulse int64, async bool) (errorText string, errorCode int64, err error)
Описание метода
Направление и скорость задаются через значение импульса. Вращение выполняется до тех пор, пока не будет вызвана функция остановки.
Дает команду сервоприводу с дескриптором descriptor вращаться до тех пор, пока не будет вызвана функция остановки. Направление и скорость вращения задается параметром pulse, соответствующее значению управляющего импульса. Параметр async устанавливает режим выполнения команды - асинхронный или синхронный.
Размер рабочего диапазона для mg996r - по часовой стрелке 1020 мкс (от 400 до 1420 мкс), против часовой стрелки 1020 мкс (от 1540 до 2560 мкс). Максимальная скорость при вращении по часовой стрелке достигается при минимальном значении из рабочего диапазона, для вращения против часовой наоборот, минимальное значение из рабочего диапазона вращает сервопривод с минимальной скоростью. Для управляющего сигнала между диапазонами вращение не происходит.
Даже в рамках одной и той же модели сервопривода существует погрешность, допускаемая при производстве, которая приводит к тому, что рабочий диапазон длин импульсов отличается. Для точной работы каждый конкретный сервопривод должен быть откалиброван: путём экспериментов необходимо подобрать корректный диапазон, характерный именно для него. С помощью метода инициализации собственного компонента сервопривода вращения можно инициализировать сервопривод с откалиброванными характеристиками.
При синхронном режиме программа, которая вызвала данную функцию, сначала ожидает её выполнение, а потом продолжает вызовы других команд. При асинхронном режиме функция вызывается, но ожидания её завершения не происходит. Другие команды могут перекрыть её выполнение и функция не отработает.
Параметры и возвращаемые значения
Параметр | Тип для Shared object | Тип для Golang gRPC | Описание |
---|---|---|---|
descriptor | int (тип C) | int64 | Дескриптор сервопривода |
pulse | int (тип C) | int64 | Значение импульса (мкс) |
async | bool (тип C) | bool | Признак асинхронного выполнения команды |
errorText | char[1000] (тип C) | string | Текст ошибки (передается как параметр, если происходит ошибка метод записывает в этот параметр текст ошибки) |
errorCode | int (тип C) | int64 | Код ошибки |
Примеры
Пример №1 - Вращение сервопривода против часовой стрелки
В данном примере осуществляется вращение сервопривода против часовой стрелки с максимальной скоростью, соответствующее максимальному значению управляющего импульса для поворота против часовой стрелки (2520 микросекунд).
- Python
# Вращение сервопривода против часовой стрелки в асинхронном режиме
errCode = lib.RI_SDK_exec_RServoDrive_RotateByPulse(rservo, 2520, True, errTextC)
if errCode != 0:
print(errCode, errTextC.raw.decode())
sys.exit(2)
# Остановим выполнение программы на 3 секунды чтобы увидеть вращение
time.sleep(3)
# Продолжим выполнение программы и удаление библиотеки остановит вращение
- C
// Вращение сервопривода против часовой стрелки в асинхронном режиме
errCode = RI_SDK_exec_RServoDrive_RotateByPulse(rservo, 2520, true, errorText);
if (errCode != 0) {
//Возвращаем текст и код ошибки
printf("errorText:%s\n", errorText);
return errCode;
}
// Остановим выполнение программы на 3 секунды чтобы увидеть вращение
sleep (3);
// Продолжим выполнение программы и удаление библиотеки остановит вращение
- C++
// Вращение сервопривода против часовой стрелки в асинхронном режиме
errCode = RI_SDK_exec_RServoDrive_RotateByPulse(rservo, 2520, true, errorText);
if (errCode != 0) {
//Возвращаем текст и код ошибки
printf("errorText:%s\n", errorText);
return errCode;
}
// Остановим выполнение программы на 3 секунды чтобы увидеть вращение
sleep (3);
// Продолжим выполнение программы и удаление библиотеки остановит вращение
- Golang
// Вращение сервопривода против часовой стрелки в асинхронном режиме
errCode = C.RI_SDK_exec_RServoDrive_RotateByPulse(rservo, 2520, true, &errorTextC[0])
if errCode != 0 {
fmt.Printf("errorCode:%d - errorText:%s\n", errCode, C.GoString(&errorTextC[0]))
return
}
// Остановим выполнение программы на 3 секунды чтобы увидеть вращение
time.Sleep(time.Second * 3)
// Продолжим выполнение программы и удаление библиотеки остановит вращение
- Golang gRPC
// Вращение сервопривода против часовой стрелки в асинхронном режиме
errorText, errCode, err = client.RoboSdkApi.RI_SDK_Exec_RServoDrive_RotateByPulse(rservo, 2520, true)
if err != nil {
fmt.Printf("gRPC Error: %v\n", err)
return
}
if errCode != 0 {
fmt.Printf("errorCode:%d - errorText:%s\n %d", errCode, errorText, rservo)
return
}
// Остановим выполнение программы на 3 секунды чтобы увидеть вращение
time.Sleep(time.Second * 3)
// Продолжим выполнение программы и удаление библиотеки остановит вращение
- PHP
# Вращение сервопривода против часовой стрелки в асинхронном режиме
$errCode = $ffi->RI_SDK_exec_RServoDrive_RotateByPulse($rservo->cdata, 2520, true, $errorText);
if ($errCode) {
print("errorText:" . FFI::string($errorText). " errCode: " . $errCode . " \n");
return $errCode;
}
# Остановим выполнение программы на 3 секунды чтобы увидеть вращение
sleep(3);
# Продолжим выполнение программы и удаление библиотеки остановит вращение
Полный текст примера
- Python
from ctypes.util import find_library
import platform
import sys
import time
from ctypes import *
# Подключаем внешнюю библиотеку для работы с SDK
platform = platform.system()
if platform == "Windows":
libName = "librisdk.dll"
if platform == "Linux":
libName = "librisdk.so"
pathLib = find_library(libName)
lib = cdll.LoadLibrary(pathLib)
# Указываем типы аргументов для функций библиотеки RI_SDK
lib.RI_SDK_InitSDK.argtypes = [c_int, c_char_p]
lib.RI_SDK_CreateModelComponent.argtypes = [c_char_p, c_char_p, c_char_p, POINTER(c_int), c_char_p]
lib.RI_SDK_LinkPWMToController.argtypes = [c_int, c_int, c_uint8, c_char_p]
lib.RI_SDK_LinkRServodriveToController.argtypes = [c_int, c_int, c_int, c_char_p]
lib.RI_SDK_DestroySDK.argtypes = [c_bool, c_char_p]
lib.RI_SDK_exec_RServoDrive_RotateByPulse.argtypes = [c_int, c_int, c_bool, c_char_p]
def main():
errTextC = create_string_buffer(1000) # Текст ошибки. C type: char*
i2c = c_int()
pwm = c_int()
rservo = c_int()
# Инициализация библиотеки RI SDK с уровнем логирования 3
errCode = lib.RI_SDK_InitSDK(3, errTextC)
if errCode != 0:
print(errCode, errTextC.raw.decode())
sys.exit(2)
# Создание компонента i2c адаптера модели ch341
errCode = lib.RI_SDK_CreateModelComponent("connector".encode(), "i2c_adapter".encode(), "ch341".encode(), i2c, errTextC)
if errCode != 0:
print(errCode, errTextC.raw.decode())
sys.exit(2)
print("i2c: ", i2c.value)
# Создание компонента ШИМ модели pca9685
errCode = lib.RI_SDK_CreateModelComponent("connector".encode(), "pwm".encode(), "pca9685".encode(), pwm, errTextC)
if errCode != 0:
print(errCode, errTextC.raw.decode())
sys.exit(2)
print("pwm: ", pwm.value)
# Создание компонента сервопривода модели mg996r
errCode = lib.RI_SDK_CreateModelComponent("executor".encode(), "servodrive_rotate".encode(), "mg996r".encode(), rservo, errTextC)
if errCode != 0:
print(errCode, errTextC.raw.decode())
sys.exit(2)
print("servodrive rotate: ", rservo.value)
# Связывание i2c с ШИМ
errCode = lib.RI_SDK_LinkPWMToController(pwm, i2c, 0x40, errTextC)
if errCode != 0:
print(errCode, errTextC.raw.decode())
sys.exit(2)
# Связывание ШИМ с сервоприводом
errCode = lib.RI_SDK_LinkRServodriveToController(rservo, pwm, 0, errTextC)
if errCode != 0:
print(errCode, errTextC.raw.decode())
sys.exit(2)
# Вращение сервопривода против часовой стрелки в асинхронном режиме
errCode = lib.RI_SDK_exec_RServoDrive_RotateByPulse(rservo, 2520, True, errTextC)
if errCode != 0:
print(errCode, errTextC.raw.decode())
sys.exit(2)
# Остановим выполнение программы на 3 секунды чтобы увидеть вращение
time.sleep(3)
# Продолжим выполнение программы и удаление библиотеки остановит вращение
# Удаление библиотеки со всеми компонентами
errCode = lib.RI_SDK_DestroySDK(True, errTextC)
if errCode != 0:
print(errCode, errTextC.raw.decode())
sys.exit(2)
print("Success")
main()
- C
#include <stdbool.h>
#include <unistd.h>
#include "./librisdk.h" // Подключение библиотеки
int main(){
char errorText[1000]; // текст ошибки. Передается как входной параметр,при возникновении ошибки в эту переменную будет записан текст ошибки
int errCode; //код ошибки
int i2c, pwm, rservo;
// Инициализация библиотеки RI SDK с уровнем логирования 3
errCode = RI_SDK_InitSDK(3, errorText);
if (errCode != 0) {
printf("errorText:%s\n", errorText);
return errCode;
}
// Создание компонента i2c адаптера модели ch341
errCode = RI_SDK_CreateModelComponent("connector", "i2c_adapter", "ch341", &i2c, errorText);
if (errCode != 0) {
printf("errorText:%s\n", errorText);
return errCode;
}
printf("i2c: %d\n", i2c);
// Создание компонента ШИМ модели pca9685
errCode = RI_SDK_CreateModelComponent("connector", "pwm", "pca9685", &pwm, errorText);
if (errCode != 0) {
printf("errorText:%s\n", errorText);
return errCode;
}
printf("pwm: %d\n", pwm);
errCode = RI_SDK_CreateModelComponent("executor", "servodrive_rotate", "mg996r", &rservo, errorText);
if (errCode != 0) {
printf("errorText:%s\n", errorText);
return errCode;
}
printf("servodrive rotate : %d\n", rservo);
// Связывание i2c с ШИМ
errCode = RI_SDK_LinkPWMToController(pwm, i2c, 0x40, errorText);
if (errCode != 0) {
printf("errorText:%s\n", errorText);
return errCode;
}
// Связывание ШИМ с сервоприводом
errCode = RI_SDK_LinkRServodriveToController(rservo, pwm, 0, errorText);
if (errCode != 0) {
printf("errorText:%s\n", errorText);
return errCode;
}
// Вращение сервопривода против часовой стрелки в асинхронном режиме
errCode = RI_SDK_exec_RServoDrive_RotateByPulse(rservo, 2520, true, errorText);
if (errCode != 0) {
//Возвращаем текст и код ошибки
printf("errorText:%s\n", errorText);
return errCode;
}
// Остановим выполнение программы на 3 секунды чтобы увидеть вращение
sleep (3);
// Продолжим выполнение программы и удаление библиотеки остановит вращение
// Удаление библиотеки со всеми компонентами
errCode = RI_SDK_DestroySDK(true, errorText);
if (errCode != 0) {
printf("errorText:%s\n", errorText);
return errCode;
}
printf("Success");
return 0;
}
- C++
#include <stdbool.h>
#include <unistd.h>
#include "./librisdk.h" // Подключение библиотеки
int main(){
char errorText[1000]; // текст ошибки. Передается как входной параметр,при возникновении ошибки в эту переменную будет записан текст ошибки
int errCode; //код ошибки
int i2c;
int pwm;
int rservo;
// Инициализация библиотеки RI SDK с уровнем логирования 3
errCode = RI_SDK_InitSDK(3, errorText);
if (errCode != 0) {
printf("errorText:%s\n", errorText);
return errCode;
}
// Создание компонента i2c адаптера модели ch341
char i2cGroup[] = "connector";
char i2cDevice[] = "i2c_adapter";
char i2cModel[] = "ch341";
errCode = RI_SDK_CreateModelComponent(i2cGroup, i2cDevice, i2cModel, &i2c, errorText);
if (errCode != 0) {
printf("errorText:%s\n", errorText);
return errCode;
}
printf("i2c: %d\n", i2c);
// Создание компонента ШИМ модели pca9685
char pwmGroup[] = "connector";
char pwmDevice[] = "pwm";
char pwmModel[] = "pca9685";
errCode = RI_SDK_CreateModelComponent(pwmGroup, pwmDevice, pwmModel, &pwm, errorText);
if (errCode != 0) {
printf("errorText:%s\n", errorText);
return errCode;
}
printf("pwm: %d\n", pwm);
// Создание компонента сервопривода модели mg996r
char servoGroup[] = "executor";
char servoDevice[] = "servodrive_rotate";
char servoModel[] = "mg996r";
errCode = RI_SDK_CreateModelComponent(servoGroup, servoDevice, servoModel, &rservo, errorText);
if (errCode != 0) {
printf("errorText:%s\n", errorText);
return errCode;
}
printf("servodrive rotate: %d\n", rservo);
// Связывание i2c с ШИМ
errCode = RI_SDK_LinkPWMToController(pwm, i2c, 0x40, errorText);
if (errCode != 0) {
printf("errorText:%s\n", errorText);
return errCode;
}
// Связывание ШИМ с сервоприводом
errCode = RI_SDK_LinkRServodriveToController(rservo, pwm, 0, errorText);
if (errCode != 0) {
printf("errorText:%s\n", errorText);
return errCode;
}
// Вращение сервопривода против часовой стрелки в асинхронном режиме
errCode = RI_SDK_exec_RServoDrive_RotateByPulse(rservo, 2520, true, errorText);
if (errCode != 0) {
//Возвращаем текст и код ошибки
printf("errorText:%s\n", errorText);
return errCode;
}
// Остановим выполнение программы на 3 секунды чтобы увидеть вращение
sleep (3);
// Продолжим выполнение программы и удаление библиотеки остановит вращение
// Удаление библиотеки со всеми компонентами
errCode = RI_SDK_DestroySDK(true, errorText);
if (errCode != 0) {
printf("errorText:%s\n", errorText);
return errCode;
}
printf("Success");
return 0;
}
- Golang
package main
/*
#cgo CFLAGS: -I.
#cgo LDFLAGS: -L. -lrisdk
#include <librisdk.h> // Подключаем внешнюю библиотеку для работы с SDK.
*/
import "C"
import (
"fmt"
)
var (
errorTextC [1000]C.char // Текст ошибки. C type: char*
errCode C.int // Код ошибки. C type: int
i2c C.int
pwm C.int
rservo C.int
)
func main() {
// Инициализация библиотеки RI SDK с уровнем логирования 3
errCode = C.RI_SDK_InitSDK(3, &errorTextC[0])
if errCode != 0 {
fmt.Printf("errorCode:%d - errorText:%s\n", errCode, C.GoString(&errorTextC[0]))
return
}
// Создание компонента i2c адаптера модели ch341
errCode = C.RI_SDK_CreateModelComponent(C.CString("connector"), C.CString("i2c_adapter"), C.CString("ch341"), &i2c, &errorTextC[0])
if errCode != 0 {
fmt.Printf("errorCode:%d - errorText:%s\n", errCode, C.GoString(&errorTextC[0]))
return
}
fmt.Println("i2c: ", i2c)
// Создание компонента ШИМ модели pca9685
errCode = C.RI_SDK_CreateModelComponent(C.CString("connector"), C.CString("pwm"), C.CString("pca9685"), &pwm, &errorTextC[0])
if errCode != 0 {
fmt.Printf("errorCode:%d - errorText:%s\n", errCode, C.GoString(&errorTextC[0]))
return
}
fmt.Println("pwm: ", pwm)
// Создание компонента сервопривода модели mg996r
errCode = C.RI_SDK_CreateModelComponent(C.CString("executor"), C.CString("servodrive_rotate"), C.CString("mg996r"), &rservo, &errorTextC[0])
if errCode != 0 {
fmt.Printf("errorCode:%d - errorText:%s\n", errCode, C.GoString(&errorTextC[0]))
return
}
fmt.Println("servodrive rotate: ", rservo)
// Связывание i2c с ШИМ
errCode = C.RI_SDK_LinkPWMToController(pwm, i2c, 0x40, &errorTextC[0])
if errCode != 0 {
fmt.Printf("errorCode:%d - errorText:%s\n", errCode, C.GoString(&errorTextC[0]))
return
}
// Связывание ШИМ с сервоприводом
errCode = C.RI_SDK_LinkRServodriveToController(rservo, pwm, 0, &errorTextC[0])
if errCode != 0 {
fmt.Printf("errorCode:%d - errorText:%s\n", errCode, C.GoString(&errorTextC[0]))
return
}
// Вращение сервопривода против часовой стрелки в асинхронном режиме
errCode = C.RI_SDK_exec_RServoDrive_RotateByPulse(rservo, 2520, true, &errorTextC[0])
if errCode != 0 {
fmt.Printf("errorCode:%d - errorText:%s\n", errCode, C.GoString(&errorTextC[0]))
return
}
// Остановим выполнение программы на 3 секунды чтобы увидеть вращение
time.Sleep(time.Second * 3)
// Продолжим выполнение программы и удаление библиотеки остановит вращение
// Удаление библиотеки со всеми компонентами
errCode = C.RI_SDK_DestroySDK(true, &errorTextC[0])
if errCode != 0 {
fmt.Printf("errorCode:%d - errorText:%s\n", errCode, C.GoString(&errorTextC[0]))
return
}
fmt.Println("Success")
}
- Golang gRPC
package main
import (
"fmt"
"github.com/rbs-ri/go-risdk"
"time"
)
var (
client *risdk.ClientRPC // Объект взяимодействия с API SDK
errorText string // Текст ошибки
errCode int64 // Код ошибки
err error // Ошибка gRPC
i2c int64
pwm int64
rservo int64
)
func main() {
// Открываем соединение для работы с API SDK по RPC
client = risdk.GetClientRPC()
// Закрываем соединение с RPC
defer client.Client.Kill()
// Инициализация библиотеки RI SDK с уровнем логирования 3
errorText, errCode, err = client.RoboSdkApi.RI_SDK_InitSDK(3)
if err != nil {
fmt.Printf("gRPC Error: %v\n", err)
return
}
if errCode != 0 {
fmt.Printf("errorCode:%d - errorText:%s\n", errCode, errorText)
return
}
// Создание компонента i2c адаптера модели ch341
i2c, errorText, errCode, err = client.RoboSdkApi.RI_SDK_CreateModelComponent("connector", "i2c_adapter", "ch341")
if err != nil {
fmt.Printf("gRPC Error: %v\n", err)
return
}
if errCode != 0 {
fmt.Printf("errorCode:%d - errorText:%s\n", errCode, errorText)
return
}
fmt.Println("i2c: ", i2c)
// Создание компонента ШИМ модели pca9685
pwm, errorText, errCode, err = client.RoboSdkApi.RI_SDK_CreateModelComponent("connector", "pwm", "pca9685")
if err != nil {
fmt.Printf("gRPC Error: %v\n", err)
return
}
if errCode != 0 {
fmt.Printf("errorCode:%d - errorText:%s\n", errCode, errorText)
return
}
fmt.Println("pwm: ", pwm)
// Создание компонента сервопривода вращения модели mg996r
rservo, errorText, errCode, err = client.RoboSdkApi.RI_SDK_CreateModelComponent("executor", "servodrive_rotate", "mg996r")
if err != nil {
fmt.Printf("gRPC Error: %v\n", err)
return
}
if errCode != 0 {
fmt.Printf("errorCode:%d - errorText:%s\n", errCode, errorText)
return
}
fmt.Println("servodrive rotate : ", rservo)
// Связывание i2c с ШИМ
errorText, errCode, err = client.RoboSdkApi.RI_SDK_LinkPWMToController(pwm, i2c, 0x40)
if err != nil {
fmt.Printf("gRPC Error: %v\n", err)
return
}
if errCode != 0 {
fmt.Printf("errorCode:%d - errorText:%s\n", errCode, errorText)
return
}
// Связывание ШИМ с сервоприводом
errorText, errCode, err = client.RoboSdkApi.RI_SDK_LinkRServodriveToController(rservo, pwm, 0)
if err != nil {
fmt.Printf("gRPC Error: %v\n", err)
return
}
if errCode != 0 {
fmt.Printf("errorCode:%d - errorText:%s\n", errCode, errorText)
return
}
// Вращение сервопривода против часовой стрелки в асинхронном режиме
errorText, errCode, err = client.RoboSdkApi.RI_SDK_Exec_RServoDrive_RotateByPulse(rservo, 2520, true)
if err != nil {
fmt.Printf("gRPC Error: %v\n", err)
return
}
if errCode != 0 {
fmt.Printf("errorCode:%d - errorText:%s\n %d", errCode, errorText, rservo)
return
}
// Остановим выполнение программы на 3 секунды чтобы увидеть вращение
time.Sleep(time.Second * 3)
// Продолжим выполнение программы и удаление библиотеки остановит вращение
// Удаление библиотеки со всеми компонентами
errorText, errCode, err = client.RoboSdkApi.RI_SDK_DestroySDK(true)
if err != nil {
fmt.Printf("gRPC Error: %v\n", err)
return
}
if errCode != 0 {
fmt.Printf("errorCode:%d - errorText:%s\n", errCode, errorText)
return
}
fmt.Println("Success")
}
- PHP
<?php
// Подключаем внешнюю библиотеку для работы с SDK
$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); // Текст ошибки. Передается как входной параметр,при возникновении ошибки в эту переменную будет записан текст ошибки
$i2c = $ffi->new('int', 0);
$pwm = $ffi->new('int', 0);
$rservo = $ffi->new('int', 0);
// Инициализация библиотеки RI SDK с уровнем логирования 3
$errCode = $ffi->RI_SDK_InitSDK(3, $errorText);
if ($errCode) {
print("errorText:" . FFI::string($errorText) . " errCode: " . $errCode . " \n");
return $errCode;
}
// Создание компонента i2c адаптера модели ch341
$errCode = $ffi->RI_SDK_CreateModelComponent("connector", "i2c_adapter", "ch341", FFI::addr($i2c), $errorText);
if ($errCode) {
print("errorText:" . FFI::string($errorText). " errCode: " . $errCode . " \n");
return $errCode;
}
print("i2c: " . $i2c->cdata . "\n");
// Создание компонента ШИМ модели pca9685
$errCode = $ffi->RI_SDK_CreateModelComponent("connector", "pwm", "pca9685", FFI::addr($pwm), $errorText);
if ($errCode) {
print("errorText:" . FFI::string($errorText). " errCode: " . $errCode . " \n");
return $errCode;
}
print("pwm: " . $pwm->cdata . "\n");
// Создание компонента сервопривода вращения модели mg996r
$errCode = $ffi->RI_SDK_CreateModelComponent("executor", "servodrive_rotate", "mg996r", FFI::addr($rservo), $errorText);
if ($errCode) {
print("errorText:" . FFI::string($errorText). " errCode: " . $errCode . " \n");
return $errCode;
}
print("servodrive rotate: " . $rservo->cdata . "\n");
// Связывание i2c с ШИМ
$errCode = $ffi->RI_SDK_LinkPWMToController($pwm->cdata, $i2c->cdata, 0x40, $errorText);
if ($errCode) {
print("errorText:" . FFI::string($errorText). " errCode: " . $errCode . " \n");
return $errCode;
}
// Связывание ШИМ с сервоприводом
$errCode = $ffi->RI_SDK_LinkRServodriveToController($rservo->cdata, $pwm->cdata, 0, $errorText);
if ($errCode) {
print("errorText:" . FFI::string($errorText). " errCode: " . $errCode . " \n");
return $errCode;
}
# Вращение сервопривода против часовой стрелки в асинхронном режиме
$errCode = $ffi->RI_SDK_exec_RServoDrive_RotateByPulse($rservo->cdata, 2520, true, $errorText);
if ($errCode) {
print("errorText:" . FFI::string($errorText). " errCode: " . $errCode . " \n");
return $errCode;
}
# Остановим выполнение программы на 3 секунды чтобы увидеть вращение
sleep(3);
# Продолжим выполнение программы и удаление библиотеки остановит вращение
// Удаление библиотеки со всеми компонентами
$errCode = $ffi->RI_SDK_DestroySDK(true, $errorText);
if ($errCode) {
print("errorText:" . FFI::string($errorText). " errCode: " . $errCode . " \n");
return $errCode;
}
print("Success \n");
?>