Snippets

Furhat Robotics Example questions and answer flow

Created by Ludvig Linse last modified
<?xml version="1.0" encoding="utf-8"?>
<flow name="QuestionsAndAnswersFlow" package="iristk.app.questionsAndAnswers" initial="Passive"
	xmlns:this="iristk.app.questionsAndAnswers.QuestionsAndAnswersFlow" xmlns="iristk.flow"
	xmlns:p="iristk.flow.param" xmlns:agent="iristk.situated.SystemAgentFlow"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="iristk.flow flow.xsd iristk.situated.SystemAgentFlow SystemAgentFlow.xsd">

<!-- 

NOTE: ABOVE <name>, <package> and <xmlns:this> tags needs to be named according to your skill name. The easiest thing is to copy paste the below into your existing flow

-->

	<param name="agent" type="iristk.situated.SystemAgentFlow" />
	<var name="system" type="iristk.situated.SystemAgent" value="agent.getSystemAgent()" />

	<!-- Variables to make sure we don't get stuck in a loop if recognizer or 
		microphones don't work properly and we either don't get a match to our grammar 
		(unmatched), get no text back from the recognizer (undefined) or no sound 
		is picked up (silence). -->
	<var name="attemptsUnmatched" type="Integer" value="0" />
	<var name="attemptsUndefined" type="Integer" value="0" />
	<var name="attemptsSilence" type="Integer" value="0" />


	<state id="Passive">

		<onentry>
			<!-- Initializing / resetting variables -->
			<exec>
		        attemptsUnmatched = 0;
		        attemptsUndefined = 0;
		        attemptsSilence = 0;
		    </exec>

			<!-- If we have users, we go to question and answer state -->
			<if cond="system.hasUsers()">
				<agent:attendRandom />
				<goto state="QnA" />
				<!-- If no users, we listen (and hope for a wakeup word) -->
				<else />
				<agent:attendNobody />
				<agent:listen />
			</if>
			<reentry />
		</onentry>

		<!-- Goes to QnA mode if Furhat senses a user entering -->
		<onevent name="sense.user.enter">
			<agent:attend target="event:user" />
			<if cond="system.isAttending(event)">
				<goto state="QnA" />
			</if>
		</onevent>

		<!-- Goes to QnA mode if Furhat hear's a wakeup word -->
		<onevent name="sense.user.speak" cond="event?:sem:wakeup">
			<goto state="QnA" />
		</onevent>
	</state>

	<state id="QnA" extends="Dialog">

		<!-- Intro question -->
		<onentry>
			<agent:say>Hi, do you have any question for me?</agent:say>
			<agent:listen />
		</onentry>

		<!-- if the users says no or bye, we go back to passive state -->
		<onevent name="sense.user.speak" cond="event?:sem:no">
			<agent:say>Okay, bye</agent:say>
			<goto state="Passive" />
		</onevent>

		<!-- if the user says something that we have an answer for (see grammar 
			file), we reply with the answer -->
		<onevent name="sense.user.speak" cond="event?:sem:answer">
			<agent:say>
				<expr>event:sem:answer</expr>
			</agent:say>
			<agent:say>Anything else?</agent:say>
			<agent:listen />
		</onevent>

	</state>

	<state id="Dialog">

		<!-- 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, iristk.speech.RecResult.NOMATCH)">
			<exec>
		        attemptsUnmatched++;
		        attemptsUndefined = 0;
		        attemptsSilence = 0;
		    </exec>

			<if cond="3 > attemptsUnmatched">
				<agent:say>
					<random>
						<block>Oh, you think so?</block>
						<block>Okay</block>
						<block>Interesting</block>
					</random>
				</agent:say>
				<else />
				<agent:say>Try to ask me a question</agent:say>
				<exec>attemptsUnmatched = 0</exec>
			</if>
			<agent:listen />
		</onevent>

		<!-- Catches speak events that are undefined, i.e no text are returned 
			from the recognizer. If three of these events are received in a row, we go 
			to passive state -->
		<onevent name="sense.user.speak">
			<exec>
		        attemptsUnmatched = 0;
		        attemptsUndefined++;
		        attemptsSilence = 0;
		    </exec>

			<if cond="3 > attemptsUndefined">
				<agent:say>Sorry, I didn't get that.</agent:say>
				<agent:listen />
				<else />
				<agent:say>Still can't understand. Is something wrong with the
					recognizer? Going back to sleep, say hello to activate me again
				</agent:say>
				<goto state="Passive" />
			</if>
		</onevent>

		<!-- Catches when no sound is picked up. If three of these events are received 
			in a row, we go to passive state -->
		<onevent name="sense.user.silence">
			<exec>
		        attemptsUnmatched = 0;
		        attemptsUndefined = 0;
		        attemptsSilence++;
		    </exec>

			<if cond="3 > attemptsSilence">
				<agent:say>Sorry, I didn't hear anything.</agent:say>
				<agent:listen />
				<else />
				<agent:say>Still can't hear anything. Going back to sleep, say hello
					to activate me again</agent:say>
				<goto state="Passive" />
			</if>
		</onevent>

		<!-- Catches when user leaves and if so, goes to passive -->
		<onevent name="sense.user.leave" cond="system.isAttending(event)">
			<if cond="system.hasUsers()">
				<agent:attendRandom />
				<reentry />
				<else />
				<goto state="Passive" />
			</if>
		</onevent>
	</state>

</flow>
<?xml version="1.0" encoding="utf-8"?>
<grammar xml:lang="en-US" version="1.0" root="root"
	xmlns="http://www.w3.org/2001/06/grammar" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.w3.org/2001/06/grammar http://www.iristk.net/xml/srgs.xsd"
	tag-format="semantics/1.0">

	<rule id="root" scope="public">
		<one-of>
			<item>
				yes
				<tag>out.yes=1</tag>
			</item>
			<item>
				no
				<tag>out.no=1</tag>
			</item>
			<item>
				<ruleref uri="#questions" />
				<tag>out.answer = rules.questions</tag>
			</item>
			<item>
				<ruleref uri="#wakeup" />
				<tag> out.wakeup = "direct"</tag>
			</item>
		</one-of>
	</rule>

	<rule id="questions">
		<one-of>
			<item>
				<one-of>
					<item>what is</item>
					<item>what's</item>
				</one-of>
				your name?
				<tag>out = "my name is fur hat"</tag>
			</item>
			<item>
				what are you?
				<tag>out = "I am a socially intelligent robot"</tag>
			</item>
			<item>
				how old are you?
				<tag>out = "I am 2 years old"</tag>
			</item>
			<item>
				who made you?
				<tag>out = "Fur hat Robotics created me"</tag>
			</item>
			<item>
				<one-of>
					<item>what's</item>
					<item>what is</item>
				</one-of>
				your name
				<tag>out = "My name is Fur hat"</tag>
			</item>
			<item>
				Who built you
				<tag>out = "Fur hat robotics made me"</tag>
			</item>
			<item>
				What can you do
				<tag>out = "I can answer questions"</tag>
			</item>
		</one-of>
	</rule>

	<rule id="wakeup">
		<one-of>
			<item>furhat</item>
			<item>ferret</item>
			<item>fur hat</item>
			<item>hello</item>
			<item>wake up</item>
			<item>hi</item>
		</one-of>
	</rule>

</grammar>

Comments (0)

HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.