Browse Source

Provide functions to create topics and publishers

tags/v0.3.3-rc1
Philipp Oppermann 2 years ago
parent
commit
7baecea71d
Failed to extract signature
4 changed files with 51 additions and 16 deletions
  1. +3
    -0
      examples/c++-ros2-dataflow/node-rust-api/main.cc
  2. +2
    -4
      libraries/extensions/ros2-bridge/msg-gen/src/lib.rs
  3. +45
    -10
      libraries/extensions/ros2-bridge/msg-gen/src/types/message.rs
  4. +1
    -2
      libraries/extensions/ros2-bridge/msg-gen/src/types/package.rs

+ 3
- 0
examples/c++-ros2-dataflow/node-rust-api/main.cc View File

@@ -9,6 +9,9 @@ int main()
std::cout << "HELLO FROM C++" << std::endl;

auto ros2_context = init_ros2_context();
auto node = ros2_context->new_node("/ros2_demo", "turtle_teleop");
auto vel_topic = node->create_topic_geometry_msgs_Twist("/turtle1", "cmd_vel", 0);
auto vel_publisher = node->create_publisher(vel_topic, 0);

geometry_msgs::Twist twist = {
.linear = {.x = 1, .y = 0, .z = 0},


+ 2
- 4
libraries/extensions/ros2-bridge/msg-gen/src/lib.rs View File

@@ -29,13 +29,12 @@ where
let mut message_topic_impls = Vec::new();
let mut aliases = Vec::new();
for package in &packages {
let package_name = Ident::new(&package.name, Span::call_site());
for message in &package.messages {
let (def, imp) = message.struct_token_stream(&package_name, create_cxx_bridge);
let (def, imp) = message.struct_token_stream(&package.name, create_cxx_bridge);
shared_type_defs.push(def);
message_struct_impls.push(imp);
if create_cxx_bridge {
let (topic_def, topic_impl) = message.topic_def(&package_name);
let (topic_def, topic_impl) = message.topic_def(&package.name);
message_topic_defs.push(topic_def);
message_topic_impls.push(topic_impl);
}
@@ -52,7 +51,6 @@ where
type Ros2Node;
fn init_ros2_context() -> Result<Box<Ros2Context>>;
fn new_node(self: &Ros2Context, name_space: &str, base_name: &str) -> Result<Box<Ros2Node>>;

#(#message_topic_defs)*
}
},


+ 45
- 10
libraries/extensions/ros2-bridge/msg-gen/src/types/message.rs View File

@@ -125,7 +125,7 @@ pub struct Message {
impl Message {
pub fn struct_token_stream(
&self,
package_name: &Ident,
package_name: &str,
gen_cxx_bridge: bool,
) -> (impl ToTokens, impl ToTokens) {
let cxx_name = format_ident!("{}", self.name);
@@ -176,27 +176,62 @@ impl Message {
}
}

pub fn topic_def(&self, package_name: &Ident) -> (impl ToTokens, impl ToTokens) {
pub fn topic_def(&self, package_name: &str) -> (impl ToTokens, impl ToTokens) {
if self.members.is_empty() {
return (quote! {}, quote! {});
};

let topic_name = format_ident!("Topic__{package_name}__{}", self.name);
let fn_name = format_ident!("new__Topic__{package_name}__{}", self.name);
let cxx_topic_name = format_ident!("Topic_{}", self.name);
let cxx_fn_name = format!("create_{cxx_topic_name}");
let create_topic = format_ident!("new__Topic__{package_name}__{}", self.name);
let cxx_create_topic = format!("create_topic_{package_name}_{}", self.name);

let publisher_name = format_ident!("Publisher__{package_name}__{}", self.name);
let cxx_publisher_name = format_ident!("Publisher_{}", self.name);
let create_publisher = format_ident!("new__Publisher__{package_name}__{}", self.name);
let cxx_create_publisher = format_ident!("create_publisher");
let struct_raw_name = format_ident!("{package_name}__{}", self.name);
let self_name = &self.name;

let def = quote! {
#[namespace = #package_name]
#[cxx_name = #cxx_topic_name]
type #topic_name;
#[cxx_name = #cxx_create_topic]
fn #create_topic(self: &Ros2Node, name_space: &str, base_name: &str, qos: u32) -> Result<Box<#topic_name>>;

#[namespace = #package_name]
#[cxx_name = #cxx_fn_name]
fn #fn_name() -> Box<#topic_name>;
#[cxx_name = #cxx_publisher_name]
type #publisher_name;
#[cxx_name = #cxx_create_publisher]
fn #create_publisher(self: &mut Ros2Node, topic: &Box<#topic_name>, qos: u32) -> Result<Box<#publisher_name>>;
};
let imp = quote! {
#[allow(non_camel_case_types)]
pub struct #topic_name;
#[allow(non_snake_case)]
pub fn #fn_name() -> Box<#topic_name> {
Box::new(#topic_name)
pub struct #topic_name(rustdds::Topic);

impl Ros2Node {
#[allow(non_snake_case)]
pub fn #create_topic(&self, name_space: &str, base_name: &str, qos: u32) -> eyre::Result<Box<#topic_name>> {
let name = ros2_client::Name::new(name_space, base_name).map_err(|e| eyre::eyre!(e))?;
let type_name = ros2_client::MessageTypeName::new(#package_name, #self_name);
let qos = Default::default(); // TODO
let topic = self.0.create_topic(&name, type_name, &qos)?;
Ok(Box::new(#topic_name(topic)))
}
}

#[allow(non_camel_case_types)]
pub struct #publisher_name(ros2_client::Subscription<ffi::#struct_raw_name>);

impl Ros2Node {
#[allow(non_snake_case)]
pub fn #create_publisher(&mut self, topic: &Box<#topic_name>, qos: u32) -> eyre::Result<Box<#publisher_name>> {
let subscription = self.0.create_subscription(&topic.0, None)?; // TODO
Ok(Box::new(#publisher_name(subscription)))
}
}

};
(def, imp)
}


+ 1
- 2
libraries/extensions/ros2-bridge/msg-gen/src/types/package.rs View File

@@ -27,7 +27,6 @@ impl Package {
}

pub fn message_structs(&self, gen_cxx_bridge: bool) -> (impl ToTokens, impl ToTokens) {
let package_name = Ident::new(&self.name, Span::call_site());
if self.messages.is_empty() {
// empty msg
(quote! {}, quote! {})
@@ -35,7 +34,7 @@ impl Package {
let items = self
.messages
.iter()
.map(|v| v.struct_token_stream(&package_name, gen_cxx_bridge));
.map(|v| v.struct_token_stream(&self.name, gen_cxx_bridge));
let defs = items.clone().map(|(def, _)| def);
let impls = items.clone().map(|(_, im)| im);
let def_tokens = quote! {


Loading…
Cancel
Save