3.9.4 Селекторы и последовательности

Как мы узнали ранее, деревья поведения используют два основных типа сложного поведения: селекторы и последовательности. Селектор пробует каждую из своих подзадач по очереди, пока одна из них не завершится успешно, в то время как последовательность выполняет каждое из своих дочерних поведений вплоть до ошибки одной из них. Таким образом, селекторы и последовательности существенно дополняют друг друга. Удивительно, но эти два типа отношений родитель-ребенок вместе с несколькими вариациями – это почти все, что нам нужно для создания очень сложных моделей поведения роботов. Чтобы понять, как это происходит, давайте рассмотрим их более подробно.

Селектор начинается с выполнения первой задачи среди своих дочерних узлов, и если задача выполняется успешно, то состояние селектора также устанавливается на «УСПЕХ», а все остальные дочерние задачи игнорируются. Однако если первая подзадача завершается неудачно, то состояние селектора также устанавливается в значение «НЕУДАЧА» и выполняется следующая подзадача в его списке. Таким образом, селектор выбирает одно поведение из своей коллекции дочерних поведений, всегда перемещаясь в порядке списка, то есть, слева направо, если он ссылается на древовидную диаграмму, или сверху вниз, если он использует маркированный список. Поэтому мы можем думать о селекторе как о простом виде "решателя проблем". Начиная со своего самого приоритетного под-поведения, он пробует каждое "решение" до тех пор, пока оно не будет успешным или пока у него не закончатся поведения, в этом случае он передает окончательный результат «НЕУДАЧА» своему родителю, который затем остается разбираться с ситуацией. (Об этом чуть позже.)

Поведение «СТОЯТЬ СПОКОЙНО» в нашем примере является относительно простым селектором. Сначала мы запускаем задачу «ПРОВЕРИТЬ БАТАРЕЮ», если она возвращает «УСПЕХ» (батарея в порядке), мы передаем этот результат родительской задаче, которая затем также имеет статус «УСПЕХ», и мы закончили. Однако, если задача «ПРОВЕРИТЬ БАТАРЕЮ» возвращает сбой (низкий уровень заряда батареи), мы переходим к задаче «ЗАРЯЖАТЬСЯ», которая пытается устранить проблему, перейдя к док-станции и зарядив робота. Можно также добавить поведение «УВЕДОМЛЕНИЯ», чтобы в случае неудачи задачи «ЗАРЯЖАТЬСЯ», робот мог вызвать помощь с помощью преобразования текста в речь или предупредить человека по электронной почте.

Последовательность также начинается с первого поведения в списке подзадач, но на этот раз, если задача выполнена успешно, выполняется следующая подзадача в списке. Процесс продолжается до тех пор, пока либо подзадачи завершатся неудачей, либо у нас закончатся подзадачи. Если вся последовательность завершена, то родительской задаче передается статус успешного выполнения. Однако, если последовательность прерывается из-за сбоя подзадачи, то «ОШИБКА» возвращается вверх по дереву.

Обратите внимание, что «ПОВЕДЕНИЕ» верхнего уровня для нашего патрульного бота должно быть последовательным: если подзадача «СТОЯТЬ СПОКОЙНО» терпит неудачу (что происходит, когда задачи «ПРОВЕРИТЬ БАТАРЕЮ» терпят неудачу), то последовательность дает сбой, и мы не переходим к задаче патрулирования.

На первый взгляд кажется, что мы будем использовать последовательность для задачи «ПАТРУЛИРОВАТЬ», так как мы хотим, чтобы робот перемещался из одной точки пути к другой. Однако, что произойдет, если робот по какой-то причине не сможет добраться до одной из путевых точек? Возможно, это место в настоящее время недоступно из-за какого-то препятствия. Последовательность не будет работать в этот момент, так как одна из ее подзадач потерпела неудачу. Это часто является желаемым результатом. Например, если мы смешиваем ингредиенты для торта и на полпути обнаруживаем, что у нас закончились яйца, нам, вероятно, следует прекратить смешивать, пока мы не сделаем некоторые покупки. Но для патрульного бота мы могли бы предпочесть, чтобы робот продолжил движение к следующей путевой точке, а не прерывал весь патруль. С небольшой модификацией последовательности сложного поведения, мы можем произвести желаемое поведение, о чем узнаем далее.

Last updated