Skip to content

Reset Workspace Walls When Customizing Configurations #139

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions feedingwebapp/src/Pages/Constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ export const START_CARTESIAN_CONTROLLER_ACTION_NAME = 'ActivateCartesianControll
export const START_CARTESIAN_CONTROLLER_ACTION_TYPE = 'ada_feeding_msgs/action/Trigger'
export const START_JOINT_CONTROLLER_ACTION_NAME = 'ActivateJointController'
export const START_JOINT_CONTROLLER_ACTION_TYPE = 'ada_feeding_msgs/action/Trigger'
export const RECOMPUTE_WORKSPACE_WALLS_ACTION_NAME = 'recompute_workspace_walls'
export const RECOMPUTE_WORKSPACE_WALLS_ACTION_TYPE = 'ada_feeding_msgs/action/Trigger'

/**
* For states that call ROS services, this dictionary contains
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,7 @@ const CustomizeConfiguration = (props) => {
localParamValues={currentConfigurationParams}
setLocalParamValues={setCurrentConfigurationParams}
resetToPresetSuccessCallback={resetToPresetSuccessCallback}
resetWorkspaceWallsOnParameterUpdate={true}
>
{renderSettings()}
</SettingsPageParent>
Expand Down
87 changes: 76 additions & 11 deletions feedingwebapp/src/Pages/Settings/SettingsPageParent.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,22 @@ import PropTypes from 'prop-types'
import { View } from 'react-native'

// Local imports
import { useROS, createROSService, createROSServiceRequest, getValueFromParameter, getParameterFromValue } from '../../ros/ros_helpers'
import {
useROS,
createROSService,
createROSServiceRequest,
getValueFromParameter,
getParameterFromValue,
callROSAction,
createROSActionClient,
createROSMessage,
destroyActionClient
} from '../../ros/ros_helpers'
import {
GET_PARAMETERS_SERVICE_NAME,
GET_PARAMETERS_SERVICE_TYPE,
RECOMPUTE_WORKSPACE_WALLS_ACTION_NAME,
RECOMPUTE_WORKSPACE_WALLS_ACTION_TYPE,
SET_PARAMETERS_SERVICE_NAME,
SET_PARAMETERS_SERVICE_TYPE
} from '../Constants'
Expand All @@ -30,6 +42,7 @@ const SettingsPageParent = (props) => {

// Get relevant local state variables
const isResettingToPreset = useRef(false)
const numTimesResetWorkspaceWalls = useRef(0)

// Flag to check if the current orientation is portrait
const isPortrait = useMediaQuery({ query: '(orientation: portrait)' })
Expand All @@ -49,6 +62,14 @@ const SettingsPageParent = (props) => {
let getParametersService = useRef(createROSService(ros.current, GET_PARAMETERS_SERVICE_NAME, GET_PARAMETERS_SERVICE_TYPE))
let setParametersService = useRef(createROSService(ros.current, SET_PARAMETERS_SERVICE_NAME, SET_PARAMETERS_SERVICE_TYPE))

/**
* Create the ROS Action Client. This is created in useRef to avoid
* re-creating it upon re-renders.
*/
let recomputeWorkspaceWallsAction = useRef(
createROSActionClient(ros.current, RECOMPUTE_WORKSPACE_WALLS_ACTION_NAME, RECOMPUTE_WORKSPACE_WALLS_ACTION_TYPE)
)

/**
* Get the paramater values in the specified namespace or, if they don't exist,
* in the default namespace. Set the local state to these values.
Expand Down Expand Up @@ -130,20 +151,50 @@ const SettingsPageParent = (props) => {
console.log('Sending SetParameter request', currentRequest)
service.callService(currentRequest, (response) => {
console.log('For request', currentRequest, 'received SetParameter response', response)
// If this is wrapping up a reset to preset, call the callback
if (isResettingToPreset.current) {
let resetToPresetSuccessCallback = props.resetToPresetSuccessCallback.current
resetToPresetSuccessCallback()
isResettingToPreset.current = false
// If it was succesful, and if the props specify, then call the action to update the
// workspace walls.
if (response.result.successful) {
if (props.resetWorkspaceWallsOnParameterUpdate) {
console.log('Calling recompute_workspace_walls action')
// numTimesResetWorkspaceWalls is used to ensure the result callback
// only gets registered the first time. This is okay because none of the
// values in the callback are expected to change.
callROSAction(
recomputeWorkspaceWallsAction.current,
createROSMessage({}),
null,
numTimesResetWorkspaceWalls.current > 0
? null
: (result) => {
console.log('Received result from recompute_workspace_walls action', result)
// If this is wrapping up a reset to preset, call the callback
if (isResettingToPreset.current) {
let resetToPresetSuccessCallback = props.resetToPresetSuccessCallback.current
resetToPresetSuccessCallback()
isResettingToPreset.current = false
}
}
)
numTimesResetWorkspaceWalls.current++
} else {
// If this is wrapping up a reset to preset, call the callback
if (isResettingToPreset.current) {
let resetToPresetSuccessCallback = props.resetToPresetSuccessCallback.current
resetToPresetSuccessCallback()
isResettingToPreset.current = false
}
}
}
})
}, [
props.paramNames,
isResettingToPreset,
numTimesResetWorkspaceWalls,
props.localParamValues,
settingsPresets,
props.paramNames,
props.resetToPresetSuccessCallback,
props.resetWorkspaceWallsOnParameterUpdate,
setParametersService,
isResettingToPreset,
props.resetToPresetSuccessCallback
settingsPresets
])

/**
Expand All @@ -155,6 +206,16 @@ const SettingsPageParent = (props) => {
setGlobalParameter()
}, [setGlobalParameter])

/**
* When the component is unmounted, destroy the action client.
*/
useEffect(() => {
let action = recomputeWorkspaceWallsAction.current
return () => {
destroyActionClient(action)
}
}, [])

/**
* A callback for when the user asks to reset parameters to a preset.
*/
Expand Down Expand Up @@ -294,6 +355,9 @@ SettingsPageParent.propTypes = {
resetToPresetSuccessCallback: PropTypes.shape({
current: PropTypes.func.isRequired
}),
// A prop to specify whether to invoke the action that resets workspace walls
// when the global parameters have been updated
resetWorkspaceWallsOnParameterUpdate: PropTypes.bool,
// A function to call when the user is done with the page
doneCallback: PropTypes.func.isRequired
}
Expand All @@ -303,7 +367,8 @@ SettingsPageParent.defaultProps = {
modalChildren: <></>,
resetToPresetSuccessCallback: {
current: () => {}
}
},
resetWorkspaceWallsOnParameterUpdate: false
}

export default SettingsPageParent
4 changes: 4 additions & 0 deletions feedingwebapp/src/ros/ros_helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ export function createROSServiceRequest(data) {
return new ROSLIB.ServiceRequest(data)
}

// TODO: Should we add a `destroyService` function like we have for the action client?
// The difference is that roslibjs explicitly provides a function to destroy the action
// client, but only provides a function to unadvertise a service client.

/**
* Create a ROS Action Client.
*
Expand Down