In this tutorial, you will learn the basics of how to make your Furhat talk, move his head and gesticulate though a presentation skill.
Note: this tutorial assumes that you:
- Have a Furhat robot
- Can access the robot through a web browser
Creating a new skill
- Start by browsing to your Furhat using your web browser and typing in its IP-address and logging in with your admin password. If not, go to Accessing Furhat.
- Go to LiveMode
- In the bottom, select "Create new skill"
- Name your skill something appropriate, for example TestPresentation and select the Presentation template.
- Go back to LiveMode and you will see the new skill in the list of Skill packages. Press the Skill Button to test-run the skill.
Note: Currently, when creating a skill from the web interface, you will get a nullpointer exception if you restart the mode. To get around this error you have to restart the furhat server. On a Furhat robot, this is done using the top right menu in web interface. If you are using the SDK and development server, close down the server and start it up again.
Understanding the skill resources
(Nb. In this tutorial we are using the web interface and will thus not have to worry about the Skill java class. It is automatically created for you and no modifications are needed)
The skill comes with two resources loaded; Properties (See Skill properties file) & Flow (See Irisflow Overview). Links to these are shown in the Skill's listing along with a Reload link that we don't need to worry about for now.
Understanding the flow
Open the Flow resource. It starts like this:
<?xml version="1.0" encoding="utf-8"?> <flow name="TestPresentationFlow" package="iristk.app.testPresentation" initial="Start" xmlns:this="iristk.app.testPresentation.TestPresentationFlow" 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"> <param name="agent" type="iristk.situated.SystemAgentFlow"/> <var name="system" type="iristk.situated.SystemAgent" value="agent.getSystemAgent()"/>
- name and package: The package and name of the resulting Java class after compilation
- initial: The initial state when the flow starts.
Then a parameter (something sent into the flow) is defined, our agent. Think of this as a representation of our Furhat robot, that you for example can use to make the robot talk.
Finally, the system variable (something defined in the flow) is defined and given a value from the agent mentioned above. Think of the system variable as a container of the agent's attentional state. More of this is explained in the next tutorial.
The next part of the flow contains a single state:
<state id="Start"> <onentry> <agent:say>Hello there</agent:say> <wait msec="1000"/> <agent:attend x="-0.5" y="0" z="1"/> <agent:say>I can look to the right</agent:say> <wait msec="1000"/> <agent:attend x="0" y="0" z="1"/> <agent:say>And I can look straight ahead</agent:say> <wait msec="1000"/> <agent:say>I can show different emotions</agent:say> <agent:gesture name="'express_sad'" async="false"/> <agent:gesture name="'smile'"/> <agent:say>That's all for now</agent:say> </onentry> </state> </flow>
The initial (and only) state Start contains one event handler called
<onentry>, which is triggered when the state is entered. The event handler does in turn contain a set of actions that will be executed:
- <agent:say>: Makes Furhat say a certain text. Behind the scenes: Calls the state say in the linked flow iristk.flow.SystemAgentFlow with the contents of the element (the text to speak) as a parameter. The called state will send an event to the synthesizer to synthesize the text, and then return when the synthesizer is done.
- <wait>: Pauses the flow
- <agent:attend>: Makes Furhat look at a point 0.5m to the right and 1m in front. Behind the scenes: calles the state attend in the SystemAgentFlow which makes Furhat look at the specified coordinates.
- <agent:gesture>: Makes Furhat do a specific gesture (if it is defined). Async="false" means that the flow will wait until the gesture has been completed before it continues. Default is true, i.e the flow continues without waiting for the gesture to continue.
Compiling and running the flow
If you change the flow XML, it needs to be compiled to Java code for the change to take effect. You can do this by pressing Compile or Compile and Run.