diff --git a/feedingwebapp/src/Pages/Constants.js b/feedingwebapp/src/Pages/Constants.js index 0bf1cd4..0ac1b99 100644 --- a/feedingwebapp/src/Pages/Constants.js +++ b/feedingwebapp/src/Pages/Constants.js @@ -125,6 +125,10 @@ export const SET_PARAMETERS_SERVICE_TYPE = 'rcl_interfaces/srv/SetParametersAtom // The names of parameters users can change in the settings menu export const DISTANCE_TO_MOUTH_PARAM = 'MoveToMouth.tree_kwargs.plan_distance_from_mouth' +export const MOVE_TO_MOUTH_SPEED_PARAM = 'MoveToMouth.tree_kwargs.max_linear_speed' +export const MOVE_TO_MOUTH_SPEED_NEAR_MOUTH_PARAM = 'MoveToMouth.tree_kwargs.linear_speed_near_mouth' +export const MOVE_FROM_MOUTH_SPEED_PARAM = 'MoveFromMouth.tree_kwargs.max_linear_speed_to_staging_configuration' +export const MOVE_FROM_MOUTH_SPEED_NEAR_MOUTH_PARAM = 'MoveFromMouth.tree_kwargs.linear_speed_near_mouth' export const ABOVE_PLATE_PARAM_JOINTS = 'MoveAbovePlate.tree_kwargs.joint_positions' export const STAGING_PARAM_JOINTS = 'MoveToStagingConfiguration.tree_kwargs.goal_configuration' export const STAGING_PARAM_POSITION = 'MoveFromMouth.tree_kwargs.staging_configuration_position' diff --git a/feedingwebapp/src/Pages/GlobalState.jsx b/feedingwebapp/src/Pages/GlobalState.jsx index 45308a7..5d6e211 100644 --- a/feedingwebapp/src/Pages/GlobalState.jsx +++ b/feedingwebapp/src/Pages/GlobalState.jsx @@ -76,8 +76,8 @@ export { NON_MOVING_STATES } /** * SETTINGS_STATE controls which settings page to display. * - MAIN: The main page, with options to navigate to the other pages. - * - DISTANCE_TO_MOUTH: Allow the user to customize how close the robot gets - * to their mouth. + * - BITE_TRANSFER: Allow the user to customize how close the robot gets + * to their mouth and the speed of approach/departure. * - ABOVE_PLATE: Allow the user to customize how high the fixed above plate * arm configuration. * - RESTING_CONFIGURATION: Allow the user to customize the fixed resting @@ -89,7 +89,7 @@ export { NON_MOVING_STATES } */ export const SETTINGS_STATE = { MAIN: 'MAIN', - DISTANCE_TO_MOUTH: 'DISTANCE_TO_MOUTH', + BITE_TRANSFER: 'BITE_TRANSFER', ABOVE_PLATE: 'ABOVE_PLATE', RESTING_CONFIGURATION: 'RESTING_CONFIGURATION', STAGING_CONFIGURATION: 'STAGING_CONFIGURATION', diff --git a/feedingwebapp/src/Pages/Settings/BiteTransfer.jsx b/feedingwebapp/src/Pages/Settings/BiteTransfer.jsx index e0c3d24..bcfba22 100644 --- a/feedingwebapp/src/Pages/Settings/BiteTransfer.jsx +++ b/feedingwebapp/src/Pages/Settings/BiteTransfer.jsx @@ -7,7 +7,14 @@ import Button from 'react-bootstrap/Button' import { View } from 'react-native' // Local imports -import { getRobotMotionText, DISTANCE_TO_MOUTH_PARAM } from '../Constants' +import { + getRobotMotionText, + DISTANCE_TO_MOUTH_PARAM, + MOVE_TO_MOUTH_SPEED_PARAM, + MOVE_TO_MOUTH_SPEED_NEAR_MOUTH_PARAM, + MOVE_FROM_MOUTH_SPEED_PARAM, + MOVE_FROM_MOUTH_SPEED_NEAR_MOUTH_PARAM +} from '../Constants' import { useGlobalState, MEAL_STATE, SETTINGS_STATE } from '../GlobalState' import RobotMotion from '../Home/MealStates/RobotMotion' import DetectingFaceSubcomponent from '../Home/MealStates/DetectingFaceSubcomponent' @@ -28,8 +35,17 @@ const BiteTransfer = (props) => { // Create relevant local state variables // Configure the parameters for SettingsPageParent - const paramNames = useMemo(() => [DISTANCE_TO_MOUTH_PARAM], []) - const [currentDistanceToMouth, setCurrentDistanceToMouth] = useState([null]) + const paramNames = useMemo( + () => [ + DISTANCE_TO_MOUTH_PARAM, + MOVE_TO_MOUTH_SPEED_PARAM, + MOVE_TO_MOUTH_SPEED_NEAR_MOUTH_PARAM, + MOVE_FROM_MOUTH_SPEED_PARAM, + MOVE_FROM_MOUTH_SPEED_NEAR_MOUTH_PARAM + ], + [] + ) + const [currentParams, setCurrentParams] = useState([null, null, null, null, null]) const [localCurrAndNextMealState, setLocalCurrAndNextMealState] = useState( globalMealState === MEAL_STATE.U_BiteDone || globalMealState === MEAL_STATE.R_DetectingFace || settingsPageAtMouth ? [MEAL_STATE.R_MovingFromMouth, null] @@ -53,6 +69,8 @@ const BiteTransfer = (props) => { // Get min and max distance to mouth const minDistanceToMouth = 1 // cm const maxDistanceToMouth = 10 // cm + const minLinearSpeed = 2 // cm/s + const maxLinearSpeed = 15 // cm/s // When we set local meal state, also update bite transfer page at face const setLocalCurrMealStateWrapper = useCallback( @@ -166,16 +184,57 @@ const BiteTransfer = (props) => { if (value > maxDistanceToMouth) { value = maxDistanceToMouth } - let fullDistanceToMouth = [value / 100.0, currentDistanceToMouth[0][1], currentDistanceToMouth[0][2]] - setCurrentDistanceToMouth([fullDistanceToMouth]) + let distance_m = value / 100.0 + setCurrentParams((currentParams) => [ + [distance_m, currentParams[0][1], currentParams[0][2]], + currentParams[1], + currentParams[2], + currentParams[3], + currentParams[4] + ]) + }, + [minDistanceToMouth, maxDistanceToMouth] + ) + + // Callback for when the user changes the speed to the mouth + const onSpeedChange = useCallback( + (_ev, data, index) => { + let value = data.value !== null ? data.value : parseFloat(data.displayValue) + if (value < minLinearSpeed) { + value = minLinearSpeed + } + if (value > maxLinearSpeed) { + value = maxLinearSpeed + } + let speed_mps = value / 100.0 + setCurrentParams((currentParams) => [ + currentParams[0], + index === 1 ? speed_mps : currentParams[1], + index === 2 ? speed_mps : currentParams[2], + index === 3 ? speed_mps : currentParams[3], + index === 4 ? speed_mps : currentParams[4] + ]) }, - [currentDistanceToMouth, minDistanceToMouth, maxDistanceToMouth] + [minLinearSpeed, maxLinearSpeed] ) // Callback to render the main contents of the page const distanceToMouthId = useId() + const moveToMouthSpeedId = useId() + const moveToMouthSpeedNearMouthId = useId() + const moveFromMouthSpeedId = useId() + const moveFromMouthSpeedNearMouthId = useId() + const speedParameterIdsAndDescriptions = useMemo( + () => [ + [moveToMouthSpeedId, 'Approach Speed (cm/s)'], + [moveToMouthSpeedNearMouthId, 'Approach Speed Near Mouth (cm/s)'], + [moveFromMouthSpeedId, 'Retreat Speed (cm/s)'], + [moveFromMouthSpeedNearMouthId, 'Retreat Speed Near Mouth (cm/s)'] + ], + [moveToMouthSpeedId, moveToMouthSpeedNearMouthId, moveFromMouthSpeedId, moveFromMouthSpeedNearMouthId] + ) const renderBiteTransferSettings = useCallback(() => { - if (currentDistanceToMouth[0] === null) { + if (currentParams.some((param) => param === null)) { return ( <> { Distance To Mouth (cm) { size: 'large' }} /> + {speedParameterIdsAndDescriptions.map(([id, description], index) => ( + <> + + onSpeedChange(_ev, data, index + 1)} + appearance='filled-lighter' + style={{ + fontSize: textFontSize, + width: '90%', + color: 'black' + }} + incrementButton={{ + 'aria-label': 'Increase value by 1.0', + 'aria-roledescription': 'spinner', + size: 'large' + }} + /> + + ))} { }, [ dimension, textFontSize, - currentDistanceToMouth, + currentParams, onDistanceToMouthChange, + onSpeedChange, distanceToMouthId, + speedParameterIdsAndDescriptions, moveToMouthButtonClicked, moveAwayFromMouthButtonClicked ]) @@ -368,8 +461,8 @@ const BiteTransfer = (props) => { modalOnHide={() => setLocalCurrMealStateWrapper(null)} modalChildren={renderModalBody()} paramNames={paramNames} - localParamValues={currentDistanceToMouth} - setLocalParamValues={setCurrentDistanceToMouth} + localParamValues={currentParams} + setLocalParamValues={setCurrentParams} > {renderBiteTransferSettings()} diff --git a/feedingwebapp/src/Pages/Settings/Main.jsx b/feedingwebapp/src/Pages/Settings/Main.jsx index 87cbbc9..09c1022 100644 --- a/feedingwebapp/src/Pages/Settings/Main.jsx +++ b/feedingwebapp/src/Pages/Settings/Main.jsx @@ -163,9 +163,9 @@ const Main = () => { // Configure the different options in the settings menu let settingsConfig = [ { - title: 'Distance to Mouth', + title: 'Motion to/from Mouth', icon: moveToMouthConfigurationImage, - onClick: () => onClickSettingsPage(SETTINGS_STATE.DISTANCE_TO_MOUTH) + onClick: () => onClickSettingsPage(SETTINGS_STATE.BITE_TRANSFER) }, { title: 'Above Plate', diff --git a/feedingwebapp/src/Pages/Settings/Settings.jsx b/feedingwebapp/src/Pages/Settings/Settings.jsx index 3bdec42..b325b71 100644 --- a/feedingwebapp/src/Pages/Settings/Settings.jsx +++ b/feedingwebapp/src/Pages/Settings/Settings.jsx @@ -42,7 +42,7 @@ const Settings = (props) => { switch (settingsState) { case SETTINGS_STATE.MAIN: return
- case SETTINGS_STATE.DISTANCE_TO_MOUTH: + case SETTINGS_STATE.BITE_TRANSFER: return case SETTINGS_STATE.ABOVE_PLATE: return (