Данный проект позволяет создавать говорящих роботов, которые могут видеть своих собеседников и реагировать на их эмоции и параметры. Для создания механизма поведения робота используется продукционная база знаний прямого вывода.
В основе системы лежит универсальное приложение Windows 10 (UWP), которое может работать на ПК под управлением Windows 10 или на Raspberry Pi с Windows 10 IoT. В приложении осуществляется доступ к камере и распознавание наличия лица. Когда лицо найдено, оно отправляется на анализ в Face API и Emotion API, и полученные данные подаются на вход экспертной системе.
Экспертная система реализована в отдельном проекте RuleEngine
. База знаний, задающая поведение робота, описывается на специальном языке представления знаний, основанном на продукционном представлении, с XML-синтаксисом.
UWP-приложение осуществляет распознавание попадания лица в кадр и выпадения из него. При этом осуществляется задержка в 1-3 секунды, чтобы убедиться, что лицо действительно стабильно появилось в кадре или исчезло, и это не вызвано временным изменением освещения. При попадании лица в кадр на 3 секунды, происходит его распознавание, и генерируется событие FaceIn
, т.е. в базу знаний добавляются следующие переменные:
Event = FaceIn
FaceCount
- количество распознанных лицGender
- пол, который может бытьM
,F
,MF
(группа лиц с преобладанием мужчин) илиFM
(группа лиц с преобладанием женщин)Age
- возраст (или средний возраст всех лиц в кадре), округленном до целого
При выпадении лица из кадра все переменные очищаются, и генерируется событие FaceOut
(т.е. добавляется переменная Event=FaceOut
).
При нажатии клавиш 0..9, инициируется событие Event=Key_x
. После обработки события рекомендуется очистить переменную Event
, поскольку автоматически это не происходит, что может быть интерпретировано как нажатие этой же клавиши при переходе в другое состояние. Типичный шаблон обработчика клавиши такой:
<Rule>
<If><Compare Var="Event" Value="Key_5"/><Compare Var="State" Value="St0"/></If>
<Then><Clear Var="Event"/><Say Text="Something"/><Assign Var="State" Value="St1"/></Then>
</Rule>
Когда перед экраном нет лица, периодически генерируются события Event=Ping
. Их можно использовать, чтобы робот сам по себе что-то делал. Периодичность событий задаётся в файле Config.cs
.
При работе приложения можно также нажимать следующие системные клавиши:
- S - печатать значение переменных в отладочной консоли
Программа робота состоит из правил, каждое правило имеет набор условий (<If>...</If>
), при выполнении которых выполняется набор действий Actions
, перечисленных в <Then>...</Then>
. Все действия выполняются по-очереди.
Возможные действия правил:
- присвоение значений переменным (
<Assign Var="Name" Value="Value">
) - очистка значения переменной (
<Clear Var="Name">
) - проговаривание фразы (
<Say Text="..."/>
) - случайный выбор одного из нескольких действий (
<OneOf>...</OneOf>
) - внешние события-расширения, описанные в оболочке (
<External>
)
Условия могут быть следующего вида:
- Сравнение переменной со значением
<Compare Var="Name" Type="xx" Value="..."/>
, где Type - вид сравнения (eq
- равно,ne
- не равно,gt
- больше,lt
- меньше). Если тип опущен, то подразумеваетсяeq
- Проверка попадания переменной в диапазон
<Interval Var="Name" Min="..." Max="..."/>
- Составные условия:
<And>...</And>
и<Or>..</Or>
. Если в теге<If>
перечислено несколько условий, то подразумевается<And>
Все правила выполняются в порядке приоритетов (Priority
), затем в порядке следования - т.е. первым выполняется первое правило с минимальным приоритетом, все условия которого истины. При этом правило помечается как выполнившееся, и в следующий раз выполняться уже не будет.
Возможно также объединять правила в RuleSet-ы. При этом:
- Если первое выбранное правило входит в RuleSet, то будет выполнено случайным образом произвольное из истиных правил в данном RuleSet-е
- После выполнение правила, входящего в RuleSet, весь RuleSet помечается как выполненный
База знаний начинается тегом <RuleEngine>
, и состоит из секции правил <Rules>...</Rules>
и начального состояния - множества предустановленных переменных, описываемого в секции <State>
.
При присвоении значений переменным и при сравнении можно использовать специальные шаблоны, включающие в себя символы {
и }
. Основные виды шаблонов:
- Подстановка значения переменной
${Var}
. Подстановка всегда выполняется первой, чтобы после подстановки могли правильно примениться другие шаблоны - Случайный выбор одной из строк
{A|B}
. Это удобно использовать для обогащения речи робота, например
<Say Text="Oh, you are such a {nice|cool|cute|brave} human!"/>
- Переключатель
{X:a=A|b=B|C}
. ВыражениеX
сравнивается по-очереди с каждым из вариантов: еслиX=a
, то возвращаетсяA
, еслиX=b
-B
, в противном случае возвращаетсяC
. Например:
<Say Text="Oh, you are such a {nice|cool|cute|brave} {{$Gender}:M=man|F=woman}!"/>
В данной реализации поддерживаются следующие внешние операции:
<External Command="Recapture" Param="...">
- произвести повторный захват изображения с камеры. Параметры могут быть следующими:EndSpeech
- сразу после окончания фразыAfter:xx
- после заданного количества секунд (удобно использовать для захвата изображения где-то в середине фразы)- параметр отсутствует - немедленный захват
<External Command="LED" Param="XX:xxxxx">
- отобразить изображение на LED-панели.XX
- имя панели (в текущем варианте используетсяLE
иRE
для левого и правого глаза иM
для рта)