@@ -3,6 +3,8 @@ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
3
3
import PropTypes from 'prop-types'
4
4
import { useId , Label , SpinButton } from '@fluentui/react-components'
5
5
import Button from 'react-bootstrap/Button'
6
+ import Dropdown from 'react-bootstrap/Dropdown'
7
+ import SplitButton from 'react-bootstrap/SplitButton'
6
8
// The Modal is a screen that appears on top of the main app, and can be toggled
7
9
// on and off.
8
10
import Modal from 'react-bootstrap/Modal'
@@ -14,9 +16,10 @@ import {
14
16
GET_PARAMETERS_SERVICE_NAME ,
15
17
GET_PARAMETERS_SERVICE_TYPE ,
16
18
SET_PARAMETERS_SERVICE_NAME ,
17
- SET_PARAMETERS_SERVICE_TYPE
19
+ SET_PARAMETERS_SERVICE_TYPE ,
20
+ DISTANCE_TO_MOUTH_PARAM
18
21
} from '../Constants'
19
- import { useGlobalState , MEAL_STATE , SETTINGS_STATE } from '../GlobalState'
22
+ import { useGlobalState , MEAL_STATE , SETTINGS_STATE , DEFAULT_NAMESPACE } from '../GlobalState'
20
23
import RobotMotion from '../Home/MealStates/RobotMotion'
21
24
import DetectingFaceSubcomponent from '../Home/MealStates/DetectingFaceSubcomponent'
22
25
@@ -26,6 +29,7 @@ import DetectingFaceSubcomponent from '../Home/MealStates/DetectingFaceSubcompon
26
29
*/
27
30
const BiteTransfer = ( props ) => {
28
31
// Get relevant global state variables
32
+ const settingsPresets = useGlobalState ( ( state ) => state . settingsPresets )
29
33
const setSettingsState = useGlobalState ( ( state ) => state . setSettingsState )
30
34
const globalMealState = useGlobalState ( ( state ) => state . mealState )
31
35
const setPaused = useGlobalState ( ( state ) => state . setPaused )
@@ -130,27 +134,27 @@ const BiteTransfer = (props) => {
130
134
let service = getParametersService . current
131
135
// First, attempt to get the current distance to mouth
132
136
let currentRequest = createROSServiceRequest ( {
133
- names : [ ' current.MoveToMouth.tree_kwargs.plan_distance_from_mouth' ]
137
+ names : [ settingsPresets . current . concat ( '.' , DISTANCE_TO_MOUTH_PARAM ) ]
134
138
} )
135
139
service . callService ( currentRequest , ( response ) => {
136
140
console . log ( 'Got current plan_distance_from_mouth response' , response )
137
- if ( response . values [ 0 ] . type === 0 ) {
141
+ if ( response . values . length === 0 || response . values [ 0 ] . type === 0 ) {
138
142
// Parameter not set
139
143
// Second, attempt to get the default distance to mouth
140
144
let defaultRequest = createROSServiceRequest ( {
141
- names : [ 'default.MoveToMouth.tree_kwargs.plan_distance_from_mouth' ]
145
+ names : [ DEFAULT_NAMESPACE . concat ( '.' , DISTANCE_TO_MOUTH_PARAM ) ]
142
146
} )
143
147
service . callService ( defaultRequest , ( response ) => {
144
148
console . log ( 'Got default plan_distance_from_mouth response' , response )
145
- if ( response . values . length > 0 ) {
149
+ if ( response . values . length > 0 && response . values [ 0 ] . type === 8 ) {
146
150
setCurrentDistanceToMouth ( getParameterValue ( response . values [ 0 ] ) )
147
151
}
148
152
} )
149
153
} else {
150
154
setCurrentDistanceToMouth ( getParameterValue ( response . values [ 0 ] ) )
151
155
}
152
156
} )
153
- } , [ getParametersService , setCurrentDistanceToMouth , setDoneButtonIsClicked , setPaused ] )
157
+ } , [ getParametersService , setCurrentDistanceToMouth , setDoneButtonIsClicked , setPaused , settingsPresets ] )
154
158
155
159
// Callback to set the distance to mouth parameter
156
160
const setDistanceToMouth = useCallback (
@@ -159,7 +163,7 @@ const BiteTransfer = (props) => {
159
163
let request = createROSServiceRequest ( {
160
164
parameters : [
161
165
{
162
- name : ' current.MoveToMouth.tree_kwargs.plan_distance_from_mouth' ,
166
+ name : settingsPresets . current . concat ( '.' , DISTANCE_TO_MOUTH_PARAM ) ,
163
167
value : {
164
168
type : 8 , // double array
165
169
double_array_value : fullDistanceToMouth
@@ -174,23 +178,29 @@ const BiteTransfer = (props) => {
174
178
}
175
179
} )
176
180
} ,
177
- [ setParametersService , setCurrentDistanceToMouth ]
181
+ [ setParametersService , setCurrentDistanceToMouth , settingsPresets ]
178
182
)
179
183
180
184
// Callback to restore the distance to mouth to the default
181
- const restoreToDefaultButtonClicked = useCallback ( ( ) => {
182
- let service = getParametersService . current
183
- // Attempt to get the default distance to mouth
184
- let defaultRequest = createROSServiceRequest ( {
185
- names : [ 'default.MoveToMouth.tree_kwargs.plan_distance_from_mouth' ]
186
- } )
187
- service . callService ( defaultRequest , ( response ) => {
188
- console . log ( 'Got default plan_distance_from_mouth response' , response )
189
- if ( response . values . length > 0 ) {
190
- setDistanceToMouth ( getParameterValue ( response . values [ 0 ] ) )
191
- }
192
- } )
193
- } , [ getParametersService , setDistanceToMouth ] )
185
+ const restoreToPreset = useCallback (
186
+ ( preset ) => {
187
+ console . log ( 'restoreToPreset called with' , preset )
188
+ let service = getParametersService . current
189
+ // Attempt to get the default distance to mouth
190
+ let defaultRequest = createROSServiceRequest ( {
191
+ names : [ preset . concat ( '.' , DISTANCE_TO_MOUTH_PARAM ) ]
192
+ } )
193
+ service . callService ( defaultRequest , ( response ) => {
194
+ console . log ( 'Got plan_distance_from_mouth response' , response )
195
+ if ( response . values . length > 0 && response . values [ 0 ] . type === 8 ) {
196
+ setDistanceToMouth ( getParameterValue ( response . values [ 0 ] ) )
197
+ } else {
198
+ restoreToPreset ( DEFAULT_NAMESPACE )
199
+ }
200
+ } )
201
+ } ,
202
+ [ getParametersService , setDistanceToMouth ]
203
+ )
194
204
195
205
// Callback to move the robot to the mouth
196
206
const moveToMouthButtonClicked = useCallback ( ( ) => {
@@ -275,7 +285,8 @@ const BiteTransfer = (props) => {
275
285
flexDirection : 'column' ,
276
286
justifyContent : 'center' ,
277
287
alignItems : 'center' ,
278
- width : '100%'
288
+ width : '100%' ,
289
+ zIndex : 1
279
290
} }
280
291
>
281
292
< Label
@@ -306,7 +317,7 @@ const BiteTransfer = (props) => {
306
317
size : 'large'
307
318
} }
308
319
/>
309
- < Button
320
+ < SplitButton
310
321
variant = 'warning'
311
322
className = 'mx-2 mb-2 btn-huge'
312
323
size = 'lg'
@@ -315,10 +326,17 @@ const BiteTransfer = (props) => {
315
326
width : '60%' ,
316
327
color : 'black'
317
328
} }
318
- onClick = { restoreToDefaultButtonClicked }
329
+ title = { 'Set to ' . concat ( DEFAULT_NAMESPACE ) }
330
+ onClick = { ( ) => restoreToPreset ( DEFAULT_NAMESPACE ) }
319
331
>
320
- Set to Default
321
- </ Button >
332
+ { settingsPresets . customNames
333
+ . filter ( ( x ) => x !== settingsPresets . current )
334
+ . map ( ( preset ) => (
335
+ < Dropdown . Item key = { preset } onClick = { ( ) => restoreToPreset ( preset ) } >
336
+ Set to { preset }
337
+ </ Dropdown . Item >
338
+ ) ) }
339
+ </ SplitButton >
322
340
</ View >
323
341
< View
324
342
style = { {
@@ -396,7 +414,8 @@ const BiteTransfer = (props) => {
396
414
distanceToMouthId ,
397
415
moveToMouthButtonClicked ,
398
416
moveAwayFromMouthButtonClicked ,
399
- restoreToDefaultButtonClicked
417
+ restoreToPreset ,
418
+ settingsPresets
400
419
] )
401
420
402
421
// When a face is detected, switch to MoveToMouth
@@ -435,18 +454,52 @@ const BiteTransfer = (props) => {
435
454
< >
436
455
< View
437
456
style = { {
438
- flex : 2 ,
457
+ flex : 4 ,
439
458
flexDirection : 'column' ,
440
459
justifyContent : 'center' ,
441
460
alignItems : 'center' ,
442
461
width : '100%'
443
462
} }
444
463
>
445
- < h5 style = { { textAlign : 'center' , fontSize : textFontSize } } > Customize Bite Transfer</ h5 >
464
+ < p style = { { textAlign : 'center' , fontSize : textFontSize , margin : 0 } } className = 'txt-huge' >
465
+ Bite Transfer Settings
466
+ </ p >
467
+ </ View >
468
+ < View
469
+ style = { {
470
+ flex : 3 ,
471
+ flexDirection : 'row' ,
472
+ justifyContent : 'center' ,
473
+ alignItems : 'center' ,
474
+ width : '100%'
475
+ } }
476
+ >
477
+ < View
478
+ style = { {
479
+ flex : 1 ,
480
+ justifyContent : 'center' ,
481
+ alignItems : 'end' ,
482
+ width : '100%'
483
+ } }
484
+ >
485
+ < p style = { { fontSize : textFontSize , textAlign : 'right' , margin : '0rem' } } > Preset:</ p >
486
+ </ View >
487
+ < View
488
+ style = { {
489
+ flex : 1 ,
490
+ justifyContent : 'center' ,
491
+ alignItems : 'start' ,
492
+ width : '100%'
493
+ } }
494
+ >
495
+ < Button variant = 'secondary' disabled size = 'lg' style = { { marginLeft : '1rem' } } >
496
+ { settingsPresets . current }
497
+ </ Button >
498
+ </ View >
446
499
</ View >
447
500
< View
448
501
style = { {
449
- flex : 16 ,
502
+ flex : 32 ,
450
503
flexDirection : 'column' ,
451
504
justifyContent : 'center' ,
452
505
alignItems : 'center' ,
@@ -457,7 +510,7 @@ const BiteTransfer = (props) => {
457
510
</ View >
458
511
< View
459
512
style = { {
460
- flex : 2 ,
513
+ flex : 4 ,
461
514
flexDirection : 'column' ,
462
515
justifyContent : 'center' ,
463
516
alignItems : 'center' ,
0 commit comments