Interested Article - RCML

RCML ( англ. R obot C ontrol M eta L anguage , произносится [ ар-си-эм-эль ] — компилируемый статически типизированный язык программирования высокого уровня . Разработан для получения одинакового результата независимо от исполнения робота . Позволяет создавать условия для совместной работы нескольких роботов. Используется для описания действий робота или группы роботов . Включает ряд визуальных аспектов представления кода относительно классов и объектов из языков программирования, реализующих парадигму объектно-ориентированного программирования .

Введение в RCML

Цели RCML

  1. Получение одинакового результата, независимо от исполнения робота.
    На основе предоставляемых роботом низкоуровневых функций , могут быть созданы более высокоуровневые функции, необходимые для реализации конкретной задачи в рамках аппаратных и программных возможностей используемого робота без какой-либо его модификации.
  2. Создание условий для совместной работы нескольких роботов.
    RCML позволяет задействовать несколько роботов для выполнения задачи, при этом следует описать, как должен действовать тот или иной робот по отношению к действиям другого робота.
    Это даёт ряд возможностей для кооперации роботов:
    • Отправка роботам команд в синхронном режиме.
    • Асинхронное параллельное выполнение роботами задач.
    • Взаимозависимость действий роботов в группе.
  3. Значительное упрощение программирования робота, снижение порога входа в эту область.
    На основе низкоуровневого функционала робота, может быть создан высокоуровневый функционал. В дальнейшем на базе высокоуровнего API робота может быть написана программа, реализующая требуемый технологический процесс .
  4. Оптимальный выбор робота для решения конкретной задачи.
    RCML предусматривает работу с группой однотипных роботов и позволяет установить алгоритм выбора наиболее подходящего робота-исполнителя из группы.
  5. Переключение робота между несколькими одновременными задачами.
    Во время исполнения программы при задействовании конкретного робота из группы, можно его высвободить, если робот больше не нужен. Освобождённый робот может быть задействован в другой программе, реализующей иную задачу.

Связанные области

  • Производство и промышленность
    RCML позволяет зависимость результата от конкретного робота и учитывать только функциональные возможности устройства. Используя только функционал робота, программисты могут писать универсальные программы, замена исполнительных устройств в которых не влияет на конечный результат работы.
  • Инжиниринговые компании
    Используя эффект роботонезависимости результата, инжиниринговые компании могут разрабатывать программы, реализующие тот или иной технологический процесс без привязки к конкретному роботу, тем самым снижая риски , связанные с зависимостью от конкретных аппаратных решений, и удешевляя миграцию продуктов компаний на новых роботов, имеющих необходимый функционал.
  • Разработчики программного обеспечения
    Разработчики ПО могут создавать новые, более сложные и высокоуровневые функциональные возможности роботов, используя низкоуровневые функции, описанные разработчиками роботов.
  • Научно-исследовательские институты и лаборатории
    RCML может быть интегрирован с функционалом сторонних систем, что даёт возможность быстрой адаптации этих систем на всех исполнительных устройствах , имеющих необходимые функциональные возможности.
  • Разработчики и производители роботов
    Интеграция новых роботов с RCML является одним из возможных путей расширения рынка сбыта, открывая возможность применения роботов в кругу ранее нерешённых задач.
  • Робототехнические сообщества
    Через RCML они могут быть объединены существующие робототехнические решения и налажено взаимодействие с прочими робототехническими системами.

Синтаксис RCML

Синтаксис RCML близок к языкам программирования C , Java и JavaScript . Сходство синтаксиса необходимо для обеспечения лёгкого перехода для программистов с других языков .

Особенности RCML

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

Понятие робота в RCML

Робот в RCML представляется как некий исполнительный ресурс, который может быть задействован для выполнения определённой задачи (функции), а затем освобождён для повторного задействования, но, например, в уже другой задаче.

Модуль робота предоставляет среде RCML описание класса робота , закреплённого за ним, предполагается, что локально в объектном мире, где используется RCML, может быть, как один, так и несколько роботов одного класса, закреплённых за одним модулем робота. Причём в среде RCML в рамках модуля робота присутствует два ключевых типа объектов, в соответствии с рисунком:

Виртуальное представление классов объектов в среде RCML
  • модуль робота исполняет функции контроллера роботов вверенного ему класса, то есть выполняет функции выбора свободного робота для задействования и освобождения робота после работы;
  • представление робота – отражение конкретного физического робота в виртуальной среде RCML, через него транслируются команды физическому роботу.

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

Модули роботов

Роль модулей роботов в связи с физическими роботами

Модули роботов занимают одно из ключевых положений в RCML, поскольку именно через них осуществляется связь и передача команд физическому роботу.

Модуль робота отвечает за передачу команд от интерпретатора RCML одному или нескольким роботам одного класса (или типа), которые объединены под этим модулем. Рекомендуется для каждого класса или типа робота использовать отдельный модуль. Интерпретатор RCML через задекларированный API устанавливает связь с модулем робота, который в свою очередь устанавливает связь с каждым закреплённым за ним роботом. Таким образом, через модуль робота скрывается реализация связи и управления роботом от интерпретатора, что позволяет подключать к нему самых разных роботов.

Модули функций

Через модули функций возможно добавление в RCML новых функций, которые не целесообразно или невозможно реализовывать на данном языке, например, какие-либо сложные вычисления. Таким образом, через отдельный API модули функции позволяют реализовать связь RCML с программным обеспечением других производителей.

Модули управления

Модули управления служат для связи различных управляющих устройств со средой RCML с целью использования данных устройств в ручном управлении роботами, чьи модули предоставляют такую возможность. Данный тип модулей подобен модулям роботов в том плане, что через заданный API происходит разрыв зависимостей между управляющим устройством и роботом. Таким образом, реализуется возможность управления одним и тем же роботом разными устройствами, а также возможность применения одного и того же устройства управления для разных роботов. Разумеется, при этом достигается тот же эффект сокрытия реализации связи устройства управления от среды RCML и достигается возможность подключения самых разных устройств управления.

Использование робота в программе

Чтобы задействовать робота в программе, необходимо указать его класс и функцию, которую он должен выполнить. Именование класса робота совпадает с именованием модуля робота в файле config.ini, но класс робота в RCML программе должен указываться через ключевое слово robot и знак подчёркивания.

Например, нужно вызвать робота из модуля test, тогда указание его класса будет иметь вид:

robot_test

Встретив наименование класса робота в тексте программы, RCML пошлёт запрос к соответствующему модулю робота и остановит выполнение программы, пока не будет найден свободный робот требуемого класса.

Вызов функции робота

Функции роботов программируются разработчиком робота вместе с модулем робота и описываются в документации к модулю робота.

Вызов функции визуально похож на вызов метода объекта в С-подобных языках программирования . Следует указание класса робота, затем через знак указателя -> обозначается требуемая функция, затем в круглых скобках ( ) перечисляется список аргументов этой функции.

Синтаксис вызова функции робота:

robot_класс_робота->функция_робота(аргументы);

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

Работа с конкретным экземпляром робота

Часто бывает необходимо вызвать не одну функцию у робота, а сразу несколько, и их должен выполнить один робот как заданную последовательность действий. Если вызвать необходимую последовательность функций, то при наличии нескольких роботов одного класса вполне вероятно, что заданные функции будут выполняться разными роботами. В случае если же робот заданного класса всего один в наличии, то для каждой функции он будет каждый раз задействован и освобождён.

Наиболее эффективно и рационально задействовать робота единожды и передавать ему команды так, как это необходимо, а затем его освободить, таким образом реализовав сеанс работы робота. Для этого требуется задействовать робота нужного класса и запомнить связь с задействованным конкретным роботом. Это можно сделать, сохраняя робота в специальный тип переменных , перед идентификатором которых должен быть поставлен символ @ . Например, задействование робота класса test и сохранение связи с конкретным полученным экземпляром в переменной @r :

@r = robot_test;

Чтобы вызвать выполнение функции у данного задействованного робота, нужно вызывать функцию, обращаясь к данной переменной, а не к классу робота. Например, вызов у используемого робота той же самой функции do_something с параметрами:

@r->do_something(1000);

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

Высвобождение задействованного робота

Робота, сохранённого в тип переменной @ , можно освободить, используя специальный оператор delete , когда это потребуется. С данным оператором должна указываться специальная переменная, хранящая указатель на освобождаемого робота. Пример освобождения робота, указатель на которого был ранее присвоен в переменную @r :

delete @r;

Все роботы, задействованные и не освобождённые через оператор delete , будут освобождены только при завершении выполнения функции, в которой они были задействованы. Данное утверждение не относится к функциям робота, написанным на RCML, т.к. в эти функции выполняются в контексте экземпляра робота, и в них нельзя задействовать экземпляр робота.

Автоматический выбор робота

Одна из возможностей RCML — это автоматический подбор робота под задачу. Чтобы использовать данную возможность, нужно указывать только ключевое слово robot вместо конкретного класса робота в тех местах, где требуется указание класса робота: вызовы функций робота или присвоение робота в переменную. Например:

robot->do_something(1000);
@r = robot;
@r->do_something();

Использование только ключевого слова robot вместо полного имени класса робота далее будет называться абстрактным роботом.

В случае использования специальной переменной @ для связи с абстрактным роботом RCML проанализирует каждый вызов функции относительно данной переменной и составит список кандидатов только из тех типов роботов, которые имеют все вызываемые функции относительно данной переменной.

Указание режимов выполнения функций

Исполнение функций, написанных на RCML, может выполняться в двух основных режимах:

  • с ожиданием выполнения функции – в данном случае интерпретатор, встретив команду вызова функции, просто переходит на начало вызываемой функции и последовательно выполняет её код;
  • без ожидания выполнения функции – в данном случае запускается дочерний поток, который начинает выполнять код вызываемой функции. Исполнение функции, в которой произошёл вызов, продолжается с места следующим за вызовом.

В случае выполнения функции «без ожидания», создаваемый поток может быть перенесён в отдельное вычислительное ядро средствами ОС , и таким образом может быть получен эффект параллельного выполнения кода на RCML.

По умолчанию все функции вызываются в режиме с ожиданием выполнения функции. Этот режим является режимом по умолчанию.

Исключения

RCML позволяет обрабатывать исключительные ситуации, аналогично языкам программирования C , Java и JavaScript .

Однако в RCML, оператор try может принимать параметры, указывающие, как именно ему работать. Первый параметр - это строковая константа с указанием режима работы, в зависимости от указанного режима может указываться второй параметр вещественного типа данных.

Всего у оператора try три режима работы:

  • "error_default" - режим работы по умолчанию, как обычный оператор try . В этом случае второй параметр оператора try не указывается. Если параметры оператора try опускаются как в вышеприведённом примере, то оператор try работает именно в этом режиме.
  • "error_time_limit" – режим работы с отсчётом лимита времени, за который должен быть выполнен блок кода оператора try . В данном случае указывается второй параметр, который задаёт количество миллисекунд, являющийся лимитом на выполнение блока кода оператора try . В случае если данный блок не будет выполнен за указанное время, будет брошено исключение. В случае если исключение будет брошено раньше, отсчёт времени будет прекращён, а само исключение будет обработано в обычном режиме.
  • "error_try_count" – режим работы с отсчётом количества попыток, данных для выполнения блока оператора try . В данном режиме второй параметр принимает количество допустимых попыток исполнения данного блока. При каждом брошенном исключении в блоке оператора try счётчик количества попыток будет уменьшаться на 1, и если он достигнет нуля, то будет произведена обычная обработка исключения.

Несмотря на то, что оператор try может принимать параметры, он не является функцией и не возвращает значение.

Через оператор throw с исключением можно передать значение исключения.

Режим ручного управления

Среда RCML может предоставить возможность ручного управления конкретным экземпляром робота посредством конкретного управляющего устройства при вызове системной функции hand_control с соответствующими параметрами.

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

Виртуальное представление классов объектов в среде RCML

На рисунке есть гусеничный робот (изображён слева), который может переходить в своё новое абсолютное положение на плоскости посредством ряда изменений своего положения по двум осям: оси передвижения R (вперёд или назад) и оси вращения A (влево или право). И есть простое управляющее устройство по типу джойстика (изображено справа), которое может отклоняться в плоскости от своего начального положения по двум осям X и Y . Соответственно, через RCML возможно связать оси джойстика и робота так, чтобы отклонение джойстика приводило к движению робота. Например, отклонение джойстика по оси Y в положительную сторону приводило к движению вперёд, а отклонение джойстика по оси X в отрицательную сторону приводило к повороту робота влево. Предположим, что данный робот представлен в среде RCML модулем робота parrot , а джойстик, соответственно, модулем управления joy , тогда RCML код для их связи в режиме ручного управления для получения эффекта, приведённого в примере, будет следующим:

@r = robot_tarakan;
hand_control(@r, joy, R, Y, A, X);

Пакетная передача команд роботам

У представления робота в среде RCML есть очередь команд , которая наполняется командами путём вызова функций робота из кода на RCML. При поступлении команды в пустую очередь, команда будет передана роботу на исполнение. Пока исполняется первая команда, все вновь поступившие команды становятся в очередь. Робот выполняет функцию в материальном мире обычно медленнее, чем RCML интерпретатор успевает выполнить очередной код на RCML и дойти до следующего вызова функции робота, т.е. обычно действия робота "медлительнее" действий вычислительного процессора.

Однако бывает иная ситуация, когда роботу необходимо выполнить серию быстрых перемещений без остановки, а расчёт параметров этих перемещений занимает больше времени, чем выполняется перемещение. Тогда эффективнее заранее рассчитать параметры перемещений и передать роботу сразу пакет команд с рассчитанными параметрами, чтобы робот не замедлялся в ожидании очередной команды. Бывают ситуации, что сам механизм вызова функций работает медленнее, чем робот исполняет команды, и возникает задержка в быстрой серии перемещений.

Чтобы скомпенсировать этот эффект, был введён механизм пакетной передачи команд роботу. Команды, получаемые посредством вызова функций робота, можно скомпоновать в единый пакет и передать целиком представлению робота. Чтобы отправить команду в пакет, нужно поставить перед вызовом функции символ > . Чтобы отправить пакет на выполнение, нужно вызвать системную функцию send_package() .

Возможно составление пакета сразу для двух роботов, команды из этого пакета будут переданы сразу двум представлениям роботов, дополнительно можно комбинировать типы вызовов функций.

Примеры на RCML

Простейшая программа на RCML

Простейшая программа на RCML имеет следующий вид:

function main() {
	return;
}

Программа сразу после запуска завершит работу.

Программа "Hello,_world!

Вывод в консоль строки " Hello world! ", через модуль тестового робота.

function main() {
	robot_test->print("Hello world!\n", 0);
}

Пример программы работающей с пулом роботов

Как отмечалось ранее RCML ориентирован на работу с пулом (множеством) роботов, из которого выделяются исполнители для решения динамически возникающих задач.

Пусть есть пул роботов, некоторые роботы из этого пула способны выполнить необходимую технологическую функцию do_something() . Необходимость выполнения данной функции определяет некий внешний сенсор, тогда программа для динамического распределения задач выполнения данной функции будет иметь вид:

function main() {
    loop {
        have_new_task = get_data_from_sensor();
        if (have_new_task) { 
            ~robot->do_something();
        }
        system.sleep(300);
    }
}

В данной программе в цикле с интервалом 300 мс, опрашивается внешний сенсор посредством функции get_data_from_sensor() , строка 3. В случае если возникла необходимость выполнения функции, то будет задействован первый свободный робот из пула, способный выполнить функцию do_something() , строка 5. При этом программа не будет ожидать выполнения функции роботом, т.к. установлен флаг выполнения функции без ожидания ~ . Это позволит программе не замедлиться в период выполнения роботом своей функции и продолжить опрашивать сенсор с заданным интервалом.

В случае если через очередные 300 мс, снова потребуется выполнение функции, а первый задействованный робот ещё не закончил работу, то RCML задействует второго робота из пула, и т.д. После выполнения заданной функции роботы будут автоматически освобождены и возвращены в общий пул. В случае если все роботы будут задействованы, программа будет ожидать освобождения робота.

Данный приём позволяет динамически распределять среди роботов задачи из очереди и задействовать сразу нескольких роботов.

Пример программы для работы с пулом разнотипных роботов

Пусть имеется задача перемещения деталей весом от 1 до 15 кг, детали поступают последовательно, однако их необходимо перемещать по возможности наиболее быстро. Имеется пул разнотипных роботов, среди которых роботы класса robot_heavy большей грузоподъёмности (до 10 кг) и robot_light меньшей грузоподъёмности (до 5 кг). При этом robot_heavy перемещает деталь за 10 секунд, а robot_light за 5 секунд. Таким образом, выполняемые роботами задачи параметризованы, и на основе имеющегося параметра (веса детали) необходимо принимать наиболее рациональное решение какой тип робота задействовать, чтобы обеспечить минимальный простой и максимальную производительность участка. С целью показать применение пакетов команд в рамках данного примера допустим, что деталь весом более 10 кг могут нести два робота одновременно.

function main() {
    loop {
        detail_weight = get_weight_from_sensor(); //Получение веса детали
        if (detail_weight < 5) { //Если вес до 5 кг 
            ~robot->move_detail(); //Можно задействовать любого робота
        }
        if ((detail_weight >= 5) && (detail_weight < 10)) { //Если вес от 5 до 10 кг
            ~robot_heavy->move_detail(); //Можно задействовать только более грузоподъемного робота    
        }
        if (detail_weight >= 10) { //Если вес от 10 кг
            >robot_heavy->move_detail(); //Один робот обязательно должен быть более грузоподъемный
            >robot->move_detail(); //Второй робот может быть любым
            ~system.send_package(); //Отправка пакета команд для роботов на выполнение
        }
        system.sleep(300);
    }
}

В случае если вес детали менее 5 кг, то деталь может нести робот любого класса, строка 5. Однако, RCML сначала опросит всех роботов класса robot_light и если среди них не окажется свободного, то будет произведён опрос роботов класса robot_heavy (Приоритет опроса классов роботов задаётся в конфигурации интерпретатора RCML). Первый свободный робот будет задействован для перемещения, по аналогии с предыдущим примером, без ожидания основной программы выполнения роботом своей функции - перемещения детали. Таким образом RCML попытается задействовать сначала робота наиболее подходящего класса robot_light , а если свободного робота такого класса нет, то будет задействован робот менее подходящего класса robot_heavy , чтобы не допустить простоя.

Однако в случае, если вес детали от 5 до 10 кг, то можно задействовать только более грузоподъемного робота, строка 7.

В случае если вес детали от 10 кг, то надо задействовать двух роботов, среди которых один должен быть более грузоподъёмным, а второй любым. Стоит отметить, что в данном случае команда на перемещение детали передаётся двум роботам одновременно, посредством механизма составления пакетов команд (строки 11-15).

Следует отметить, что данный пример предполагает, что детали поступают строго последовательно, т.е. следующая деталь поступает только тогда, когда робот забрал предыдущую и переносит её некоторое время. Таким образом, очередь заданий для роботов также последовательна и в случае, если поступает несколько тяжёлых деталей, а затем лёгкая, то лёгкая деталь будет перемещена, только когда все тяжёлые детали будут перемещены, из-за этого возможен простой роботов класса robot_light .

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

Усложним предыдущий пример. Пусть детали поступают в некий контейнер беспорядочно, система технического зрения наблюдает контейнер и распознает детали в нём, получая координаты и тип детали, а по типу определяет её вес. При распознавании очередной детали нужно поставить задачу роботам на перемещение детали. При распознавании деталей некая функция get_new_detail_index() будет возвращать уникальный индекс распознанной детали, по которому впоследствии можно получить координаты и вес детали, необходимые для принятия решения по задействованию роботов и перемещению, соответственно.

function executeMoveTask(detail_index) {
    detail_weight = get_weight_by_index(detail_index); //Получение веса детали
    detail_coords = get_coords_by_index(detail_index);
    if (detail_weight < 5) { //Если вес до 5 кг 
        ~robot->move_detail(detail_coords); //Можно задействовать любого робота
    }
    if ((detail_weight >= 5) && (detail_weight < 10)) { //Если вес от 5 до 10 кг
        ~robot_heavy->move_detail(detail_coords); //Можно задействовать только более грузоподъемного робота    
    }
    if (detail_weight >= 10) { //Если вес от 10 кг
        >robot_heavy->move_detail(detail_coords); //Один робот обязательно должен быть более грузоподъемный
        >robot->move_detail(detail_coords); //Второй робот может быть любым
        ~system.send_package(); //Отправка пакета команд для роботов на выполнение
    }
}

function main() {
    loop {
        new_detail_index = get_new_detail_index(); //Получение очередного индекса детали
        if (new_detail_index) { //Новая деталь поступила
            ~executeMoveTask(new_detail_index); //Выполняем задачу по перемещению
        }
        system.sleep(300);
    }
}

В данном примере при поступлении новой детали в контейнер, будет получен её уникальный индекс (строка 19), который будет передан в функцию executeMoveTask (строка 21), в которой выполняется задействование роботов, т.е. по сути формирование запросов к пулу роботов. Особо следует отметить, что данная функция вызывается с флагом без ожидания ~ .

В сумме это даёт следующий эффект: если в контейнер поступило некоторое большое количество тяжёлых деталей весом до 10 кг, и из пула свободных роботов были задействованы все грузоподъёмные роботы robot_heavy , а затем в контейнер поступило некоторое количество легкий деталей весом до 5 кг, то RCML сможет задействовать ранее простаивающих роботов класса robot_light до того как роботы класса robot_heavy переместят все тяжёлые детали. Переместив задействование робота в отдельную функцию выполняемую без ожидания по сути мы получили возможность формировать различные очереди задач для различных классов роботов. Таким образом, простой роботов при наличии подходящих для них задач, будет сведён к минимуму, что было невозможно в предыдущем примере при строгой очерёдности поступления задач.

Пример создания RCML программы, универсальной для разных классов роботов

RCML даёт возможность программисту явно указать, что некоторые роботы могут выполнять одну и ту же функцию одинаково и тем самым они могут считаться взаимозаменяемыми при выполнении данной функции, хотя при этом роботы имеют различный API предоставляемый для программиста на уровне RCML.

В вышеприведённых примерах встречаются строки вида robot->move_detail() , с использованием ключевого слова robot . Данное ключевое слово сообщает RCML, что для выполнения данной функции можно задействовать любого робота из пула обладающего запрашиваемой функцией move_detail() .

Пусть у классов роботов robot_heavy и robot_light имеется набор функций для управления захватом и перемещением захвата, однако функции в этих набор имеют разные имена и отличающиеся параметры.

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

function robot_heavy::move_to(x, y, z, w, p, r) {
    //Далее следует код для перемещения в заданную точку, 
    //путём обращения к функциям специфичным для роботов класса robot_heavy
    robot->set_real_di("x",x);
    robot->set_real_di("y",y);
    robot->set_real_di("z",z);
    robot->set_real_di("w",w);
    robot->set_real_di("p",p);
    robot->set_real_di("r",r);
    robot->go_position();
}
function robot_heavy::gripper(s) {
    //Специфичный, для robot_heavy, код управления захватом
    if (s) {
        robot->set_gripper_pos(124,25);
    } else {
        robot->set_gripper_pos(350,50);
    }
}
function robot_light::move_to(x, y, z, w, p, r) {
    //Специфичный, для robot_light, код перемещения захвата
    robot->move_to(x,y,z);
    robot->set_angle(w,p,r);
}
function robot_light::gripper(s) {
    //Специфичный, для robot_light, код управления захватом
    if (s) {
        robot->pump_on();
    } else {
        robot->pump_off();
    }
}
function main() {
    //Универсальный код для перемещения детали роботом любого класса
    robot->move_to(46,76,73,235,-34,23); //Переместиться к заготовке
    robot->gripper(1); //Захватить деталь
    robot->move_to(235,34,47,262,673,74); //Переместить деталь к позиции 1
    system.sleep(15000); //Ожидать время измерения детали на позиции 1

    if (some_check()) {
        //Переместить захват робота к контейнеру с качественными деталями
        robot->move_to(35,63,23,25,-48,245); 
        robot->gripper(0); //Освободить деталь
    } else {
        //Переместить захват робота к контейнеру с браком
        robot->move_to(568,778,346,-54,2,34); 
        robot->gripper(0); //Освободить деталь
    }
}

В данном случае алгоритм перемещения и проверки сможет выполнять как класс роботов robot_heavy , так и класс роботов robot_light , хотя они имеют разный API предоставляемый на уровне RCML.

См. также

Примечания

  1. . Дата обращения: 26 февраля 2016. 3 марта 2016 года.
  2. . Дата обращения: 26 февраля 2016. Архивировано из 5 марта 2016 года.
  3. . Дата обращения: 26 февраля 2016. 3 марта 2016 года.
  4. . Дата обращения: 26 февраля 2016. Архивировано из 3 марта 2016 года.

Литература

  • Д.К. Сутормин, М.В. Тюлькин. = Robot Control Meta Language. Метаязык для роботов, 2-е издание. — Пермь: Астер Диджитал, 2015. — 108 с. — ISBN 978-5-9905-655-0-0 (рус.) ISBN 978-5-9905-655-3-1 (англ.).
  • Дейкстра Э. Дисциплина программирования = A discipline of programming. — 1-е изд. — М. : Мир, 1978. — 275 с.
  • Александр Степанов, Пол Мак-Джонс. Начала программирования = Elements of Programming. — М. : Вильямс, 2011. — С. 272. — ISBN 978-5-8459-1708-9 .
  • Макаров И. М., Топчеев Ю. И. Робототехника: История и перспективы. — М. : Наука ; Изд-во МАИ, 2003. — 349 с. — (Информатика: неограниченные возможности и возможные ограничения). — ISBN 5-02-013159-8 .
  • Роберт У. Себеста. Основные концепции языков программирования / Пер. с англ. — 5-е изд. — М. : Вильямс, 2001. — 672 с. — ISBN 5-8459-0192-8 (рус.) ISBN 0-201-75295-6 (англ.).
  • Иан Соммервилл. Инженерия программного обеспечения / Пер. с англ. — 6-е издание. — М. : Вильямс, 2002. — 624 с.
  • Иан Грэхем. Объектно-ориентированные методы. Принципы и практика / Пер. с англ. — 3-е изд. — М. : Вильямс, 2004. — 880 с.

Ссылки

  • Официальный сайт разработчика RCML
  • от 13 февраля 2016 на Wayback Machine


Источник —

Same as RCML