From 506de760c008c3e4cda2b07dbe019925fb448891 Mon Sep 17 00:00:00 2001 From: Esteve Fernandez Date: Mon, 28 Nov 2022 16:39:43 +0100 Subject: [PATCH 01/19] Added skeleton examples for action client and server --- .../minimal_action_client_server/Cargo.toml | 29 +++++++++++++++++++ .../minimal_action_client_server/package.xml | 26 +++++++++++++++++ .../src/minimal_action_client.rs | 11 +++++++ .../src/minimal_action_server.rs | 11 +++++++ 4 files changed, 77 insertions(+) create mode 100644 examples/minimal_action_client_server/Cargo.toml create mode 100644 examples/minimal_action_client_server/package.xml create mode 100644 examples/minimal_action_client_server/src/minimal_action_client.rs create mode 100644 examples/minimal_action_client_server/src/minimal_action_server.rs diff --git a/examples/minimal_action_client_server/Cargo.toml b/examples/minimal_action_client_server/Cargo.toml new file mode 100644 index 000000000..bbcb3d324 --- /dev/null +++ b/examples/minimal_action_client_server/Cargo.toml @@ -0,0 +1,29 @@ +[package] +name = "examples_rclrs_minimal_action_client_server" +version = "0.3.1" +# This project is not military-sponsored, Jacob's employment contract just requires him to use this email address +authors = ["Esteve Fernandez ", "Nikolai Morin ", "Jacob Hassold "] +edition = "2021" + +[[bin]] +name = "minimal_action_client" +path = "src/minimal_action_client.rs" + +[[bin]] +name = "minimal_action_server" +path = "src/minimal_action_server.rs" + +[dependencies] +anyhow = {version = "1", features = ["backtrace"]} + +[dependencies.rclrs] +version = "0.3" + +[dependencies.rosidl_runtime_rs] +version = "0.3" + +[dependencies.action_msgs] +version = "*" + +[package.metadata.ros] +install_to_share = ["launch"] diff --git a/examples/minimal_action_client_server/package.xml b/examples/minimal_action_client_server/package.xml new file mode 100644 index 000000000..177aee989 --- /dev/null +++ b/examples/minimal_action_client_server/package.xml @@ -0,0 +1,26 @@ + + + + examples_rclrs_minimal_action_client_server + 0.3.1 + Package containing an example of actions in rclrs. + Esteve Fernandez + Nikolai Morin + + Jacob Hassold + Apache License 2.0 + + rclrs + rosidl_runtime_rs + action_msgs + + rclrs + rosidl_runtime_rs + action_msgs + + + ament_cargo + + diff --git a/examples/minimal_action_client_server/src/minimal_action_client.rs b/examples/minimal_action_client_server/src/minimal_action_client.rs new file mode 100644 index 000000000..d1d32f3b1 --- /dev/null +++ b/examples/minimal_action_client_server/src/minimal_action_client.rs @@ -0,0 +1,11 @@ +use std::env; + +use anyhow::{Error, Result}; + +fn main() -> Result<(), Error> { + let context = rclrs::Context::new(env::args())?; + + let _node = rclrs::create_node(&context, "minimal_action_client")?; + + Ok(()) +} diff --git a/examples/minimal_action_client_server/src/minimal_action_server.rs b/examples/minimal_action_client_server/src/minimal_action_server.rs new file mode 100644 index 000000000..4a1995d9a --- /dev/null +++ b/examples/minimal_action_client_server/src/minimal_action_server.rs @@ -0,0 +1,11 @@ +use std::env; + +use anyhow::{Error, Result}; + +fn main() -> Result<(), Error> { + let context = rclrs::Context::new(env::args())?; + + let mut node = rclrs::create_node(&context, "minimal_action_server")?; + + rclrs::spin(&node).map_err(|err| err.into()) +} From 061d5e2a990634b47746d8be311ec266b7e416fe Mon Sep 17 00:00:00 2001 From: Esteve Fernandez Date: Mon, 28 Nov 2022 17:18:07 +0100 Subject: [PATCH 02/19] Added action template --- examples/minimal_action_client_server/Cargo.toml | 3 --- .../src/minimal_action_server.rs | 2 +- .../rosidl_generator_rs_generate_interfaces.cmake | 11 ++++++----- rosidl_generator_rs/resource/action.rs.em | 9 +++++++++ 4 files changed, 16 insertions(+), 9 deletions(-) create mode 100644 rosidl_generator_rs/resource/action.rs.em diff --git a/examples/minimal_action_client_server/Cargo.toml b/examples/minimal_action_client_server/Cargo.toml index bbcb3d324..4f51278fc 100644 --- a/examples/minimal_action_client_server/Cargo.toml +++ b/examples/minimal_action_client_server/Cargo.toml @@ -24,6 +24,3 @@ version = "0.3" [dependencies.action_msgs] version = "*" - -[package.metadata.ros] -install_to_share = ["launch"] diff --git a/examples/minimal_action_client_server/src/minimal_action_server.rs b/examples/minimal_action_client_server/src/minimal_action_server.rs index 4a1995d9a..bf05587b6 100644 --- a/examples/minimal_action_client_server/src/minimal_action_server.rs +++ b/examples/minimal_action_client_server/src/minimal_action_server.rs @@ -5,7 +5,7 @@ use anyhow::{Error, Result}; fn main() -> Result<(), Error> { let context = rclrs::Context::new(env::args())?; - let mut node = rclrs::create_node(&context, "minimal_action_server")?; + let node = rclrs::create_node(&context, "minimal_action_server")?; rclrs::spin(&node).map_err(|err| err.into()) } diff --git a/rosidl_generator_rs/cmake/rosidl_generator_rs_generate_interfaces.cmake b/rosidl_generator_rs/cmake/rosidl_generator_rs_generate_interfaces.cmake index fd48a5545..6dd727132 100644 --- a/rosidl_generator_rs/cmake/rosidl_generator_rs_generate_interfaces.cmake +++ b/rosidl_generator_rs/cmake/rosidl_generator_rs_generate_interfaces.cmake @@ -53,13 +53,13 @@ foreach(_idl_file ${rosidl_generate_interfaces_ABS_IDL_FILES}) if(_parent_folder STREQUAL "msg") set(_has_msg TRUE) - set(_idl_file_without_actions ${_idl_file_without_actions} ${_idl_file}) + set(_idl_files ${_idl_files} ${_idl_file}) elseif(_parent_folder STREQUAL "srv") set(_has_srv TRUE) - set(_idl_file_without_actions ${_idl_file_without_actions} ${_idl_file}) + set(_idl_files ${_idl_files} ${_idl_file}) elseif(_parent_folder STREQUAL "action") set(_has_action TRUE) - message(WARNING "Rust actions generation is not implemented") + set(_idl_files ${_idl_files} ${_idl_file}) else() message(FATAL_ERROR "Interface file with unknown parent folder: ${_idl_file}") endif() @@ -107,12 +107,13 @@ endforeach() set(target_dependencies "${rosidl_generator_rs_BIN}" ${rosidl_generator_rs_GENERATOR_FILES} + "${rosidl_generator_rs_TEMPLATE_DIR}/action.rs.em" "${rosidl_generator_rs_TEMPLATE_DIR}/msg_idiomatic.rs.em" "${rosidl_generator_rs_TEMPLATE_DIR}/msg_rmw.rs.em" "${rosidl_generator_rs_TEMPLATE_DIR}/msg.rs.em" "${rosidl_generator_rs_TEMPLATE_DIR}/srv.rs.em" ${rosidl_generate_interfaces_ABS_IDL_FILES} - ${_idl_file_without_actions} + ${_idl_files} ${_dependency_files}) foreach(dep ${target_dependencies}) if(NOT EXISTS "${dep}") @@ -125,7 +126,7 @@ rosidl_write_generator_arguments( "${generator_arguments_file}" PACKAGE_NAME "${PROJECT_NAME}" IDL_TUPLES "${rosidl_generate_interfaces_IDL_TUPLES}" - ROS_INTERFACE_FILES "${_idl_file_without_actions}" + ROS_INTERFACE_FILES "${_idl_files}" ROS_INTERFACE_DEPENDENCIES "${_dependencies}" OUTPUT_DIR "${_output_path}" TEMPLATE_DIR "${rosidl_generator_rs_TEMPLATE_DIR}" diff --git a/rosidl_generator_rs/resource/action.rs.em b/rosidl_generator_rs/resource/action.rs.em new file mode 100644 index 000000000..bb74ad772 --- /dev/null +++ b/rosidl_generator_rs/resource/action.rs.em @@ -0,0 +1,9 @@ +@{ +TEMPLATE( + 'msg_idiomatic.rs.em', + package_name=package_name, interface_path=interface_path, + msg_specs=msg_specs, + get_rs_name=get_rs_name, get_rmw_rs_type=get_rmw_rs_type, + get_idiomatic_rs_type=get_idiomatic_rs_type, + constant_value_to_rs=constant_value_to_rs) +}@ From 78317d3d29ace9028bf52dcd5e82dbf5c51a55bf Mon Sep 17 00:00:00 2001 From: Esteve Fernandez Date: Mon, 28 Nov 2022 17:47:22 +0100 Subject: [PATCH 03/19] Added action generation --- rosidl_generator_rs/resource/action.rs.em | 30 ++++++++++++++++++- .../rosidl_generator_rs/__init__.py | 27 +++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/rosidl_generator_rs/resource/action.rs.em b/rosidl_generator_rs/resource/action.rs.em index bb74ad772..ff76ff092 100644 --- a/rosidl_generator_rs/resource/action.rs.em +++ b/rosidl_generator_rs/resource/action.rs.em @@ -1,8 +1,36 @@ +@{ +action_msg_specs = [] + +for subfolder, action in action_specs: + action_msg_specs.append((subfolder, action.goal)) + action_msg_specs.append((subfolder, action.result)) + action_msg_specs.append((subfolder, action.feedback)) + action_msg_specs.append((subfolder, action.feedback_message)) + +action_srv_specs = [] + +for subfolder, action in action_specs: + action_srv_specs.append((subfolder, action.send_goal_service)) + action_srv_specs.append((subfolder, action.get_result_service)) +}@ + +pub mod rmw { +@{ +TEMPLATE( + 'msg_rmw.rs.em', + package_name=package_name, interface_path=interface_path, + msg_specs=action_msg_specs, + get_rs_name=get_rs_name, get_rmw_rs_type=get_rmw_rs_type, + get_idiomatic_rs_type=get_idiomatic_rs_type, + constant_value_to_rs=constant_value_to_rs) +}@ +} // mod rmw + @{ TEMPLATE( 'msg_idiomatic.rs.em', package_name=package_name, interface_path=interface_path, - msg_specs=msg_specs, + msg_specs=action_msg_specs, get_rs_name=get_rs_name, get_rmw_rs_type=get_rmw_rs_type, get_idiomatic_rs_type=get_idiomatic_rs_type, constant_value_to_rs=constant_value_to_rs) diff --git a/rosidl_generator_rs/rosidl_generator_rs/__init__.py b/rosidl_generator_rs/rosidl_generator_rs/__init__.py index 502d1d34d..b7850a6d8 100644 --- a/rosidl_generator_rs/rosidl_generator_rs/__init__.py +++ b/rosidl_generator_rs/rosidl_generator_rs/__init__.py @@ -23,6 +23,11 @@ import rosidl_pycommon from rosidl_parser.definition import AbstractGenericString +from rosidl_parser.definition import AbstractNestedType +from rosidl_parser.definition import AbstractSequence +from rosidl_parser.definition import AbstractString +from rosidl_parser.definition import AbstractWString +from rosidl_parser.definition import Action from rosidl_parser.definition import Array from rosidl_parser.definition import BasicType from rosidl_parser.definition import BoundedSequence @@ -86,6 +91,10 @@ def generate_rs(generator_arguments_file, typesupport_impls): os.path.join(template_dir, 'srv.rs.em'): ['rust/src/%s.rs'], } + mapping_actions = { + os.path.join(template_dir, 'action.rs.em'): ['rust/src/%s.rs'], + } + # Ensure the required templates exist for template_file in mapping_msgs.keys(): assert os.path.exists(template_file), \ @@ -93,6 +102,9 @@ def generate_rs(generator_arguments_file, typesupport_impls): for template_file in mapping_srvs.keys(): assert os.path.exists(template_file), \ 'Services template file %s not found' % template_file + for template_file in mapping_actions.keys(): + assert os.path.exists(template_file), \ + 'Actions template file %s not found' % template_file data = { 'pre_field_serde': pre_field_serde, @@ -107,6 +119,7 @@ def generate_rs(generator_arguments_file, typesupport_impls): convert_lower_case_underscore_to_camel_case, 'msg_specs': [], 'srv_specs': [], + 'action_specs': [], 'package_name': args['package_name'], 'typesupport_impls': typesupport_impls, 'interface_path': idl_rel_path, @@ -121,6 +134,9 @@ def generate_rs(generator_arguments_file, typesupport_impls): for service in idl_content.get_elements_of_type(Service): data['srv_specs'].append(('srv', service)) + for action in idl_content.get_elements_of_type(Action): + data['action_specs'].append(('action', action)) + if data['msg_specs']: for template_file, generated_filenames in mapping_msgs.items(): for generated_filename in generated_filenames: @@ -143,6 +159,17 @@ def generate_rs(generator_arguments_file, typesupport_impls): generated_file, minimum_timestamp=latest_target_timestamp) + if data['action_specs']: + for template_file, generated_filenames in mapping_actions.items(): + for generated_filename in generated_filenames: + generated_file = os.path.join(args['output_dir'], + generated_filename % 'action') + rosidl_pycommon.expand_template( + os.path.join(template_dir, template_file), + data.copy(), + generated_file, + minimum_timestamp=latest_target_timestamp) + rosidl_pycommon.expand_template( os.path.join(template_dir, 'lib.rs.em'), data.copy(), From a8b56cc0f9c0eeb2b8c929d451f277796e439665 Mon Sep 17 00:00:00 2001 From: Esteve Fernandez Date: Mon, 28 Nov 2022 18:21:03 +0100 Subject: [PATCH 04/19] Added basic create_action_client function --- .../minimal_action_client_server/Cargo.toml | 2 +- .../minimal_action_client_server/package.xml | 4 +-- .../src/minimal_action_client.rs | 4 ++- rclrs/src/action.rs | 28 +++++++++++++++++++ rclrs/src/lib.rs | 2 ++ rclrs/src/node.rs | 26 +++++++++++++++-- rosidl_generator_rs/resource/action.rs.em | 17 +++++++++++ rosidl_generator_rs/resource/lib.rs.em | 4 +++ rosidl_runtime_rs/src/lib.rs | 2 +- rosidl_runtime_rs/src/traits.rs | 14 ++++++++++ 10 files changed, 95 insertions(+), 8 deletions(-) create mode 100644 rclrs/src/action.rs diff --git a/examples/minimal_action_client_server/Cargo.toml b/examples/minimal_action_client_server/Cargo.toml index 4f51278fc..5224a60c7 100644 --- a/examples/minimal_action_client_server/Cargo.toml +++ b/examples/minimal_action_client_server/Cargo.toml @@ -22,5 +22,5 @@ version = "0.3" [dependencies.rosidl_runtime_rs] version = "0.3" -[dependencies.action_msgs] +[dependencies.example_interfaces] version = "*" diff --git a/examples/minimal_action_client_server/package.xml b/examples/minimal_action_client_server/package.xml index 177aee989..b410cc76e 100644 --- a/examples/minimal_action_client_server/package.xml +++ b/examples/minimal_action_client_server/package.xml @@ -14,11 +14,11 @@ rclrs rosidl_runtime_rs - action_msgs + example_interfaces rclrs rosidl_runtime_rs - action_msgs + example_interfaces ament_cargo diff --git a/examples/minimal_action_client_server/src/minimal_action_client.rs b/examples/minimal_action_client_server/src/minimal_action_client.rs index d1d32f3b1..5e2ac1d26 100644 --- a/examples/minimal_action_client_server/src/minimal_action_client.rs +++ b/examples/minimal_action_client_server/src/minimal_action_client.rs @@ -5,7 +5,9 @@ use anyhow::{Error, Result}; fn main() -> Result<(), Error> { let context = rclrs::Context::new(env::args())?; - let _node = rclrs::create_node(&context, "minimal_action_client")?; + let mut node = rclrs::create_node(&context, "minimal_client")?; + + let _client = node.create_action_client::("fibonacci")?; Ok(()) } diff --git a/rclrs/src/action.rs b/rclrs/src/action.rs new file mode 100644 index 000000000..0132fc242 --- /dev/null +++ b/rclrs/src/action.rs @@ -0,0 +1,28 @@ +use crate::{rcl_bindings::*, RclrsError}; +use std::sync::{Arc, Mutex, MutexGuard}; + +use std::marker::PhantomData; + +pub struct ActionClient +where + T: rosidl_runtime_rs::Action, +{ + _marker: PhantomData, +} + +impl ActionClient +where + T: rosidl_runtime_rs::Action, +{ + /// Creates a new action client. + pub(crate) fn new(rcl_node_mtx: Arc>, topic: &str) -> Result + // This uses pub(crate) visibility to avoid instantiating this struct outside + // [`Node::create_client`], see the struct's documentation for the rationale + where + T: rosidl_runtime_rs::Action, + { + Ok(Self { + _marker: Default::default(), + }) + } +} diff --git a/rclrs/src/lib.rs b/rclrs/src/lib.rs index 325cd5b9a..701779863 100644 --- a/rclrs/src/lib.rs +++ b/rclrs/src/lib.rs @@ -5,6 +5,7 @@ //! //! [1]: https://github.com/ros2-rust/ros2_rust/blob/main/README.md +mod action; mod arguments; mod client; mod clock; @@ -30,6 +31,7 @@ pub mod dynamic_message; use std::sync::Arc; use std::time::Duration; +pub use action::*; pub use arguments::*; pub use client::*; pub use clock::*; diff --git a/rclrs/src/node.rs b/rclrs/src/node.rs index f1792c1e6..c5f3a1c4e 100644 --- a/rclrs/src/node.rs +++ b/rclrs/src/node.rs @@ -13,9 +13,9 @@ pub use self::builder::*; pub use self::graph::*; use crate::rcl_bindings::*; use crate::{ - Client, ClientBase, Clock, Context, GuardCondition, ParameterBuilder, ParameterInterface, - ParameterVariant, Parameters, Publisher, QoSProfile, RclrsError, Service, ServiceBase, - Subscription, SubscriptionBase, SubscriptionCallback, TimeSource, ToResult, + ActionClient, Client, ClientBase, Clock, Context, GuardCondition, ParameterBuilder, + ParameterInterface, ParameterVariant, Parameters, Publisher, QoSProfile, RclrsError, Service, + ServiceBase, Subscription, SubscriptionBase, SubscriptionCallback, TimeSource, ToResult, }; impl Drop for rcl_node_t { @@ -195,6 +195,26 @@ impl Node { Ok(client) } + /// Creates a [`Client`][1]. + /// + /// [1]: crate::ActionClient + // TODO: make action client's lifetime depend on node's lifetime + pub fn create_action_client( + &mut self, + topic: &str, + ) -> Result>, RclrsError> + where + T: rosidl_runtime_rs::Action, + { + let client = Arc::new(ActionClient::::new( + Arc::clone(&self.rcl_node_mtx), + topic, + )?); + // self.clients + // .push(Arc::downgrade(&client) as Weak); + Ok(client) + } + /// Creates a [`GuardCondition`][1] with no callback. /// /// A weak pointer to the `GuardCondition` is stored within this node. diff --git a/rosidl_generator_rs/resource/action.rs.em b/rosidl_generator_rs/resource/action.rs.em index ff76ff092..40c5acd59 100644 --- a/rosidl_generator_rs/resource/action.rs.em +++ b/rosidl_generator_rs/resource/action.rs.em @@ -35,3 +35,20 @@ TEMPLATE( get_idiomatic_rs_type=get_idiomatic_rs_type, constant_value_to_rs=constant_value_to_rs) }@ + +@[for subfolder, action_spec in action_specs] + +@{ +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; + } + +@[end for] diff --git a/rosidl_generator_rs/resource/lib.rs.em b/rosidl_generator_rs/resource/lib.rs.em index 51e4a5ba4..79a0e1def 100644 --- a/rosidl_generator_rs/resource/lib.rs.em +++ b/rosidl_generator_rs/resource/lib.rs.em @@ -7,3 +7,7 @@ pub mod msg; @[if len(srv_specs) > 0]@ pub mod srv; @[end if]@ + +@[if len(action_specs) > 0]@ +pub mod action; +@[end if]@ diff --git a/rosidl_runtime_rs/src/lib.rs b/rosidl_runtime_rs/src/lib.rs index 93f844192..01ad9f464 100644 --- a/rosidl_runtime_rs/src/lib.rs +++ b/rosidl_runtime_rs/src/lib.rs @@ -9,4 +9,4 @@ mod string; pub use string::{BoundedString, BoundedWString, String, StringExceedsBoundsError, WString}; mod traits; -pub use traits::{Message, RmwMessage, SequenceAlloc, Service}; +pub use traits::{Action, Message, RmwMessage, SequenceAlloc, Service}; diff --git a/rosidl_runtime_rs/src/traits.rs b/rosidl_runtime_rs/src/traits.rs index d468a42d5..fee02fb5b 100644 --- a/rosidl_runtime_rs/src/traits.rs +++ b/rosidl_runtime_rs/src/traits.rs @@ -160,3 +160,17 @@ pub trait Service: 'static { /// Get a pointer to the correct `rosidl_service_type_support_t` structure. fn get_type_support() -> *const std::os::raw::c_void; } + +/// Trait for actions. +/// +/// User code never needs to call this trait's method, much less implement this trait. +pub trait Action: 'static { + /// The goal message associated with this service. + type Goal: Message; + + /// The result message associated with this service. + type Result: Message; + + /// The feedback message associated with this service. + type Feedback: Message; +} From fd5cfb6857a73898cd2278a5fa6add0580a86be3 Mon Sep 17 00:00:00 2001 From: Esteve Fernandez Date: Tue, 29 Nov 2022 17:22:33 +0100 Subject: [PATCH 05/19] Fix linter --- .../minimal_action_client_server/src/minimal_action_client.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/minimal_action_client_server/src/minimal_action_client.rs b/examples/minimal_action_client_server/src/minimal_action_client.rs index 5e2ac1d26..cb8df7ea5 100644 --- a/examples/minimal_action_client_server/src/minimal_action_client.rs +++ b/examples/minimal_action_client_server/src/minimal_action_client.rs @@ -7,7 +7,8 @@ fn main() -> Result<(), Error> { let mut node = rclrs::create_node(&context, "minimal_client")?; - let _client = node.create_action_client::("fibonacci")?; + let _client = + node.create_action_client::("fibonacci")?; Ok(()) } From 449980c03ae786db784398cdb967fa62d5a3307b Mon Sep 17 00:00:00 2001 From: Esteve Fernandez Date: Mon, 17 Jul 2023 10:08:00 +0200 Subject: [PATCH 06/19] Split action client and server examples --- .../Cargo.toml | 6 +---- .../package.xml | 4 +-- .../src/minimal_action_client.rs | 0 examples/minimal_action_server/Cargo.toml | 22 ++++++++++++++++ examples/minimal_action_server/package.xml | 26 +++++++++++++++++++ .../src/minimal_action_server.rs | 0 6 files changed, 51 insertions(+), 7 deletions(-) rename examples/{minimal_action_client_server => minimal_action_client}/Cargo.toml (81%) rename examples/{minimal_action_client_server => minimal_action_client}/package.xml (86%) rename examples/{minimal_action_client_server => minimal_action_client}/src/minimal_action_client.rs (100%) create mode 100644 examples/minimal_action_server/Cargo.toml create mode 100644 examples/minimal_action_server/package.xml rename examples/{minimal_action_client_server => minimal_action_server}/src/minimal_action_server.rs (100%) diff --git a/examples/minimal_action_client_server/Cargo.toml b/examples/minimal_action_client/Cargo.toml similarity index 81% rename from examples/minimal_action_client_server/Cargo.toml rename to examples/minimal_action_client/Cargo.toml index 5224a60c7..b1de4903b 100644 --- a/examples/minimal_action_client_server/Cargo.toml +++ b/examples/minimal_action_client/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "examples_rclrs_minimal_action_client_server" +name = "examples_rclrs_minimal_action_client" version = "0.3.1" # This project is not military-sponsored, Jacob's employment contract just requires him to use this email address authors = ["Esteve Fernandez ", "Nikolai Morin ", "Jacob Hassold "] @@ -9,10 +9,6 @@ edition = "2021" name = "minimal_action_client" path = "src/minimal_action_client.rs" -[[bin]] -name = "minimal_action_server" -path = "src/minimal_action_server.rs" - [dependencies] anyhow = {version = "1", features = ["backtrace"]} diff --git a/examples/minimal_action_client_server/package.xml b/examples/minimal_action_client/package.xml similarity index 86% rename from examples/minimal_action_client_server/package.xml rename to examples/minimal_action_client/package.xml index b410cc76e..a2576efb1 100644 --- a/examples/minimal_action_client_server/package.xml +++ b/examples/minimal_action_client/package.xml @@ -3,9 +3,9 @@ href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?> - examples_rclrs_minimal_action_client_server + examples_rclrs_minimal_action_client 0.3.1 - Package containing an example of actions in rclrs. + Minimal action client examples for rclrs. Esteve Fernandez Nikolai Morin diff --git a/examples/minimal_action_client_server/src/minimal_action_client.rs b/examples/minimal_action_client/src/minimal_action_client.rs similarity index 100% rename from examples/minimal_action_client_server/src/minimal_action_client.rs rename to examples/minimal_action_client/src/minimal_action_client.rs diff --git a/examples/minimal_action_server/Cargo.toml b/examples/minimal_action_server/Cargo.toml new file mode 100644 index 000000000..1599d15ad --- /dev/null +++ b/examples/minimal_action_server/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "examples_rclrs_minimal_action_server" +version = "0.3.1" +# This project is not military-sponsored, Jacob's employment contract just requires him to use this email address +authors = ["Esteve Fernandez ", "Nikolai Morin ", "Jacob Hassold "] +edition = "2021" + +[[bin]] +name = "minimal_action_server" +path = "src/minimal_action_server.rs" + +[dependencies] +anyhow = {version = "1", features = ["backtrace"]} + +[dependencies.rclrs] +version = "0.3" + +[dependencies.rosidl_runtime_rs] +version = "0.3" + +[dependencies.example_interfaces] +version = "*" diff --git a/examples/minimal_action_server/package.xml b/examples/minimal_action_server/package.xml new file mode 100644 index 000000000..74ae8e40e --- /dev/null +++ b/examples/minimal_action_server/package.xml @@ -0,0 +1,26 @@ + + + + examples_rclrs_minimal_action_server + 0.3.1 + Minimal action server examples for rclrs. + Esteve Fernandez + Nikolai Morin + + Jacob Hassold + Apache License 2.0 + + rclrs + rosidl_runtime_rs + example_interfaces + + rclrs + rosidl_runtime_rs + example_interfaces + + + ament_cargo + + diff --git a/examples/minimal_action_client_server/src/minimal_action_server.rs b/examples/minimal_action_server/src/minimal_action_server.rs similarity index 100% rename from examples/minimal_action_client_server/src/minimal_action_server.rs rename to examples/minimal_action_server/src/minimal_action_server.rs From c075470c0c99f9e9092bd6554e93698fc176d30a Mon Sep 17 00:00:00 2001 From: Esteve Fernandez Date: Mon, 17 Jul 2023 13:55:08 +0200 Subject: [PATCH 07/19] checkin --- .../src/minimal_action_server.rs | 42 ++++++++++- rclrs/src/action.rs | 70 ++++++++++++++++++- rclrs/src/lib.rs | 2 + rclrs/src/node.rs | 36 ++++++++-- rclrs/src/rcl_bindings.rs | 2 + rclrs/src/rcl_wrapper.h | 3 + 6 files changed, 146 insertions(+), 9 deletions(-) diff --git a/examples/minimal_action_server/src/minimal_action_server.rs b/examples/minimal_action_server/src/minimal_action_server.rs index bf05587b6..8e64e09f2 100644 --- a/examples/minimal_action_server/src/minimal_action_server.rs +++ b/examples/minimal_action_server/src/minimal_action_server.rs @@ -1,11 +1,51 @@ use std::env; +use std::sync::Arc; +use std::thread; use anyhow::{Error, Result}; +type Fibonacci = example_interfaces::action::Fibonacci; +type GoalHandleFibonacci = rclrs::ServerGoalHandle; + +fn handle_goal( + _uuid: &rclrs::GoalUUID, + goal: Arc, +) -> rclrs::GoalResponse { + println!("Received goal request with order {}", goal.order); + if goal.order > 9000 { + rclrs::GoalResponse::Reject + } else { + rclrs::GoalResponse::AcceptAndExecute + } +} + +fn handle_cancel(_goal_handle: Arc) -> rclrs::CancelResponse { + println!("Got request to cancel goal"); + rclrs::CancelResponse::Accept +} + +fn execute(goal_handle: Arc) { + println!("Executing goal"); + thread::sleep(std::time::Duration::from_millis(100)); +} + +fn handle_accepted(goal_handle: Arc) { + thread::spawn(move || { + execute(goal_handle); + }); +} + fn main() -> Result<(), Error> { let context = rclrs::Context::new(env::args())?; - let node = rclrs::create_node(&context, "minimal_action_server")?; + let mut node = rclrs::create_node(&context, "minimal_action_server")?; + + let _action_server = node.create_action_server::( + "fibonacci", + handle_goal, + handle_cancel, + handle_accepted, + ); rclrs::spin(&node).map_err(|err| err.into()) } diff --git a/rclrs/src/action.rs b/rclrs/src/action.rs index 0132fc242..f9096374a 100644 --- a/rclrs/src/action.rs +++ b/rclrs/src/action.rs @@ -1,8 +1,27 @@ use crate::{rcl_bindings::*, RclrsError}; use std::sync::{Arc, Mutex, MutexGuard}; +// SAFETY: The functions accessing this type, including drop(), shouldn't care about the thread +// they are running in. Therefore, this type can be safely sent to another thread. +unsafe impl Send for rcl_action_goal_handle_t {} + +unsafe impl Sync for rcl_action_goal_handle_t {} + use std::marker::PhantomData; +pub type GoalUUID = [u8; RCL_ACTION_UUID_SIZE]; + +pub enum GoalResponse { + Reject = 1, + AcceptAndExecute = 2, + AcceptAndDefer = 3, +} + +pub enum CancelResponse { + Reject = 1, + Accept = 2, +} + pub struct ActionClient where T: rosidl_runtime_rs::Action, @@ -16,8 +35,6 @@ where { /// Creates a new action client. pub(crate) fn new(rcl_node_mtx: Arc>, topic: &str) -> Result - // This uses pub(crate) visibility to avoid instantiating this struct outside - // [`Node::create_client`], see the struct's documentation for the rationale where T: rosidl_runtime_rs::Action, { @@ -26,3 +43,52 @@ where }) } } + +pub struct ActionServer +where + T: rosidl_runtime_rs::Action, +{ + _marker: PhantomData, +} + +impl ActionServer +where + T: rosidl_runtime_rs::Action, +{ + /// Creates a new action server. + pub(crate) fn new(rcl_node_mtx: Arc>, topic: &str) -> Result + where + T: rosidl_runtime_rs::Action, + { + Ok(Self { + _marker: Default::default(), + }) + } +} + +pub struct ServerGoalHandle +where + T: rosidl_runtime_rs::Action, +{ + rcl_handle: Arc, + _marker: PhantomData, +} + +impl ServerGoalHandle +where + T: rosidl_runtime_rs::Action, +{ + pub(crate) fn new(rcl_handle: Arc) {} + + pub(crate) fn is_canceling() -> bool { + false + } + + pub(crate) fn is_active() -> bool { + false + } + + pub(crate) fn is_executing() -> bool { + false + } +} diff --git a/rclrs/src/lib.rs b/rclrs/src/lib.rs index 701779863..67cc0c6b9 100644 --- a/rclrs/src/lib.rs +++ b/rclrs/src/lib.rs @@ -42,6 +42,8 @@ pub use node::*; pub use parameter::*; pub use publisher::*; pub use qos::*; +use rcl_bindings::rcl_context_is_valid; +use rcl_bindings::rcl_action_goal_handle_t; pub use rcl_bindings::rmw_request_id_t; pub use service::*; pub use subscription::*; diff --git a/rclrs/src/node.rs b/rclrs/src/node.rs index c5f3a1c4e..50a640c99 100644 --- a/rclrs/src/node.rs +++ b/rclrs/src/node.rs @@ -13,9 +13,10 @@ pub use self::builder::*; pub use self::graph::*; use crate::rcl_bindings::*; use crate::{ - ActionClient, Client, ClientBase, Clock, Context, GuardCondition, ParameterBuilder, - ParameterInterface, ParameterVariant, Parameters, Publisher, QoSProfile, RclrsError, Service, - ServiceBase, Subscription, SubscriptionBase, SubscriptionCallback, TimeSource, ToResult, + ActionClient, ActionServer, CancelResponse, Client, ClientBase, Clock, Context, GoalResponse, + GoalUUID, GuardCondition, ParameterInterface, ParameterVariant, Parameters, Publisher, + QoSProfile, RclrsError, ServerGoalHandle, Service, ServiceBase, Subscription, SubscriptionBase, + SubscriptionCallback, TimeSource, ToResult, }; impl Drop for rcl_node_t { @@ -195,7 +196,7 @@ impl Node { Ok(client) } - /// Creates a [`Client`][1]. + /// Creates an [`ActionClient`][1]. /// /// [1]: crate::ActionClient // TODO: make action client's lifetime depend on node's lifetime @@ -206,13 +207,36 @@ impl Node { where T: rosidl_runtime_rs::Action, { - let client = Arc::new(ActionClient::::new( + let action_client = Arc::new(ActionClient::::new( Arc::clone(&self.rcl_node_mtx), topic, )?); // self.clients // .push(Arc::downgrade(&client) as Weak); - Ok(client) + Ok(action_client) + } + + /// Creates an [`ActionServer`][1]. + /// + /// [1]: crate::ActionServer + // TODO: make action server's lifetime depend on node's lifetime + pub fn create_action_server( + &mut self, + topic: &str, + handle_goal: fn(&crate::action::GoalUUID, Arc) -> GoalResponse, + handle_cancel: fn(Arc>) -> CancelResponse, + handle_accepted: fn(Arc>), + ) -> Result>, RclrsError> + where + T: rosidl_runtime_rs::Action, + { + let action_server = Arc::new(ActionServer::::new( + Arc::clone(&self.rcl_node_mtx), + topic, + )?); + // self.servers + // .push(Arc::downgrade(&server) as Weak); + Ok(action_server) } /// Creates a [`GuardCondition`][1] with no callback. diff --git a/rclrs/src/rcl_bindings.rs b/rclrs/src/rcl_bindings.rs index 94491bc91..e90cf4556 100644 --- a/rclrs/src/rcl_bindings.rs +++ b/rclrs/src/rcl_bindings.rs @@ -138,6 +138,7 @@ cfg_if::cfg_if! { pub struct rosidl_message_type_support_t; pub const RMW_GID_STORAGE_SIZE: usize = 24; + pub const RCL_ACTION_UUID_SIZE: usize = 24; extern "C" { pub fn rcl_context_is_valid(context: *const rcl_context_t) -> bool; @@ -146,5 +147,6 @@ cfg_if::cfg_if! { include!(concat!(env!("OUT_DIR"), "/rcl_bindings_generated.rs")); pub const RMW_GID_STORAGE_SIZE: usize = rmw_gid_storage_size_constant; + pub const RCL_ACTION_UUID_SIZE: usize = rcl_action_uuid_size_constant; } } diff --git a/rclrs/src/rcl_wrapper.h b/rclrs/src/rcl_wrapper.h index fe97cb4e5..14bd42189 100644 --- a/rclrs/src/rcl_wrapper.h +++ b/rclrs/src/rcl_wrapper.h @@ -1,5 +1,7 @@ #include #include +#include +#include #include #include #include @@ -7,3 +9,4 @@ #include const size_t rmw_gid_storage_size_constant = RMW_GID_STORAGE_SIZE; +const size_t rcl_action_uuid_size_constant = UUID_SIZE; \ No newline at end of file From 65ffc989b4da6d4351cebd5551328c472ab96122 Mon Sep 17 00:00:00 2001 From: Esteve Fernandez Date: Mon, 17 Jul 2023 15:05:07 +0200 Subject: [PATCH 08/19] checkin --- .../src/minimal_action_server.rs | 31 ++++++++++++++++++- rclrs/src/action.rs | 6 ++-- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/examples/minimal_action_server/src/minimal_action_server.rs b/examples/minimal_action_server/src/minimal_action_server.rs index 8e64e09f2..9ae1f8cc3 100644 --- a/examples/minimal_action_server/src/minimal_action_server.rs +++ b/examples/minimal_action_server/src/minimal_action_server.rs @@ -26,7 +26,36 @@ fn handle_cancel(_goal_handle: Arc) -> rclrs::CancelRespons fn execute(goal_handle: Arc) { println!("Executing goal"); - thread::sleep(std::time::Duration::from_millis(100)); + let feedback = example_interfaces::action::Fibonacci_Feedback { + sequence: Vec::new(), + }; + feedback.sequence.push(0); + feedback.sequence.push(1); + let result = example_interfaces::action::Fibonacci_Result { + sequence: Vec::new(), + }; + + let mut i = 1; + while i < goal_handle.goal().unwrap().order && rclrs::ok() { + if goal_handle.is_canceling() { + result.sequence = feedback.sequence.clone(); + goal_handle.canceled(&result); + println!("Goal canceled"); + return; + } + // Update sequence + feedback.sequence.push(feedback.sequence[i as usize] + feedback.sequence[(i - 1) as usize]); + // Publish feedback + goal_handle.publish_feedback(&feedback); + println!("Publishing feedback"); + thread::sleep(std::time::Duration::from_millis(100)); + } + // Check if goal is done + if rclrs::ok() { + result.sequence = feedback.sequence.clone(); + goal_handle.succeed(&result); + println!("Goal succeeded"); + } } fn handle_accepted(goal_handle: Arc) { diff --git a/rclrs/src/action.rs b/rclrs/src/action.rs index f9096374a..919e0484d 100644 --- a/rclrs/src/action.rs +++ b/rclrs/src/action.rs @@ -80,15 +80,15 @@ where { pub(crate) fn new(rcl_handle: Arc) {} - pub(crate) fn is_canceling() -> bool { + pub(crate) fn is_canceling(&self) -> bool { false } - pub(crate) fn is_active() -> bool { + pub(crate) fn is_active(&self) -> bool { false } - pub(crate) fn is_executing() -> bool { + pub(crate) fn is_executing(&self) -> bool { false } } From 01e5b59be7222b42e498184edb3df1c3b89046b3 Mon Sep 17 00:00:00 2001 From: Esteve Fernandez Date: Thu, 10 Aug 2023 11:52:39 +0200 Subject: [PATCH 09/19] checkin --- examples/minimal_action_client/src/minimal_action_client.rs | 2 +- examples/minimal_action_server/src/minimal_action_server.rs | 2 +- rclrs/src/lib.rs | 2 -- rclrs/src/node.rs | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/examples/minimal_action_client/src/minimal_action_client.rs b/examples/minimal_action_client/src/minimal_action_client.rs index cb8df7ea5..e67c46656 100644 --- a/examples/minimal_action_client/src/minimal_action_client.rs +++ b/examples/minimal_action_client/src/minimal_action_client.rs @@ -5,7 +5,7 @@ use anyhow::{Error, Result}; fn main() -> Result<(), Error> { let context = rclrs::Context::new(env::args())?; - let mut node = rclrs::create_node(&context, "minimal_client")?; + let node = rclrs::create_node(&context, "minimal_client")?; let _client = node.create_action_client::("fibonacci")?; diff --git a/examples/minimal_action_server/src/minimal_action_server.rs b/examples/minimal_action_server/src/minimal_action_server.rs index 9ae1f8cc3..253393882 100644 --- a/examples/minimal_action_server/src/minimal_action_server.rs +++ b/examples/minimal_action_server/src/minimal_action_server.rs @@ -76,5 +76,5 @@ fn main() -> Result<(), Error> { handle_accepted, ); - rclrs::spin(&node).map_err(|err| err.into()) + rclrs::spin(node).map_err(|err| err.into()) } diff --git a/rclrs/src/lib.rs b/rclrs/src/lib.rs index 67cc0c6b9..701779863 100644 --- a/rclrs/src/lib.rs +++ b/rclrs/src/lib.rs @@ -42,8 +42,6 @@ pub use node::*; pub use parameter::*; pub use publisher::*; pub use qos::*; -use rcl_bindings::rcl_context_is_valid; -use rcl_bindings::rcl_action_goal_handle_t; pub use rcl_bindings::rmw_request_id_t; pub use service::*; pub use subscription::*; diff --git a/rclrs/src/node.rs b/rclrs/src/node.rs index 50a640c99..712a83f7b 100644 --- a/rclrs/src/node.rs +++ b/rclrs/src/node.rs @@ -201,7 +201,7 @@ impl Node { /// [1]: crate::ActionClient // TODO: make action client's lifetime depend on node's lifetime pub fn create_action_client( - &mut self, + &self, topic: &str, ) -> Result>, RclrsError> where From 540c1d06d24d36d2f7d8b9d5772fec176e705bae Mon Sep 17 00:00:00 2001 From: Esteve Fernandez Date: Thu, 10 Aug 2023 12:29:15 +0200 Subject: [PATCH 10/19] fix visibility --- rclrs/src/action.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rclrs/src/action.rs b/rclrs/src/action.rs index 919e0484d..c8a75c59c 100644 --- a/rclrs/src/action.rs +++ b/rclrs/src/action.rs @@ -78,17 +78,17 @@ impl ServerGoalHandle where T: rosidl_runtime_rs::Action, { - pub(crate) fn new(rcl_handle: Arc) {} + pub fn new(rcl_handle: Arc) {} - pub(crate) fn is_canceling(&self) -> bool { + pub fn is_canceling(&self) -> bool { false } - pub(crate) fn is_active(&self) -> bool { + pub fn is_active(&self) -> bool { false } - pub(crate) fn is_executing(&self) -> bool { + pub fn is_executing(&self) -> bool { false } } From bf48e396829dde5c07a6590cefd0cabb209a53d0 Mon Sep 17 00:00:00 2001 From: Esteve Fernandez Date: Wed, 8 Nov 2023 10:10:13 +0100 Subject: [PATCH 11/19] Instantiate a new ActionClient --- rclrs/src/action.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/rclrs/src/action.rs b/rclrs/src/action.rs index c8a75c59c..4fb7c3d0f 100644 --- a/rclrs/src/action.rs +++ b/rclrs/src/action.rs @@ -78,7 +78,12 @@ impl ServerGoalHandle where T: rosidl_runtime_rs::Action, { - pub fn new(rcl_handle: Arc) {} + pub fn new(rcl_handle: Arc) -> Self { + Self { + rcl_handle, + _marker: Default::default(), + } + } pub fn is_canceling(&self) -> bool { false From 0d59fb0857c055e9ddfe0b2aff2fce63d46bdd77 Mon Sep 17 00:00:00 2001 From: Esteve Fernandez Date: Mon, 28 Nov 2022 17:47:22 +0100 Subject: [PATCH 12/19] dded action generation --- rosidl_generator_rs/resource/action.rs.em | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/rosidl_generator_rs/resource/action.rs.em b/rosidl_generator_rs/resource/action.rs.em index 40c5acd59..115186f7d 100644 --- a/rosidl_generator_rs/resource/action.rs.em +++ b/rosidl_generator_rs/resource/action.rs.em @@ -26,6 +26,17 @@ TEMPLATE( }@ } // mod rmw +@{ +TEMPLATE( + 'msg_idiomatic.rs.em', + package_name=package_name, interface_path=interface_path, + msg_specs=action_msg_specs, + get_rs_name=get_rs_name, get_rmw_rs_type=get_rmw_rs_type, + get_idiomatic_rs_type=get_idiomatic_rs_type, + constant_value_to_rs=constant_value_to_rs) +}@ +} // mod rmw + @{ TEMPLATE( 'msg_idiomatic.rs.em', From d9f6d0ac3aa2f5ec6a4ed10b926e67976bfb3a22 Mon Sep 17 00:00:00 2001 From: Esteve Fernandez Date: Mon, 17 Jul 2023 13:55:08 +0200 Subject: [PATCH 13/19] checkin --- rclrs/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rclrs/src/lib.rs b/rclrs/src/lib.rs index 701779863..67cc0c6b9 100644 --- a/rclrs/src/lib.rs +++ b/rclrs/src/lib.rs @@ -42,6 +42,8 @@ pub use node::*; pub use parameter::*; pub use publisher::*; pub use qos::*; +use rcl_bindings::rcl_context_is_valid; +use rcl_bindings::rcl_action_goal_handle_t; pub use rcl_bindings::rmw_request_id_t; pub use service::*; pub use subscription::*; From 0bc7c5926b16167791e4141482a93832e289b8d4 Mon Sep 17 00:00:00 2001 From: Esteve Fernandez Date: Mon, 17 Jul 2023 13:55:08 +0200 Subject: [PATCH 14/19] checkin --- .../minimal_action_server/src/minimal_action_server.rs | 7 +++++++ rclrs/src/node.rs | 6 +++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/examples/minimal_action_server/src/minimal_action_server.rs b/examples/minimal_action_server/src/minimal_action_server.rs index 253393882..0c6ba4046 100644 --- a/examples/minimal_action_server/src/minimal_action_server.rs +++ b/examples/minimal_action_server/src/minimal_action_server.rs @@ -76,5 +76,12 @@ fn main() -> Result<(), Error> { handle_accepted, ); + let _action_server = node.create_action_server::( + "fibonacci", + handle_goal, + handle_cancel, + handle_accepted, + ); + rclrs::spin(node).map_err(|err| err.into()) } diff --git a/rclrs/src/node.rs b/rclrs/src/node.rs index 712a83f7b..5b3ca6f01 100644 --- a/rclrs/src/node.rs +++ b/rclrs/src/node.rs @@ -14,9 +14,9 @@ pub use self::graph::*; use crate::rcl_bindings::*; use crate::{ ActionClient, ActionServer, CancelResponse, Client, ClientBase, Clock, Context, GoalResponse, - GoalUUID, GuardCondition, ParameterInterface, ParameterVariant, Parameters, Publisher, - QoSProfile, RclrsError, ServerGoalHandle, Service, ServiceBase, Subscription, SubscriptionBase, - SubscriptionCallback, TimeSource, ToResult, + GoalUUID, GuardCondition, ParameterBuilder, ParameterInterface, ParameterVariant, Parameters, + Publisher, QoSProfile, RclrsError, ServerGoalHandle, Service, ServiceBase, Subscription, + SubscriptionBase, SubscriptionCallback, TimeSource, ToResult, }; impl Drop for rcl_node_t { From 5ef63f5f0daf22020136812aeefc60ac6cf498ef Mon Sep 17 00:00:00 2001 From: Esteve Fernandez Date: Fri, 17 Nov 2023 15:34:07 +0100 Subject: [PATCH 15/19] checkin --- .../minimal_action_server/src/minimal_action_server.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/examples/minimal_action_server/src/minimal_action_server.rs b/examples/minimal_action_server/src/minimal_action_server.rs index 0c6ba4046..253393882 100644 --- a/examples/minimal_action_server/src/minimal_action_server.rs +++ b/examples/minimal_action_server/src/minimal_action_server.rs @@ -76,12 +76,5 @@ fn main() -> Result<(), Error> { handle_accepted, ); - let _action_server = node.create_action_server::( - "fibonacci", - handle_goal, - handle_cancel, - handle_accepted, - ); - rclrs::spin(node).map_err(|err| err.into()) } From 8cdeea84ada55a2b7e5f1b4b37ef6c6fd9030c30 Mon Sep 17 00:00:00 2001 From: Esteve Fernandez Date: Fri, 17 Nov 2023 16:22:37 +0100 Subject: [PATCH 16/19] checkin --- examples/minimal_action_client/Cargo.toml | 4 ++-- examples/minimal_action_server/Cargo.toml | 4 ++-- rosidl_generator_rs/resource/action.rs.em | 2 ++ 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/examples/minimal_action_client/Cargo.toml b/examples/minimal_action_client/Cargo.toml index b1de4903b..96275ba4e 100644 --- a/examples/minimal_action_client/Cargo.toml +++ b/examples/minimal_action_client/Cargo.toml @@ -13,10 +13,10 @@ path = "src/minimal_action_client.rs" anyhow = {version = "1", features = ["backtrace"]} [dependencies.rclrs] -version = "0.3" +version = "0.4" [dependencies.rosidl_runtime_rs] -version = "0.3" +version = "0.4" [dependencies.example_interfaces] version = "*" diff --git a/examples/minimal_action_server/Cargo.toml b/examples/minimal_action_server/Cargo.toml index 1599d15ad..3ec27526c 100644 --- a/examples/minimal_action_server/Cargo.toml +++ b/examples/minimal_action_server/Cargo.toml @@ -13,10 +13,10 @@ path = "src/minimal_action_server.rs" anyhow = {version = "1", features = ["backtrace"]} [dependencies.rclrs] -version = "0.3" +version = "0.4" [dependencies.rosidl_runtime_rs] -version = "0.3" +version = "0.4" [dependencies.example_interfaces] version = "*" diff --git a/rosidl_generator_rs/resource/action.rs.em b/rosidl_generator_rs/resource/action.rs.em index 115186f7d..6b55f294f 100644 --- a/rosidl_generator_rs/resource/action.rs.em +++ b/rosidl_generator_rs/resource/action.rs.em @@ -21,6 +21,7 @@ TEMPLATE( package_name=package_name, interface_path=interface_path, msg_specs=action_msg_specs, get_rs_name=get_rs_name, get_rmw_rs_type=get_rmw_rs_type, + pre_field_serde=pre_field_serde, get_idiomatic_rs_type=get_idiomatic_rs_type, constant_value_to_rs=constant_value_to_rs) }@ @@ -32,6 +33,7 @@ TEMPLATE( package_name=package_name, interface_path=interface_path, msg_specs=action_msg_specs, get_rs_name=get_rs_name, get_rmw_rs_type=get_rmw_rs_type, + pre_field_serde=pre_field_serde, get_idiomatic_rs_type=get_idiomatic_rs_type, constant_value_to_rs=constant_value_to_rs) }@ From 3921709178abff3f8c21e17cc24d4d52e39d18e9 Mon Sep 17 00:00:00 2001 From: Esteve Fernandez Date: Fri, 17 Nov 2023 17:20:05 +0100 Subject: [PATCH 17/19] checkin --- .../src/minimal_action_server.rs | 35 ++++++++++--------- rclrs/src/action.rs | 12 ++++++- 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/examples/minimal_action_server/src/minimal_action_server.rs b/examples/minimal_action_server/src/minimal_action_server.rs index 253393882..a964b53bb 100644 --- a/examples/minimal_action_server/src/minimal_action_server.rs +++ b/examples/minimal_action_server/src/minimal_action_server.rs @@ -27,35 +27,36 @@ fn handle_cancel(_goal_handle: Arc) -> rclrs::CancelRespons fn execute(goal_handle: Arc) { println!("Executing goal"); let feedback = example_interfaces::action::Fibonacci_Feedback { - sequence: Vec::new(), - }; - feedback.sequence.push(0); - feedback.sequence.push(1); - let result = example_interfaces::action::Fibonacci_Result { - sequence: Vec::new(), + sequence: [0, 1].to_vec(), }; - let mut i = 1; - while i < goal_handle.goal().unwrap().order && rclrs::ok() { + for i in 1..goal_handle.goal_request.order { if goal_handle.is_canceling() { - result.sequence = feedback.sequence.clone(); + let result = example_interfaces::action::Fibonacci_Result { + sequence: Vec::new(), + }; + goal_handle.canceled(&result); println!("Goal canceled"); return; } - // Update sequence - feedback.sequence.push(feedback.sequence[i as usize] + feedback.sequence[(i - 1) as usize]); + + // Update sequence sequence + feedback + .sequence + .push(feedback.sequence[i as usize] + feedback.sequence[(i - 1) as usize]); // Publish feedback goal_handle.publish_feedback(&feedback); println!("Publishing feedback"); thread::sleep(std::time::Duration::from_millis(100)); } - // Check if goal is done - if rclrs::ok() { - result.sequence = feedback.sequence.clone(); - goal_handle.succeed(&result); - println!("Goal succeeded"); - } + + let result = example_interfaces::action::Fibonacci_Result { + sequence: Vec::new(), + }; + result.sequence = feedback.sequence.clone(); + goal_handle.succeed(&result); + println!("Goal succeeded"); } fn handle_accepted(goal_handle: Arc) { diff --git a/rclrs/src/action.rs b/rclrs/src/action.rs index 4fb7c3d0f..46e895788 100644 --- a/rclrs/src/action.rs +++ b/rclrs/src/action.rs @@ -71,6 +71,7 @@ where T: rosidl_runtime_rs::Action, { rcl_handle: Arc, + goal_request: Arc, _marker: PhantomData, } @@ -78,9 +79,10 @@ impl ServerGoalHandle where T: rosidl_runtime_rs::Action, { - pub fn new(rcl_handle: Arc) -> Self { + pub fn new(rcl_handle: Arc, goal_request: Arc) -> Self { Self { rcl_handle, + goal_request: Arc::clone(&goal_request), _marker: Default::default(), } } @@ -96,4 +98,12 @@ where pub fn is_executing(&self) -> bool { false } + + pub fn succeed(&self, result: &T::Result) -> Result<(), RclrsError> { + Ok(()) + } + + pub fn canceled(&self, result: &T::Result) -> Result<(), RclrsError> { + Ok(()) + } } From 583f16646fde2a3175ff47a470426b2679037956 Mon Sep 17 00:00:00 2001 From: Esteve Fernandez Date: Wed, 17 Jan 2024 15:58:56 +0100 Subject: [PATCH 18/19] Fix missing exported pre_field_serde field --- rosidl_generator_rs/resource/action.rs.em | 1 + 1 file changed, 1 insertion(+) diff --git a/rosidl_generator_rs/resource/action.rs.em b/rosidl_generator_rs/resource/action.rs.em index 6b55f294f..f9adb0b6c 100644 --- a/rosidl_generator_rs/resource/action.rs.em +++ b/rosidl_generator_rs/resource/action.rs.em @@ -45,6 +45,7 @@ TEMPLATE( package_name=package_name, interface_path=interface_path, msg_specs=action_msg_specs, get_rs_name=get_rs_name, get_rmw_rs_type=get_rmw_rs_type, + pre_field_serde=pre_field_serde, get_idiomatic_rs_type=get_idiomatic_rs_type, constant_value_to_rs=constant_value_to_rs) }@ From e6840c29612d46bdccde15ff76bfac07018c68e6 Mon Sep 17 00:00:00 2001 From: Esteve Fernandez Date: Wed, 17 Jan 2024 16:16:26 +0100 Subject: [PATCH 19/19] Removed extra code --- rosidl_generator_rs/resource/action.rs.em | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/rosidl_generator_rs/resource/action.rs.em b/rosidl_generator_rs/resource/action.rs.em index f9adb0b6c..b37919dc3 100644 --- a/rosidl_generator_rs/resource/action.rs.em +++ b/rosidl_generator_rs/resource/action.rs.em @@ -27,18 +27,6 @@ TEMPLATE( }@ } // mod rmw -@{ -TEMPLATE( - 'msg_idiomatic.rs.em', - package_name=package_name, interface_path=interface_path, - msg_specs=action_msg_specs, - get_rs_name=get_rs_name, get_rmw_rs_type=get_rmw_rs_type, - pre_field_serde=pre_field_serde, - get_idiomatic_rs_type=get_idiomatic_rs_type, - constant_value_to_rs=constant_value_to_rs) -}@ -} // mod rmw - @{ TEMPLATE( 'msg_idiomatic.rs.em',