Skip to content

Commit 351634c

Browse files
author
Alexandre ROUX
committed
peppergamepad-1.0.4
Add start() and stop() methods Bug fixes Warnings removal Stop RemoteRobotController in onRobotFocusLost() Update README
1 parent 74b2b1b commit 351634c

File tree

9 files changed

+119
-67
lines changed

9 files changed

+119
-67
lines changed

README.md

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ This video was filmed at SoftBank Robotics Europe, and shows the basic control s
1212

1313
## Getting Started
1414

15-
1615
### Prerequisites
1716

1817
A robotified project for Pepper with QiSDK. Read the [documentation](https://developer.softbankrobotics.com/pepper-qisdk) if needed
@@ -41,7 +40,6 @@ Full implementation details are available to see in the sample project.
4140

4241
Make sure to replace 'Tag' by the number of the version of the library you want to use.
4342

44-
4543
## Usage
4644

4745
*This README assumes some standard setup can be done by the user, such as initialising variables or implementing code in the correct functions. Refer to the Sample Project for full usage code.*
@@ -50,8 +48,7 @@ Initialise the QISDK in the onCreate. If you are unsure how to do this, refer to
5048

5149
QiSDK.register(this, this)
5250

53-
In the `onRobotFocusGained`, disable BasicAwareness, and instantiate a `RemoteRobotController` object by passing it the QiContext.
54-
51+
In the `onRobotFocusGained`, disable BasicAwareness, and instantiate a `RemoteRobotController` object by passing it the QiContext. Then start it.
5552

5653
```
5754
override fun onRobotFocusGained(qiContext: QiContext) {
@@ -68,17 +65,13 @@ override fun onRobotFocusGained(qiContext: QiContext) {
6865
}
6966
7067
remoteRobotController = RemoteRobotController(qiContext)
68+
remoteRobotController.start()
7169
}
7270
```
73-
74-
75-
76-
7771
Get the position of the controller and call updateTarget method. It is important to call this function in a thread, as it is using references to the QISDK.
7872
```
7973
remoteRobotController.updateTarget(leftJoystickX, leftJoystickY, rightJoystickX, rightJoystickY)
8074
```
81-
8275
- Left joystick makes Pepper translate
8376
- Right joystick makes Pepper rotate
8477

@@ -126,6 +119,14 @@ private fun getCenteredAxis(event: MotionEvent, device: InputDevice, axis: Int):
126119
}
127120
```
128121

122+
You can stop `RemoteRobotController` object whenever you want by calling the `stop()` method. This can be helpfull if you want to run animations for instance:
123+
124+
```
125+
remoteRobotController.stop()
126+
myCustomAnimation.run()
127+
remoteRobotController.start()
128+
```
129+
129130
## License
130131

131132
This project is licensed under the BSD 3-Clause "New" or "Revised" License- see the [COPYING](COPYING.md) file for details

pepper-gamepad-root/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
// Top-level build file where you can add configuration options common to all sub-projects/modules.
22

33
buildscript {
4-
ext.kotlin_version = '1.3.41'
4+
ext.kotlin_version = '1.3.61'
55
repositories {
66
google()
77
jcenter()
88
}
99
dependencies {
10-
classpath 'com.android.tools.build:gradle:3.4.2'
10+
classpath 'com.android.tools.build:gradle:3.6.1'
1111
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
1212

1313
// NOTE: Do not place your application dependencies here; they belong

pepper-gamepad-root/gradle/wrapper/gradle-wrapper.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
33
distributionPath=wrapper/dists
44
zipStoreBase=GRADLE_USER_HOME
55
zipStorePath=wrapper/dists
6-
distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip
6+
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip

pepper-gamepad-root/pepper-gamepad/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ apply plugin: 'kotlin-android'
55
android {
66
archivesBaseName = "pepper-gamepad"
77
version = "1.0.3"
8-
compileSdkVersion 28
8+
compileSdkVersion 29
99
defaultConfig {
1010
minSdkVersion 23
11-
targetSdkVersion 28
11+
targetSdkVersion 29
1212
versionCode 4
1313
versionName "1.0.3"
1414
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

pepper-gamepad-root/pepper-gamepad/src/main/java/com/softbankrobotics/peppergamepad/RemoteRobotController.kt

Lines changed: 94 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -16,33 +16,49 @@ import kotlin.math.cos
1616
import kotlin.math.roundToInt
1717
import kotlin.math.sin
1818

19-
class RemoteRobotController(context: QiContext) {
19+
class RemoteRobotController(private val qiContext: QiContext) {
2020

2121
private val TAG = "RemoteRobotController"
2222

23-
private val qiContext = context
24-
23+
var isRunning = false
24+
private set
25+
private var startAfterInitialization = false
2526
private var isMoving = false
2627

2728
private var currentLeftJoystickX = 0
2829
private var currentLeftJoystickY = 0
2930
private var currentRightJoystickX = 0
3031
private var currentRightJoystickY = 0
3132

32-
private var lookAtFuture: Future<Void>
33+
private lateinit var lookAtFuture: Future<Void>
3334
private lateinit var animateFuture: Future<Void>
3435

35-
private var defaultPosition: Transform
36-
private var targetFrame: AttachedFrame
37-
private var lookAt: LookAt
36+
private lateinit var defaultPosition: Transform
37+
private lateinit var targetFrame: AttachedFrame
38+
private lateinit var lookAt: LookAt
39+
3840
init {
39-
val robotFrame = qiContext.actuation.robotFrame()
40-
defaultPosition = TransformBuilder.create().fromXTranslation(100.0)
41-
targetFrame = robotFrame.makeAttachedFrame(defaultPosition)
42-
lookAt = LookAtBuilder.with(qiContext).withFrame(targetFrame.frame()).build()
43-
lookAt.addOnStartedListener {
44-
Log.i(TAG, "LookAt started")
41+
qiContext.actuation.async().gazeFrame().andThenConsume { robotFrame ->
42+
defaultPosition = TransformBuilder.create().fromXTranslation(100.0)
43+
targetFrame = robotFrame.makeAttachedFrame(defaultPosition)
44+
lookAt = LookAtBuilder.with(qiContext).withFrame(targetFrame.frame()).build()
45+
lookAt.addOnStartedListener {
46+
Log.i(TAG, "LookAt started")
47+
}
48+
if (startAfterInitialization) start()
49+
}
50+
}
51+
52+
fun start() {
53+
Log.d(TAG, "start")
54+
55+
if (!::lookAt.isInitialized) {
56+
startAfterInitialization = true
57+
return
4558
}
59+
60+
if (isRunning) return
61+
4662
lookAtFuture = lookAt.async().run()
4763
lookAtFuture.thenConsume {
4864
when {
@@ -51,13 +67,33 @@ class RemoteRobotController(context: QiContext) {
5167
lookAtFuture.isCancelled -> Log.e(TAG, "LookAt cancelled")
5268
}
5369
}
70+
71+
isRunning = true
5472
}
5573

56-
fun updateTarget(newLeftJoystickX: Float, newLeftJoystickY: Float, newRightJoystickX: Float, newRightJoystickY: Float) {
57-
Log.d(TAG, "updateTarget newLeftJoystickX=$newLeftJoystickX " +
58-
"newLeftJoystickY=$newLeftJoystickY " +
59-
"newRightJoystickX=$newRightJoystickX " +
60-
"newRightJoystickY=$newRightJoystickY")
74+
fun stop() {
75+
Log.d(TAG, "stop")
76+
77+
if (!isRunning) return
78+
79+
lookAtFuture.requestCancellation()
80+
animateFuture.requestCancellation()
81+
82+
isRunning = false
83+
}
84+
85+
fun updateTarget(
86+
newLeftJoystickX: Float,
87+
newLeftJoystickY: Float,
88+
newRightJoystickX: Float,
89+
newRightJoystickY: Float
90+
) {
91+
Log.d(
92+
TAG, "updateTarget newLeftJoystickX=$newLeftJoystickX " +
93+
"newLeftJoystickY=$newLeftJoystickY " +
94+
"newRightJoystickX=$newRightJoystickX " +
95+
"newRightJoystickY=$newRightJoystickY"
96+
)
6197

6298
// Round values
6399
var roundedNewLeftJoystickX = 0
@@ -91,46 +127,59 @@ class RemoteRobotController(context: QiContext) {
91127
}
92128

93129
private fun makeTranslation() {
94-
Log.d(TAG, "makeTranslation currentLeftJoystickX=$currentLeftJoystickX currentLeftJoystickY=$currentLeftJoystickY")
130+
Log.d(
131+
TAG,
132+
"makeTranslation currentLeftJoystickX=$currentLeftJoystickX currentLeftJoystickY=$currentLeftJoystickY"
133+
)
134+
135+
if (!isRunning) return
95136

96137
if (::animateFuture.isInitialized && !animateFuture.isDone) {
97138
animateFuture.requestCancellation()
98139
} else if (!(currentLeftJoystickX == 0 && currentLeftJoystickY == 0) && !isMoving) {
99140
isMoving = true
100-
lookAt.policy = LookAtMovementPolicy.HEAD_ONLY
101-
102-
val targetX = -currentLeftJoystickY.toDouble()
103-
val targetY = -currentLeftJoystickX.toDouble()
104-
105-
val animationString = "[\"Holonomic\", [\"Line\", [$targetX, $targetY]], 0.0, 40.0]"
106-
val animation = AnimationBuilder.with(qiContext).withTexts(animationString).build()
107-
val animate = AnimateBuilder.with(qiContext).withAnimation(animation).build()
108-
animate.addOnStartedListener {
109-
Log.i(TAG, "Animate started")
110-
111-
if (!(targetX == -currentLeftJoystickY.toDouble() && targetY == -currentLeftJoystickX.toDouble())) {
112-
animateFuture.requestCancellation()
141+
lookAt.async().setPolicy(LookAtMovementPolicy.HEAD_ONLY).andThenConsume {
142+
val targetX = -currentLeftJoystickY.toDouble()
143+
val targetY = -currentLeftJoystickX.toDouble()
144+
145+
val animationString = "[\"Holonomic\", [\"Line\", [$targetX, $targetY]], 0.0, 40.0]"
146+
val animation = AnimationBuilder.with(qiContext).withTexts(animationString).build()
147+
val animate = AnimateBuilder.with(qiContext).withAnimation(animation).build()
148+
animate.addOnStartedListener {
149+
Log.i(TAG, "Animate started")
150+
151+
if (!(targetX == -currentLeftJoystickY.toDouble() && targetY == -currentLeftJoystickX.toDouble())) {
152+
animateFuture.requestCancellation()
153+
}
113154
}
114-
}
115155

116-
animateFuture = animate.async().run()
117-
animateFuture.thenConsume {
118-
when {
119-
animateFuture.isSuccess -> Log.i(TAG, "Animate finished with success")
120-
animateFuture.hasError() -> Log.e(TAG, "Animate error: ${animateFuture.errorMessage}")
121-
animateFuture.isCancelled -> Log.i(TAG, "Animate cancelled")
156+
animateFuture = animate.async().run()
157+
animateFuture.thenConsume {
158+
when {
159+
animateFuture.isSuccess -> Log.i(TAG, "Animate finished with success")
160+
animateFuture.hasError() -> Log.e(
161+
TAG,
162+
"Animate error: ${animateFuture.errorMessage}"
163+
)
164+
animateFuture.isCancelled -> Log.i(TAG, "Animate cancelled")
165+
}
166+
167+
lookAt.policy = LookAtMovementPolicy.HEAD_AND_BASE
168+
isMoving = false
169+
170+
makeTranslation()
122171
}
123-
124-
lookAt.policy = LookAtMovementPolicy.HEAD_AND_BASE
125-
isMoving = false
126-
127-
makeTranslation()
128172
}
129173
}
130174
}
131175

132176
private fun makeRotation() {
133-
Log.d(TAG, "makeRotation currentRightJoystickX=$currentRightJoystickX currentRightJoystickY=$currentRightJoystickY")
177+
Log.d(
178+
TAG,
179+
"makeRotation currentRightJoystickX=$currentRightJoystickX currentRightJoystickY=$currentRightJoystickY"
180+
)
181+
182+
if (!isRunning) return
134183

135184
if (currentRightJoystickX == 0 && currentRightJoystickY == 0) {
136185
targetFrame.update(defaultPosition)

pepper-gamepad-root/sample-app/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ apply plugin: 'kotlin-android'
55
apply plugin: 'kotlin-android-extensions'
66

77
android {
8-
compileSdkVersion 28
8+
compileSdkVersion 29
99
defaultConfig {
1010
applicationId "com.softbankrobotics.peppergamepadsample"
1111
minSdkVersion 23
12-
targetSdkVersion 28
12+
targetSdkVersion 29
1313
versionCode 2
1414
versionName "1.1.0"
1515
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

pepper-gamepad-root/sample-app/src/main/java/com/softbankrobotics/peppergamepadsample/MainActivity.kt

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ class MainActivity : Activity(), RobotLifecycleCallbacks, InputDeviceListener {
149149
}
150150
}
151151
remoteRobotController = RemoteRobotController(qiContext)
152-
Log.i(TAG, "after RemoteRobotController instantiation")
152+
remoteRobotController.start()
153153
}
154154

155155
override fun onGenericMotionEvent(event: MotionEvent): Boolean {
@@ -168,7 +168,12 @@ class MainActivity : Activity(), RobotLifecycleCallbacks, InputDeviceListener {
168168

169169
if (::remoteRobotController.isInitialized) {
170170
thread {
171-
remoteRobotController.updateTarget(leftJoystickX, leftJoystickY, rightJoystickX, rightJoystickY)
171+
remoteRobotController.updateTarget(
172+
leftJoystickX,
173+
leftJoystickY,
174+
rightJoystickX,
175+
rightJoystickY
176+
)
172177
}
173178
} else {
174179
Log.d(TAG, "@@@@@@@@@ not initialized")
@@ -202,6 +207,7 @@ class MainActivity : Activity(), RobotLifecycleCallbacks, InputDeviceListener {
202207
override fun onRobotFocusLost() {
203208
Log.i(TAG, "onRobotFocusLost")
204209
qiContext = null
210+
remoteRobotController.stop()
205211
}
206212

207213
override fun onRobotFocusRefused(reason: String?) {

pepper-gamepad-root/sample-app/src/main/res/values-fr/strings.xml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<resources>
33
<string name="app_name">Pepper Gamepad Sample</string>
4-
<string name="no_controller_detected_message">Connectez une manette pour utiliser l\'application.</string>
5-
<string name="no_controller_detected_title">Aucune manette détectée</string>
64
<string-array name="welcome">
75
<item>Génial, on part en balade! Prends ta manette, jette un oeil aux contrôles et on y va!</item>
86
<item>Super, j\'avais hâte de me dégourdir les roues! J\'espère que tu as ta manette, je t\'affiche un petit rappel des contrôles avant d\'y aller.</item>

pepper-gamepad-root/sample-app/src/main/res/values/strings.xml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
<resources>
22
<string name="app_name">Pepper Gamepad Sample</string>
3-
<string name="no_controller_detected_title">No controller detected</string>
4-
<string name="no_controller_detected_message">Please connect a controller to use the app.</string>
53
<string-array name="welcome">
64
<item>Great, let\'s have fun together! Take the game pad, look at the controls and we\'re good to go!</item>
75
<item>Time to put these wheels to good use! I hope you have a game pad ready, take a look at the controls and let\'s go!</item>

0 commit comments

Comments
 (0)