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

Golang

Подключение RI_SDK динамической библиотеки к приложению на Golang.

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

  • Windows
На данный момент Golang не поддерживает работу с Shared Object на Windows
  • Linux
touch shared_client.go

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

. workspace/
    --- > shared_client.go
    --- > librisdk.h
    --- > librisdk.so

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

package main
/*
#cgo CFLAGS: -I.
#cgo LDFLAGS: -L. -lrisdk
#include <librisdk.h>
*/
import "C"
import (
    "fmt"
)

func main() {

    fmt.Println("Success")
}

Для запуска скрипта выполним в терминале следующие команды:
Укажем компилятору gcc что динамические библиотеки можно искать в текущей директории.

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.

Выполним компиляцию

go build -o go_shared_client.bin shared_client.go

Значение shared_client.go указывает на файл, который необходимо собрать.
Значение -o go_shared_client.bin указывает на путь к скомпиленному файлу.

Получаем результат выполнения собранной программы

./go_shared_client.bin

Создадим компонент внутри функции main

var (
    logLevel   = C.int(1)   //уровень логирования
    errorTextC [1000]C.char //текст ошибки
    errorCode  C.int        //код ошибки
)

// Инициализируем SDK
errorCode = C.RI_SDK_InitSDK(logLevel, &errorTextC[0])
if errorCode != 0 {
    // Возвращаем текст и код ошибки
    errorText := C.GoString(&errorTextC[0])
    err = fmt.Errorf("errorCode:%d - errorText:%s", errorCode, errorText)
    return
}

var descriptor = C.int(0)

// Создаем базовый компонент
errorCode = C.RI_SDK_CreateBasic(&descriptor, &errorTextC[0])
if errorCode != 0 {
    // Возвращаем текст и код ошибки
    errorText := C.GoString(&errorTextC[0])
    err = fmt.Errorf("errorCode:%d - errorText:%s", errorCode, errorText)
    return
}

// Выведем полученный дескриптор компонента
fmt.Printf("descriptor:%d--\n", descriptor)

Скомпилируем и запустим скрипт.

./go_shared_client.bin

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

descriptor:1--
Success

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

Описание

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

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

. workspace/
    --- > demo.go
    --- > librisdk.h
    --- > librisdk.so

Реализация

package main

/*
#cgo CFLAGS: -I.
#cgo LDFLAGS: -L. -lrisdk
#include <librisdk.h>
*/
import "C"
import (
    "fmt"
    "time"
)

var (
    body_start_pulse        = C.int(1500) // стартовая позиция тела
    arrowR_start_pulse      = C.int(2000) // стартовая возиция правой стрелы
    arrowL_start_pulse      = C.int(1000) // стартовая позиция левой стрелы
    claw_start_pulse        = C.int(1000) // стартовая позиция клешни
    claw_rotate_start_pulse = C.int(1500) // стартовая позиция поворота клешни

    arrowR_over_cube_position = C.int(-30) // позиция правой стрелы над кубиком
    arrowL_over_cube_position = C.int(-10) // позиция левой стрелы над кубиком
    claw_unclenched_position  = C.int(80)  // позиция открытой клешни
    arrowR_cube_position      = C.int(-75) // позиция правой стрелы на месте кубика
    arrowL_cube_position      = C.int(55)  // позиция левой стрелы на месте кубика

    logLevel = C.int(2)   // уровень логирования
    speed    = C.int(100) // скорость в градусах в секунду
)

// структура дескрипторов устройства
type device struct {
    i2c        C.int // дескриптор i2c
    pwm        C.int // дескриптор pwm
    body       C.int // дескриптор сервопривода тела
    claw       C.int // дескриптор сервопривода клешни
    arrowR     C.int // дескриптор сервопривода правой стрелы
    arrowL     C.int // дескриптор сервопривода левой стрелы
    clawRotate C.int // дескриптор сервопривода поворота клешни
    led        C.int // дескриптор светодиода
}

// инициализация структуры устройства
var robohand device

type servo struct {
    descriptor    *C.int // дескриптор сервопривода
    startPosition *C.int // стартовая позиция сервопривода
}

// массив дескрипторов сервоприводов
var servos = [5]servo{
    {
        descriptor:    &robohand.body,
        startPosition: &body_start_pulse,
    },
    {
        descriptor:    &robohand.claw,
        startPosition: &claw_start_pulse,
    },
    {
        descriptor:    &robohand.arrowR,
        startPosition: &arrowR_start_pulse,
    },
    {
        descriptor:    &robohand.arrowL,
        startPosition: &arrowL_start_pulse,
    },
    {
        descriptor:    &robohand.clawRotate,
        startPosition: &claw_rotate_start_pulse,
    },
}

// initServos - создает сервоприводы и линкует их
func initServos() error {
    var (
        errorTextC [1000]C.char //текст ошибки. Передается как входной параметр,при возникновении ошибки в эту переменную будет записан текст ошибки
        errCode    C.int        //код ошибки
    )
    //создаем 5 сервоприводов и линкуем их к пинам 0-4
    for i := 0; i < 5; i++ {
        // создаем компонент сервопривода с конкретной моделью как исполняемое устройство и получаем дескриптор сервопривода
        errCode = C.RI_SDK_CreateModelComponent(C.CString("executor"), C.CString("servodrive"), C.CString("mg90s"), servos[i].descriptor, &errorTextC[0])
        if errCode != 0 {
            return fmt.Errorf("errorCode:%d - errorText:%s", errCode, C.GoString(&errorTextC[0]))
        }
        //связываем сервопривод с ШИМ,передаем дескриптор сервопривода и ШИМ
        errCode = C.RI_SDK_LinkServodriveToController(*servos[i].descriptor, robohand.pwm, C.int(i), &errorTextC[0])
        if errCode != 0 {
            return fmt.Errorf("errorCode:%d - errorText:%s", errCode, C.GoString(&errorTextC[0]))
        }
    }

    return nil
}

// initDevice - инициализация библиотеки и устройств
func initDevice() error {
    var (
        errorTextC [1000]C.char //текст ошибки
        errCode    C.int        //код ошибки
    )

    // Инициализируем SDK
    errCode = C.RI_SDK_InitSDK(logLevel, &errorTextC[0])
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, C.GoString(&errorTextC[0]))
    }
    // создаем компонент ШИМ с конкретной моделью как соединитель и получаем дескриптор компонента
    errCode = C.RI_SDK_CreateModelComponent(C.CString("connector"), C.CString("pwm"), C.CString("pca9685"), &robohand.pwm, &errorTextC[0])
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, C.GoString(&errorTextC[0]))
    }
    // создаем компонент i2c адатера
    // Здесь осуществлен примитивное определение подключенной модели адаптера
    // Сначала пробуем создать i2c адаптер модели ch341 и связать с ним ШИМ
    errCode = C.RI_SDK_CreateModelComponent(C.CString("connector"), C.CString("i2c_adapter"), C.CString("ch341"), &robohand.i2c, &errorTextC[0])
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, C.GoString(&errorTextC[0]))
    }
    //связываем i2c адаптер с ШИМ по адресу 0x40
    errCode = C.RI_SDK_LinkPWMToController(robohand.pwm, robohand.i2c, 0x40, &errorTextC[0])
    if errCode != 0 {
        // Если не получается то пробуем создать i2c адаптер модели cp2112
        errCode = C.RI_SDK_CreateModelComponent(C.CString("connector"), C.CString("i2c_adapter"), C.CString("cp2112"), &robohand.i2c, &errorTextC[0])
        if errCode != 0 {
            return fmt.Errorf("errorCode:%d - errorText:%s", errCode, C.GoString(&errorTextC[0]))
        }
        //связываем i2c адаптер с ШИМ по адресу 0x40
        errCode = C.RI_SDK_LinkPWMToController(robohand.pwm, robohand.i2c, 0x40, &errorTextC[0])
        if errCode != 0 {
            return fmt.Errorf("errorCode:%d - errorText:%s", errCode, C.GoString(&errorTextC[0]))
        }
    }
    // создаем компонент светодиода с конкретной моделью (ky016) как исполняемое устройство и получаем дескриптор светодиода
    errCode = C.RI_SDK_CreateModelComponent(C.CString("executor"), C.CString("led"), C.CString("ky016"), &robohand.led, &errorTextC[0])
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, C.GoString(&errorTextC[0]))
    }
    //связываем светодиод адаптер с ШИМ,передаем значения трех пинов к которым подключен светодиод
    errCode = C.RI_SDK_LinkLedToController(robohand.led, robohand.pwm, 15, 14, 13, &errorTextC[0])
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, C.GoString(&errorTextC[0]))
    }

    //инициализируем сервоприводы
    err := initServos()
    if err != nil {
        return err
    }

    return nil
}

// startPosition - переводит сервопривод в стартовое положение
func startPosition(s servo) error {
    var (
        errorTextC [1000]C.char //текст ошибки
        errCode    C.int        //код ошибки
    )
    //выполняем поворот сервопривода в заданный угол,передаем дескриптор сервопривода,значение угла
    errCode = C.RI_SDK_exec_ServoDrive_TurnByPulse(*s.descriptor, *s.startPosition, &errorTextC[0])
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, C.GoString(&errorTextC[0]))
    }

    //небольшая пауза для последовательного движения
    time.Sleep(500 * time.Millisecond)
    return nil
}

// startPositionAllServo - переводит все сервоприводы в стартовую позицию
func startPositionAllServo() error {
    var (
        errorTextC [1000]C.char //текст ошибки
        errCode    C.int        //код ошибки
    )

    //выполняем одиночное свечение светодиодом,передаем дескриптор светодиода,3 параметра цвета(RGB), и включаем асинхронный режим работы
    errCode = C.RI_SDK_exec_RGB_LED_SinglePulse(robohand.led, 255, 0, 0, 0, true, &errorTextC[0])
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, C.GoString(&errorTextC[0]))
    }

    //приводим сервоприводы в стартовое положение
    for i := 0; i < 5; i++ {
        err := startPosition(servos[i])
        if err != nil {
            return err
        }
    }

    //выполняем одиночное свечение светодиодом,передаем дескриптор светодиода,3 параметра цвета(RGB), и включаем асинхронный режим работы
    errCode = C.RI_SDK_exec_RGB_LED_SinglePulse(robohand.led, 0, 255, 0, 0, true, &errorTextC[0])
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, C.GoString(&errorTextC[0]))
    }
    //небольшая пауза для последовательного движения
    time.Sleep(500 * time.Millisecond)
    return nil
}

// rotateBody - вращение тела в указанный угол
func rotateBody(angle, speed C.int) error {

    var (
        errorTextC [1000]C.char //текст ошибки
        errCode    C.int        //код ошибки
    )
    //выполняем мигание с заданной частотой,передаем дескриптор светодиода,3 параметра цвета(RGB),частоту,продолжительность и включаем асинхронный режим работы
    errCode = C.RI_SDK_exec_RGB_LED_FlashingWithFrequency(robohand.led, 0, 255, 0, 5, 0, true, &errorTextC[0])
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, C.GoString(&errorTextC[0]))
    }
    //выполняем поворот на заданный угол,передаем дескриптор тела,угол,скорость и асинхронный режим работы
    errCode = C.RI_SDK_exec_ServoDrive_Turn(robohand.body, angle, speed, false, &errorTextC[0])
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, C.GoString(&errorTextC[0]))
    }
    //выполняем поворот на заданный угол,передаем дескриптор клешни,угол,скорость и асинхронный режим работы
    errCode = C.RI_SDK_exec_ServoDrive_Turn(robohand.clawRotate, C.int(45), speed, false, &errorTextC[0])
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, C.GoString(&errorTextC[0]))
    }
    //выполняем поворот на заданный угол,передаем дескриптор клешни,угол,скорость и асинхронный режим работы
    errCode = C.RI_SDK_exec_ServoDrive_Turn(robohand.clawRotate, C.int(-45), speed, false, &errorTextC[0])
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, C.GoString(&errorTextC[0]))
    }
    return nil
}

// get - берет кубик
func get() error {
    var (
        errorTextC [1000]C.char //текст ошибки
        errCode    C.int        //код ошибки
    )
    //выполняем мерцание светодиодом,передаем дескриптор светодиода,3 параметра цвета(RGB),продолжительность,кол-во повторений и включаем асинхронный режим работы
    errCode = C.RI_SDK_exec_RGB_LED_Flicker(robohand.led, C.int(0), C.int(0), C.int(255), C.int(500), C.int(0), true, &errorTextC[0])
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, C.GoString(&errorTextC[0]))
    }
    //выполняем поворот на заданный угол,передаем дескриптор стрелы,угол,скорость и асинхронный режим работы
    errCode = C.RI_SDK_exec_ServoDrive_Turn(robohand.arrowR, arrowR_over_cube_position, speed, false, &errorTextC[0])
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, C.GoString(&errorTextC[0]))
    }
    //выполняем поворот на заданный угол,передаем дескриптор стрелы,угол,скорость и асинхронный режим работы
    errCode = C.RI_SDK_exec_ServoDrive_Turn(robohand.arrowL, arrowL_over_cube_position, speed, false, &errorTextC[0])
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, C.GoString(&errorTextC[0]))
    }
    //выполняем поворот на заданный угол,передаем дескриптор клешни,угол,скорость и асинхронный режим работы
    errCode = C.RI_SDK_exec_ServoDrive_Turn(robohand.claw, claw_unclenched_position, speed, false, &errorTextC[0])
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, C.GoString(&errorTextC[0]))
    }
    //выполняем поворот на заданный угол,передаем дескриптор стрелы,угол,скорость и асинхронный режим работы
    errCode = C.RI_SDK_exec_ServoDrive_Turn(robohand.arrowR, (arrowR_cube_position - arrowR_over_cube_position), speed, false, &errorTextC[0])
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, C.GoString(&errorTextC[0]))
    }
    //выполняем поворот на заданный угол,передаем дескриптор стрелы,угол,скорость и асинхронный режим работы
    errCode = C.RI_SDK_exec_ServoDrive_Turn(robohand.arrowL, (arrowL_cube_position - arrowL_over_cube_position), speed, false, &errorTextC[0])
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, C.GoString(&errorTextC[0]))
    }
    //выполняем поворот на заданный угол,передаем дескриптор клешни,угол,скорость и асинхронный режим работы
    errCode = C.RI_SDK_exec_ServoDrive_Turn(robohand.claw, (-1)*claw_unclenched_position, speed, false, &errorTextC[0])
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, C.GoString(&errorTextC[0]))
    }
    //выполняем поворот на заданный угол,передаем дескриптор стрелы,угол,скорость и асинхронный режим работы
    errCode = C.RI_SDK_exec_ServoDrive_Turn(robohand.arrowR, (-1)*arrowR_cube_position, speed, false, &errorTextC[0])
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, C.GoString(&errorTextC[0]))
    }
    //выполняем поворот на заданный угол,передаем дескриптор стрелы,угол,скорость и асинхронный режим работы
    errCode = C.RI_SDK_exec_ServoDrive_Turn(robohand.arrowL, (-1)*arrowL_cube_position, speed, false, &errorTextC[0])
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, C.GoString(&errorTextC[0]))
    }
    return nil
}

// put - кладет кубик
func put() error {
    var (
        errorTextC [1000]C.char //текст ошибки
        errCode    C.int        //код ошибки
    )
    //выполняем мерцание светодиодом,передаем дескриптор светодиода,3 параметра цвета(RGB),продолжительность,кол-во повторений и включаем асинхронный режим работы
    errCode = C.RI_SDK_exec_RGB_LED_Flicker(robohand.led, C.int(0), C.int(0), C.int(255), C.int(500), C.int(0), true, &errorTextC[0])
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, C.GoString(&errorTextC[0]))
    }
    //выполняем поворот на заданный угол,передаем дескриптор стрелы,угол,скорость и асинхронный режим работы
    errCode = C.RI_SDK_exec_ServoDrive_Turn(robohand.arrowR, arrowR_cube_position, speed, false, &errorTextC[0])
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, C.GoString(&errorTextC[0]))
    }
    //выполняем поворот на заданный угол,передаем дескриптор клешни,угол,скорость и асинхронный режим работы
    errCode = C.RI_SDK_exec_ServoDrive_Turn(robohand.arrowL, arrowL_cube_position, speed, false, &errorTextC[0])
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, C.GoString(&errorTextC[0]))
    }
    errCode = C.RI_SDK_exec_ServoDrive_Turn(robohand.claw, claw_unclenched_position, speed, false, &errorTextC[0])
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, C.GoString(&errorTextC[0]))
    }
    //выполняем поворот на заданный угол,передаем дескриптор стрелы,угол,скорость и асинхронный режим работы
    errCode = C.RI_SDK_exec_ServoDrive_Turn(robohand.arrowR, (-1)*arrowR_cube_position, speed, false, &errorTextC[0])
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, C.GoString(&errorTextC[0]))
    }
    //выполняем поворот на заданный угол,передаем дескриптор стрелы,угол,скорость и асинхронный режим работы
    errCode = C.RI_SDK_exec_ServoDrive_Turn(robohand.arrowL, (-1)*arrowL_cube_position, speed, false, &errorTextC[0])
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, C.GoString(&errorTextC[0]))
    }
    //выполняем поворот на заданный угол,передаем дескриптор клешни,угол,скорость и асинхронный режим работы
    errCode = C.RI_SDK_exec_ServoDrive_Turn(robohand.claw, (-1)*claw_unclenched_position, speed, false, &errorTextC[0])
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, C.GoString(&errorTextC[0]))
    }

    return nil
}

// destructServos - уничтожает сервоприводы
func destructServos() error {
    var (
        errorTextC [1000]C.char //текст ошибки
        errCode    C.int        //код ошибки
    )
    for i := 0; i < 5; i++ {
        errCode = C.RI_SDK_DestroyComponent(*servos[i].descriptor, &errorTextC[0])
        if errCode != 0 {
            return fmt.Errorf("errorCode:%d - errorText:%s", errCode, C.GoString(&errorTextC[0]))
        }
    }

    return nil
}

// destruct - уничтожает все компоненты и библиотеку
func destruct() error {

    var (
        errorTextC [1000]C.char //текст ошибки
        errCode    C.int        //код ошибки
    )

    //выполняем одиночное свечение светодиодом,передаем дескриптор светодиода,3 параметра цвета(RGB), и включаем асинхронный режим работы
    errCode = C.RI_SDK_exec_RGB_LED_SinglePulse(robohand.led, C.int(255), C.int(0), C.int(0), C.int(0), true, &errorTextC[0])
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, C.GoString(&errorTextC[0]))
    }
    //уничтожаем сервоприводы
    err := destructServos()
    if err != nil {
        return err
    }
    //останавливаем свечение светодиода с определенным дескриптором
    errCode = C.RI_SDK_exec_RGB_LED_Stop(robohand.led, &errorTextC[0])
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, C.GoString(&errorTextC[0]))
    }
    //удаляем компонент светодиода по дескриптору
    errCode = C.RI_SDK_DestroyComponent(robohand.led, &errorTextC[0])
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, C.GoString(&errorTextC[0]))
    }
    //сбрасываем все порты на ШИМ
    errCode = C.RI_SDK_sigmod_PWM_ResetAll(robohand.pwm, &errorTextC[0])
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, C.GoString(&errorTextC[0]))
    }
    //удаляем компонент ШИМ
    errCode = C.RI_SDK_DestroyComponent(robohand.pwm, &errorTextC[0])
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, C.GoString(&errorTextC[0]))
    }
    //удаляем компонент i2c
    errCode = C.RI_SDK_DestroyComponent(robohand.i2c, &errorTextC[0])
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, C.GoString(&errorTextC[0]))
    }
    //удаляем sdk со всеми компонентами в реестре компонентов
    errCode = C.RI_SDK_DestroySDK(true, &errorTextC[0])
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, C.GoString(&errorTextC[0]))
    }
    return nil
}

// start - запускает демо программу
func start() error {
    // Инициализируем библиотеку и компоненты
    err := initDevice()
    if err != nil {
        return err
    }

    // Приводим сервоприводы к стартовой позиции
    err = startPositionAllServo()
    if err != nil {
        return err
    }

    // Двигаем тело к местонахождению кубика
    err = rotateBody(45, speed)
    if err != nil {
        return err
    }

    // Берем кубик
    err = get()
    if err != nil {
        return err
    }

    //Двигаем тело к новому местонахождению кубика
    err = rotateBody(-90, speed)
    if err != nil {
        return err
    }

    //Кладем кубик
    err = put()
    if err != nil {
        return err
    }

    // Возвращаем тело в стартовое положение
    err = rotateBody(45, speed)
    if err != nil {
        return err
    }

    // Уничтожаем компоненты и библиотеку
    err = destruct()
    if err != nil {
        return err
    }
    return nil
}

func main() {
    //запускаем программу
    err := start()
    if err != nil {
        fmt.Println(err.Error())
        return
    }

    return
}

Подключение RI_SDK gRPC микросервиса к приложению на Golang

Создадим Golang файл и файл с для перечисления внешних зависимостей

  • Windows
type nul > grpc_client.go
type nul > go.mod
  • Linux
touch grpc_client.go
touch go.mod

Если вы используете текстовый редактор,то необходимо изменить кодировку grpc_client.go на UTF-8 без BOM, либо использовать IDE (VsCode,etc.).

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

. workspace/
    --- > grpc_client.go
    --- > risdk.bin/.exe
    --- > go.mod
    --- > libusb-1.0.dll/.so

В файле go.mod укажем что мы будем использовать пакет go-risdk последней версии

module mod
go 1.17
require github.com/rbs-ri/go-risdk latest

Создадим компонент внутри функции main


package main

import (
    "fmt"
    "github.com/rbs-ri/go-risdk"
)

func main() {
    //Открываем соединение для работы с API SDK по gRPC
    client := risdk.GetClientRPC()
    //Закрываем соединение с gRPC
    defer client.Client.Kill()

      // Инициализруем SDK
      errorText, errorCode, err := client.RoboSdkApi.RI_SDK_InitSDK(2)
      if errorCode != 0 || err != nil {
        fmt.Printf("\n Не удалось инициализировать SDK. код ошибки:%d, описание:%s, ошибка:%s", errorCode, errorText, err)
        return
      }


      // Создаем базовый компонент SDK
      descriptor, errorText, errorCode, err := client.RoboSdkApi.RI_SDK_CreateBasic()
      if errorCode != 0 || err != nil {
        fmt.Printf("\n Не удалось создать базовый компонент. код ошибки:%d, описание:%s, ошибка:%s", errorCode, errorText, err)
        return
      }
      fmt.Printf("Компонент с дескриптором:%d создан \n", descriptor)
}

Обновим зависимости внутри пакета

go mod tidy

Выполним компиляцию

go build -o grpc_client.bin grpc_client.go

Значение grpc_client.go указывает на файл, который необходимо собрать.
Значение -o grpc_client.bin указывает на путь к скомпиленному файлу.

Теперь запустим скрипт

./grpc_client.bin

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

Current path:  /home/mihail/Documents/projects_go/src/ri_sdk
2021-11-08T15:15:04.817+0400 [DEBUG] plugin: starting plugin: path=/home/mihail/Documents/projects_go/src/ri_sdk/risdk.bin args=[/home/mihail/Documents/projects_go/src/ri_sdk/risdk.bin]
2021-11-08T15:15:04.818+0400 [DEBUG] plugin: plugin started: path=/home/mihail/Documents/projects_go/src/ri_sdk/risdk.bin pid=9570
2021-11-08T15:15:04.818+0400 [DEBUG] plugin: waiting for RPC address: path=/home/mihail/Documents/projects_go/src/ri_sdk/risdk.bin
2021-11-08T15:15:04.823+0400 [DEBUG] plugin: using plugin: version=1
2021-11-08T15:15:04.823+0400 [DEBUG] plugin.risdk.bin: plugin address: address=/tmp/plugin1567377908 network=unix timestamp=2021-11-08T15:15:04.823+0400
2021-11-08T15:15:04.824+0400 [TRACE] plugin.stdio: waiting for stdio data
Компонент с дескриптором:1 создан
2021-11-08T15:15:04.827+0400 [DEBUG] plugin.stdio: received EOF, stopping recv loop: err="rpc error: code = Unavailable desc = transport is closing"
2021-11-08T15:15:04.827+0400 [DEBUG] plugin: plugin process exited: path=/home/mihail/Documents/projects_go/src/ri_sdk/risdk.bin pid=9570
2021-11-08T15:15:04.827+0400 [DEBUG] plugin: plugin exited

Пример программы на Golasng, использующий RI_SDK gRPC микросервис

Описание

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

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

. workspace/
    --- > demo.go
    --- > risdk.exe/.bin
    --- > go.mod
    --- > CH341DLL.DLL/ CH341DLLA64.DLL
    --- > SLABHIDDevice.dll
    --- > SLABHIDtoSMBus.dll
    --- > libusb-1.0.dll/.so

Реализация

package main

import (
    "fmt"
    "time"

    "github.com/rbs-ri/go-risdk"
)

var (
    body_start_pulse        int64 = 1500// стартовая позиция тела
    arrowR_start_pulse      int64 = 2000 // стартовая возиция правой стрелы
    arrowL_start_pulse      int64 = 1000 // стартовая позиция левой стрелы
    claw_start_pulse        int64 = 1000 // стартовая позиция клешни
    claw_rotate_start_pulse int64 = 1500 // стартовая позиция поворота клешни

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

    logLevel int64            = 2   // уровень логирования
    speed    int64            = 100 // скорость в градусах в секунду
    client   *risdk.ClientRPC       // клиент
)

// структура дескрипторов устройства
type device struct {
    i2c        int64 // дескриптор i2c
    pwm        int64 // дескриптор pwm
    body       int64 // дескриптор сервопривода тела
    claw       int64 // дескриптор сервопривода клешни
    arrowR     int64 // дескриптор сервопривода правой стрелы
    arrowL     int64 // дескриптор сервопривода левой стрелы
    clawRotate int64 // дескриптор сервопривода поворота клешни
    led        int64 // дескриптор светодиода
}

// инициализация структуры устройства
var robohand device

type servo struct {
    descriptor    *int64 // дескриптор сервопривода
    startPosition *int64 // стартовая позиция сервопривода
}

// массив дескрипторов сервоприводов
var servos = [5]servo{
    {
        descriptor:    &robohand.body,
        startPosition: &body_start_pulse,
    },
    {
        descriptor:    &robohand.claw,
        startPosition: &claw_start_pulse,
    },
    {
        descriptor:    &robohand.arrowR,
        startPosition: &arrowR_start_pulse,
    },
    {
        descriptor:    &robohand.arrowL,
        startPosition: &arrowL_start_pulse,
    },
    {
        descriptor:    &robohand.clawRotate,
        startPosition: &claw_rotate_start_pulse,
    },
}

// initServos - создает сервоприводы и линкует их
func initServos() error {
    var (
        errorText string // текст ошибки. Передается как входной параметр,при возникновении ошибки в эту переменную будет записан текст ошибки
        errCode   int64  // код ошибки
    )
    //создаем 5 сервоприводов и линкуем их к пинам 0-4
    for i := 0; i < 5; i++ {
        // создаем компонент сервопривода с конкретной моделью как исполняемое устройство и получаем дескриптор сервопривода
        *servos[i].descriptor, errorText, errCode, _ = client.RoboSdkApi.RI_SDK_CreateModelComponent("executor", "servodrive", "mg90s")
        if errCode != 0 {
            return fmt.Errorf("errorCode:%d - errorText:%s", errCode, errorText)
        }
        //связываем сервопривод с ШИМ,передаем дескрипторы сервопривода и ШИМ
        errorText, errCode, _ = client.RoboSdkApi.RI_SDK_LinkServodriveToController(*servos[i].descriptor, robohand.pwm, int64(i))
        if errCode != 0 {
            return fmt.Errorf("errorCode:%d - errorText:%s", errCode, errorText)
        }
    }

    return nil
}

// initDevice - инициализация библиотеки и устройств
func initDevice() error {
    var (
        errorText string //текст ошибки
        errCode   int64  //код ошибки
        err       error  //ошибка
    )

    // Инициализируем SDK
    errorText, errCode, err = client.RoboSdkApi.RI_SDK_InitSDK(logLevel)
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, errorText)
    }
    // создаем компонент ШИМ с конкретной моделью как соединитель и получаем дескриптор компонента
    robohand.pwm, errorText, errCode, err = client.RoboSdkApi.RI_SDK_CreateModelComponent("connector", "pwm", "pca9685")
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, errorText)
    }
    // создаем компонент i2c адатера
    // Здесь осуществлен примитивное определение подключенной модели адаптера
    // Сначала пробуем создать i2c адаптер модели ch341 и связать с ним ШИМ
    robohand.i2c, errorText, errCode, err = client.RoboSdkApi.RI_SDK_CreateModelComponent("connector", "i2c_adapter", "ch341")
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, errorText)
    }

    //связываем i2c адаптер с ШИМ по адресу 0x40
    errorText, errCode, err = client.RoboSdkApi.RI_SDK_LinkPWMToController(robohand.pwm, robohand.i2c, 0x40)
    if errCode != 0 {
        // Если не получается то пробуем создать i2c адаптер модели cp2112
        robohand.i2c, errorText, errCode, err = client.RoboSdkApi.RI_SDK_CreateModelComponent("connector", "i2c_adapter", "cp2112")
        if errCode != 0 {
            return fmt.Errorf("errorCode:%d - errorText:%s", errCode, errorText)
        }

        //связываем i2c адаптер с ШИМ по адресу 0x40
        errorText, errCode, err = client.RoboSdkApi.RI_SDK_LinkPWMToController(robohand.pwm, robohand.i2c, 0x40)
        if errCode != 0 {
            return fmt.Errorf("errorCode:%d - errorText:%s", errCode, errorText)
        }
    }
    // создаем компонент светодиода с конкретной моделью (ky016) как исполняемое устройство и получаем дескриптор светодиода
    robohand.led, errorText, errCode, err = client.RoboSdkApi.RI_SDK_CreateModelComponent("executor", "led", "ky016")
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, errorText)
    }
    //связываем светодиод адаптер с ШИМ,передаем значения трех пинов к которым подключен светодиод
    errorText, errCode, err = client.RoboSdkApi.RI_SDK_LinkLedToController(robohand.led, robohand.pwm, 15, 14, 13)
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, errorText)
    }
    //инициализируем сервоприводы
    err = initServos()
    if err != nil {
        return err
    }

    return nil
}

// startPosition - переводит сервопривод в стартовое положение
func startPosition(s servo) error {
    var (
        errorText string
        errCode   int64
    )
    //выполняем поворот сервопривода в заданный угол,передаем дескриптор сервопривода,значение угла
    errorText, errCode, _ = client.RoboSdkApi.RI_SDK_Exec_ServoDrive_TurnByPulse(*s.descriptor, *s.startPosition)
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, errorText)
    }

    time.Sleep(500 * time.Millisecond)
    return nil
}

// startPositionAllServo - переводит все сервоприводы в стартовую позицию
func startPositionAllServo() error {
    var (
        errorText string //текст ошибки
        errCode   int64  //код ошибки
    )
    //выполняем одиночное свечение светодиодом,передаем дескриптор светодиода,3 параметра цвета(RGB), и включаем асинхронный режим работы
    errorText, errCode, _ = client.RoboSdkApi.RI_SDK_Exec_RGB_LED_SinglePulse(robohand.led, 255, 0, 0, 0, true)
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, errorText)
    }
    //приводим сервоприводы в стартовое положение
    for i := 0; i < 5; i++ {
        err := startPosition(servos[i])
        if err != nil {
            return err
        }
    }
    //выполняем одиночное свечение светодиодом,передаем дескриптор светодиода,3 параметра цвета(RGB), и включаем асинхронный режим работы
    errorText, errCode, _ = client.RoboSdkApi.RI_SDK_Exec_RGB_LED_SinglePulse(robohand.led, 0, 255, 0, 0, true)
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, errorText)
    }
    //небольшая пауза для последовательного движения
    time.Sleep(500 * time.Millisecond)
    return nil
}

// rotateBody - вращение тела в указанный угол
func rotateBody(angle, speed int64) error {
    var (
        errorText string //текст ошибки
        errCode   int64  //код ошибки
    )
    //выполняем мигание с заданной частотой,передаем дескриптор светодиода,3 параметра цвета(RGB),частоту,продолжительность и включаем асинхронный режим работы
    errorText, errCode, _ = client.RoboSdkApi.RI_SDK_Exec_RGB_LED_FlashingWithFrequency(robohand.led, 0, 255, 0, 5, 0, true)
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, errorText)
    }
    //выполняем поворот на заданный угол,передаем дескриптор тела,угол,скорость и асинхронный режим работы
    errorText, errCode, _ = client.RoboSdkApi.RI_SDK_Exec_ServoDrive_Turn(robohand.body, angle, speed, false)
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, errorText)
    }
    //выполняем поворот на заданный угол,передаем дескриптор клешни,угол,скорость и асинхронный режим работы
    errorText, errCode, _ = client.RoboSdkApi.RI_SDK_Exec_ServoDrive_Turn(robohand.clawRotate, 45, speed, false)
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, errorText)
    }
    //выполняем поворот на заданный угол,передаем дескриптор клешни,угол,скорость и асинхронный режим работы
    errorText, errCode, _ = client.RoboSdkApi.RI_SDK_Exec_ServoDrive_Turn(robohand.clawRotate, -45, speed, false)
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, errorText)
    }
    return nil
}

// get - берет кубик
func get() error {
    var (
        errorText string //текст ошибки
        errCode   int64  //код ошибки
    )
    //выполняем мерцание светодиодом,передаем дескриптор светодиода,3 параметра цвета(RGB),продолжительность,кол-во повторений и включаем асинхронный режим работы
    errorText, errCode, _ = client.RoboSdkApi.RI_SDK_Exec_RGB_LED_Flicker(robohand.led, 0, 0, 255, 500, 0, true)
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, errorText)
    }
    //выполняем поворот на заданный угол,передаем дескриптор стрелы,угол,скорость и асинхронный режим работы
    errorText, errCode, _ = client.RoboSdkApi.RI_SDK_Exec_ServoDrive_Turn(robohand.arrowR, arrowR_over_cube_position, speed, false)
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, errorText)
    }
    //выполняем поворот на заданный угол,передаем дескриптор стрелы,угол,скорость и асинхронный режим работы
    errorText, errCode, _ = client.RoboSdkApi.RI_SDK_Exec_ServoDrive_Turn(robohand.arrowL, arrowL_over_cube_position, speed, false)
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, errorText)
    }
    //выполняем поворот на заданный угол,передаем дескриптор клешни,угол,скорость и асинхронный режим работы
    errorText, errCode, _ = client.RoboSdkApi.RI_SDK_Exec_ServoDrive_Turn(robohand.claw, claw_unclenched_position, speed, false)
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, errorText)
    }
    //выполняем поворот на заданный угол,передаем дескриптор стрелы,угол,скорость и асинхронный режим работы
    errorText, errCode, _ = client.RoboSdkApi.RI_SDK_Exec_ServoDrive_Turn(robohand.arrowR, (arrowR_cube_position - arrowR_over_cube_position), speed, false)
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, errorText)
    }
    //выполняем поворот на заданный угол,передаем дескриптор стрелы,угол,скорость и асинхронный режим работы
    errorText, errCode, _ = client.RoboSdkApi.RI_SDK_Exec_ServoDrive_Turn(robohand.arrowL, (arrowL_cube_position - arrowL_over_cube_position), speed, false)
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, errorText)
    }
    //выполняем поворот на заданный угол,передаем дескриптор клешни,угол,скорость и асинхронный режим работы
    errorText, errCode, _ = client.RoboSdkApi.RI_SDK_Exec_ServoDrive_Turn(robohand.claw, (-1)*claw_unclenched_position, speed, false)
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, errorText)
    }
    //выполняем поворот на заданный угол,передаем дескриптор стрелы,угол,скорость и асинхронный режим работы
    errorText, errCode, _ = client.RoboSdkApi.RI_SDK_Exec_ServoDrive_Turn(robohand.arrowR, (-1)*arrowR_cube_position, speed, false)
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, errorText)
    }
    //выполняем поворот на заданный угол,передаем дескриптор стрелы,угол,скорость и асинхронный режим работы
    errorText, errCode, _ = client.RoboSdkApi.RI_SDK_Exec_ServoDrive_Turn(robohand.arrowL, (-1)*arrowL_cube_position, speed, false)
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, errorText)
    }

    return nil
}

// put - кладет кубик
func put() error {
    var (
        errorText string //текст ошибки
        errCode   int64  //код ошибки
    )

    //выполняем мерцание светодиодом,передаем дескриптор светодиода,3 параметра цвета(RGB),продолжительность,кол-во повторений и включаем асинхронный режим работы
    errorText, errCode, _ = client.RoboSdkApi.RI_SDK_Exec_RGB_LED_Flicker(robohand.led, 0, 0, 255, 500, 0, true)
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, errorText)
    }
    //выполняем поворот на заданный угол,передаем дескриптор стрелы,угол,скорость и асинхронный режим работы
    errorText, errCode, _ = client.RoboSdkApi.RI_SDK_Exec_ServoDrive_Turn(robohand.arrowR, arrowR_cube_position, speed, false)
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, errorText)
    }
    //выполняем поворот на заданный угол,передаем дескриптор стрелы,угол,скорость и асинхронный режим работы
    errorText, errCode, _ = client.RoboSdkApi.RI_SDK_Exec_ServoDrive_Turn(robohand.arrowL, arrowL_cube_position, speed, false)
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, errorText)
    }
    //выполняем поворот на заданный угол,передаем дескриптор клешни,угол,скорость и асинхронный режим работы
    errorText, errCode, _ = client.RoboSdkApi.RI_SDK_Exec_ServoDrive_Turn(robohand.claw, claw_unclenched_position, speed, false)
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, errorText)
    }
    //выполняем поворот на заданный угол,передаем дескриптор стрелы,угол,скорость и асинхронный режим работы
    errorText, errCode, _ = client.RoboSdkApi.RI_SDK_Exec_ServoDrive_Turn(robohand.arrowR, (-1)*arrowR_cube_position, speed, false)
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, errorText)
    }
    //выполняем поворот на заданный угол,передаем дескриптор стрелы,угол,скорость и асинхронный режим работы
    errorText, errCode, _ = client.RoboSdkApi.RI_SDK_Exec_ServoDrive_Turn(robohand.arrowL, (-1)*arrowL_cube_position, speed, false)
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, errorText)
    }
    //выполняем поворот на заданный угол,передаем дескриптор клешни,угол,скорость и асинхронный режим работы
    errorText, errCode, _ = client.RoboSdkApi.RI_SDK_Exec_ServoDrive_Turn(robohand.claw, (-1)*claw_unclenched_position, speed, false)
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, errorText)
    }

    return nil
}

// destructServos - уничтожает сервоприводы
func destructServos() error {
    var (
        errorText string //текст ошибки
        errCode   int64  //код ошибки
    )

    for i := 0; i < 5; i++ {
        errorText, errCode, _ = client.RoboSdkApi.RI_SDK_DestroyComponent(*servos[i].descriptor)
        if errCode != 0 {
            return fmt.Errorf("errorCode:%d - errorText:%s", errCode, errorText)
        }
    }

    return nil
}

// destruct - уничтожает все компоненты и библиотеку
func destruct() error {

    var (
        errorText string //текст ошибки
        errCode   int64  //код ошибки
        err       error
    )
    //выполняем одиночное свечение светодиодом,передаем дескриптор светодиода,3 параметра цвета(RGB), и включаем асинхронный режим работы
    errorText, errCode, err = client.RoboSdkApi.RI_SDK_Exec_RGB_LED_SinglePulse(robohand.led, 255, 0, 0, 0, true)
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, errorText)
    }
    //уничтожаем сервоприводы
    err = destructServos()
    if err != nil {
        return err
    }
    //останавливаем свечение светодиода с определенным дескриптором
    errorText, errCode, err = client.RoboSdkApi.RI_SDK_Exec_RGB_LED_Stop(robohand.led)
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, errorText)
    }
    //удаляем компонент светодиода по дескриптору
    errorText, errCode, err = client.RoboSdkApi.RI_SDK_DestroyComponent(robohand.led)
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, errorText)
    }
    //сбрасываем все порты на ШИМ
    errorText, errCode, err = client.RoboSdkApi.RI_SDK_Sigmod_PWM_ResetAll(robohand.pwm)
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, errorText)
    }
    //удаляем компонент ШИМ
    errorText, errCode, err = client.RoboSdkApi.RI_SDK_DestroyComponent(robohand.pwm)
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, errorText)
    }
    //удаляем компонент i2c
    errorText, errCode, err = client.RoboSdkApi.RI_SDK_DestroyComponent(robohand.i2c)
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, errorText)
    }
    //удаляем sdk со всеми компонентами в реестре компонентов
    errorText, errCode, err = client.RoboSdkApi.RI_SDK_DestroySDK(true)
    if errCode != 0 {
        return fmt.Errorf("errorCode:%d - errorText:%s", errCode, errorText)
    }

    return nil
}

// start - запускает демо программу
func start() error {
    // Инициализируем библиотеку и компоненты
    err := initDevice()
    if err != nil {
        return err
    }

    // Приводим сервоприводы к стартовой позиции
    err = startPositionAllServo()
    if err != nil {
        return err
    }

    // Двигаем тело к местонахождению кубика
    err = rotateBody(45, speed)
    if err != nil {
        return err
    }

    // Берем кубик
    err = get()
    if err != nil {
        return err
    }

    //Двигаем тело к новому местонахождению кубика
    err = rotateBody(-90, speed)
    if err != nil {
        return err
    }

    //Кладем кубик
    err = put()
    if err != nil {
        return err
    }

    // Возвращаем тело в стартовое положение
    err = rotateBody(45, speed)
    if err != nil {
        return err
    }

    // Уничтожаем компоненты и библиотеку
    err = destruct()
    if err != nil {
        return err
    }
    return nil
}

func main() {
    //Открываем соединение для работы с API SDK по RPC
    client = risdk.GetClientRPC()
    //Закрываем соединение с RPC
    defer client.Client.Kill()
    //запускаем программу
    err := start()
    if err != nil {
        fmt.Println(err.Error())
        return
    }

    return
}


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

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

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

Навигация

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