Skip to content

Commit

Permalink
Implement client-side trait methods for action messages
Browse files Browse the repository at this point in the history
This adds methods to ActionImpl for creating and accessing
action-specific message types. These are needed by the rclrs
ActionClient to generically read and write RMW messages.

Due to issues with qualified paths in certain places
(rust-lang/rust#86935), the generator now
refers directly to its service and message types rather than going
through associated types of the various traits. This also makes the
generated code a little easier to read, with the trait method signatures
from rosidl_runtime_rs still enforcing type-safety.
  • Loading branch information
nwn committed Sep 28, 2024
1 parent 7a39794 commit c5bd258
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 16 deletions.
67 changes: 56 additions & 11 deletions rosidl_generator_rs/resource/action.rs.em
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ from rosidl_parser.definition import (
ACTION_GOAL_SUFFIX,
ACTION_RESULT_SERVICE_SUFFIX,
ACTION_RESULT_SUFFIX,
SERVICE_REQUEST_MESSAGE_SUFFIX,
SERVICE_RESPONSE_MESSAGE_SUFFIX,
)

action_msg_specs = []
Expand Down Expand Up @@ -100,31 +102,74 @@ impl rosidl_runtime_rs::ActionImpl for @(type_name) {
type CancelGoalService = action_msgs::srv::rmw::CancelGoal;
type GetResultService = crate::@(subfolder)::rmw::@(type_name)@(ACTION_RESULT_SERVICE_SUFFIX);

fn get_goal_request_uuid(request: &<<Self::SendGoalService as rosidl_runtime_rs::Service>::Request as rosidl_runtime_rs::Message>::RmwMsg) -> [u8; 16] {
request.goal_id.uuid
fn create_goal_request(goal_id: &[u8; 16], goal: crate::@(subfolder)::rmw::@(type_name)@(ACTION_GOAL_SUFFIX)) -> crate::@(subfolder)::rmw::@(type_name)@(ACTION_GOAL_SERVICE_SUFFIX)@(SERVICE_REQUEST_MESSAGE_SUFFIX) {
crate::@(subfolder)::rmw::@(type_name)@(ACTION_GOAL_SERVICE_SUFFIX)@(SERVICE_REQUEST_MESSAGE_SUFFIX) {
goal_id: unique_identifier_msgs::msg::rmw::UUID { uuid: *goal_id },
goal,
}
}

fn get_goal_request_uuid(request: &crate::@(subfolder)::rmw::@(type_name)@(ACTION_GOAL_SERVICE_SUFFIX)@(SERVICE_REQUEST_MESSAGE_SUFFIX)) -> &[u8; 16] {
&request.goal_id.uuid
}

fn create_goal_response(accepted: bool, stamp: (i32, u32)) -> crate::@(subfolder)::rmw::@(type_name)@(ACTION_GOAL_SERVICE_SUFFIX)@(SERVICE_RESPONSE_MESSAGE_SUFFIX) {
crate::@(subfolder)::rmw::@(type_name)@(ACTION_GOAL_SERVICE_SUFFIX)@(SERVICE_RESPONSE_MESSAGE_SUFFIX) {
accepted,
stamp: builtin_interfaces::msg::rmw::Time {
sec: stamp.0,
nanosec: stamp.1,
},
}
}

fn get_goal_response_accepted(response: &crate::@(subfolder)::rmw::@(type_name)@(ACTION_GOAL_SERVICE_SUFFIX)@(SERVICE_RESPONSE_MESSAGE_SUFFIX)) -> bool {
response.accepted
}

fn set_goal_response_accepted(response: &mut <<Self::SendGoalService as rosidl_runtime_rs::Service>::Response as rosidl_runtime_rs::Message>::RmwMsg, accepted: bool) {
response.accepted = accepted;
fn get_goal_response_stamp(response: &crate::@(subfolder)::rmw::@(type_name)@(ACTION_GOAL_SERVICE_SUFFIX)@(SERVICE_RESPONSE_MESSAGE_SUFFIX)) -> (i32, u32) {
(response.stamp.sec, response.stamp.nanosec)
}

fn create_feedback_message(goal_id: &[u8; 16], feedback: &<<Self as rosidl_runtime_rs::Action>::Feedback as rosidl_runtime_rs::Message>::RmwMsg) -> <Self::FeedbackMessage as rosidl_runtime_rs::Message>::RmwMsg {
let mut message = <Self::FeedbackMessage as rosidl_runtime_rs::Message>::RmwMsg::default();
fn create_feedback_message(goal_id: &[u8; 16], feedback: crate::@(subfolder)::rmw::@(type_name)@(ACTION_FEEDBACK_SUFFIX)) -> crate::@(subfolder)::rmw::@(type_name)@(ACTION_FEEDBACK_MESSAGE_SUFFIX) {
let mut message = crate::@(subfolder)::rmw::@(type_name)@(ACTION_FEEDBACK_MESSAGE_SUFFIX)::default();
message.goal_id.uuid = *goal_id;
message.feedback = feedback.clone();
message.feedback = feedback;
message
}

fn get_result_request_uuid(request: &<<Self::GetResultService as rosidl_runtime_rs::Service>::Request as rosidl_runtime_rs::Message>::RmwMsg) -> [u8; 16] {
request.goal_id.uuid
fn get_feedback_message_uuid(feedback: &crate::@(subfolder)::rmw::@(type_name)@(ACTION_FEEDBACK_MESSAGE_SUFFIX)) -> &[u8; 16] {
&feedback.goal_id.uuid
}

fn get_feedback_message_feedback(feedback: &crate::@(subfolder)::rmw::@(type_name)@(ACTION_FEEDBACK_MESSAGE_SUFFIX)) -> &crate::@(subfolder)::rmw::@(type_name)@(ACTION_FEEDBACK_SUFFIX) {
&feedback.feedback
}

fn create_result_response(status: i8, result: <<Self as Action>::Result as Message>::RmwMsg) -> <<Self::GetResultService as Service>::Response as Message>::RmwMsg {
<<Self::GetResultService as rosidl_runtime_rs::Service>::Response as rosidl_runtime_rs::Message>::RmwMsg {
fn create_result_request(goal_id: &[u8; 16]) -> crate::@(subfolder)::rmw::@(type_name)@(ACTION_RESULT_SERVICE_SUFFIX)@(SERVICE_REQUEST_MESSAGE_SUFFIX) {
crate::@(subfolder)::rmw::@(type_name)@(ACTION_RESULT_SERVICE_SUFFIX)@(SERVICE_REQUEST_MESSAGE_SUFFIX) {
goal_id: unique_identifier_msgs::msg::rmw::UUID { uuid: *goal_id },
}
}

fn get_result_request_uuid(request: &crate::@(subfolder)::rmw::@(type_name)@(ACTION_RESULT_SERVICE_SUFFIX)@(SERVICE_REQUEST_MESSAGE_SUFFIX)) -> &[u8; 16] {
&request.goal_id.uuid
}

fn create_result_response(status: i8, result: crate::@(subfolder)::rmw::@(type_name)@(ACTION_RESULT_SUFFIX)) -> crate::@(subfolder)::rmw::@(type_name)@(ACTION_RESULT_SERVICE_SUFFIX)@(SERVICE_RESPONSE_MESSAGE_SUFFIX) {
crate::@(subfolder)::rmw::@(type_name)@(ACTION_RESULT_SERVICE_SUFFIX)@(SERVICE_RESPONSE_MESSAGE_SUFFIX) {
status,
result,
}
}

fn get_result_response_result(response: &crate::@(subfolder)::rmw::@(type_name)@(ACTION_RESULT_SERVICE_SUFFIX)@(SERVICE_RESPONSE_MESSAGE_SUFFIX)) -> &crate::@(subfolder)::rmw::@(type_name)@(ACTION_RESULT_SUFFIX) {
&response.result
}

fn get_result_response_status(response: &crate::@(subfolder)::rmw::@(type_name)@(ACTION_RESULT_SERVICE_SUFFIX)@(SERVICE_RESPONSE_MESSAGE_SUFFIX)) -> i8 {
response.status
}
}

@[end for]
34 changes: 29 additions & 5 deletions rosidl_runtime_rs/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,18 +196,42 @@ pub trait ActionImpl: 'static + Action {
/// The get_result service associated with this action.
type GetResultService: Service;

/// Create a goal request message with the given UUID and goal.
fn create_goal_request(goal_id: &[u8; 16], goal: <<Self as Action>::Goal as Message>::RmwMsg) -> <<Self::SendGoalService as Service>::Request as Message>::RmwMsg;

/// Get the UUID of a goal request.
fn get_goal_request_uuid(request: &<<Self::SendGoalService as Service>::Request as Message>::RmwMsg) -> [u8; 16];
fn get_goal_request_uuid(request: &<<Self::SendGoalService as Service>::Request as Message>::RmwMsg) -> &[u8; 16];

/// Create a goal response message with the given acceptance and timestamp.
fn create_goal_response(accepted: bool, stamp: (i32, u32)) -> <<Self::SendGoalService as Service>::Response as Message>::RmwMsg;

/// Sets the `accepted` field of a goal response.
fn set_goal_response_accepted(response: &mut <<Self::SendGoalService as Service>::Response as Message>::RmwMsg, accepted: bool);
/// Get the `accepted` field of a goal response.
fn get_goal_response_accepted(response: &<<Self::SendGoalService as Service>::Response as Message>::RmwMsg) -> bool;

/// Get the `stamp` field of a goal response.
fn get_goal_response_stamp(response: &<<Self::SendGoalService as Service>::Response as Message>::RmwMsg) -> (i32, u32);

/// Create a feedback message with the given goal ID and contents.
fn create_feedback_message(goal_id: &[u8; 16], feedback: &<<Self as Action>::Feedback as Message>::RmwMsg) -> <Self::FeedbackMessage as Message>::RmwMsg;
fn create_feedback_message(goal_id: &[u8; 16], feedback: <<Self as Action>::Feedback as Message>::RmwMsg) -> <Self::FeedbackMessage as Message>::RmwMsg;

/// Get the UUID of a feedback message.
fn get_feedback_message_uuid(feedback: &<Self::FeedbackMessage as Message>::RmwMsg) -> &[u8; 16];

/// Get the feedback of a feedback message.
fn get_feedback_message_feedback(feedback: &<Self::FeedbackMessage as Message>::RmwMsg) -> &<<Self as Action>::Feedback as Message>::RmwMsg;

/// Create a result request message with the given goal ID.
fn create_result_request(goal_id: &[u8; 16]) -> <<Self::GetResultService as Service>::Request as Message>::RmwMsg;

/// Get the UUID of a result request.
fn get_result_request_uuid(request: &<<Self::GetResultService as Service>::Request as Message>::RmwMsg) -> [u8; 16];
fn get_result_request_uuid(request: &<<Self::GetResultService as Service>::Request as Message>::RmwMsg) -> &[u8; 16];

/// Create a result response message with the given status and contents.
fn create_result_response(status: i8, result: <<Self as Action>::Result as Message>::RmwMsg) -> <<Self::GetResultService as Service>::Response as Message>::RmwMsg;

/// Get the result of a result response.
fn get_result_response_result(response: &<<Self::GetResultService as Service>::Response as Message>::RmwMsg) -> &<<Self as Action>::Result as Message>::RmwMsg;

/// Get the status of a result response.
fn get_result_response_status(response: &<<Self::GetResultService as Service>::Response as Message>::RmwMsg) -> i8;
}

0 comments on commit c5bd258

Please sign in to comment.