Making a multimodal presentation

# Part 2: Adding movement¶

By default, Pepper will do simple animations while speaking (“body language”), but it can be worth replacing those with a more relevant, specific animation - which is what we'll do in this second part.

## 1. Adding animations¶

Import an animation file, using File > New > Import animation; in the “Default” tab in Emotion > Positive, pick nicereaction_a002. It will be added in the project’s “raw” folder.

Again, in order to keep the presentation readable, create a helper function:

private fun makeAnimate(animResource: Int) : Animate {
val animation = AnimationBuilder.with(qiContext)
.withResources(animResource)
.build()

return AnimateBuilder.with(qiContext)
.withAnimation(animation)
.build()
}


Let’s use this to make Pepper animate and speak:

////////////////////////
// Presentation logic //
////////////////////////

private fun runPresentation() {
// Part 1: "Making me talk..."

// ...

// Part 2: "Let me show you..."

setImage(R.drawable.scene3)
makeSay("But there's much more to do. Let me show you ! ...").run()
makeAnimate(R.raw.nicereaction_a002).run()
}


… however, this makes Pepper first speak, then do the animation, which isn’t what we want - we want Pepper to do both simultaneously.

## 2. Running actions simultaneously¶

So far, you have only synchronous calls: all actions are being executed one after the other.

Instead of calling action.run() (a blocking call that returns once the action is finished), you can call action.async().run() and immediately get a future object that represents the execution state of that action.

You can then wait for several futures with Future.waitAll - in your case, you want to wait for the say and animate future to both finish, as in the following.

////////////////////////
// Presentation logic //
////////////////////////

private fun runPresentation() {

// ...

// Part 2: "Let me show you..."

setImage(R.drawable.scene3)
val sayMore = makeSay("But there's much more to do. Let me show you ! ...")
val animateEnthusiast = makeAnimate(R.raw.nicereaction_a002)
Future.waitAll(sayMore.async().run(),
animateEnthusiast.async().run()).value
}


## 3. Adding a callback after an animation¶

We also want to show an image after the animation is done, but while Pepper may still be speaking. You can do that by adding a callback after the animate future, in this case, “thenConsume”:

   val animateEnthusiast = makeAnimate(R.raw.nicereaction_a002)
val animFuture = animateEnthusiast.async().run()
animFuture.thenConsume {
setImage(R.drawable.scene4)
}



Your full presentation should now look like this:

////////////////////////
// Presentation logic //
////////////////////////

private fun runPresentation() {

// Part 1: "Making me talk..."

setImage(R.drawable.scene1)
makeSay("Okay, so ... making me talk is a first step a bit like ...").run()
makeSay("a rolling rock ...").run()
setImage(R.drawable.scene2)

// Part 2: "Let me show you..."

setImage(R.drawable.scene3)
val sayMore = makeSay("But there's much more to do. Let me show you ! ...")
val animateEnthusiast = makeAnimate(R.raw.nicereaction_a002)
val animFuture = animateEnthusiast.async().run()
animFuture.thenConsume {
setImage(R.drawable.scene4)
}
Future.waitAll(sayMore.async().run(),
animFuture).value

// Part 3: "I can make sound"

// to do next

}