Snippets
Furhat Robotics WIP: Example flow for a passive state with wake-up words and an active state with dialog
Created by
Ludvig Linse
last modified
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | <!-- idle state, waiting for wake-up words -->
<state id="Idle" extends="PassiveDialog">
<onentry>
<agent:listen />
<reentry />
</onentry>
<onevent name="sense.user.speak**" cond="event?:sem:wakeup">
<goto state="VerifyWakeup" p:wakeupEvent="event"/>
</onevent>
</state>
<!-- state to verify wakeup, if "furhat" is said it directly goes to Attending state -->
<state id="VerifyWakeup" extends="Dialog">
<param name="wakeupEvent" type="iristk.system.Event"/>
<onentry>
<agent:attend target="wakeupEvent:user"/>
<if cond="asString(wakeupEvent:text).contains('furhat')">
<exec>
wakeupEvent.getRecord("sem").remove("wakeup")
</exec>
<if cond="asRecord(wakeupEvent:sem).empty()">
<exec>wakeupEvent = null</exec>
<agent:say>Hey</agent:say>
</if>
<goto state="Attending" p:wakeupEvent="wakeupEvent"/>
<else/>
<agent:say>Are you talking to me?</agent:say>
<agent:listen/>
</if>
</onentry>
<onevent name="sense.user.speak**" cond="event?:sem:yes">
<agent:say>Cool</agent:say>
<goto state="Attending" />
</onevent>
<onevent name="sense.user.speak**" cond="event?:sem:no or event?:sem:exit">
<agent:say>Okay, sorry</agent:say>
<goto state="Idle" />
</onevent>
</state>
<!-- State when Furhat is actively listening without wake-up word -->
<state id="Attending" extends="PassiveDialog">
<param name="wakeupEvent" type="iristk.system.Event"/>
<onentry>
<if cond="wakeupEvent != null and wakeupEvent?:sem">
<raise event="sense.user.speak" copy="wakeupEvent"/>
<else/>
<agent:listen/>
</if>
</onentry>
<!-- answering hard-coded questions -->
<onevent name="sense.user.speak" cond="event?:sem:question">
<var name="question" type="String" value="asString(event:sem:question)"/>
<!-- Question and answer pairs, in this example hard-coded. The semantics for the questions needs to be added in grammar file -->
<if cond="question.equals('whatsYourName')">
<agent:say>My name is Fur hat</agent:say>
<!-- We should never end up here. If we do, we have added a semantic tag in grammar that we haven't caught -->
<agent:say>Sorry, I can't answer that.</agent:say>
</if>
<agent:listen />
</onevent>
</state>
<!-- master state used when in a "passive" dialog, i.e waiting for commands -->
<state id="PassiveDialog" extends="Master">
<onevent name="sense.user.speak**">
<agent:listen />
</onevent>
<onevent name="sense.user.silence">
<agent:listen />
</onevent>
<onevent name="sense.user.leave" cond="system.isAttending(event)">
<if cond="system.hasUsers()">
<agent:attendRandom />
</if>
</onevent>
</state>
<!-- master state used when in an "active" dialog, i.e expecting answers from users -->
<state id="Dialog" extends="Master">
<!-- Start smiling when someone starts speaking -->
<onevent name="sense.user.speech.start" cond="system.isAttending(event) and eq(event:speakers, 1)">
<agent:gesture name="'smile'" />
</onevent>
<!-- Catch speak events that we our grammar can't handle -->
<onevent name="sense.user.speak" cond="!eq(event:text, 'NO_MATCH')">
<agent:say>Sorry, I don't understand that</agent:say>
<agent:listen />
</onevent>
<onevent name="sense.user.speak">
<agent:say>Sorry, what was that?</agent:say>
<agent:listen />
</onevent>
<onevent name="sense.user.silence">
<agent:say>Sorry, I didn't hear anything</agent:say>
<agent:listen />
</onevent>
<onevent name="sense.user.speak.multi">
<send event="sense.user.speak" copy="event"/>
</onevent>
<onevent name="sense.user.speak.side">
<send event="sense.user.speak" copy="event"/>
</onevent>
</state>
<!-- master state used by both passive and active dialog master states -->
<state id="Master">
<onevent name="sense.user.enter">
<agent:attend target="event:user" />
</onevent>
<onevent name="sense.user.leave" cond="system.isAttending(event)">
<if cond="system.hasUsers()">
<agent:attendRandom />
</if>
</onevent>
</state>
|
Comments (0)
You can clone a snippet to your computer for local editing. Learn more.