Goal
In this tutorial, we will make Pepper move, using the GoTo action.
Prerequisites
Before stepping in this tutorial, you should be familiar with the action notion.
For further details, see: Running Actions on Pepper.
Let’s start a new project
For further details, see: Creating a robot application.
Let’s see how to make Pepper move at a predefined location.
To do this, we need to create the position to go to.
A Frame is a data which describes a spacial position.
Here we need to get the target frame: this is the location we want Pepper to go to.
To retrieve the target frame, we will first need to get the robot frame.
The robot frame is provided by a service called Actuation
.
We can retrieve it if we use the getActuation
method on the
QiContext.
Put the following code in the onRobotFocusGained
method:
// Get the Actuation service from the QiContext.
val actuation: Actuation = qiContext.actuation
// Get the Actuation service from the QiContext.
Actuation actuation = qiContext.getActuation();
Now we can get the robot frame:
// Get the robot frame.
val robotFrame: Frame = actuation.robotFrame()
// Get the robot frame.
Frame robotFrame = actuation.robotFrame();
Next, we create a 1 meter forward translation corresponding to the transform between the robot frame current location and the target frame:
// Create a transform corresponding to a 1 meter forward translation.
val transform: Transform = TransformBuilder.create().fromXTranslation(1.0)
// Create a transform corresponding to a 1 meter forward translation.
Transform transform = TransformBuilder.create().fromXTranslation(1);
We will now create the target frame.
The Mapping
service provides a method to create a FreeFrame
:
// Get the Mapping service from the QiContext.
val mapping: Mapping = qiContext.mapping
// Create a FreeFrame with the Mapping service.
val targetFrame: FreeFrame = mapping.makeFreeFrame()
// Get the Mapping service from the QiContext.
Mapping mapping = qiContext.getMapping();
// Create a FreeFrame with the Mapping service.
FreeFrame targetFrame = mapping.makeFreeFrame();
A FreeFrame
represents a location free to be placed anywhere, that does not
move when other frames move.
The global position of a FreeFrame
can be updated by applying a
Transform to a base Frame
. The timestamp is left to 0, to update
targetFrame relatively to the last known location of robotFrame.
// Update the target location relatively to Pepper's current location.
targetFrame.update(robotFrame, transform, 0L)
// Update the target location relatively to Pepper's current location.
targetFrame.update(robotFrame, transform, 0L);
We now have the target frame. We will use it to build the GoTo action.
You can make Pepper move by using the GoTo interface.
Add a GoTo field in your MainActivity
:
// Store the GoTo action.
private var goTo: GoTo? = null
// Store the GoTo action.
private GoTo goTo;
We will create a GoTo action with a GoToBuilder
in the
onRobotFocusGained
method:
// Create a GoTo action.
goTo = GoToBuilder.with(qiContext) // Create the builder with the QiContext.
.withFrame(targetFrame.frame()) // Set the target frame.
.build() // Build the GoTo action.
// Create a GoTo action.
goTo = GoToBuilder.with(qiContext) // Create the builder with the QiContext.
.withFrame(targetFrame.frame()) // Set the target frame.
.build(); // Build the GoTo action.
The GoTo interface has a addOnStartedListener
method that allows you
to be notified when the GoTo action starts. We will use it to log to
the console:
// Add an on started listener on the GoTo action.
goTo?.addOnStartedListener { Log.i(TAG, "GoTo action started.") }
// Add an on started listener on the GoTo action.
goTo.addOnStartedListener(() -> Log.i(TAG, "GoTo action started."));
Do not forget to remove this listener on GoTo in the
onRobotFocusLost
method:
// Remove on started listeners from the GoTo action.
goTo?.removeAllOnStartedListeners()
// Remove on started listeners from the GoTo action.
if (goTo != null) {
goTo.removeAllOnStartedListeners();
}
We will now run the GoTo in the onRobotFocusGained
method:
// Execute the GoTo action asynchronously.
val goToFuture: Future<Void>? = goTo?.async()?.run()
// Execute the GoTo action asynchronously.
Future<Void> goToFuture = goTo.async().run();
And display a log trace indicating that the action finished with success or error:
// Add a lambda to the action execution.
goToFuture?.thenConsume { future ->
if (future.isSuccess) {
Log.i(TAG, "GoTo action finished with success.")
} else if (future.hasError()) {
Log.e(TAG, "GoTo action finished with error.", future.error)
}
}
// Add a lambda to the action execution.
goToFuture.thenConsume(future -> {
if (future.isSuccess()) {
Log.i(TAG, "GoTo action finished with success.");
} else if (future.hasError()) {
Log.e(TAG, "GoTo action finished with error.", future.getError());
}
});
The sources for this tutorial are available on GitHub.
Step | Action |
---|---|
Install and run the application. For further details, see: Running an application. |
|
Choose “Step forward”. You should observe the following: |
You are now able to make Pepper move!