@@ -7,7 +7,14 @@ import Button from 'react-bootstrap/Button'
7
7
import { View } from 'react-native'
8
8
9
9
// Local imports
10
- import { getRobotMotionText , DISTANCE_TO_MOUTH_PARAM } from '../Constants'
10
+ import {
11
+ getRobotMotionText ,
12
+ DISTANCE_TO_MOUTH_PARAM ,
13
+ MOVE_TO_MOUTH_SPEED_PARAM ,
14
+ MOVE_TO_MOUTH_SPEED_NEAR_MOUTH_PARAM ,
15
+ MOVE_FROM_MOUTH_SPEED_PARAM ,
16
+ MOVE_FROM_MOUTH_SPEED_NEAR_MOUTH_PARAM
17
+ } from '../Constants'
11
18
import { useGlobalState , MEAL_STATE , SETTINGS_STATE } from '../GlobalState'
12
19
import RobotMotion from '../Home/MealStates/RobotMotion'
13
20
import DetectingFaceSubcomponent from '../Home/MealStates/DetectingFaceSubcomponent'
@@ -28,8 +35,17 @@ const BiteTransfer = (props) => {
28
35
29
36
// Create relevant local state variables
30
37
// Configure the parameters for SettingsPageParent
31
- const paramNames = useMemo ( ( ) => [ DISTANCE_TO_MOUTH_PARAM ] , [ ] )
32
- const [ currentDistanceToMouth , setCurrentDistanceToMouth ] = useState ( [ null ] )
38
+ const paramNames = useMemo (
39
+ ( ) => [
40
+ DISTANCE_TO_MOUTH_PARAM ,
41
+ MOVE_TO_MOUTH_SPEED_PARAM ,
42
+ MOVE_TO_MOUTH_SPEED_NEAR_MOUTH_PARAM ,
43
+ MOVE_FROM_MOUTH_SPEED_PARAM ,
44
+ MOVE_FROM_MOUTH_SPEED_NEAR_MOUTH_PARAM
45
+ ] ,
46
+ [ ]
47
+ )
48
+ const [ currentParams , setCurrentParams ] = useState ( [ null , null , null , null , null ] )
33
49
const [ localCurrAndNextMealState , setLocalCurrAndNextMealState ] = useState (
34
50
globalMealState === MEAL_STATE . U_BiteDone || globalMealState === MEAL_STATE . R_DetectingFace || settingsPageAtMouth
35
51
? [ MEAL_STATE . R_MovingFromMouth , null ]
@@ -53,6 +69,8 @@ const BiteTransfer = (props) => {
53
69
// Get min and max distance to mouth
54
70
const minDistanceToMouth = 1 // cm
55
71
const maxDistanceToMouth = 10 // cm
72
+ const minLinearSpeed = 2 // cm/s
73
+ const maxLinearSpeed = 15 // cm/s
56
74
57
75
// When we set local meal state, also update bite transfer page at face
58
76
const setLocalCurrMealStateWrapper = useCallback (
@@ -166,16 +184,57 @@ const BiteTransfer = (props) => {
166
184
if ( value > maxDistanceToMouth ) {
167
185
value = maxDistanceToMouth
168
186
}
169
- let fullDistanceToMouth = [ value / 100.0 , currentDistanceToMouth [ 0 ] [ 1 ] , currentDistanceToMouth [ 0 ] [ 2 ] ]
170
- setCurrentDistanceToMouth ( [ fullDistanceToMouth ] )
187
+ let distance_m = value / 100.0
188
+ setCurrentParams ( ( currentParams ) => [
189
+ [ distance_m , currentParams [ 0 ] [ 1 ] , currentParams [ 0 ] [ 2 ] ] ,
190
+ currentParams [ 1 ] ,
191
+ currentParams [ 2 ] ,
192
+ currentParams [ 3 ] ,
193
+ currentParams [ 4 ]
194
+ ] )
195
+ } ,
196
+ [ minDistanceToMouth , maxDistanceToMouth ]
197
+ )
198
+
199
+ // Callback for when the user changes the speed to the mouth
200
+ const onSpeedChange = useCallback (
201
+ ( _ev , data , index ) => {
202
+ let value = data . value !== null ? data . value : parseFloat ( data . displayValue )
203
+ if ( value < minLinearSpeed ) {
204
+ value = minLinearSpeed
205
+ }
206
+ if ( value > maxLinearSpeed ) {
207
+ value = maxLinearSpeed
208
+ }
209
+ let speed_mps = value / 100.0
210
+ setCurrentParams ( ( currentParams ) => [
211
+ currentParams [ 0 ] ,
212
+ index === 1 ? speed_mps : currentParams [ 1 ] ,
213
+ index === 2 ? speed_mps : currentParams [ 2 ] ,
214
+ index === 3 ? speed_mps : currentParams [ 3 ] ,
215
+ index === 4 ? speed_mps : currentParams [ 4 ]
216
+ ] )
171
217
} ,
172
- [ currentDistanceToMouth , minDistanceToMouth , maxDistanceToMouth ]
218
+ [ minLinearSpeed , maxLinearSpeed ]
173
219
)
174
220
175
221
// Callback to render the main contents of the page
176
222
const distanceToMouthId = useId ( )
223
+ const moveToMouthSpeedId = useId ( )
224
+ const moveToMouthSpeedNearMouthId = useId ( )
225
+ const moveFromMouthSpeedId = useId ( )
226
+ const moveFromMouthSpeedNearMouthId = useId ( )
227
+ const speedParameterIdsAndDescriptions = useMemo (
228
+ ( ) => [
229
+ [ moveToMouthSpeedId , 'Approach Speed (cm/s)' ] ,
230
+ [ moveToMouthSpeedNearMouthId , 'Approach Speed Near Mouth (cm/s)' ] ,
231
+ [ moveFromMouthSpeedId , 'Retreat Speed (cm/s)' ] ,
232
+ [ moveFromMouthSpeedNearMouthId , 'Retreat Speed Near Mouth (cm/s)' ]
233
+ ] ,
234
+ [ moveToMouthSpeedId , moveToMouthSpeedNearMouthId , moveFromMouthSpeedId , moveFromMouthSpeedNearMouthId ]
235
+ )
177
236
const renderBiteTransferSettings = useCallback ( ( ) => {
178
- if ( currentDistanceToMouth [ 0 ] === null ) {
237
+ if ( currentParams . some ( ( param ) => param === null ) ) {
179
238
return (
180
239
< >
181
240
< View
@@ -225,7 +284,7 @@ const BiteTransfer = (props) => {
225
284
Distance To Mouth (cm)
226
285
</ Label >
227
286
< SpinButton
228
- value = { currentDistanceToMouth [ 0 ] [ 0 ] * 100 }
287
+ value = { currentParams [ 0 ] [ 0 ] * 100 }
229
288
id = { distanceToMouthId }
230
289
step = { 0.5 }
231
290
onChange = { onDistanceToMouthChange }
@@ -241,6 +300,38 @@ const BiteTransfer = (props) => {
241
300
size : 'large'
242
301
} }
243
302
/>
303
+ { speedParameterIdsAndDescriptions . map ( ( [ id , description ] , index ) => (
304
+ < >
305
+ < Label
306
+ htmlFor = { id }
307
+ style = { {
308
+ fontSize : textFontSize ,
309
+ width : '90%' ,
310
+ color : 'black' ,
311
+ textAlign : 'center'
312
+ } }
313
+ >
314
+ { description }
315
+ </ Label >
316
+ < SpinButton
317
+ value = { currentParams [ index + 1 ] * 100 }
318
+ id = { id }
319
+ step = { 1.0 }
320
+ onChange = { ( _ev , data ) => onSpeedChange ( _ev , data , index + 1 ) }
321
+ appearance = 'filled-lighter'
322
+ style = { {
323
+ fontSize : textFontSize ,
324
+ width : '90%' ,
325
+ color : 'black'
326
+ } }
327
+ incrementButton = { {
328
+ 'aria-label' : 'Increase value by 1.0' ,
329
+ 'aria-roledescription' : 'spinner' ,
330
+ size : 'large'
331
+ } }
332
+ />
333
+ </ >
334
+ ) ) }
244
335
</ View >
245
336
< View
246
337
style = { {
@@ -321,9 +412,11 @@ const BiteTransfer = (props) => {
321
412
} , [
322
413
dimension ,
323
414
textFontSize ,
324
- currentDistanceToMouth ,
415
+ currentParams ,
325
416
onDistanceToMouthChange ,
417
+ onSpeedChange ,
326
418
distanceToMouthId ,
419
+ speedParameterIdsAndDescriptions ,
327
420
moveToMouthButtonClicked ,
328
421
moveAwayFromMouthButtonClicked
329
422
] )
@@ -368,8 +461,8 @@ const BiteTransfer = (props) => {
368
461
modalOnHide = { ( ) => setLocalCurrMealStateWrapper ( null ) }
369
462
modalChildren = { renderModalBody ( ) }
370
463
paramNames = { paramNames }
371
- localParamValues = { currentDistanceToMouth }
372
- setLocalParamValues = { setCurrentDistanceToMouth }
464
+ localParamValues = { currentParams }
465
+ setLocalParamValues = { setCurrentParams }
373
466
>
374
467
{ renderBiteTransferSettings ( ) }
375
468
</ SettingsPageParent >
0 commit comments