RCML

Поделись знанием:
Перейти к: навигация, поиск
RCML (англ. Robot Control Meta Language) Метаязык для роботов
Класс языка:

процедурный

Тип исполнения:

компилируемый

Появился в:

2014

Автор:

[robotct.com/ Robot Control Technologies]

Расширение файлов:

.rcml

Выпуск:

1.0.6 (18.12.2015)

Система типов:

статическая слабая

Повлиял на:

Robot Build Language

Сайт:

[robotct.com/ Официальный сайт разработчика]

RCML (англ. Robot Control Meta Language, произносится [ар-си-эм-эль] — компилируемый статически типизированный язык программирования высокого уровня. Разработан для получения одинакового результата независимо от исполнения робота[1]. Позволяет создавать условия для совместной работы нескольких роботов. Используется для описания действий робота или группы роботов[2]. Включает ряд визуальных аспектов представления кода относительно классов и объектов из языков программирования, реализующих парадигму объектно-ориентированного программирования[3].





Содержание

Введение в RCML

Цели RCML

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

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

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

Синтаксис RCML

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

Особенности 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 при переходе в режим ручного управления заключается в связывании осей робота, по которым он может так или иначе передвигаться, с осями управляющего устройства, по которым данное устройство может фиксировать изменения.

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

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

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

У представления робота в среде 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.

См. также

Напишите отзыв о статье "RCML"

Примечания

  1. [properm.ru/news/business/104205/ "Интервью с разработчиками RCML", портал Properm, 2015]
  2. [rosnauka.org/36364/ "RCML Описание технологии", Премия Роснаука, 2015]
  3. [www.strf.ru/material.aspx?CatalogId=222&d_no=96040#.VrHkCLKLRhE "Из интервью разработчиков", Электронное издание «Наука и технологии России», 2015]
  4. [robotct.ru/aboutrcml#paragraph-41 "Основы построения программ на RCML"]

Литература

  • Д.К. Сутормин, М.В. Тюлькин. = 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 с.

Ссылки

  • [robotct.com/ RCML] Официальный сайт разработчика RCML
  • [robotct.com/aboutrcml Официальное руководство по RCML]
  • [www.youtube.com/watch?v=jnWZXRb-yvc Что такое RCML? Видеоролик на Youtube]

Отрывок, характеризующий RCML

– Ах боже мой! Боже мой! Что ж это?.. Живот! Это конец! Ах боже мой! – слышались голоса между офицерами. – На волосок мимо уха прожужжала, – говорил адъютант. Мужики, приладивши носилки на плечах, поспешно тронулись по протоптанной ими дорожке к перевязочному пункту.
– В ногу идите… Э!.. мужичье! – крикнул офицер, за плечи останавливая неровно шедших и трясущих носилки мужиков.
– Подлаживай, что ль, Хведор, а Хведор, – говорил передний мужик.
– Вот так, важно, – радостно сказал задний, попав в ногу.
– Ваше сиятельство? А? Князь? – дрожащим голосом сказал подбежавший Тимохин, заглядывая в носилки.
Князь Андрей открыл глаза и посмотрел из за носилок, в которые глубоко ушла его голова, на того, кто говорил, и опять опустил веки.
Ополченцы принесли князя Андрея к лесу, где стояли фуры и где был перевязочный пункт. Перевязочный пункт состоял из трех раскинутых, с завороченными полами, палаток на краю березника. В березнике стояла фуры и лошади. Лошади в хребтугах ели овес, и воробьи слетали к ним и подбирали просыпанные зерна. Воронья, чуя кровь, нетерпеливо каркая, перелетали на березах. Вокруг палаток, больше чем на две десятины места, лежали, сидели, стояли окровавленные люди в различных одеждах. Вокруг раненых, с унылыми и внимательными лицами, стояли толпы солдат носильщиков, которых тщетно отгоняли от этого места распоряжавшиеся порядком офицеры. Не слушая офицеров, солдаты стояли, опираясь на носилки, и пристально, как будто пытаясь понять трудное значение зрелища, смотрели на то, что делалось перед ними. Из палаток слышались то громкие, злые вопли, то жалобные стенания. Изредка выбегали оттуда фельдшера за водой и указывали на тех, который надо было вносить. Раненые, ожидая у палатки своей очереди, хрипели, стонали, плакали, кричали, ругались, просили водки. Некоторые бредили. Князя Андрея, как полкового командира, шагая через неперевязанных раненых, пронесли ближе к одной из палаток и остановились, ожидая приказания. Князь Андрей открыл глаза и долго не мог понять того, что делалось вокруг него. Луг, полынь, пашня, черный крутящийся мячик и его страстный порыв любви к жизни вспомнились ему. В двух шагах от него, громко говоря и обращая на себя общее внимание, стоял, опершись на сук и с обвязанной головой, высокий, красивый, черноволосый унтер офицер. Он был ранен в голову и ногу пулями. Вокруг него, жадно слушая его речь, собралась толпа раненых и носильщиков.
– Мы его оттеда как долбанули, так все побросал, самого короля забрали! – блестя черными разгоряченными глазами и оглядываясь вокруг себя, кричал солдат. – Подойди только в тот самый раз лезервы, его б, братец ты мой, звания не осталось, потому верно тебе говорю…
Князь Андрей, так же как и все окружавшие рассказчика, блестящим взглядом смотрел на него и испытывал утешительное чувство. «Но разве не все равно теперь, – подумал он. – А что будет там и что такое было здесь? Отчего мне так жалко было расставаться с жизнью? Что то было в этой жизни, чего я не понимал и не понимаю».


Один из докторов, в окровавленном фартуке и с окровавленными небольшими руками, в одной из которых он между мизинцем и большим пальцем (чтобы не запачкать ее) держал сигару, вышел из палатки. Доктор этот поднял голову и стал смотреть по сторонам, но выше раненых. Он, очевидно, хотел отдохнуть немного. Поводив несколько времени головой вправо и влево, он вздохнул и опустил глаза.
– Ну, сейчас, – сказал он на слова фельдшера, указывавшего ему на князя Андрея, и велел нести его в палатку.
В толпе ожидавших раненых поднялся ропот.
– Видно, и на том свете господам одним жить, – проговорил один.
Князя Андрея внесли и положили на только что очистившийся стол, с которого фельдшер споласкивал что то. Князь Андрей не мог разобрать в отдельности того, что было в палатке. Жалобные стоны с разных сторон, мучительная боль бедра, живота и спины развлекали его. Все, что он видел вокруг себя, слилось для него в одно общее впечатление обнаженного, окровавленного человеческого тела, которое, казалось, наполняло всю низкую палатку, как несколько недель тому назад в этот жаркий, августовский день это же тело наполняло грязный пруд по Смоленской дороге. Да, это было то самое тело, та самая chair a canon [мясо для пушек], вид которой еще тогда, как бы предсказывая теперешнее, возбудил в нем ужас.
В палатке было три стола. Два были заняты, на третий положили князя Андрея. Несколько времени его оставили одного, и он невольно увидал то, что делалось на других двух столах. На ближнем столе сидел татарин, вероятно, казак – по мундиру, брошенному подле. Четверо солдат держали его. Доктор в очках что то резал в его коричневой, мускулистой спине.
– Ух, ух, ух!.. – как будто хрюкал татарин, и вдруг, подняв кверху свое скуластое черное курносое лицо, оскалив белые зубы, начинал рваться, дергаться и визжат ь пронзительно звенящим, протяжным визгом. На другом столе, около которого толпилось много народа, на спине лежал большой, полный человек с закинутой назад головой (вьющиеся волоса, их цвет и форма головы показались странно знакомы князю Андрею). Несколько человек фельдшеров навалились на грудь этому человеку и держали его. Белая большая полная нога быстро и часто, не переставая, дергалась лихорадочными трепетаниями. Человек этот судорожно рыдал и захлебывался. Два доктора молча – один был бледен и дрожал – что то делали над другой, красной ногой этого человека. Управившись с татарином, на которого накинули шинель, доктор в очках, обтирая руки, подошел к князю Андрею. Он взглянул в лицо князя Андрея и поспешно отвернулся.
– Раздеть! Что стоите? – крикнул он сердито на фельдшеров.
Самое первое далекое детство вспомнилось князю Андрею, когда фельдшер торопившимися засученными руками расстегивал ему пуговицы и снимал с него платье. Доктор низко нагнулся над раной, ощупал ее и тяжело вздохнул. Потом он сделал знак кому то. И мучительная боль внутри живота заставила князя Андрея потерять сознание. Когда он очнулся, разбитые кости бедра были вынуты, клоки мяса отрезаны, и рана перевязана. Ему прыскали в лицо водою. Как только князь Андрей открыл глаза, доктор нагнулся над ним, молча поцеловал его в губы и поспешно отошел.
После перенесенного страдания князь Андрей чувствовал блаженство, давно не испытанное им. Все лучшие, счастливейшие минуты в его жизни, в особенности самое дальнее детство, когда его раздевали и клали в кроватку, когда няня, убаюкивая, пела над ним, когда, зарывшись головой в подушки, он чувствовал себя счастливым одним сознанием жизни, – представлялись его воображению даже не как прошедшее, а как действительность.
Около того раненого, очертания головы которого казались знакомыми князю Андрею, суетились доктора; его поднимали и успокоивали.
– Покажите мне… Ооооо! о! ооооо! – слышался его прерываемый рыданиями, испуганный и покорившийся страданию стон. Слушая эти стоны, князь Андрей хотел плакать. Оттого ли, что он без славы умирал, оттого ли, что жалко ему было расставаться с жизнью, от этих ли невозвратимых детских воспоминаний, оттого ли, что он страдал, что другие страдали и так жалостно перед ним стонал этот человек, но ему хотелось плакать детскими, добрыми, почти радостными слезами.
Раненому показали в сапоге с запекшейся кровью отрезанную ногу.
– О! Ооооо! – зарыдал он, как женщина. Доктор, стоявший перед раненым, загораживая его лицо, отошел.
– Боже мой! Что это? Зачем он здесь? – сказал себе князь Андрей.
В несчастном, рыдающем, обессилевшем человеке, которому только что отняли ногу, он узнал Анатоля Курагина. Анатоля держали на руках и предлагали ему воду в стакане, края которого он не мог поймать дрожащими, распухшими губами. Анатоль тяжело всхлипывал. «Да, это он; да, этот человек чем то близко и тяжело связан со мною, – думал князь Андрей, не понимая еще ясно того, что было перед ним. – В чем состоит связь этого человека с моим детством, с моею жизнью? – спрашивал он себя, не находя ответа. И вдруг новое, неожиданное воспоминание из мира детского, чистого и любовного, представилось князю Андрею. Он вспомнил Наташу такою, какою он видел ее в первый раз на бале 1810 года, с тонкой шеей и тонкими рукамис готовым на восторг, испуганным, счастливым лицом, и любовь и нежность к ней, еще живее и сильнее, чем когда либо, проснулись в его душе. Он вспомнил теперь ту связь, которая существовала между им и этим человеком, сквозь слезы, наполнявшие распухшие глаза, мутно смотревшим на него. Князь Андрей вспомнил все, и восторженная жалость и любовь к этому человеку наполнили его счастливое сердце.
Князь Андрей не мог удерживаться более и заплакал нежными, любовными слезами над людьми, над собой и над их и своими заблуждениями.
«Сострадание, любовь к братьям, к любящим, любовь к ненавидящим нас, любовь к врагам – да, та любовь, которую проповедовал бог на земле, которой меня учила княжна Марья и которой я не понимал; вот отчего мне жалко было жизни, вот оно то, что еще оставалось мне, ежели бы я был жив. Но теперь уже поздно. Я знаю это!»


Страшный вид поля сражения, покрытого трупами и ранеными, в соединении с тяжестью головы и с известиями об убитых и раненых двадцати знакомых генералах и с сознанием бессильности своей прежде сильной руки произвели неожиданное впечатление на Наполеона, который обыкновенно любил рассматривать убитых и раненых, испытывая тем свою душевную силу (как он думал). В этот день ужасный вид поля сражения победил ту душевную силу, в которой он полагал свою заслугу и величие. Он поспешно уехал с поля сражения и возвратился к Шевардинскому кургану. Желтый, опухлый, тяжелый, с мутными глазами, красным носом и охриплым голосом, он сидел на складном стуле, невольно прислушиваясь к звукам пальбы и не поднимая глаз. Он с болезненной тоской ожидал конца того дела, которого он считал себя причиной, но которого он не мог остановить. Личное человеческое чувство на короткое мгновение взяло верх над тем искусственным призраком жизни, которому он служил так долго. Он на себя переносил те страдания и ту смерть, которые он видел на поле сражения. Тяжесть головы и груди напоминала ему о возможности и для себя страданий и смерти. Он в эту минуту не хотел для себя ни Москвы, ни победы, ни славы. (Какой нужно было ему еще славы?) Одно, чего он желал теперь, – отдыха, спокойствия и свободы. Но когда он был на Семеновской высоте, начальник артиллерии предложил ему выставить несколько батарей на эти высоты, для того чтобы усилить огонь по столпившимся перед Князьковым русским войскам. Наполеон согласился и приказал привезти ему известие о том, какое действие произведут эти батареи.
Адъютант приехал сказать, что по приказанию императора двести орудий направлены на русских, но что русские все так же стоят.
– Наш огонь рядами вырывает их, а они стоят, – сказал адъютант.
– Ils en veulent encore!.. [Им еще хочется!..] – сказал Наполеон охриплым голосом.
– Sire? [Государь?] – повторил не расслушавший адъютант.
– Ils en veulent encore, – нахмурившись, прохрипел Наполеон осиплым голосом, – donnez leur en. [Еще хочется, ну и задайте им.]
И без его приказания делалось то, чего он хотел, и он распорядился только потому, что думал, что от него ждали приказания. И он опять перенесся в свой прежний искусственный мир призраков какого то величия, и опять (как та лошадь, ходящая на покатом колесе привода, воображает себе, что она что то делает для себя) он покорно стал исполнять ту жестокую, печальную и тяжелую, нечеловеческую роль, которая ему была предназначена.
И не на один только этот час и день были помрачены ум и совесть этого человека, тяжеле всех других участников этого дела носившего на себе всю тяжесть совершавшегося; но и никогда, до конца жизни, не мог понимать он ни добра, ни красоты, ни истины, ни значения своих поступков, которые были слишком противоположны добру и правде, слишком далеки от всего человеческого, для того чтобы он мог понимать их значение. Он не мог отречься от своих поступков, восхваляемых половиной света, и потому должен был отречься от правды и добра и всего человеческого.
Не в один только этот день, объезжая поле сражения, уложенное мертвыми и изувеченными людьми (как он думал, по его воле), он, глядя на этих людей, считал, сколько приходится русских на одного француза, и, обманывая себя, находил причины радоваться, что на одного француза приходилось пять русских. Не в один только этот день он писал в письме в Париж, что le champ de bataille a ete superbe [поле сражения было великолепно], потому что на нем было пятьдесят тысяч трупов; но и на острове Св. Елены, в тиши уединения, где он говорил, что он намерен был посвятить свои досуги изложению великих дел, которые он сделал, он писал:
«La guerre de Russie eut du etre la plus populaire des temps modernes: c'etait celle du bon sens et des vrais interets, celle du repos et de la securite de tous; elle etait purement pacifique et conservatrice.
C'etait pour la grande cause, la fin des hasards elle commencement de la securite. Un nouvel horizon, de nouveaux travaux allaient se derouler, tout plein du bien etre et de la prosperite de tous. Le systeme europeen se trouvait fonde; il n'etait plus question que de l'organiser.
Satisfait sur ces grands points et tranquille partout, j'aurais eu aussi mon congres et ma sainte alliance. Ce sont des idees qu'on m'a volees. Dans cette reunion de grands souverains, nous eussions traites de nos interets en famille et compte de clerc a maitre avec les peuples.
L'Europe n'eut bientot fait de la sorte veritablement qu'un meme peuple, et chacun, en voyageant partout, se fut trouve toujours dans la patrie commune. Il eut demande toutes les rivieres navigables pour tous, la communaute des mers, et que les grandes armees permanentes fussent reduites desormais a la seule garde des souverains.
De retour en France, au sein de la patrie, grande, forte, magnifique, tranquille, glorieuse, j'eusse proclame ses limites immuables; toute guerre future, purement defensive; tout agrandissement nouveau antinational. J'eusse associe mon fils a l'Empire; ma dictature eut fini, et son regne constitutionnel eut commence…
Paris eut ete la capitale du monde, et les Francais l'envie des nations!..
Mes loisirs ensuite et mes vieux jours eussent ete consacres, en compagnie de l'imperatrice et durant l'apprentissage royal de mon fils, a visiter lentement et en vrai couple campagnard, avec nos propres chevaux, tous les recoins de l'Empire, recevant les plaintes, redressant les torts, semant de toutes parts et partout les monuments et les bienfaits.
Русская война должна бы была быть самая популярная в новейшие времена: это была война здравого смысла и настоящих выгод, война спокойствия и безопасности всех; она была чисто миролюбивая и консервативная.
Это было для великой цели, для конца случайностей и для начала спокойствия. Новый горизонт, новые труды открывались бы, полные благосостояния и благоденствия всех. Система европейская была бы основана, вопрос заключался бы уже только в ее учреждении.
Удовлетворенный в этих великих вопросах и везде спокойный, я бы тоже имел свой конгресс и свой священный союз. Это мысли, которые у меня украли. В этом собрании великих государей мы обсуживали бы наши интересы семейно и считались бы с народами, как писец с хозяином.
Европа действительно скоро составила бы таким образом один и тот же народ, и всякий, путешествуя где бы то ни было, находился бы всегда в общей родине.
Я бы выговорил, чтобы все реки были судоходны для всех, чтобы море было общее, чтобы постоянные, большие армии были уменьшены единственно до гвардии государей и т.д.
Возвратясь во Францию, на родину, великую, сильную, великолепную, спокойную, славную, я провозгласил бы границы ее неизменными; всякую будущую войну защитительной; всякое новое распространение – антинациональным; я присоединил бы своего сына к правлению империей; мое диктаторство кончилось бы, в началось бы его конституционное правление…
Париж был бы столицей мира и французы предметом зависти всех наций!..
Потом мои досуги и последние дни были бы посвящены, с помощью императрицы и во время царственного воспитывания моего сына, на то, чтобы мало помалу посещать, как настоящая деревенская чета, на собственных лошадях, все уголки государства, принимая жалобы, устраняя несправедливости, рассевая во все стороны и везде здания и благодеяния.]
Он, предназначенный провидением на печальную, несвободную роль палача народов, уверял себя, что цель его поступков была благо народов и что он мог руководить судьбами миллионов и путем власти делать благодеяния!
«Des 400000 hommes qui passerent la Vistule, – писал он дальше о русской войне, – la moitie etait Autrichiens, Prussiens, Saxons, Polonais, Bavarois, Wurtembergeois, Mecklembourgeois, Espagnols, Italiens, Napolitains. L'armee imperiale, proprement dite, etait pour un tiers composee de Hollandais, Belges, habitants des bords du Rhin, Piemontais, Suisses, Genevois, Toscans, Romains, habitants de la 32 e division militaire, Breme, Hambourg, etc.; elle comptait a peine 140000 hommes parlant francais. L'expedition do Russie couta moins de 50000 hommes a la France actuelle; l'armee russe dans la retraite de Wilna a Moscou, dans les differentes batailles, a perdu quatre fois plus que l'armee francaise; l'incendie de Moscou a coute la vie a 100000 Russes, morts de froid et de misere dans les bois; enfin dans sa marche de Moscou a l'Oder, l'armee russe fut aussi atteinte par, l'intemperie de la saison; elle ne comptait a son arrivee a Wilna que 50000 hommes, et a Kalisch moins de 18000».
[Из 400000 человек, которые перешли Вислу, половина была австрийцы, пруссаки, саксонцы, поляки, баварцы, виртембергцы, мекленбургцы, испанцы, итальянцы и неаполитанцы. Императорская армия, собственно сказать, была на треть составлена из голландцев, бельгийцев, жителей берегов Рейна, пьемонтцев, швейцарцев, женевцев, тосканцев, римлян, жителей 32 й военной дивизии, Бремена, Гамбурга и т.д.; в ней едва ли было 140000 человек, говорящих по французски. Русская экспедиция стоила собственно Франции менее 50000 человек; русская армия в отступлении из Вильны в Москву в различных сражениях потеряла в четыре раза более, чем французская армия; пожар Москвы стоил жизни 100000 русских, умерших от холода и нищеты в лесах; наконец во время своего перехода от Москвы к Одеру русская армия тоже пострадала от суровости времени года; по приходе в Вильну она состояла только из 50000 людей, а в Калише менее 18000.]
Он воображал себе, что по его воле произошла война с Россией, и ужас совершившегося не поражал его душу. Он смело принимал на себя всю ответственность события, и его помраченный ум видел оправдание в том, что в числе сотен тысяч погибших людей было меньше французов, чем гессенцев и баварцев.


Несколько десятков тысяч человек лежало мертвыми в разных положениях и мундирах на полях и лугах, принадлежавших господам Давыдовым и казенным крестьянам, на тех полях и лугах, на которых сотни лет одновременно сбирали урожаи и пасли скот крестьяне деревень Бородина, Горок, Шевардина и Семеновского. На перевязочных пунктах на десятину места трава и земля были пропитаны кровью. Толпы раненых и нераненых разных команд людей, с испуганными лицами, с одной стороны брели назад к Можайску, с другой стороны – назад к Валуеву. Другие толпы, измученные и голодные, ведомые начальниками, шли вперед. Третьи стояли на местах и продолжали стрелять.
Над всем полем, прежде столь весело красивым, с его блестками штыков и дымами в утреннем солнце, стояла теперь мгла сырости и дыма и пахло странной кислотой селитры и крови. Собрались тучки, и стал накрапывать дождик на убитых, на раненых, на испуганных, и на изнуренных, и на сомневающихся людей. Как будто он говорил: «Довольно, довольно, люди. Перестаньте… Опомнитесь. Что вы делаете?»
Измученным, без пищи и без отдыха, людям той и другой стороны начинало одинаково приходить сомнение о том, следует ли им еще истреблять друг друга, и на всех лицах было заметно колебанье, и в каждой душе одинаково поднимался вопрос: «Зачем, для кого мне убивать и быть убитому? Убивайте, кого хотите, делайте, что хотите, а я не хочу больше!» Мысль эта к вечеру одинаково созрела в душе каждого. Всякую минуту могли все эти люди ужаснуться того, что они делали, бросить всо и побежать куда попало.
Но хотя уже к концу сражения люди чувствовали весь ужас своего поступка, хотя они и рады бы были перестать, какая то непонятная, таинственная сила еще продолжала руководить ими, и, запотелые, в порохе и крови, оставшиеся по одному на три, артиллеристы, хотя и спотыкаясь и задыхаясь от усталости, приносили заряды, заряжали, наводили, прикладывали фитили; и ядра так же быстро и жестоко перелетали с обеих сторон и расплюскивали человеческое тело, и продолжало совершаться то страшное дело, которое совершается не по воле людей, а по воле того, кто руководит людьми и мирами.
Тот, кто посмотрел бы на расстроенные зады русской армии, сказал бы, что французам стоит сделать еще одно маленькое усилие, и русская армия исчезнет; и тот, кто посмотрел бы на зады французов, сказал бы, что русским стоит сделать еще одно маленькое усилие, и французы погибнут. Но ни французы, ни русские не делали этого усилия, и пламя сражения медленно догорало.
Русские не делали этого усилия, потому что не они атаковали французов. В начале сражения они только стояли по дороге в Москву, загораживая ее, и точно так же они продолжали стоять при конце сражения, как они стояли при начале его. Но ежели бы даже цель русских состояла бы в том, чтобы сбить французов, они не могли сделать это последнее усилие, потому что все войска русских были разбиты, не было ни одной части войск, не пострадавшей в сражении, и русские, оставаясь на своих местах, потеряли половину своего войска.
Французам, с воспоминанием всех прежних пятнадцатилетних побед, с уверенностью в непобедимости Наполеона, с сознанием того, что они завладели частью поля сраженья, что они потеряли только одну четверть людей и что у них еще есть двадцатитысячная нетронутая гвардия, легко было сделать это усилие. Французам, атаковавшим русскую армию с целью сбить ее с позиции, должно было сделать это усилие, потому что до тех пор, пока русские, точно так же как и до сражения, загораживали дорогу в Москву, цель французов не была достигнута и все их усилия и потери пропали даром. Но французы не сделали этого усилия. Некоторые историки говорят, что Наполеону стоило дать свою нетронутую старую гвардию для того, чтобы сражение было выиграно. Говорить о том, что бы было, если бы Наполеон дал свою гвардию, все равно что говорить о том, что бы было, если б осенью сделалась весна. Этого не могло быть. Не Наполеон не дал своей гвардии, потому что он не захотел этого, но этого нельзя было сделать. Все генералы, офицеры, солдаты французской армии знали, что этого нельзя было сделать, потому что упадший дух войска не позволял этого.
Не один Наполеон испытывал то похожее на сновиденье чувство, что страшный размах руки падает бессильно, но все генералы, все участвовавшие и не участвовавшие солдаты французской армии, после всех опытов прежних сражений (где после вдесятеро меньших усилий неприятель бежал), испытывали одинаковое чувство ужаса перед тем врагом, который, потеряв половину войска, стоял так же грозно в конце, как и в начале сражения. Нравственная сила французской, атакующей армии была истощена. Не та победа, которая определяется подхваченными кусками материи на палках, называемых знаменами, и тем пространством, на котором стояли и стоят войска, – а победа нравственная, та, которая убеждает противника в нравственном превосходстве своего врага и в своем бессилии, была одержана русскими под Бородиным. Французское нашествие, как разъяренный зверь, получивший в своем разбеге смертельную рану, чувствовало свою погибель; но оно не могло остановиться, так же как и не могло не отклониться вдвое слабейшее русское войско. После данного толчка французское войско еще могло докатиться до Москвы; но там, без новых усилий со стороны русского войска, оно должно было погибнуть, истекая кровью от смертельной, нанесенной при Бородине, раны. Прямым следствием Бородинского сражения было беспричинное бегство Наполеона из Москвы, возвращение по старой Смоленской дороге, погибель пятисоттысячного нашествия и погибель наполеоновской Франции, на которую в первый раз под Бородиным была наложена рука сильнейшего духом противника.



Для человеческого ума непонятна абсолютная непрерывность движения. Человеку становятся понятны законы какого бы то ни было движения только тогда, когда он рассматривает произвольно взятые единицы этого движения. Но вместе с тем из этого то произвольного деления непрерывного движения на прерывные единицы проистекает большая часть человеческих заблуждений.
Известен так называемый софизм древних, состоящий в том, что Ахиллес никогда не догонит впереди идущую черепаху, несмотря на то, что Ахиллес идет в десять раз скорее черепахи: как только Ахиллес пройдет пространство, отделяющее его от черепахи, черепаха пройдет впереди его одну десятую этого пространства; Ахиллес пройдет эту десятую, черепаха пройдет одну сотую и т. д. до бесконечности. Задача эта представлялась древним неразрешимою. Бессмысленность решения (что Ахиллес никогда не догонит черепаху) вытекала из того только, что произвольно были допущены прерывные единицы движения, тогда как движение и Ахиллеса и черепахи совершалось непрерывно.
Принимая все более и более мелкие единицы движения, мы только приближаемся к решению вопроса, но никогда не достигаем его. Только допустив бесконечно малую величину и восходящую от нее прогрессию до одной десятой и взяв сумму этой геометрической прогрессии, мы достигаем решения вопроса. Новая отрасль математики, достигнув искусства обращаться с бесконечно малыми величинами, и в других более сложных вопросах движения дает теперь ответы на вопросы, казавшиеся неразрешимыми.
Эта новая, неизвестная древним, отрасль математики, при рассмотрении вопросов движения, допуская бесконечно малые величины, то есть такие, при которых восстановляется главное условие движения (абсолютная непрерывность), тем самым исправляет ту неизбежную ошибку, которую ум человеческий не может не делать, рассматривая вместо непрерывного движения отдельные единицы движения.
В отыскании законов исторического движения происходит совершенно то же.
Движение человечества, вытекая из бесчисленного количества людских произволов, совершается непрерывно.
Постижение законов этого движения есть цель истории. Но для того, чтобы постигнуть законы непрерывного движения суммы всех произволов людей, ум человеческий допускает произвольные, прерывные единицы. Первый прием истории состоит в том, чтобы, взяв произвольный ряд непрерывных событий, рассматривать его отдельно от других, тогда как нет и не может быть начала никакого события, а всегда одно событие непрерывно вытекает из другого. Второй прием состоит в том, чтобы рассматривать действие одного человека, царя, полководца, как сумму произволов людей, тогда как сумма произволов людских никогда не выражается в деятельности одного исторического лица.
Историческая наука в движении своем постоянно принимает все меньшие и меньшие единицы для рассмотрения и этим путем стремится приблизиться к истине. Но как ни мелки единицы, которые принимает история, мы чувствуем, что допущение единицы, отделенной от другой, допущение начала какого нибудь явления и допущение того, что произволы всех людей выражаются в действиях одного исторического лица, ложны сами в себе.
Всякий вывод истории, без малейшего усилия со стороны критики, распадается, как прах, ничего не оставляя за собой, только вследствие того, что критика избирает за предмет наблюдения большую или меньшую прерывную единицу; на что она всегда имеет право, так как взятая историческая единица всегда произвольна.
Только допустив бесконечно малую единицу для наблюдения – дифференциал истории, то есть однородные влечения людей, и достигнув искусства интегрировать (брать суммы этих бесконечно малых), мы можем надеяться на постигновение законов истории.
Первые пятнадцать лет XIX столетия в Европе представляют необыкновенное движение миллионов людей. Люди оставляют свои обычные занятия, стремятся с одной стороны Европы в другую, грабят, убивают один другого, торжествуют и отчаиваются, и весь ход жизни на несколько лет изменяется и представляет усиленное движение, которое сначала идет возрастая, потом ослабевая. Какая причина этого движения или по каким законам происходило оно? – спрашивает ум человеческий.
Историки, отвечая на этот вопрос, излагают нам деяния и речи нескольких десятков людей в одном из зданий города Парижа, называя эти деяния и речи словом революция; потом дают подробную биографию Наполеона и некоторых сочувственных и враждебных ему лиц, рассказывают о влиянии одних из этих лиц на другие и говорят: вот отчего произошло это движение, и вот законы его.
Но ум человеческий не только отказывается верить в это объяснение, но прямо говорит, что прием объяснения не верен, потому что при этом объяснении слабейшее явление принимается за причину сильнейшего. Сумма людских произволов сделала и революцию и Наполеона, и только сумма этих произволов терпела их и уничтожила.
«Но всякий раз, когда были завоевания, были завоеватели; всякий раз, когда делались перевороты в государстве, были великие люди», – говорит история. Действительно, всякий раз, когда являлись завоеватели, были и войны, отвечает ум человеческий, но это не доказывает, чтобы завоеватели были причинами войн и чтобы возможно было найти законы войны в личной деятельности одного человека. Всякий раз, когда я, глядя на свои часы, вижу, что стрелка подошла к десяти, я слышу, что в соседней церкви начинается благовест, но из того, что всякий раз, что стрелка приходит на десять часов тогда, как начинается благовест, я не имею права заключить, что положение стрелки есть причина движения колоколов.
Всякий раз, как я вижу движение паровоза, я слышу звук свиста, вижу открытие клапана и движение колес; но из этого я не имею права заключить, что свист и движение колес суть причины движения паровоза.
Крестьяне говорят, что поздней весной дует холодный ветер, потому что почка дуба развертывается, и действительно, всякую весну дует холодный ветер, когда развертывается дуб. Но хотя причина дующего при развертыванье дуба холодного ветра мне неизвестна, я не могу согласиться с крестьянами в том, что причина холодного ветра есть раэвертыванье почки дуба, потому только, что сила ветра находится вне влияний почки. Я вижу только совпадение тех условий, которые бывают во всяком жизненном явлении, и вижу, что, сколько бы и как бы подробно я ни наблюдал стрелку часов, клапан и колеса паровоза и почку дуба, я не узнаю причину благовеста, движения паровоза и весеннего ветра. Для этого я должен изменить совершенно свою точку наблюдения и изучать законы движения пара, колокола и ветра. То же должна сделать история. И попытки этого уже были сделаны.
Для изучения законов истории мы должны изменить совершенно предмет наблюдения, оставить в покое царей, министров и генералов, а изучать однородные, бесконечно малые элементы, которые руководят массами. Никто не может сказать, насколько дано человеку достигнуть этим путем понимания законов истории; но очевидно, что на этом пути только лежит возможность уловления исторических законов и что на этом пути не положено еще умом человеческим одной миллионной доли тех усилий, которые положены историками на описание деяний различных царей, полководцев и министров и на изложение своих соображений по случаю этих деяний.


Силы двунадесяти языков Европы ворвались в Россию. Русское войско и население отступают, избегая столкновения, до Смоленска и от Смоленска до Бородина. Французское войско с постоянно увеличивающеюся силой стремительности несется к Москве, к цели своего движения. Сила стремительности его, приближаясь к цели, увеличивается подобно увеличению быстроты падающего тела по мере приближения его к земле. Назади тысяча верст голодной, враждебной страны; впереди десятки верст, отделяющие от цели. Это чувствует всякий солдат наполеоновской армии, и нашествие надвигается само собой, по одной силе стремительности.
В русском войске по мере отступления все более и более разгорается дух озлобления против врага: отступая назад, оно сосредоточивается и нарастает. Под Бородиным происходит столкновение. Ни то, ни другое войско не распадаются, но русское войско непосредственно после столкновения отступает так же необходимо, как необходимо откатывается шар, столкнувшись с другим, с большей стремительностью несущимся на него шаром; и так же необходимо (хотя и потерявший всю свою силу в столкновении) стремительно разбежавшийся шар нашествия прокатывается еще некоторое пространство.
Русские отступают за сто двадцать верст – за Москву, французы доходят до Москвы и там останавливаются. В продолжение пяти недель после этого нет ни одного сражения. Французы не двигаются. Подобно смертельно раненному зверю, который, истекая кровью, зализывает свои раны, они пять недель остаются в Москве, ничего не предпринимая, и вдруг, без всякой новой причины, бегут назад: бросаются на Калужскую дорогу (и после победы, так как опять поле сражения осталось за ними под Малоярославцем), не вступая ни в одно серьезное сражение, бегут еще быстрее назад в Смоленск, за Смоленск, за Вильну, за Березину и далее.
В вечер 26 го августа и Кутузов, и вся русская армия были уверены, что Бородинское сражение выиграно. Кутузов так и писал государю. Кутузов приказал готовиться на новый бой, чтобы добить неприятеля не потому, чтобы он хотел кого нибудь обманывать, но потому, что он знал, что враг побежден, так же как знал это каждый из участников сражения.
Но в тот же вечер и на другой день стали, одно за другим, приходить известия о потерях неслыханных, о потере половины армии, и новое сражение оказалось физически невозможным.
Нельзя было давать сражения, когда еще не собраны были сведения, не убраны раненые, не пополнены снаряды, не сочтены убитые, не назначены новые начальники на места убитых, не наелись и не выспались люди.
А вместе с тем сейчас же после сражения, на другое утро, французское войско (по той стремительной силе движения, увеличенного теперь как бы в обратном отношении квадратов расстояний) уже надвигалось само собой на русское войско. Кутузов хотел атаковать на другой день, и вся армия хотела этого. Но для того чтобы атаковать, недостаточно желания сделать это; нужно, чтоб была возможность это сделать, а возможности этой не было. Нельзя было не отступить на один переход, потом точно так же нельзя было не отступить на другой и на третий переход, и наконец 1 го сентября, – когда армия подошла к Москве, – несмотря на всю силу поднявшегося чувства в рядах войск, сила вещей требовала того, чтобы войска эти шли за Москву. И войска отступили ещо на один, на последний переход и отдали Москву неприятелю.
Для тех людей, которые привыкли думать, что планы войн и сражений составляются полководцами таким же образом, как каждый из нас, сидя в своем кабинете над картой, делает соображения о том, как и как бы он распорядился в таком то и таком то сражении, представляются вопросы, почему Кутузов при отступлении не поступил так то и так то, почему он не занял позиции прежде Филей, почему он не отступил сразу на Калужскую дорогу, оставил Москву, и т. д. Люди, привыкшие так думать, забывают или не знают тех неизбежных условий, в которых всегда происходит деятельность всякого главнокомандующего. Деятельность полководца не имеет ни малейшего подобия с тою деятельностью, которую мы воображаем себе, сидя свободно в кабинете, разбирая какую нибудь кампанию на карте с известным количеством войска, с той и с другой стороны, и в известной местности, и начиная наши соображения с какого нибудь известного момента. Главнокомандующий никогда не бывает в тех условиях начала какого нибудь события, в которых мы всегда рассматриваем событие. Главнокомандующий всегда находится в средине движущегося ряда событий, и так, что никогда, ни в какую минуту, он не бывает в состоянии обдумать все значение совершающегося события. Событие незаметно, мгновение за мгновением, вырезается в свое значение, и в каждый момент этого последовательного, непрерывного вырезывания события главнокомандующий находится в центре сложнейшей игры, интриг, забот, зависимости, власти, проектов, советов, угроз, обманов, находится постоянно в необходимости отвечать на бесчисленное количество предлагаемых ему, всегда противоречащих один другому, вопросов.
Нам пресерьезно говорят ученые военные, что Кутузов еще гораздо прежде Филей должен был двинуть войска на Калужскую дорогу, что даже кто то предлагал таковой проект. Но перед главнокомандующим, особенно в трудную минуту, бывает не один проект, а всегда десятки одновременно. И каждый из этих проектов, основанных на стратегии и тактике, противоречит один другому. Дело главнокомандующего, казалось бы, состоит только в том, чтобы выбрать один из этих проектов. Но и этого он не может сделать. События и время не ждут. Ему предлагают, положим, 28 го числа перейти на Калужскую дорогу, но в это время прискакивает адъютант от Милорадовича и спрашивает, завязывать ли сейчас дело с французами или отступить. Ему надо сейчас, сию минуту, отдать приказанье. А приказанье отступить сбивает нас с поворота на Калужскую дорогу. И вслед за адъютантом интендант спрашивает, куда везти провиант, а начальник госпиталей – куда везти раненых; а курьер из Петербурга привозит письмо государя, не допускающее возможности оставить Москву, а соперник главнокомандующего, тот, кто подкапывается под него (такие всегда есть, и не один, а несколько), предлагает новый проект, диаметрально противоположный плану выхода на Калужскую дорогу; а силы самого главнокомандующего требуют сна и подкрепления; а обойденный наградой почтенный генерал приходит жаловаться, а жители умоляют о защите; посланный офицер для осмотра местности приезжает и доносит совершенно противоположное тому, что говорил перед ним посланный офицер; а лазутчик, пленный и делавший рекогносцировку генерал – все описывают различно положение неприятельской армии. Люди, привыкшие не понимать или забывать эти необходимые условия деятельности всякого главнокомандующего, представляют нам, например, положение войск в Филях и при этом предполагают, что главнокомандующий мог 1 го сентября совершенно свободно разрешать вопрос об оставлении или защите Москвы, тогда как при положении русской армии в пяти верстах от Москвы вопроса этого не могло быть. Когда же решился этот вопрос? И под Дриссой, и под Смоленском, и ощутительнее всего 24 го под Шевардиным, и 26 го под Бородиным, и в каждый день, и час, и минуту отступления от Бородина до Филей.


Русские войска, отступив от Бородина, стояли у Филей. Ермолов, ездивший для осмотра позиции, подъехал к фельдмаршалу.
– Драться на этой позиции нет возможности, – сказал он. Кутузов удивленно посмотрел на него и заставил его повторить сказанные слова. Когда он проговорил, Кутузов протянул ему руку.
– Дай ка руку, – сказал он, и, повернув ее так, чтобы ощупать его пульс, он сказал: – Ты нездоров, голубчик. Подумай, что ты говоришь.
Кутузов на Поклонной горе, в шести верстах от Дорогомиловской заставы, вышел из экипажа и сел на лавку на краю дороги. Огромная толпа генералов собралась вокруг него. Граф Растопчин, приехав из Москвы, присоединился к ним. Все это блестящее общество, разбившись на несколько кружков, говорило между собой о выгодах и невыгодах позиции, о положении войск, о предполагаемых планах, о состоянии Москвы, вообще о вопросах военных. Все чувствовали, что хотя и не были призваны на то, что хотя это не было так названо, но что это был военный совет. Разговоры все держались в области общих вопросов. Ежели кто и сообщал или узнавал личные новости, то про это говорилось шепотом, и тотчас переходили опять к общим вопросам: ни шуток, ни смеха, ни улыбок даже не было заметно между всеми этими людьми. Все, очевидно, с усилием, старались держаться на высота положения. И все группы, разговаривая между собой, старались держаться в близости главнокомандующего (лавка которого составляла центр в этих кружках) и говорили так, чтобы он мог их слышать. Главнокомандующий слушал и иногда переспрашивал то, что говорили вокруг него, но сам не вступал в разговор и не выражал никакого мнения. Большей частью, послушав разговор какого нибудь кружка, он с видом разочарования, – как будто совсем не о том они говорили, что он желал знать, – отворачивался. Одни говорили о выбранной позиции, критикуя не столько самую позицию, сколько умственные способности тех, которые ее выбрали; другие доказывали, что ошибка была сделана прежде, что надо было принять сраженье еще третьего дня; третьи говорили о битве при Саламанке, про которую рассказывал только что приехавший француз Кросар в испанском мундире. (Француз этот вместе с одним из немецких принцев, служивших в русской армии, разбирал осаду Сарагоссы, предвидя возможность так же защищать Москву.) В четвертом кружке граф Растопчин говорил о том, что он с московской дружиной готов погибнуть под стенами столицы, но что все таки он не может не сожалеть о той неизвестности, в которой он был оставлен, и что, ежели бы он это знал прежде, было бы другое… Пятые, выказывая глубину своих стратегических соображений, говорили о том направлении, которое должны будут принять войска. Шестые говорили совершенную бессмыслицу. Лицо Кутузова становилось все озабоченнее и печальнее. Из всех разговоров этих Кутузов видел одно: защищать Москву не было никакой физической возможности в полном значении этих слов, то есть до такой степени не было возможности, что ежели бы какой нибудь безумный главнокомандующий отдал приказ о даче сражения, то произошла бы путаница и сражения все таки бы не было; не было бы потому, что все высшие начальники не только признавали эту позицию невозможной, но в разговорах своих обсуждали только то, что произойдет после несомненного оставления этой позиции. Как же могли начальники вести свои войска на поле сражения, которое они считали невозможным? Низшие начальники, даже солдаты (которые тоже рассуждают), также признавали позицию невозможной и потому не могли идти драться с уверенностью поражения. Ежели Бенигсен настаивал на защите этой позиции и другие еще обсуждали ее, то вопрос этот уже не имел значения сам по себе, а имел значение только как предлог для спора и интриги. Это понимал Кутузов.
Бенигсен, выбрав позицию, горячо выставляя свой русский патриотизм (которого не мог, не морщась, выслушивать Кутузов), настаивал на защите Москвы. Кутузов ясно как день видел цель Бенигсена: в случае неудачи защиты – свалить вину на Кутузова, доведшего войска без сражения до Воробьевых гор, а в случае успеха – себе приписать его; в случае же отказа – очистить себя в преступлении оставления Москвы. Но этот вопрос интриги не занимал теперь старого человека. Один страшный вопрос занимал его. И на вопрос этот он ни от кого не слышал ответа. Вопрос состоял для него теперь только в том: «Неужели это я допустил до Москвы Наполеона, и когда же я это сделал? Когда это решилось? Неужели вчера, когда я послал к Платову приказ отступить, или третьего дня вечером, когда я задремал и приказал Бенигсену распорядиться? Или еще прежде?.. но когда, когда же решилось это страшное дело? Москва должна быть оставлена. Войска должны отступить, и надо отдать это приказание». Отдать это страшное приказание казалось ему одно и то же, что отказаться от командования армией. А мало того, что он любил власть, привык к ней (почет, отдаваемый князю Прозоровскому, при котором он состоял в Турции, дразнил его), он был убежден, что ему было предназначено спасение России и что потому только, против воли государя и по воле народа, он был избрал главнокомандующим. Он был убежден, что он один и этих трудных условиях мог держаться во главе армии, что он один во всем мире был в состоянии без ужаса знать своим противником непобедимого Наполеона; и он ужасался мысли о том приказании, которое он должен был отдать. Но надо было решить что нибудь, надо было прекратить эти разговоры вокруг него, которые начинали принимать слишком свободный характер.
Он подозвал к себе старших генералов.
– Ma tete fut elle bonne ou mauvaise, n'a qu'a s'aider d'elle meme, [Хороша ли, плоха ли моя голова, а положиться больше не на кого,] – сказал он, вставая с лавки, и поехал в Фили, где стояли его экипажи.


В просторной, лучшей избе мужика Андрея Савостьянова в два часа собрался совет. Мужики, бабы и дети мужицкой большой семьи теснились в черной избе через сени. Одна только внучка Андрея, Малаша, шестилетняя девочка, которой светлейший, приласкав ее, дал за чаем кусок сахара, оставалась на печи в большой избе. Малаша робко и радостно смотрела с печи на лица, мундиры и кресты генералов, одного за другим входивших в избу и рассаживавшихся в красном углу, на широких лавках под образами. Сам дедушка, как внутренне называла Maлаша Кутузова, сидел от них особо, в темном углу за печкой. Он сидел, глубоко опустившись в складное кресло, и беспрестанно покряхтывал и расправлял воротник сюртука, который, хотя и расстегнутый, все как будто жал его шею. Входившие один за другим подходили к фельдмаршалу; некоторым он пожимал руку, некоторым кивал головой. Адъютант Кайсаров хотел было отдернуть занавеску в окне против Кутузова, но Кутузов сердито замахал ему рукой, и Кайсаров понял, что светлейший не хочет, чтобы видели его лицо.
Вокруг мужицкого елового стола, на котором лежали карты, планы, карандаши, бумаги, собралось так много народа, что денщики принесли еще лавку и поставили у стола. На лавку эту сели пришедшие: Ермолов, Кайсаров и Толь. Под самыми образами, на первом месте, сидел с Георгием на шее, с бледным болезненным лицом и с своим высоким лбом, сливающимся с голой головой, Барклай де Толли. Второй уже день он мучился лихорадкой, и в это самое время его знобило и ломало. Рядом с ним сидел Уваров и негромким голосом (как и все говорили) что то, быстро делая жесты, сообщал Барклаю. Маленький, кругленький Дохтуров, приподняв брови и сложив руки на животе, внимательно прислушивался. С другой стороны сидел, облокотивши на руку свою широкую, с смелыми чертами и блестящими глазами голову, граф Остерман Толстой и казался погруженным в свои мысли. Раевский с выражением нетерпения, привычным жестом наперед курчавя свои черные волосы на висках, поглядывал то на Кутузова, то на входную дверь. Твердое, красивое и доброе лицо Коновницына светилось нежной и хитрой улыбкой. Он встретил взгляд Малаши и глазами делал ей знаки, которые заставляли девочку улыбаться.