@@ -8,7 +8,6 @@ import { View } from 'react-native'
8
8
// Local imports
9
9
import { useROS , createROSService , createROSServiceRequest } from '../../ros/ros_helpers'
10
10
import {
11
- ABOVE_PLATE_PARAM_JOINTS ,
12
11
CAMERA_FEED_TOPIC ,
13
12
getRobotMotionText ,
14
13
GET_JOINT_STATE_SERVICE_NAME ,
@@ -23,10 +22,16 @@ import SettingsPageParent from './SettingsPageParent'
23
22
import VideoFeed from '../Home/VideoFeed'
24
23
25
24
/**
26
- * The AbovePlate component allows users to configure the "above plate" configuration
27
- * the robot moves to before bite selection.
25
+ * The CustomizeConfiguration component allows users to configure the one of the
26
+ * fixed configurations the robot uses. In its current form, the node can take in
27
+ * multiple parameters, but will set them all to the same joint state positions.
28
28
*/
29
- const AbovePlate = ( props ) => {
29
+ const CustomizeConfiguration = ( props ) => {
30
+ // Check the props
31
+ if ( Object . values ( MEAL_STATE ) . indexOf ( props . startingMealState ) === - 1 ) {
32
+ throw new Error ( 'Invalid starting meal state ' + props . startingMealState )
33
+ }
34
+
30
35
// Get relevant global state variables
31
36
const setSettingsState = useGlobalState ( ( state ) => state . setSettingsState )
32
37
const globalMealState = useGlobalState ( ( state ) => state . mealState )
@@ -35,18 +40,17 @@ const AbovePlate = (props) => {
35
40
36
41
// Create relevant local state variables
37
42
// Configure the parameters for SettingsPageParent
38
- const paramNames = useMemo ( ( ) => [ ABOVE_PLATE_PARAM_JOINTS ] , [ ] )
39
- const [ currentAbovePlateParam , setCurrentAbovePlateParam ] = useState ( [ null ] )
43
+ const [ currentConfigurationParams , setCurrentConfigurationParams ] = useState ( props . paramNames . map ( ( ) => null ) )
40
44
const [ localCurrAndNextMealState , setLocalCurrAndNextMealState ] = useState (
41
45
globalMealState === MEAL_STATE . U_BiteDone || biteTransferPageAtFace
42
- ? [ MEAL_STATE . R_MovingFromMouth , MEAL_STATE . R_MovingAbovePlate ]
43
- : [ MEAL_STATE . R_MovingAbovePlate , null ]
46
+ ? [ MEAL_STATE . R_MovingFromMouth , props . startingMealState ]
47
+ : [ props . startingMealState , null ]
44
48
)
45
49
const actionInput = useMemo ( ( ) => ( { } ) , [ ] )
46
50
const doneButtonIsClicked = useRef ( false )
47
51
const [ zoomLevel , setZoomLevel ] = useState ( 1.0 )
48
52
const [ mountTeleopSubcomponent , setMountTeleopSubcomponent ] = useState ( false )
49
- const stopServoSuccessCallback = useRef ( ( ) => { } )
53
+ const unmountTeleopSubcomponentCallback = useRef ( ( ) => { } )
50
54
51
55
// Flag to check if the current orientation is portrait
52
56
const isPortrait = useMediaQuery ( { query : '(orientation: portrait)' } )
@@ -62,8 +66,8 @@ const AbovePlate = (props) => {
62
66
( newLocalCurrMealState , newLocalNextMealState = null ) => {
63
67
console . log ( 'setLocalCurrMealStateWrapper evaluated' )
64
68
let oldLocalCurrMealState = localCurrAndNextMealState [ 0 ]
65
- // Only mount the teleop subcomponent if the robot finished moving above the plate
66
- if ( newLocalCurrMealState === null && oldLocalCurrMealState === MEAL_STATE . R_MovingAbovePlate ) {
69
+ // Only mount the teleop subcomponent if the robot finished the prereq motion for this page
70
+ if ( newLocalCurrMealState === null && oldLocalCurrMealState === props . startingMealState ) {
67
71
setMountTeleopSubcomponent ( true )
68
72
}
69
73
// Start in a moving state, not a paused state
@@ -77,18 +81,24 @@ const AbovePlate = (props) => {
77
81
setLocalCurrAndNextMealState ( [ newLocalCurrMealState , newLocalNextMealState ] )
78
82
}
79
83
} ,
80
- [ localCurrAndNextMealState , setLocalCurrAndNextMealState , setMountTeleopSubcomponent , doneButtonIsClicked , setPaused , setSettingsState ]
84
+ [
85
+ doneButtonIsClicked ,
86
+ localCurrAndNextMealState ,
87
+ props . startingMealState ,
88
+ setLocalCurrAndNextMealState ,
89
+ setMountTeleopSubcomponent ,
90
+ setPaused ,
91
+ setSettingsState
92
+ ]
81
93
)
82
94
83
95
// Get the function that sets the local curr meal state and next meal state variables.
84
96
// Note this does not execute it. It is used to pass the function to other components.
85
97
const getSetLocalCurrMealStateWrapper = useCallback (
86
98
( newLocalCurrMealState , newLocalNextMealState = null ) => {
87
- console . log ( 'getSetLocalCurrMealStateWrapper evaluated' )
88
99
let retval = ( ) => {
89
- console . log ( 'getSetLocalCurrMealStateWrapper retval evaluated' )
90
100
setLocalCurrMealStateWrapper ( newLocalCurrMealState , newLocalNextMealState )
91
- stopServoSuccessCallback . current = ( ) => { }
101
+ unmountTeleopSubcomponentCallback . current = ( ) => { }
92
102
}
93
103
// If the teleop subcomponent was mounted, unmount it and let the stopServo
94
104
// success callback handle the rest. However, sometimes the success message
@@ -101,7 +111,7 @@ const AbovePlate = (props) => {
101
111
}
102
112
return retval
103
113
} ,
104
- [ mountTeleopSubcomponent , setLocalCurrMealStateWrapper , setMountTeleopSubcomponent , stopServoSuccessCallback ]
114
+ [ mountTeleopSubcomponent , setLocalCurrMealStateWrapper , setMountTeleopSubcomponent , unmountTeleopSubcomponentCallback ]
105
115
)
106
116
107
117
// Store the props for the RobotMotion call.
@@ -149,17 +159,17 @@ const AbovePlate = (props) => {
149
159
} )
150
160
service . callService ( request , ( response ) => {
151
161
console . log ( 'Got joint state response' , response )
152
- setCurrentAbovePlateParam ( [ response . joint_state . position ] )
162
+ setCurrentConfigurationParams ( props . paramNames . map ( ( ) => response . joint_state . position ) )
153
163
} )
154
- } , [ getJointStateService , setCurrentAbovePlateParam ] )
164
+ } , [ getJointStateService , props . paramNames , setCurrentConfigurationParams ] )
155
165
156
166
// Callback to move the robot to another configuration
157
167
const moveToButtonClicked = useCallback (
158
168
( nextMealState ) => {
159
169
doneButtonIsClicked . current = false
160
- stopServoSuccessCallback . current = getSetLocalCurrMealStateWrapper ( nextMealState )
170
+ unmountTeleopSubcomponentCallback . current = getSetLocalCurrMealStateWrapper ( nextMealState )
161
171
} ,
162
- [ getSetLocalCurrMealStateWrapper , doneButtonIsClicked , stopServoSuccessCallback ]
172
+ [ getSetLocalCurrMealStateWrapper , doneButtonIsClicked , unmountTeleopSubcomponentCallback ]
163
173
)
164
174
165
175
// Callback to return to the main settings page
@@ -191,11 +201,11 @@ const AbovePlate = (props) => {
191
201
localCurrMealState = MEAL_STATE . R_MovingAbovePlate
192
202
break
193
203
}
194
- stopServoSuccessCallback . current = getSetLocalCurrMealStateWrapper ( localCurrMealState , localNextMealState )
195
- } , [ getSetLocalCurrMealStateWrapper , globalMealState , doneButtonIsClicked , stopServoSuccessCallback ] )
204
+ unmountTeleopSubcomponentCallback . current = getSetLocalCurrMealStateWrapper ( localCurrMealState , localNextMealState )
205
+ } , [ getSetLocalCurrMealStateWrapper , globalMealState , doneButtonIsClicked , unmountTeleopSubcomponentCallback ] )
196
206
197
207
// Callback to render the main contents of the page
198
- const renderAbovePlateSettings = useCallback ( ( ) => {
208
+ const renderSettings = useCallback ( ( ) => {
199
209
return (
200
210
< View
201
211
style = { {
@@ -216,14 +226,14 @@ const AbovePlate = (props) => {
216
226
< >
217
227
< View style = { { flex : 5 , alignItems : 'center' , justifyContent : 'center' , width : '95%' , height : '95%' } } >
218
228
< TeleopSubcomponent
219
- stopServoSuccessCallback = { stopServoSuccessCallback }
229
+ unmountCallback = { unmountTeleopSubcomponentCallback }
220
230
teleopButtonOnReleaseCallback = { storeJointStatesAsLocalParam }
221
231
/>
222
232
</ View >
223
233
</ >
224
234
) : (
225
235
< p style = { { textAlign : 'center' , fontSize : ( textFontSize * 0.75 ) . toString ( ) + sizeSuffix , margin : 0 } } className = 'txt-huge' >
226
- To tune the “Above Plate ” configuration, first “Move Above Plate .”
236
+ To tune the “{ props . configurationName } ” configuration, first “{ props . buttonName } .”
227
237
</ p >
228
238
) }
229
239
</ View >
@@ -238,38 +248,24 @@ const AbovePlate = (props) => {
238
248
height : '100%'
239
249
} }
240
250
>
241
- < View style = { { flex : 1 , alignItems : 'center' , justifyContent : 'center' , width : '100%' , height : '100%' } } >
242
- < Button
243
- variant = 'warning'
244
- className = 'mx-2 mb-2 btn-huge'
245
- size = 'lg'
246
- style = { {
247
- fontSize : ( textFontSize * 0.5 ) . toString ( ) + sizeSuffix ,
248
- width : '90%' ,
249
- height : '90%' ,
250
- color : 'black'
251
- } }
252
- onClick = { ( ) => moveToButtonClicked ( MEAL_STATE . R_MovingToStagingConfiguration ) }
253
- >
254
- Move To Staging
255
- </ Button >
256
- </ View >
257
- < View style = { { flex : 1 , alignItems : 'center' , justifyContent : 'center' , width : '100%' , height : '100%' } } >
258
- < Button
259
- variant = 'warning'
260
- className = 'mx-2 mb-2 btn-huge'
261
- size = 'lg'
262
- style = { {
263
- fontSize : ( textFontSize * 0.5 ) . toString ( ) + sizeSuffix ,
264
- width : '90%' ,
265
- height : '90%' ,
266
- color : 'black'
267
- } }
268
- onClick = { ( ) => moveToButtonClicked ( MEAL_STATE . R_MovingToRestingPosition ) }
269
- >
270
- Move To Resting
271
- </ Button >
272
- </ View >
251
+ { props . otherButtonConfigs . map ( ( { name, mealState } ) => (
252
+ < View key = { name } style = { { flex : 1 , alignItems : 'center' , justifyContent : 'center' , width : '100%' , height : '100%' } } >
253
+ < Button
254
+ variant = 'warning'
255
+ className = 'mx-2 mb-2 btn-huge'
256
+ size = 'lg'
257
+ style = { {
258
+ fontSize : ( textFontSize * 0.5 ) . toString ( ) + sizeSuffix ,
259
+ width : '90%' ,
260
+ height : '90%' ,
261
+ color : 'black'
262
+ } }
263
+ onClick = { ( ) => moveToButtonClicked ( mealState ) }
264
+ >
265
+ { name }
266
+ </ Button >
267
+ </ View >
268
+ ) ) }
273
269
< View style = { { flex : 1 , flexDirection : 'column' , alignItems : 'center' , justifyContent : 'center' , width : '100%' , height : '100%' } } >
274
270
< Button
275
271
variant = 'warning'
@@ -281,9 +277,9 @@ const AbovePlate = (props) => {
281
277
height : '90%' ,
282
278
color : 'black'
283
279
} }
284
- onClick = { ( ) => moveToButtonClicked ( MEAL_STATE . R_MovingAbovePlate ) }
280
+ onClick = { ( ) => moveToButtonClicked ( props . startingMealState ) }
285
281
>
286
- Move Above Plate
282
+ { props . buttonName }
287
283
</ Button >
288
284
</ View >
289
285
</ View >
@@ -295,10 +291,14 @@ const AbovePlate = (props) => {
295
291
textFontSize ,
296
292
sizeSuffix ,
297
293
zoomLevel ,
294
+ props . buttonName ,
295
+ props . configurationName ,
296
+ props . otherButtonConfigs ,
297
+ props . startingMealState ,
298
298
props . webrtcURL ,
299
299
mountTeleopSubcomponent ,
300
300
moveToButtonClicked ,
301
- stopServoSuccessCallback ,
301
+ unmountTeleopSubcomponentCallback ,
302
302
storeJointStatesAsLocalParam
303
303
] )
304
304
@@ -311,6 +311,7 @@ const AbovePlate = (props) => {
311
311
312
312
// Render the modal body, for calling robot code from within this settings page
313
313
const renderModalBody = useCallback ( ( ) => {
314
+ console . log ( 'renderModalBody' , localCurrAndNextMealState , robotMotionProps )
314
315
let localCurrMealState = localCurrAndNextMealState [ 0 ]
315
316
switch ( localCurrMealState ) {
316
317
case MEAL_STATE . R_MovingToStagingConfiguration :
@@ -338,23 +339,38 @@ const AbovePlate = (props) => {
338
339
339
340
return (
340
341
< SettingsPageParent
341
- title = 'Above Plate ⚙'
342
+ title = { props . configurationName + ' \u2699' }
342
343
doneCallback = { doneButtonClicked }
343
344
modalShow = { localCurrAndNextMealState [ 0 ] !== null }
344
345
modalOnHide = { ( ) => setLocalCurrMealStateWrapper ( null ) }
345
346
modalChildren = { renderModalBody ( ) }
346
- paramNames = { paramNames }
347
- localParamValues = { currentAbovePlateParam }
348
- setLocalParamValues = { setCurrentAbovePlateParam }
349
- resetToPresetSuccessCallback = { ( ) => moveToButtonClicked ( MEAL_STATE . R_MovingAbovePlate ) }
347
+ paramNames = { props . paramNames }
348
+ localParamValues = { currentConfigurationParams }
349
+ setLocalParamValues = { setCurrentConfigurationParams }
350
+ resetToPresetSuccessCallback = { ( ) => moveToButtonClicked ( props . startingMealState ) }
350
351
>
351
- { renderAbovePlateSettings ( ) }
352
+ { renderSettings ( ) }
352
353
</ SettingsPageParent >
353
354
)
354
355
}
355
- AbovePlate . propTypes = {
356
+ CustomizeConfiguration . propTypes = {
357
+ // The meal state that must be executed before this page is rendered
358
+ startingMealState : PropTypes . string . isRequired ,
359
+ // The names of the parameter this component should tune.
360
+ paramNames : PropTypes . arrayOf ( PropTypes . string ) . isRequired ,
361
+ // The name of the configuration this component tunes.
362
+ configurationName : PropTypes . string . isRequired ,
363
+ // The name of the button that should be clicked to tune the configuration.
364
+ buttonName : PropTypes . string . isRequired ,
365
+ // Other button configs
366
+ otherButtonConfigs : PropTypes . arrayOf (
367
+ PropTypes . shape ( {
368
+ name : PropTypes . string . isRequired ,
369
+ mealState : PropTypes . string . isRequired
370
+ } )
371
+ ) . isRequired ,
356
372
// The URL of the webrtc signalling server
357
373
webrtcURL : PropTypes . string . isRequired
358
374
}
359
375
360
- export default AbovePlate
376
+ export default CustomizeConfiguration
0 commit comments