Last active
August 21, 2024 22:11
-
-
Save thiagobutignon/d36c06e1feb6a82479494f96cbbfeaf2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* This file is part of the Softbank Robotics tutorial project, specifically focused on animating | |
* the Pepper robot using the QiSDK framework. It demonstrates how to build and run animations | |
* alongside playing sound effects and handling robot lifecycle callbacks. | |
* | |
* @file AnimateTutorialActivity.kt | |
* @author Softbank Robotics Europe | |
* @since 2018 | |
*/ | |
package com.softbankrobotics.qisdktutorials.ui.tutorials.motion.animate | |
import android.media.MediaPlayer | |
import android.os.Bundle | |
import android.util.Log | |
import com.aldebaran.qi.sdk.QiContext | |
import com.aldebaran.qi.sdk.QiSDK | |
import com.aldebaran.qi.sdk.RobotLifecycleCallbacks | |
import com.aldebaran.qi.sdk.builder.AnimateBuilder | |
import com.aldebaran.qi.sdk.builder.AnimationBuilder | |
import com.aldebaran.qi.sdk.builder.SayBuilder | |
import com.aldebaran.qi.sdk.`object`.actuation.Animate | |
import com.softbankrobotics.qisdktutorials.R | |
import com.softbankrobotics.qisdktutorials.ui.conversation.ConversationBinder | |
import com.softbankrobotics.qisdktutorials.ui.conversation.ConversationItemType | |
import com.softbankrobotics.qisdktutorials.ui.tutorials.TutorialActivity | |
import kotlinx.android.synthetic.main.conversation_layout.* | |
private const val TAG = "AnimateTutorialActivity" // Log tag for debugging purposes. | |
/** | |
* AnimateTutorialActivity is an activity that demonstrates how to create and execute an | |
* animation on the Pepper robot. It also shows how to play sound effects during the animation | |
* and log key events such as the start and end of the animation. | |
*/ | |
class AnimateTutorialActivity : TutorialActivity(), RobotLifecycleCallbacks { | |
private var conversationBinder: ConversationBinder? = null // Binder for handling conversation view updates. | |
private var mediaPlayer: MediaPlayer? = null // MediaPlayer instance for playing sound effects. | |
private var animate: Animate? = null // Reference to the Animate action for later use. | |
/** | |
* Called when the activity is first created. Registers the RobotLifecycleCallbacks to this Activity. | |
* @param savedInstanceState Bundle containing the activity's previously saved state. | |
*/ | |
override fun onCreate(savedInstanceState: Bundle?) { | |
super.onCreate(savedInstanceState) | |
QiSDK.register(this, this) // Register the activity to handle robot lifecycle events. | |
} | |
/** | |
* Called when the activity becomes visible to the user. Initializes the MediaPlayer with a sound resource. | |
*/ | |
override fun onStart() { | |
super.onStart() | |
mediaPlayer = MediaPlayer.create(this, R.raw.elephant_sound) // Load elephant sound effect. | |
} | |
/** | |
* Called when the activity is no longer visible to the user. Releases the MediaPlayer resources. | |
*/ | |
override fun onStop() { | |
mediaPlayer?.release() // Release the MediaPlayer resources. | |
mediaPlayer = null | |
super.onStop() | |
} | |
/** | |
* Called when the activity is about to be destroyed. Unregisters the RobotLifecycleCallbacks for this Activity. | |
*/ | |
override fun onDestroy() { | |
QiSDK.unregister(this, this) // Unregister the activity from handling robot lifecycle events. | |
super.onDestroy() | |
} | |
/** | |
* Specifies the layout resource to be used by this activity. | |
*/ | |
override val layoutId = R.layout.conversation_layout | |
/** | |
* Called when the robot gains focus. This is where the main logic of building and running the animation is executed. | |
* @param qiContext The context in which the robot operates, used for building actions and animations. | |
*/ | |
override fun onRobotFocusGained(qiContext: QiContext) { | |
// Bind the conversational events to the view. | |
val conversationStatus = qiContext.conversation.status(qiContext.robotContext) | |
conversationBinder = conversation_view.bindConversationTo(conversationStatus) | |
// Create a Say action to announce the start of the animation. | |
val say = SayBuilder.with(qiContext) | |
.withText("I can perform animations: here is an elephant.") | |
.build() | |
say.run() // Execute the Say action. | |
// Create an animation using the specified resource. | |
val animation = AnimationBuilder.with(qiContext) | |
.withResources(R.raw.elephant_a001) // Set the animation resource. | |
.build() | |
// Create an Animate action with the previously built animation. | |
val animate = AnimateBuilder.with(qiContext) | |
.withAnimation(animation) // Set the animation to be executed. | |
.build() | |
.also { this.animate = it } // Store the Animate action for later use. | |
// Add a listener to handle the event when the animation starts. | |
animate.addOnStartedListener { | |
val message = "Animation started." // Log message for when the animation starts. | |
Log.i(TAG, message) | |
displayLine(message, ConversationItemType.INFO_LOG) // Display the message in the conversation view. | |
mediaPlayer?.start() // Play the sound effect when the animation starts. | |
} | |
// Run the Animate action asynchronously. | |
val animateFuture = animate.async().run() | |
// Handle the result of the Animate action. | |
animateFuture.thenConsume { | |
if (it.isSuccess) { | |
val message = "Animation finished with success." // Log message for successful completion. | |
Log.i(TAG, message) | |
displayLine(message, ConversationItemType.INFO_LOG) // Display success message. | |
} else if (it.hasError()) { | |
val message = "Animation finished with error." // Log message for failed completion. | |
Log.e(TAG, message, it.error) | |
displayLine(message, ConversationItemType.ERROR_LOG) // Display error message. | |
} | |
} | |
} | |
/** | |
* Called when the robot loses focus. Cleans up resources related to the robot's actions. | |
*/ | |
override fun onRobotFocusLost() { | |
conversationBinder?.unbind() // Unbind the conversation view from the robot's conversational status. | |
// Remove all listeners from the Animate action to prevent memory leaks. | |
animate?.removeAllOnStartedListeners() | |
} | |
/** | |
* Called when the robot focus is refused, typically due to another process having control. No action is needed here. | |
* @param reason The reason why the focus was refused. | |
*/ | |
override fun onRobotFocusRefused(reason: String) { | |
// No specific action required when focus is refused. | |
} | |
/** | |
* Displays a message in the conversation view UI component. | |
* @param text The message to display. | |
* @param type The type of message (info, error, etc.) for appropriate styling. | |
*/ | |
private fun displayLine(text: String, type: ConversationItemType) { | |
runOnUiThread { conversation_view.addLine(text, type) } // Ensures UI updates are done on the main thread. | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
///**
// * This file is part of the Softbank Robotics tutorial project, specifically focused on animating
// * the Pepper robot using the QiSDK framework. It demonstrates how to build and run animations
// * alongside playing sound effects and handling robot lifecycle callbacks.
// *
// * @file AnimateTutorialActivity.kt
// * @author Softbank Robotics Europe
// * @SInCE 2018
// /
//
//package com.softbankrobotics.qisdktutorials.ui.tutorials.motion.animate
//
//import android.media.MediaPlayer
//import android.os.Bundle
//import android.util.Log
//
//import com.aldebaran.qi.sdk.QiContext
//import com.aldebaran.qi.sdk.QiSDK
//import com.aldebaran.qi.sdk.RobotLifecycleCallbacks
//import com.aldebaran.qi.sdk.builder.AnimateBuilder
//import com.aldebaran.qi.sdk.builder.AnimationBuilder
//import com.aldebaran.qi.sdk.builder.SayBuilder
//import com.aldebaran.qi.sdk.
object
.actuation.Animate//import com.softbankrobotics.qisdktutorials.R
//import com.softbankrobotics.qisdktutorials.ui.conversation.ConversationBinder
//import com.softbankrobotics.qisdktutorials.ui.conversation.ConversationItemType
//import com.softbankrobotics.qisdktutorials.ui.tutorials.TutorialActivity
//import kotlinx.android.synthetic.main.conversation_layout.
//
//private const val TAG = "AnimateTutorialActivity" // Log tag for debugging purposes.
//
///**
// * AnimateTutorialActivity is an activity that demonstrates how to create and execute an
// * animation on the Pepper robot. It also shows how to play sound effects during the animation
// * and log key events such as the start and end of the animation.
// /
//class AnimateTutorialActivity : TutorialActivity(), RobotLifecycleCallbacks {
//
// private var conversationBinder: ConversationBinder? = null // Binder for handling conversation view updates.
// private var mediaPlayer: MediaPlayer? = null // MediaPlayer instance for playing sound effects.
// private var animate: Animate? = null // Reference to the Animate action for later use.
//
// /*
// * Called when the activity is first created. Registers the RobotLifecycleCallbacks to this Activity.
// * @param savedInstanceState Bundle containing the activity's previously saved state.
// /
// override fun onCreate(savedInstanceState: Bundle?) {
// super.onCreate(savedInstanceState)
// QiSDK.register(this, this) // Register the activity to handle robot lifecycle events.
// }
//
// /*
// * Called when the activity becomes visible to the user. Initializes the MediaPlayer with a sound resource.
// /
// override fun onStart() {
// super.onStart()
// mediaPlayer = MediaPlayer.create(this, R.raw.elephant_sound) // Load elephant sound effect.
// }
//
// /*
// * Called when the activity is no longer visible to the user. Releases the MediaPlayer resources.
// /
// override fun onStop() {
// mediaPlayer?.release() // Release the MediaPlayer resources.
// mediaPlayer = null
// super.onStop()
// }
//
// /*
// * Called when the activity is about to be destroyed. Unregisters the RobotLifecycleCallbacks for this Activity.
// /
// override fun onDestroy() {
// QiSDK.unregister(this, this) // Unregister the activity from handling robot lifecycle events.
// super.onDestroy()
// }
//
// /*
// * Specifies the layout resource to be used by this activity.
// /
// override val layoutId = R.layout.conversation_layout
//
// /*
// * Called when the robot gains focus. This is where the main logic of building and running the animation is executed.
// * @param qiContext The context in which the robot operates, used for building actions and animations.
// /
// override fun onRobotFocusGained(qiContext: QiContext) {
// // Bind the conversational events to the view.
// val conversationStatus = qiContext.conversation.status(qiContext.robotContext)
// conversationBinder = conversation_view.bindConversationTo(conversationStatus)
//
// // Create a Say action to announce the start of the animation.
// val say = SayBuilder.with(qiContext)
// .withText("I can perform animations: here is an elephant.")
// .build()
//
// say.run() // Execute the Say action.
//
// // Create an animation using the specified resource.
// val animation = AnimationBuilder.with(qiContext)
// .withResources(R.raw.elephant_a001) // Set the animation resource.
// .build()
//
// // Create an Animate action with the previously built animation.
// val animate = AnimateBuilder.with(qiContext)
// .withAnimation(animation) // Set the animation to be executed.
// .build()
// .also { this.animate = it } // Store the Animate action for later use.
//
// // Add a listener to handle the event when the animation starts.
// animate.addOnStartedListener {
// val message = "Animation started." // Log message for when the animation starts.
// Log.i(TAG, message)
// displayLine(message, ConversationItemType.INFO_LOG) // Display the message in the conversation view.
//
// mediaPlayer?.start() // Play the sound effect when the animation starts.
// }
//
// // Run the Animate action asynchronously.
// val animateFuture = animate.async().run()
//
// // Handle the result of the Animate action.
// animateFuture.thenConsume {
// if (it.isSuccess) {
// val message = "Animation finished with success." // Log message for successful completion.
// Log.i(TAG, message)
// displayLine(message, ConversationItemType.INFO_LOG) // Display success message.
// } else if (it.hasError()) {
// val message = "Animation finished with error." // Log message for failed completion.
// Log.e(TAG, message, it.error)
// displayLine(message, ConversationItemType.ERROR_LOG) // Display error message.
// }
// }
// }
//
//// override fun onRobotFocusGained(qiContext: QiContext) {
//// // Bind the conversational events to the view.
//// val conversationStatus = qiContext.conversation.status(qiContext.robotContext)
//// conversationBinder = conversation_view.bindConversationTo(conversationStatus)
////
//// // Create a Say action to announce the start of the animation.
//// val say = SayBuilder.with(qiContext)
//// .withText("I can perform animations: here is an elephant.")
//// .build()
////
//// say.run() // Execute the Say action.
////
//// // Start playing the sound effect.
//// mediaPlayer?.start()
////
//// // Loop the animation while the audio is playing.
//// loopAnimationWhileAudioPlaying(qiContext)
//// }
//
// /*
// * Called when the robot loses focus. Cleans up resources related to the robot's actions.
// /
// override fun onRobotFocusLost() {
// conversationBinder?.unbind() // Unbind the conversation view from the robot's conversational status.
//
// // Remove all listeners from the Animate action to prevent memory leaks.
// animate?.removeAllOnStartedListeners()
// }
//
//// override fun onRobotFocusLost() {
//// conversationBinder?.unbind() // Unbind the conversation view from the robot's conversational status.
////
//// // Remove all listeners from the Animate action to prevent memory leaks.
//// animate?.removeAllOnStartedListeners()
////
//// // Stop the media player if it's still playing.
//// mediaPlayer?.stop()
//// }
//
// /*
// * Called when the robot focus is refused, typically due to another process having control. No action is needed here.
// * @param reason The reason why the focus was refused.
// /
// override fun onRobotFocusRefused(reason: String) {
// // No specific action required when focus is refused.
// }
//
// /*
// * Displays a message in the conversation view UI component.
// * @param text The message to display.
// * @param type The type of message (info, error, etc.) for appropriate styling.
// /
// private fun displayLine(text: String, type: ConversationItemType) {
// runOnUiThread { conversation_view.addLine(text, type) } // Ensures UI updates are done on the main thread.
// }
//
// /*
// * Loops the animation until the audio stops playing.
// * @param qiContext The context in which the robot operates, used for building actions and animations.
// */
// private fun loopAnimationWhileAudioPlaying(qiContext: QiContext) {
// // Create an animation using the specified resource.
// val animation = AnimationBuilder.with(qiContext)
// .withResources(R.raw.elephant_a001) // Set the animation resource.
// .build()
//
// // Create an Animate action with the previously built animation.
// val animate = AnimateBuilder.with(qiContext)
// .withAnimation(animation) // Set the animation to be executed.
// .build()
// .also { this.animate = it } // Store the Animate action for later use.
//
// // Add a listener to handle the event when the animation starts.
// animate.addOnStartedListener {
// val message = "Animation started." // Log message for when the animation starts.
// Log.i(TAG, message)
// displayLine(message, ConversationItemType.INFO_LOG) // Display the message in the conversation view.
// }
//
// // Loop the animation until the media player is playing.
// while (mediaPlayer?.isPlaying == true) {
// val animateFuture = animate.async().run() // Run the Animate action asynchronously.
//
// // Handle the result of the Animate action.
// animateFuture.thenConsume {
// if (it.isSuccess) {
// val message = "Animation finished with success, repeating..." // Log message for successful completion.
// Log.i(TAG, message)
// displayLine(message, ConversationItemType.INFO_LOG) // Display success message.
// } else if (it.hasError()) {
// val message = "Animation finished with error, repeating..." // Log message for failed completion.
// Log.e(TAG, message, it.error)
// displayLine(message, ConversationItemType.ERROR_LOG) // Display error message.
// }
// }
// }
//
// val message = "Audio finished, stopping animation loop." // Log message when audio is done.
// Log.i(TAG, message)
// displayLine(message, ConversationItemType.INFO_LOG) // Display stop message.
// }
//}
package com.softbankrobotics.qisdktutorials.ui.tutorials.motion.animate
import android.media.MediaPlayer
import android.os.Bundle
import android.util.Log
import com.aldebaran.qi.sdk.QiContext
import com.aldebaran.qi.sdk.QiSDK
import com.aldebaran.qi.sdk.RobotLifecycleCallbacks
import com.aldebaran.qi.sdk.builder.AnimateBuilder
import com.aldebaran.qi.sdk.builder.AnimationBuilder
import com.aldebaran.qi.sdk.builder.SayBuilder
import com.aldebaran.qi.sdk.
object
.actuation.Animateimport com.softbankrobotics.qisdktutorials.R
import com.softbankrobotics.qisdktutorials.ui.conversation.ConversationBinder
import com.softbankrobotics.qisdktutorials.ui.conversation.ConversationItemType
import com.softbankrobotics.qisdktutorials.ui.tutorials.TutorialActivity
import kotlinx.android.synthetic.main.conversation_layout.*
private const val TAG = "AnimateTutorialActivity" // Log tag for debugging purposes.
class AnimateTutorialActivity : TutorialActivity(), RobotLifecycleCallbacks {
}