In this tutorial, we will see how to toggle Pepper’s autonomous abilities.
Note
For further details on autonomous abilities, see: Autonomous Abilities.
Prerequisites
Before stepping in this tutorial, you should be familiar with
the notion of Future
.
You can refer to Chaining operations if you need.
Let’s start a new project
For further details, see: Creating a robot application.
In the MainActivity
class, create a new holdAbilities
method:
private fun holdAbilities(qiContext: QiContext) {
// Build and store the holder for the abilities.
var holder: Holder = HolderBuilder.with(qiContext)
.withAutonomousAbilities(
AutonomousAbilitiesType.BACKGROUND_MOVEMENT,
AutonomousAbilitiesType.BASIC_AWARENESS,
AutonomousAbilitiesType.AUTONOMOUS_BLINKING
)
.build()
// Hold the abilities asynchronously.
val holdFuture: Future<Void> = holder.async().hold()
}
private void holdAbilities(QiContext qiContext) {
// Build the holder for the abilities.
Holder holder = HolderBuilder.with(qiContext)
.withAutonomousAbilities(
AutonomousAbilitiesType.BACKGROUND_MOVEMENT,
AutonomousAbilitiesType.BASIC_AWARENESS,
AutonomousAbilitiesType.AUTONOMOUS_BLINKING
)
.build();
// Hold the abilities asynchronously.
Future<Void> holdFuture = holder.async().hold();
}
To hold the abilities, we first build a Holder
with
a HolderBuilder
.
We pass the autonomous abilities we want to hold to the builder, by using the
AutonomousAbilitiesType
enum.
Next, we can call the async
and hold
methods on the holder to hold the
abilities asynchronously.
Now that we know how to disable autonomous abilities, we will see how to re-enable them.
In this section, we will see how to release autonomous abilities.
Create a new releaseAbilities
method:
private fun releaseAbilities(holder: Holder) {
// Release the holder asynchronously.
val releaseFuture: Future<Void> = holder.async().release()
}
private void releaseAbilities(Holder holder) {
// Release the holder asynchronously.
Future<Void> releaseFuture = holder.async().release();
}
To release autonomous abilities asynchronously, call the async
and
release
methods on the corresponding Holder
instance.
Next, we will implement an example to test the hold and release functionalities.
Let’s test our code using a button_switch_autonomous.
Note
The following code is just a quick way to test the functionality, this is not what you would do in a real application.
In the activity_main.xml layout file, add the following Button
:
<Button
android:id="@+id/button_switch_autonomous"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Hold"/>
Create these fields in the MainActivity
:
// A boolean used to store the abilities status.
private var abilitiesHeld: Boolean = false
// The holder for the abilities.
private var holder: Holder? = null
// The QiContext provided by the QiSDK.
private var qiContext: QiContext? = null
// The button_switch_autonomous used to toggle the abilities.
private Button buttonSwitchAutonomous;
// A boolean used to store the abilities status.
private boolean abilitiesHeld = false;
// The holder for the abilities.
private Holder holder;
// The QiContext provided by the QiSDK.
private QiContext qiContext;
Put the following code for the onRobotFocusGained
and onRobotFocusLost
methods:
override fun onRobotFocusGained(qiContext: QiContext) {
// Store the provided QiContext.
this.qiContext = qiContext
}
override fun onRobotFocusLost() {
// Remove the QiContext.
this.qiContext = null
}
@Override
public void onRobotFocusGained(QiContext qiContext) {
// Store the provided QiContext.
this.qiContext = qiContext;
}
@Override
public void onRobotFocusLost() {
// Remove the QiContext.
this.qiContext = null;
}
Set the button_switch_autonomous onClick listener in the onCreate
method.
// Set the button_switch_autonomous onClick listener.
button_switch_autonomous.setOnClickListener {
// Check that the Activity owns the focus.
if (qiContext != null) {
toggleAbilities()
}
}
// Find the button_switch_autonomous in the view.
buttonSwitchAutonomous = (Button) findViewById(R.id.button_switch_autonomous);
// Set the buttonSwitchAutonomous onClick listener.
buttonSwitchAutonomous.setOnClickListener(v -> {
// Check that the Activity owns the focus.
if (qiContext != null) {
toggleAbilities();
}
});
Add a toggleAbilities
method:
fun void toggleAbilities() {
// Disable the button_switch_autonomous.
button_switch_autonomous.isEnable = false
if (abilitiesHeld) {
releaseAbilities(holder)
} else {
holdAbilities(qiContext)
}
}
private void toggleAbilities() {
// Disable the buttonSwitchAutonomous.
buttonSwitchAutonomous.setEnabled(false);
if (abilitiesHeld) {
releaseAbilities(holder);
} else {
holdAbilities(qiContext);
}
}
Now, update the holdAbilities
method with the following
code:
// Build and store the holder for the abilities.
holder = HolderBuilder.with(qiContext)
.withAutonomousAbilities(
AutonomousAbilitiesType.BACKGROUND_MOVEMENT,
AutonomousAbilitiesType.BASIC_AWARENESS,
AutonomousAbilitiesType.AUTONOMOUS_BLINKING
)
.build()
// Hold the abilities asynchronously.
val holdFuture: Future<Void> = holder.async().hold()
// Chain the hold with a lambda on the UI thread.
holdFuture.andThenConsume(Qi.onUiThread(Consumer {
// Store the abilities status.
abilitiesHeld = true
// Change the button_switch_autonomous text.
button_switch_autonomous.text = "Release"
// Enable the button_switch_autonomous.
button_switch_autonomous.isEnabled = true
}))
// Build and store the holder for the abilities.
holder = HolderBuilder.with(qiContext)
.withAutonomousAbilities(
AutonomousAbilitiesType.BACKGROUND_MOVEMENT,
AutonomousAbilitiesType.BASIC_AWARENESS,
AutonomousAbilitiesType.AUTONOMOUS_BLINKING
)
.build();
// Hold the abilities asynchronously.
Future<Void> holdFuture = holder.async().hold();
// Chain the hold with a lambda on the UI thread.
holdFuture.andThenConsume(Qi.onUiThread((Consumer<Void>) ignore -> {
// Store the abilities status.
abilitiesHeld = true;
// Change the buttonSwitchAutonomous text.
buttonSwitchAutonomous.setText("Release");
// Enable the buttonSwitchAutonomous.
buttonSwitchAutonomous.setEnabled(true);
}));
Finally, chain releaseFuture
in the
releaseAbilities
method with a lambda on the UI thread:
// Chain the release with a lambda on the UI thread.
releaseFuture.andThenConsume(Qi.onUiThread(Consumer {
// Store the abilities status.
abilitiesHeld = false
// Change the button_switch_autonomous text.
button_switch_autonomous.text = "Hold"
// Enable the button_switch_autonomous.
button_switch_autonomous.isEnabled = true
}))
// Chain the release with a lambda on the UI thread.
releaseFuture.andThenConsume(Qi.onUiThread((Consumer<Void>) ignore -> {
// Store the abilities status.
abilitiesHeld = false;
// Change the buttonSwitchAutonomous text.
buttonSwitchAutonomous.setText("Hold");
// Enable the buttonSwitchAutonomous.
buttonSwitchAutonomous.setEnabled(true);
}));
Note
We have to execute the lambdas on the UI thread because we update the button_switch_autonomous properties in them.
The sources for this tutorial are available on GitHub.
Step | Action |
---|---|
Install and run the application. For further details, see: Running an application. |
|
Choose “Hold/release autonomous abilities”. Notice that the robot moves slightly, blinks, and tracks your movements. |
|
Click on the button_switch_autonomous and the robot will stop these behaviours after a short time. | |
Click again on the button_switch_autonomous and the robot will reactivate his abilities. |
We can now toggle abilities!
That’s it, you know how to hold and release autonomous abilities.