Mastering Execute

Goal

In this tutorial, we will go to a specific part of a QiChat Language and execute an action when it reaches Execute.

The robot will say a sentence and by reaching ^execute it will make the baseQiChatbot run a animation synchronously. Then the speech will resume to where it was stopped.

Prerequisites

Before stepping in this tutorial, you should:

Let’s start a new project

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

For further details, see: Creating a robot application.

Creating a topic file

Create a new topic file named execute.top for the English (en) language.

Add the following content to this file:

topic: ~execute()

concept:(execute) [execute executor]
u:(~execute) I've reached the execute ^execute(myExecutor) and now I continue.

For more details about the syntax, see: QiChat - Syntax.

QiChatExecutor class implementation

In this section, we will see how to extend the BaseQiChatExecutor class and implement runWith and stop methods.

  • runWith will be called when ^execute is reached in the topic.
  • stop will be called when the chat that handles the qiChatbot is canceled.
class MyQiChatExecutor(qiContext: QiContext) : BaseQiChatExecutor(qiContext) {

    override fun runWith(params: List<String>) {
    // This is called when execute is reached in the topic
        animate(qiContext)
    }

    override fun stop() {
        // This is called when chat is canceled or stopped.
        Log.i(TAG, "QiChatExecutor stopped")
    }

}
class MyQiChatExecutor extends BaseQiChatExecutor {
    private final QiContext qiContext;

    MyQiChatExecutor(QiContext context) {
        super(context);
        this.qiContext = context;
    }

    @Override
    public void runWith(List<String> params) {
        // This is called when execute is reached in the topic
        animate(qiContext);
    }

    @Override
    public void stop() {
        // This is called when chat is canceled or stopped
        Log.i(TAG, "QiChatExecutor stopped");
    }

}

Import raise_both_hands_b001 animation using the Animation Browser. It’s located in Basic movements > Both hands.

Create the following method to perform the animation:

private fun animate(qiContext: QiContext) {
    // Create an animation.
    val animation: Animation = AnimationBuilder.with(qiContext) // Create the builder with the context.
            .withResources(R.raw.raise_both_hands_b001) // Set the animation resource.
            .build() // Build the animation.

    // Create an animate action.
    val animate: Animate = AnimateBuilder.with(qiContext) // Create the builder with the context.
            .withAnimation(animation) // Set the animation.
            .build() // Build the animate action.
    animate.run()
}
private void animate(QiContext qiContext) {
    // Create an animation.
    Animation animation = AnimationBuilder.with(qiContext) // Create the builder with the context.
            .withResources(R.raw.raise_both_hands_b001) // Set the animation resource.
            .build(); // Build the animation.

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

Mapping the QiChatExecutor to a QiChatbot

Create a Topic containing ^execute then make a QiChatbot.

Add an executor that matches myExecutor keyword used in the topic. Finally run the chat asynchronously.

@Override
public void onRobotFocusGained(QiContext qiContext) {

    // Create a topic.
    val topic: Topic = TopicBuilder.with(qiContext)
        .withResource(R.raw.execute)
        .build()

    // Create a qiChatbot
    val qiChatbot: QiChatbot = QiChatbotBuilder.with(qiContext).withTopic(topic).build()

    val executors = HashMap<String, QiChatExecutor>()

    // Map the executor name from the topic to our qiChatbotExecutor
    executors["myExecutor"] = MyQiChatExecutor(qiContext)

    // Set the executors to the qiChatbot
    qiChatbot.executors = executors
    val chatbots  = mutableListOf<Chatbot>()
    chatbots.add(qiChatbot)

    // Build chat with the chatbotBuilder
    val chat: Chat = ChatBuilder.with(qiContext).withChatbot(qiChatbot).build()

    // Run an action asynchronously.
    chat.async().run()

}
@Override
public void onRobotFocusGained(QiContext qiContext) {

    // Create a topic.
    final Topic topic = TopicBuilder.with(qiContext)
            .withResource(R.raw.execute)
            .build();

    // Create a qiChatbot
    QiChatbot qiChatbot = QiChatbotBuilder.with(qiContext).withTopic(topic).build();

    Map<String, QiChatExecutor> executors = new HashMap<>();

    // Map the executor name from the topic to our qiChatExecutor
    executors.put("myExecutor", new MyQiChatExecutor(qiContext));

    // Set the executors to the qiChatbot
    qiChatbot.setExecutors(executors);
    List<Chatbot> chatbots = new ArrayList<>();
    chatbots.add(qiChatbot);

    // Build chat with the chatbotBuilder
    Chat chat = ChatBuilder.with(qiContext).withChatbot(qiChatbot).build();

    // Run an action asynchronously.
    chat.async().run();

}

If you run the application, Pepper will wait to hear ‘execute’ or ‘executor’ before executing the animation.

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 Execute”.
Say “execute” or “executor”.
Pepper performs the corresponding animation.

Pepper continues his sentence after the executor is done (when runWith returns).

../../../_images/execute.png

You are now able to use BaseQiChatExecutor!