3.9.2 Основные свойства деревьев поведения
Ключевые особенности деревьев поведения можно резюмировать следующим образом:
• Узлы представляют собой задачи и условия, а не состояния. Термины "задача" и "поведение" будут использоваться взаимозаменяемо. Как мы увидим позже, проверка состояния может рассматриваться как просто еще один вид задачи.
• Задача или поведение обычно представляют собой фрагмент кода, который выполняется в течение одного или нескольких циклов и приводит к УСПЕХУ или НЕУДАЧЕ. Если для выполнения задачи требуется более одного цикла, она будет иметь статус ЗАПУЩЕННОЙ, прежде чем вернуть свой результат. Текущее состояние задачи всегда передается ее родительской задаче в дереве.
• Задачи или модели поведения также могут представлять собой составные модели поведения, статус которых зависит от двух или более дочерних моделей поведения. Два наиболее часто используемых составных поведения - селекторы и последовательности.
◦ Селектор пытается выполнить свое первое дочернее поведение, и если ему это удается, то селектор также преуспевает. В противном случае селектор пытается выполнить следующее дочернее поведение, и так далее. Если все дочерние модели поведения не работают, селектор также не работает. Таким образом, селектор подобен решателю проблем: сначала попробует одно решение, а если это не удается, попробует следующее решение и так далее.
◦ Последовательность пытается выполнить все свои дочерние задачи одну за другой. Если какая-либо дочерняя задача терпит неудачу, то последовательность терпит неудачу. Если последовательность выполняется без сбоев вплоть до последнего дочернего поведения, то последовательность завершается успешно.
• Если задача содержит более одной подзадачи, то приоритетность подзадач определяется в соответствии с порядком их списков, т. е. слева направо на стандартной древовидной диаграмме или сверху вниз при использовании маркированного списка. Это свойство работает как своего рода встроенная архитектура подчинения (Subsumption architecture) без необходимости дополнительного кодирования.
• Связи между поведением всегда являются отношениями «родитель-ребенок» и никогда «брат-сестра». Это непосредственно вытекает из структуры дерева и позволяет нам переместить узел (или даже целое поддерево) из одной части дерева и прикрепить его где-то еще, не изменяя никаких других связей. Такие изменения могут быть сделаны даже во время выполнения. Этот вид модульности является одним из наиболее ценных признаков деревьев поведения.
• Выполнение дерева поведения всегда начинается с корневого узла и продолжается в глубинном порядке, начиная с самой левой ветви. При запуске данного узла результат (УСПЕШНЫЙ, НЕУДАЧНЫЙ или ЗАПУЩЕННЫЙ) передается его родителю. Только конечные узлы приводят непосредственно к созданию поведения или проверке условия. Внутренние узлы используются для направления потока обработки к своим дочерним узлам с помощью селекторов и последовательностей. Важным свойством деревьев поведения является то, что выполнение начинается снова в корне дерева на каждом «тике» часов. Это гарантирует, что любое изменение статуса поведения с более высоким приоритетом приведет к соответствующему изменению потока выполнения, даже если другие узлы уже запущены.
• Поведения могут быть дополнены декораторами, которые изменяют результаты поведения. Например, мы можем захотеть выполнить последовательность подзадач, но игнорировать сбои, чтобы последовательность продолжалась до конца, даже если отдельные подзадачи не увенчаются успехом. Для этого мы могли бы использовать декоратор «игнорировать неудачу», который превращает результат неудачи в успех для задачи, которую он декорирует. Мы увидим пример этого в следующем разделе, где вернемся к сценарию патрульного бота.
• Многие деревья поведения используют глобальную «черную доску» (black board), которая может хранить данные об окружающей среде, а также результаты более ранних моделей поведения. Отдельные узлы могут читать и записывать на «черную доску».
Для хорошей серии диаграмм этого процесса см. иллюстрацию в блоге Бьорна Кнафлы. (Bjoern Knafla)
Last updated
Was this helpful?