Skip to content

Commit 2b5a6b5

Browse files
committed
Partial implementation of ActionServer::publish_status()
1 parent 908859f commit 2b5a6b5

File tree

2 files changed

+44
-2
lines changed

2 files changed

+44
-2
lines changed

rclrs/src/action/server.rs

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,9 @@ where
236236

237237
// TODO: Add a UUID->goal_handle entry to a server goal map.
238238

239-
// TODO: If accept_and_execute, update goal state
239+
if response == GoalResponse::AcceptAndExecute {
240+
goal_handle.execute()?;
241+
}
240242

241243
// TODO: Call publish_status()
242244

@@ -282,6 +284,46 @@ where
282284
fn execute_goal_expired(&self) -> Result<(), RclrsError> {
283285
todo!()
284286
}
287+
288+
fn publish_status(&self) -> Result<(), RclrsError> {
289+
// We need to hold the lock across this entire method because
290+
// rcl_action_server_get_goal_handles() returns an internal pointer to the
291+
// goal data.
292+
let handle = &*self.handle.lock();
293+
294+
let mut goal_handles = std::ptr::null_mut::<*mut rcl_action_goal_handle_t>();
295+
let mut num_goal_handles = 0;
296+
unsafe {
297+
// SAFETY: The action server is locked for this entire function, ensuring that the
298+
// goal_handles array remains valid, unless rcl_shutdown is called. However, that is
299+
// outside our control.
300+
rcl_action_server_get_goal_handles(handle, &mut goal_handles, &mut num_goal_handles)
301+
}.ok()?;
302+
303+
let mut goal_statuses = unsafe {
304+
// SAFETY: No preconditions
305+
rcl_action_get_zero_initialized_goal_status_array()
306+
};
307+
unsafe {
308+
// SAFETY: The action server is locked through the handle and goal_statuses is
309+
// zero-initialized.
310+
rcl_action_get_goal_status_array(handle, &mut goal_statuses)
311+
}.ok()?;
312+
// TODO(nwn): Ensure that rcl_action_goal_status_array_fini() is always called on exit.
313+
314+
let goal_status_slice = unsafe {
315+
// SAFETY: rcl_action_get_goal_status_array initializes goal_statues.msg.status_list as
316+
// an array of goal statuses with the indicated size. The memory backing this array is
317+
// not modified by anything else during the lifetime of the slice.
318+
std::slice::from_raw_parts(goal_statuses.msg.status_list.data, goal_statuses.msg.status_list.size)
319+
};
320+
for goal_status in goal_status_slice {
321+
// Copy into the correct message type to pass to rcl_action_publish_status().
322+
}
323+
// Call rcl_action_publish_status().
324+
325+
todo!()
326+
}
285327
}
286328

287329
impl<T> ActionServerBase for ActionServer<T>

rclrs/src/action/server_goal_handle.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ where
134134
/// called on a goal handle after this is called.
135135
///
136136
/// Returns an error if the goal is in any state other than pending.
137-
pub fn execute(&self, result: &ActionT::Result) -> Result<(), RclrsError> {
137+
pub fn execute(&self) -> Result<(), RclrsError> {
138138
self.update_state(rcl_action_goal_event_t::GOAL_EVENT_EXECUTE)?;
139139

140140
// TODO: Invoke on_executing callback

0 commit comments

Comments
 (0)