Mastering Animation labels

Goal

In this tutorial, we will synchronize Pepper’s speech with its animation, using labels in an Animation.

Prerequisites

Before stepping in this tutorial, you should:

  • Know how to use Android resources.
  • Be familiar with the Action notion. For further details, see: Running Actions on Pepper.
  • Be familiar with the Animate action. For further details, see: Animate.
  • Be familiar with the Say action. For further details, see: Say.

Let’s start a new project

  • Start a new project, let’s call it AnimationLabelPepper.
  • Robotify it and make sure it implements the QiSDK & the Robot Life Cycle.

For further details, see: Creating a robot application.

Adding labels to an animation resource

We could create a new animation from scratch, using the Animation Editor or the Trajectory Editor, but for this tutorial, let’s select a predefined one. We will then add labels to the animation.

Step Action

In Android Studio, choose File > New > Import animation…

The Animation Browser / Viewer opens:

../../../_images/animation_browser.png

In Action > Dances, select the dance_b001 animation and click the Select button.

Result: The dance_b001.qianim file is added to your res/raw folder and opens.

Add a label layer and create the following labels:

  • label one at frame 35
  • label two at frame 75
  • label three at frame 118
  • label four at frame 159

For further details, see: Creating labels.

Close the animation file window and return to your MainActivity window.

Building the animation

From this animation file we must now build an Animation object.

To do this, we use the AnimationBuilder class.

In the onRobotFocusGained method, add the following code:

// Create an animation.
val animation: Animation = AnimationBuilder.with(qiContext) // Create the builder with the context.
                                .withResources(R.raw.dance_b001) // Set the animation resource.
                                .build() // Build the animation.
// Create an animation.
Animation animation = AnimationBuilder.with(qiContext) // Create the builder with the context.
                                      .withResources(R.raw.dance_b001) // Set the animation resource.
                                      .build(); // Build the animation.

Using the animation

We will animate Pepper by using the Animate interface.

Add an Animate field in your MainActivity:

// Store the Animate action.
private val animate: Animate? = null
// Store the Animate action.
private Animate animate;

Create it with an AnimateBuilder in the onRobotFocusGained method:

// Create an animate action.
animate = AnimateBuilder.with(qiContext) // Create the builder with the context.
                                .withAnimation(animation) // Set the animation.
                                .build() // Build the animate action.
// Create an animate action.
animate = AnimateBuilder.with(qiContext) // Create the builder with the context.
                                .withAnimation(animation) // Set the animation.
                                .build(); // Build the animate action.

We used the previously created Animation to set the animation Pepper will perform.

Running the animation

We can now run the Animate:

// Run the animate action asynchronously.
val animateFuture: Future<Void>? = animate?.async()?.run()
// Run the animate action asynchronously.
Future<Void> animateFuture = animate.async().run();

Say the label names when reached

To be notified when a label is reached, let’s use the addOnLabelReachedListener method. For this example, we will make Pepper say the name of the reached labels.

Add this before the run:

// Say the name of the reached labels
animate?.addOnLabelReachedListener { label, time ->
    // Create a Say object using the label name
    val sayLabel: Say = SayBuilder.with(qiContext)
            .withText(label)
            .build()

    // Run the Say object
    sayLabel.async().run()
}
// Say the name of the reached labels
animate.addOnLabelReachedListener((label, time) -> {
    // Create a Say object using the label name
    Say sayLabel = SayBuilder.with(qiContext)
            .withText(label)
            .build();

    // Run the Say object
    sayLabel.async().run();
});

Do not forget to remove this listener on Animate in the onRobotFocusLost method:

// Remove on label reached listeners from the animate action.
animate?.removeAllOnLabelReachedListeners()
// Remove on label reached listeners from the animate action.
if (animate != null) {
    animate.removeAllOnLabelReachedListeners();
}

Let’s try it

github_icon The sources for this tutorial are available on GitHub.

Step Action

Install and run the application.

For further details, see: Running an application.

Choose “Mastering Animation labels”.

You should observe the following:

  • the log “Animation started.” is displayed in the console,

  • Pepper executes the animation,

  • Pepper says the label names when reached,

  • the log “Animation finished with success.” is displayed in the console.

    ../../../_images/animation_labels.png

That’s it! You can now synchronize events with Pepper’s animations!