Skip to content
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

Action message support #417

Merged
merged 27 commits into from
Oct 26, 2024
Merged
Changes from 1 commit
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
110d965
Added action template
esteve Nov 28, 2022
047c8f1
Added action generation
esteve Nov 28, 2022
556a606
Added basic create_action_client function
esteve Nov 28, 2022
dfdcbd3
dded action generation
esteve Nov 28, 2022
67c3b8b
checkin
esteve Nov 17, 2023
b197155
Fix missing exported pre_field_serde field
esteve Jan 17, 2024
13474d1
Removed extra code
esteve Jan 17, 2024
3e70087
Sketch out action server construction and destruction
nwn Jun 6, 2024
17cd980
Fix action typesupport function
nwn Jun 11, 2024
fb9b0e4
Add ActionImpl trait with internal messages and services
nwn Jul 13, 2024
5f3373f
Split srv.rs.em into idiomatic and rmw template files
nwn Jul 20, 2024
562132b
Generate underlying service definitions for actions
nwn Jul 20, 2024
dc90b21
Add runtime trait to get the UUID from a goal request
nwn Jul 20, 2024
1ed2981
Integrate RMW message methods into ActionImpl
nwn Aug 7, 2024
568bb7c
Add rosidl_runtime_rs::ActionImpl::create_feedback_message()
nwn Aug 9, 2024
23e9c94
Add GetResultService methods to ActionImpl
nwn Aug 16, 2024
6d7021a
Implement ActionImpl trait methods in generator
nwn Aug 16, 2024
7a39794
Replace set_result_response_status with create_result_response
nwn Aug 23, 2024
c5bd258
Implement client-side trait methods for action messages
nwn Sep 28, 2024
2748b5f
Format the rosidl_runtime_rs::ActionImpl trait
nwn Sep 30, 2024
507a7af
Wrap longs lines in rosidl_generator_rs action.rs
nwn Oct 1, 2024
7d30fb1
Use idiomatic message types in Action trait
nwn Oct 11, 2024
3c1663f
Cleanup ActionImpl using type aliases
mxgrey Oct 3, 2024
0493705
Formatting
nwn Oct 11, 2024
8bedfe0
Switch from std::os::raw::c_void to std::ffi::c_void
nwn Oct 12, 2024
5dece63
Clean up rosidl_generator_rs's cmake files
nwn Oct 13, 2024
db575ef
Add a short doc page on the message generation pipeline
nwn Oct 13, 2024
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
Prev Previous commit
Next Next commit
Fix action typesupport function
  • Loading branch information
nwn committed Sep 28, 2024
commit 17cd98053ef199194b45aa674611ff53d7dfc3f5
29 changes: 17 additions & 12 deletions rosidl_generator_rs/resource/action.rs.em
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,23 @@ TEMPLATE(
type_name = action_spec.namespaced_type.name
}@

// Corresponds to @(package_name)__@(subfolder)__@(type_name)
pub struct @(type_name);

impl rosidl_runtime_rs::Action for @(type_name) {
type Goal = crate::@(subfolder)::rmw::@(type_name)_Goal;
type Result = crate::@(subfolder)::rmw::@(type_name)_Result;
type Feedback = crate::@(subfolder)::rmw::@(type_name)_Feedback;

fn get_type_support() -> *const std::os::raw::c_void {
// SAFETY: No preconditions for this function.
unsafe { rosidl_typesupport_c__get_action_type_support_handle__@(package_name)__@(subfolder)__@(type_name)() }
}
#[link(name = "@(package_name)__rosidl_typesupport_c")]
extern "C" {
fn rosidl_typesupport_c__get_action_type_support_handle__@(package_name)__@(subfolder)__@(type_name)() -> *const std::os::raw::c_void;
}

// Corresponds to @(package_name)__@(subfolder)__@(type_name)
pub struct @(type_name);

impl rosidl_runtime_rs::Action for @(type_name) {
type Goal = crate::@(subfolder)::rmw::@(type_name)_Goal;
type Result = crate::@(subfolder)::rmw::@(type_name)_Result;
type Feedback = crate::@(subfolder)::rmw::@(type_name)_Feedback;

fn get_type_support() -> *const std::os::raw::c_void {
// SAFETY: No preconditions for this function.
unsafe { rosidl_typesupport_c__get_action_type_support_handle__@(package_name)__@(subfolder)__@(type_name)() }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a little confusing to me. Looking at (what I believe to be) the impl for this typesupport function (link)

  1. Why are we actually returning a void pointer here? This function is not marked as unsafe, but any handling of the return value may well need to use unsafe code. Could we not return a well formed type, such as rosidl_service_type_support_t?

  2. This function seems to initialize the request and response members, but I don't actually see where those members are. The @(type_name) struct appears empty. How is this working?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. You're right, we could have this return a more specific type than just c_void. However, doing so hasn't been necessary yet, and this is following the same pattern as the existing get_type_support functions for messages and services. To make this happen, we would have to create a Rust binding for the rosidl_{message,service,action}_type_support_t structs, probably in rosidl_runtime_rs. I would be inclined to leave this for a separate PR to avoid growing the scope of this one.
  2. I'm not sure what you mean here. The @(type_name) struct is empty since it's not really meant to be instantiated. It would only be used as a generic impl Action argument and to access the specific Goal, Feedback, and Result associated message types.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Sure, I'm fine leaving this to another PR. Just took a look at our usages (1) of this function historically and we do have as casts everywhere. as casts can be problematic. So it would be nice to eventually not need this. However, maybe there is some other reason I'm missing as to why we return void* here.

  2. I was referring to the data that function actually mutates in its implementation. I was misunderstanding and assumed that we actually held a handle to that data, but apparently we do not. It is a global variable managed by I guess the rosidl_runtime(?) that will be generated for each service.

static rosidl_service_type_support_t @(function_prefix)__@(spec.srv_name)_service_type_support_handle = {
  0,
  &@(function_prefix)__@(spec.srv_name)_service_members,
  get_service_typesupport_handle_function,
};

This is outside the scope of this PR though. Just calling attention to it because we've been bitten by global variables we directly interact with via FFI before, see #386

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Yes, you're right, it would be good to avoid those as casts. I think the only thing preventing that would be defining the appropriate binding type in the rosidl_runtime_rs package. I can make an attempt at that in a follow-up PR.
  2. The typesupport structs are global statics that are managed by the various typesupport implementations. Some of them seem to handle it a bit more dubiously than others, so that's a good thing to watch out for.

}
}

@[end for]