Skip to content

Commit 98ca809

Browse files
authored
Allow users to skip acquisition on error (#144)
* Allow users to skip acquisition on error * Fixes from testing
1 parent 17e17ce commit 98ca809

File tree

3 files changed

+85
-37
lines changed

3 files changed

+85
-37
lines changed

feedingwebapp/src/Pages/Constants.js

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,6 @@ export const SERVO_CARTESIAN_TOPIC_MSG = 'geometry_msgs/msg/TwistStamped'
4343
export const SERVO_JOINT_TOPIC = '/web_app/servo_node/delta_joint_cmds'
4444
export const SERVO_JOINT_TOPIC_MSG = 'control_msgs/msg/JointJog'
4545

46-
// States from which, if they fail, it is NOT okay for the user to retry the
47-
// same action.
48-
let NON_RETRYABLE_STATES = new Set()
49-
NON_RETRYABLE_STATES.add(MEAL_STATE.R_BiteAcquisition)
50-
export { NON_RETRYABLE_STATES }
51-
5246
/**
5347
* For states that call ROS actions, this dictionary contains
5448
* the action name and the message type

feedingwebapp/src/Pages/Home/Home.jsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,9 @@ function Home(props) {
118118
let currentMealState = MEAL_STATE.R_BiteAcquisition
119119
let nextMealState = MEAL_STATE.U_BiteAcquisitionCheck
120120
let backMealState = MEAL_STATE.R_MovingAbovePlate
121+
// TODO: Add an icon for this errorMealState!
122+
let errorMealState = MEAL_STATE.R_MovingToRestingPosition
123+
let errorMealStateDescription = 'Skip Acquisition'
121124
return (
122125
<RobotMotion
123126
debug={props.debug}
@@ -127,6 +130,9 @@ function Home(props) {
127130
backMealState={backMealState}
128131
actionInput={biteAcquisitionActionInput}
129132
waitingText={getRobotMotionText(currentMealState)}
133+
allowRetry={false} // Don't allow retrying bite acquisition
134+
errorMealState={errorMealState}
135+
errorMealStateDescription={errorMealStateDescription}
130136
/>
131137
)
132138
}

feedingwebapp/src/Pages/Home/MealStates/RobotMotion.jsx

Lines changed: 79 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import { useGlobalState } from '../../GlobalState'
2222
import {
2323
CLEAR_OCTOMAP_SERVICE_NAME,
2424
CLEAR_OCTOMAP_SERVICE_TYPE,
25-
NON_RETRYABLE_STATES,
2625
ROS_ACTIONS_NAMES,
2726
MOTION_STATUS_SUCCESS,
2827
ROS_ACTION_STATUS_CANCEL_GOAL,
@@ -124,15 +123,28 @@ const RobotMotion = (props) => {
124123
[setActionStatus]
125124
)
126125

126+
/**
127+
* Callback function to change the meal state.
128+
*/
129+
const changeMealState = useCallback(
130+
(nextMealState, msg = null) => {
131+
if (msg) {
132+
console.log(msg)
133+
}
134+
setPaused(false)
135+
let setMealState = props.setMealState
136+
setMealState(nextMealState)
137+
},
138+
[setPaused, props.setMealState]
139+
)
140+
127141
/**
128142
* Callback function for when the robot has finished moving to its staging
129143
* location.
130144
*/
131145
const robotMotionDone = useCallback(() => {
132-
console.log('robotMotionDone')
133-
let setMealState = props.setMealState
134-
setMealState(props.nextMealState)
135-
}, [props.nextMealState, props.setMealState])
146+
changeMealState(props.nextMealState, 'robotMotionDone')
147+
}, [changeMealState, props.nextMealState])
136148

137149
/**
138150
* Callback function for when the action sends a response. It updates the
@@ -264,10 +276,8 @@ const RobotMotion = (props) => {
264276
}, [clearOctomapService, resumeCallback])
265277

266278
const backCallback = useCallback(() => {
267-
setPaused(false)
268-
let setMealState = props.setMealState
269-
setMealState(props.backMealState)
270-
}, [setPaused, props.backMealState, props.setMealState])
279+
changeMealState(props.backMealState, 'backCallback')
280+
}, [changeMealState, props.backMealState])
271281

272282
/**
273283
* Get the action status text and progress bar or blank view to render.
@@ -279,12 +289,12 @@ const RobotMotion = (props) => {
279289
* @param {showTime} - indicates if elapsed time needs to be shown
280290
* @param {time} - calculated elapsed time, 0 if time not available
281291
* @param {progress} - progress proportion; if null progress bar not shown
282-
* @param {retry} - indicates if retry needed for error
292+
* @param {error} - indicates if there was an error
283293
*
284294
* @returns {JSX.Element} the action status text, progress bar or blank view
285295
*/
286296
const actionStatusTextAndVisual = useCallback(
287-
(flexSizeOuter, flexSizeTextInner, flexSizeVisualInner, text, showTime, time, progress, retry = false) => {
297+
(flexSizeOuter, flexSizeTextInner, flexSizeVisualInner, text, showTime, time, progress, error = false) => {
288298
return (
289299
<>
290300
<View style={{ flex: flexSizeOuter, flexDirection: dimension, alignItems: 'center', justifyContent: 'center', width: '100%' }}>
@@ -294,19 +304,41 @@ const RobotMotion = (props) => {
294304
</p>
295305
<p style={{ fontSize: motionTextFontSize }}>{text}</p>
296306
{showTime ? <p style={{ fontSize: motionTextFontSize }}>&nbsp;&nbsp;Elapsed: {time} sec</p> : <></>}
297-
{retry ? (
298-
<Button
299-
variant='warning'
300-
className='mx-2 btn-huge'
301-
size='lg'
302-
onClick={retryCallback}
303-
style={{
304-
width: '90%',
305-
height: '20%'
306-
}}
307-
>
308-
<h5 style={{ textAlign: 'center', fontSize: motionTextFontSize }}>Retry</h5>
309-
</Button>
307+
{error ? (
308+
<>
309+
{props.allowRetry ? (
310+
<Button
311+
variant='warning'
312+
className='mx-2 btn-huge'
313+
size='lg'
314+
onClick={retryCallback}
315+
style={{
316+
width: '90%',
317+
height: '20%'
318+
}}
319+
>
320+
<h5 style={{ textAlign: 'center', fontSize: motionTextFontSize }}>Retry</h5>
321+
</Button>
322+
) : (
323+
<></>
324+
)}
325+
{props.errorMealState ? (
326+
<Button
327+
variant='warning'
328+
className='mx-2 btn-huge'
329+
size='lg'
330+
onClick={() => changeMealState(props.errorMealState, 'errorMealState')}
331+
style={{
332+
width: '90%',
333+
height: '20%'
334+
}}
335+
>
336+
<h5 style={{ textAlign: 'center', fontSize: motionTextFontSize }}>{props.errorMealStateDescription}</h5>
337+
</Button>
338+
) : (
339+
<></>
340+
)}
341+
</>
310342
) : (
311343
<></>
312344
)}
@@ -326,7 +358,17 @@ const RobotMotion = (props) => {
326358
</>
327359
)
328360
},
329-
[dimension, props.waitingText, motionTextFontSize, waitingTextFontSize, retryCallback]
361+
[
362+
dimension,
363+
props.waitingText,
364+
props.allowRetry,
365+
props.errorMealState,
366+
props.errorMealStateDescription,
367+
motionTextFontSize,
368+
waitingTextFontSize,
369+
retryCallback,
370+
changeMealState
371+
]
330372
)
331373

332374
/**
@@ -342,7 +384,7 @@ const RobotMotion = (props) => {
342384
let showTime = false
343385
let time = 0
344386
let progress = null
345-
let retry = false
387+
let error = false
346388
switch (actionStatus.actionStatus) {
347389
case ROS_ACTION_STATUS_EXECUTE:
348390
if (actionStatus.feedback) {
@@ -377,9 +419,9 @@ const RobotMotion = (props) => {
377419
* users on how to troubleshoot/fix it.
378420
*/
379421
text = 'Robot encountered an error'
380-
retry = NON_RETRYABLE_STATES.has(props.mealState) ? false : true
422+
error = true
381423
return (
382-
<>{actionStatusTextAndVisual(flexSizeOuter, flexSizeTextInner, flexSizeVisualInner, text, showTime, time, progress, retry)}</>
424+
<>{actionStatusTextAndVisual(flexSizeOuter, flexSizeTextInner, flexSizeVisualInner, text, showTime, time, progress, error)}</>
383425
)
384426
case ROS_ACTION_STATUS_CANCELED:
385427
return <>{actionStatusTextAndVisual(flexSizeOuter, flexSizeTextInner, flexSizeVisualInner, text, showTime, time, progress)}</>
@@ -397,7 +439,7 @@ const RobotMotion = (props) => {
397439
}
398440
}
399441
},
400-
[paused, dimension, actionStatusTextAndVisual, props.mealState]
442+
[paused, dimension, actionStatusTextAndVisual]
401443
)
402444

403445
// Render the component
@@ -421,7 +463,7 @@ const RobotMotion = (props) => {
421463
pauseCallback={pauseCallback}
422464
backCallback={props.backMealState ? backCallback : null}
423465
backMealState={props.backMealState}
424-
resumeCallback={NON_RETRYABLE_STATES.has(props.mealState) ? null : resumeCallback}
466+
resumeCallback={props.allowRetry ? resumeCallback : null}
425467
paused={paused}
426468
/>
427469
</>
@@ -454,10 +496,16 @@ RobotMotion.propTypes = {
454496
// the action client, then calling it again, etc.)
455497
actionInput: PropTypes.object.isRequired,
456498
// The static text to display while the robot is executing the action
457-
waitingText: PropTypes.string.isRequired
499+
waitingText: PropTypes.string.isRequired,
500+
// Whether to show the retry/resume option if the action fails
501+
allowRetry: PropTypes.bool,
502+
// If error, show the user the option to transition to this meal state
503+
errorMealState: PropTypes.string,
504+
errorMealStateDescription: PropTypes.string
458505
}
459506

460507
RobotMotion.defaultProps = {
508+
allowRetry: true,
461509
debug: false
462510
}
463511

0 commit comments

Comments
 (0)