Описание поведения на языке BML

Язык BML (Behavior Markup Language) позволяет описывать поведение для выполнения на роботе. Исходно язык BML описан в публикациях:

Мы основываемся на международном стандарте BML, но при этом используем упрощённый вариант языка, достаточный для управления роботом Ф-2.

Язык BML создан на базе XML. BML очень похож на привычный язык описания страниц интернета – HTML, что упрощает его изучение. Отдельный пакет на языке BML описывает фрагмент поведения для робота. Пакет ограничивается тегами bml, внутри пакета описывается движение робота – так называемая лексема (lexeme). Например, робот может всем телом выполнить жест appeal3 и при этом сказать Привет. Для этого в составе пакета BML нужны два тега – тег figure (исполнение всем телом робота некоторой лексемы-жеста) и тег speech:

<scenario id="greeting">
  <bml>
    <figure lexeme="appeal3"/>
    <speech text="Привет"/>
  </bml>
</scenario>

В архитектуре робота каждый фрагмент BML должен быть порождён некоторым сценарием. То есть обязательно должно существовать некоторое внутреннее состояние (сценарий), которое породило поведение. В качестве такого сценария может выступать эмоция, коммуникативная цель или физиологическое действие робота, например, “дыхание”. Поэтому при запуске на роботе каждый пакет BML нужно заключать в некоторый сценарий (тег scenario). В редакторе BML названия сценариев условны (можно давать любые названия), то если робот управляется когнитивным компонентом, то эти сценарии будут соответствовать внутренним состояниям робота.

Амплитуда жеста

С помощью параметра amount можно регулировать амплитуду жеста – делать жест менее размашистым. Исходно этот параметр равен единице, и жест выполняется так, как он выглядит в словаре. Чтобы изменить амплитуду, для параметра amount нужно указывать значение в интервале от 0 до 1. В следующем примере жест appeal3 будет выполняться с половинной (0.5) амплитудой:

<scenario id="half_greeting">
  <bml>
    <figure lexeme="appeal3" amount="0.5"/>
  </bml>
</scenario>

– обратите внимание: по правилам XML дробная часть отделяется точкой, а не запятой. Ноль можно не указывать, например: amount=".6"

Комбинация движений в пакете BML

Внутри одного пакта BML могут объединяться движения разными частями тела. Это могут быть движения головой, глазами, телом и т. д. Конкретный тег (head, pupils, body) описывает часть тела, которая будет выполнять жест, а параметр lexeme указывает жест, из которого будет взято движение для этой части тела. Здесь робот головой выполняет жест eyes_up_left3 (смотрит влево), а телом выполняет жест breath23 – имитирует дыхание:

<scenario id="thoughtful">
  <bml>
    <head lexeme="eyes_up_left3"/>
    <body lexeme="breath23"/>
  </bml>
</scenario>

Жесты для пакетов BML можно брать из Общего словаря

Мы используем термин “жест” в очень широком значении. Мы считаем, что “жест” – это некоторое движение, элемент поведения, которое входит в словарь и сохранено в качестве отдельного элемента в базу жестов. То есть движения глаз и элементы мимики тоже считаются “жестами” или “лексемами”, следуя терминологии разработчиков BML.

Отдельный жест в базе жестов описывает движения определённых исполнительных органов. Например, жест eyes_up_left3 включает движение глазами и шеей, но никак не использует руки. А жест appeal8 включает действия почти всеми частями тела робота. Тег figure позволяет взять из жеста движения всеми частями тела (которые описаны в жесте) и выполнить эти движения на роботе:

<scenario id="interested">
  <bml>
    <figure lexeme="eyes_up_left3"/>
  </bml>
</scenario>

При использовании тега figure жест монопольно захватит все части тела робота. Жест будет выполняться на всех частях тела, которые он включает, а другие части тела останутся неподвижными. То есть тег figure несовместим во времени с другими тегами. От жеста можно взять только часть движений, например, только движение левой рукой. В этом случае нужно использовать более конкретный тег hand_l – тег для левой руки. Внутри одного пакета BML можно скомбинировать несколько движений из разных жестов. Если эти движения занимают разные части тела и не конфликтуют, то они будут выполнены одновременно. В следующем примере движение головой из жеста eyes_up_left3 выполнится одновременно с движением левой рукой из жеста appeal3:

<scenario id="puzzled">
  <bml>
    <head lexeme="eyes_up_left3"/>
    <hand_l lexeme="appeal3"/>
  </bml>
</scenario>

В этом случае робот выполняет жест eyes_up_left3 головой и глазами, а из жеста appeal3 возьмёт только движение левой рукой

Речь

Робот может произносить высказывания с помощью тега <speech text="Привет"/>. Речь исполняется одновременно с другими движениями внутри одного пакета BML. Речь накладывается на тег figure и заменяет мимику рта на речевые движения губ.

<scenario id="provoking">
  <bml>
    <head lexeme="eyes_up_left3"/>
    <hand_l lexeme="appeal3"/>
    <speech text="Привет"/>
  </bml>
</scenario>

Теги BML объединяются в иерархию, например, тег hands включает теги hand_l и hand_r, а тег figure включает в себя вообще все теги тела робота, кроме речи и взгляда. Теги из разных ветвей иерархии совместимы и будут выполняться одновременно.

Иерархия тегов BML выглядит следующим образом:

gaze (использует pupils, neck – если тег neck свободен)

speech (перезаписывает mouth)

figure

head

neck (ранее head_rotation)

face

pupils (дополнителен с gaze)

brows

mouth (дополнителен с speech)

eyes

lids

body

hands

hand_l

hand_r

(Тег speech может накладываться на другие жесты, заменяя движения рта, которые были в них описаны. Но speech не может заменять тег mouth: если mouth и speech появляются в одном пакете BML, они будут исполнены последовательно)

При выполнении тег займёт все исполнительные органы, которые от него зависят. Поэтому более общий тег (например, figure), займёт все исполнительные органы робота и для конкретного тега (например, hands) не останется места. В этом случае второй тег будет выполнен после первого: когда первый тег закончится и освободит исполнительные органы робота.

Здесь движения выполняются параллельно (объединяются):

<scenario id="provoking">
  <bml>
    <head lexeme="eyes_up_left3"/>
    <hand_l lexeme="appeal3"/>
  </bml>
</scenario>

Но здесь движения выполняются последовательно, поскольку первый жест вводится тегом figure и занимает всю “фигуру” (тело) робота.

<scenario id="provoking">
  <bml>
    <figure lexeme="eyes_up_left3"/>
    <hand_l lexeme="appeal3"/>
  </bml>
</scenario>

Синхронизация движений в пакете BML

Если между тегами в пакете BML нет конфликтов, то эти теги начнутся одновременно. При планировании поведения может потребоваться иное соотношение тегов. Иногда нужно, чтобы робот кивнул одновременно с махом рукой, то есть пик движения кивок должен совпадать с пиком движения мах рукой. Задать такие соответствия можно через синхронизацию тегов по контрольным точкам. У каждого жеста есть контрольные точки start и end, также у жеста может быть точка stroke (пик жеста). Узнать, какие контрольные точки присутствуют у конкретного жеста, можно в базе жестов. В следующем примере пик кивка (nod3-blink) будет приходиться на пик маха рукой (appeal7):

<scenario id="provoking">
  <bml>
    <head id="1" lexeme="nod3-blink"/>
    <hands lexeme="appeal7" stroke="1:stroke"/>
  </bml>
</scenario>

В этом примере тег head обозначен идентификатором “1” (id="1"). Кроме того, на теге hands указано, что его пик (stroke) совпадает с пиком тега “1” (stroke="1:stroke"). В результате теги head и hands будут совмещены по своим пикам.

А в этом примере кивок будет следовать за движением руки:

<scenario id="provoking">
  <bml>
    <head id="1" lexeme="nod3-blink"/>
    <hands lexeme="appeal7" end="1:start"/>
  </bml>
</scenario>

– здесь на теге hands указано, что конец (end) этого тега должен совпадать с началом тега “1” (end="1:start"). То есть начало тега “1” (head) будет подвинуто и синхронизировано с концом тега hands: тег head начнётся сразу после тега hands.

Высказывания тоже обладают ключевыми точками start, end и stroke. Точка stroke ставится в середину высказывания, поскольку пока у нас нет информации о более точном месте фразового ударения. Это позволяет синхронизировать действия с высказываниями внутри одного пакета BML:

<scenario id="provoking">
  <bml>
    <head lexeme="nod1" stroke="1:stroke"/>
    <mouth lexeme="smile-op1" start="1:end"/>
    <hands lexeme="appeal7" end="1:start"/>
    <speech id="1" text="Не верю" end="1:start"/>
  </bml>
</scenario>

– при выполнении этого BML робот сначала сложит руки, потом произнесёт высказывания (кивнув в середине), а потом улыбнётся.

Внутри пакета BML синхронизация тегов должна быть устроена древовидно: нельзя, чтобы два тега ссылались друг на друга или чтобы у двух тегов было по две точки синхронизации.

Сценарии и объединение пакетов BML

Один пакет BML представляет собой некоторую единицу поведения. Чтобы построить продолжительное поведение, нужно объединить несколько пакетов BML в сценарий. Тогда пакеты будут выполнены последовательно:

<scenario id="lamenting">
  <bml>
    <figure lexeme="nod4"/>
    <speech text="Нет"/>
  </bml>
  <bml>
    <figure lexeme="appeal3"/>
    <speech text="Я не верю"/>
  </bml>
  <bml>
    <figure lexeme="referent_right_long1"/>
    <speech text="Пусть все уйдут!"/>
  </bml>
</scenario>

– такой подход позволяет построить поведение, где жест выполняется одновременно с соответствующим высказыванием: жесты и высказывания упакованы в отдельные пакеты BML и не разъезжаются во времени. Такой сценарий отражает длинный монолог, который должен быть воспроизведён от начала до конца.

Вместе с тем, поведение человека может определяться сразу несколькими внутренними состояниями (сценариями): человек может кивать собеседнику, смотреть вбок на некоторый объект, теребить пальцы – все эти элементы поведения могут быть подсказаны разными внутренними состояниями. Объединение этих элементов на роботе позволяет создать сложное поведение. Чтобы воспроизвести такое поведение, нужно создать несколько сценариев, у которых пакеты BML будут совместимы по своим тегам – то есть будут затрагивать различные части тела робота. Два сценария могут выполняться одновременно, если их пакеты BML совместимы по тегам. Например, в следующем примере первый пакет BML задаёт движение головой, а второй – движение рукой. Поскольку пакеты BML принадлежат разным сценариям, они будут выполнены одновременно:

<behavior>
  <scenario id="head_reaction">
    <bml>
      <head lexeme="nod4"/>
    </bml>
  </scenario>
  <scenario id="hands_reaction">
    <bml>
      <hands lexeme="appeal3"/>
    </bml>
  </scenario>
</behavior>

Чтобы объединить в редакторе несколько сценариев, используется общий тег behavior

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



Подробнее про API программного обеспечения робота