Skip to content

Commit f463369

Browse files
committed
Added basic create_action_client function
1 parent 795a3ac commit f463369

File tree

10 files changed

+95
-8
lines changed

10 files changed

+95
-8
lines changed

examples/minimal_action_client_server/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,5 @@ version = "0.3"
2222
[dependencies.rosidl_runtime_rs]
2323
version = "0.3"
2424

25-
[dependencies.action_msgs]
25+
[dependencies.example_interfaces]
2626
version = "*"

examples/minimal_action_client_server/package.xml

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@
1414

1515
<build_depend>rclrs</build_depend>
1616
<build_depend>rosidl_runtime_rs</build_depend>
17-
<build_depend>action_msgs</build_depend>
17+
<build_depend>example_interfaces</build_depend>
1818

1919
<exec_depend>rclrs</exec_depend>
2020
<exec_depend>rosidl_runtime_rs</exec_depend>
21-
<exec_depend>action_msgs</exec_depend>
21+
<exec_depend>example_interfaces</exec_depend>
2222

2323
<export>
2424
<build_type>ament_cargo</build_type>

examples/minimal_action_client_server/src/minimal_action_client.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ use anyhow::{Error, Result};
55
fn main() -> Result<(), Error> {
66
let context = rclrs::Context::new(env::args())?;
77

8-
let _node = rclrs::create_node(&context, "minimal_action_client")?;
8+
let mut node = rclrs::create_node(&context, "minimal_client")?;
9+
10+
let _client = node.create_action_client::<example_interfaces::action::Fibonacci>("fibonacci")?;
911

1012
Ok(())
1113
}

rclrs/src/action.rs

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
use crate::{rcl_bindings::*, RclrsError};
2+
use std::sync::{Arc, Mutex, MutexGuard};
3+
4+
use std::marker::PhantomData;
5+
6+
pub struct ActionClient<T>
7+
where
8+
T: rosidl_runtime_rs::Action,
9+
{
10+
_marker: PhantomData<T>,
11+
}
12+
13+
impl<T> ActionClient<T>
14+
where
15+
T: rosidl_runtime_rs::Action,
16+
{
17+
/// Creates a new action client.
18+
pub(crate) fn new(rcl_node_mtx: Arc<Mutex<rcl_node_t>>, topic: &str) -> Result<Self, RclrsError>
19+
// This uses pub(crate) visibility to avoid instantiating this struct outside
20+
// [`Node::create_client`], see the struct's documentation for the rationale
21+
where
22+
T: rosidl_runtime_rs::Action,
23+
{
24+
Ok(Self {
25+
_marker: Default::default(),
26+
})
27+
}
28+
}

rclrs/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
//!
66
//! [1]: https://github.com/ros2-rust/ros2_rust/blob/main/README.md
77
8+
mod action;
89
mod arguments;
910
mod client;
1011
mod context;
@@ -25,6 +26,7 @@ pub mod dynamic_message;
2526

2627
use std::time::Duration;
2728

29+
pub use action::*;
2830
pub use arguments::*;
2931
pub use client::*;
3032
pub use context::*;

rclrs/src/node.rs

+23-3
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ pub use self::builder::*;
1313
pub use self::graph::*;
1414
use crate::rcl_bindings::*;
1515
use crate::{
16-
Client, ClientBase, Context, GuardCondition, ParameterOverrideMap, Publisher, QoSProfile,
17-
RclrsError, Service, ServiceBase, Subscription, SubscriptionBase, SubscriptionCallback,
18-
ToResult,
16+
ActionClient, Client, ClientBase, Context, GuardCondition, ParameterOverrideMap, Publisher,
17+
QoSProfile, RclrsError, Service, ServiceBase, Subscription, SubscriptionBase,
18+
SubscriptionCallback, ToResult,
1919
};
2020

2121
impl Drop for rcl_node_t {
@@ -190,6 +190,26 @@ impl Node {
190190
Ok(client)
191191
}
192192

193+
/// Creates a [`Client`][1].
194+
///
195+
/// [1]: crate::ActionClient
196+
// TODO: make action client's lifetime depend on node's lifetime
197+
pub fn create_action_client<T>(
198+
&mut self,
199+
topic: &str,
200+
) -> Result<Arc<ActionClient<T>>, RclrsError>
201+
where
202+
T: rosidl_runtime_rs::Action,
203+
{
204+
let client = Arc::new(ActionClient::<T>::new(
205+
Arc::clone(&self.rcl_node_mtx),
206+
topic,
207+
)?);
208+
// self.clients
209+
// .push(Arc::downgrade(&client) as Weak<dyn ClientBase>);
210+
Ok(client)
211+
}
212+
193213
/// Creates a [`GuardCondition`][1] with no callback.
194214
///
195215
/// A weak pointer to the `GuardCondition` is stored within this node.

rosidl_generator_rs/resource/action.rs.em

+17
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,20 @@ TEMPLATE(
3535
get_idiomatic_rs_type=get_idiomatic_rs_type,
3636
constant_value_to_rs=constant_value_to_rs)
3737
}@
38+
39+
@[for subfolder, action_spec in action_specs]
40+
41+
@{
42+
type_name = action_spec.namespaced_type.name
43+
}@
44+
45+
// Corresponds to @(package_name)__@(subfolder)__@(type_name)
46+
pub struct @(type_name);
47+
48+
impl rosidl_runtime_rs::Action for @(type_name) {
49+
type Goal = crate::@(subfolder)::rmw::@(type_name)_Goal;
50+
type Result = crate::@(subfolder)::rmw::@(type_name)_Result;
51+
type Feedback = crate::@(subfolder)::rmw::@(type_name)_Feedback;
52+
}
53+
54+
@[end for]

rosidl_generator_rs/resource/lib.rs.em

+4
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,7 @@ pub mod msg;
77
@[if len(srv_specs) > 0]@
88
pub mod srv;
99
@[end if]@
10+
11+
@[if len(action_specs) > 0]@
12+
pub mod action;
13+
@[end if]@

rosidl_runtime_rs/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ mod string;
99
pub use string::{BoundedString, BoundedWString, String, StringExceedsBoundsError, WString};
1010

1111
mod traits;
12-
pub use traits::{Message, RmwMessage, SequenceAlloc, Service};
12+
pub use traits::{Action, Message, RmwMessage, SequenceAlloc, Service};

rosidl_runtime_rs/src/traits.rs

+14
Original file line numberDiff line numberDiff line change
@@ -160,3 +160,17 @@ pub trait Service: 'static {
160160
/// Get a pointer to the correct `rosidl_service_type_support_t` structure.
161161
fn get_type_support() -> *const std::os::raw::c_void;
162162
}
163+
164+
/// Trait for actions.
165+
///
166+
/// User code never needs to call this trait's method, much less implement this trait.
167+
pub trait Action: 'static {
168+
/// The goal message associated with this service.
169+
type Goal: Message;
170+
171+
/// The result message associated with this service.
172+
type Result: Message;
173+
174+
/// The feedback message associated with this service.
175+
type Feedback: Message;
176+
}

0 commit comments

Comments
 (0)