Comments (7)
Hi there!
I've been using ros2_rust
along with bevy
(although v0.11) without much problems.
Here's how I integrate ROS 2 interfaces within my bevy application:
- I have a dedicated startup plugin that initializes a
bevy Resource
which is a struct that bundles anrclrs::Context
and anArc<rclrs::Node>
. ADefault
trait for this resource is defined which instantiates the context and node. The same plugin also adds a system which retrieves the above resource, checks if the context is okay and if so, callsrclrs::spin_once()
with a clone of the node. - In plugins where I need to define, pub/sub/client/services, I define a
bevy Component
struct with the correspondingrclrs
entity. Then, there are systems that query for the Resource above, initialize the component using the node from the resource, and finally insert the component into the entities.
Hope that helps!
from ros2_rust.
use bevy::prelude::*;
use std::sync::{Arc, Mutex};
use std_msgs::msg::String as StringMsg;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(NodePlugin)
.add_systems(Startup, setup)
.add_systems(Update,print_string)
.run();
}
fn setup() {
eprintln!("Bevy initialized.");
}
fn print_string(
string_node: ResMut<NodeSetting>,
) {
let s = string_node.data.clone().lock().unwrap().clone().unwrap();
eprintln!("{}",&s.data);
eprintln!("Received string.");
}
pub struct NodePlugin;
#[derive(Resource)]
struct NodeSetting {
node: Arc<rclrs::Node>,
_subscription: Arc<rclrs::Subscription<StringMsg>>,
data: Arc<Mutex<Option<StringMsg>>>,
}
impl Plugin for NodePlugin {
fn build (&self, app: &mut App){
let context = rclrs::Context::new(std::env::args()).unwrap();
let node = rclrs::Node::new(&context, "republisher").unwrap();
let data = Arc::new(Mutex::new(None));
let data_cb = Arc::clone(&data);
let string_node = NodeSetting {
node: node.clone(),
data: data.clone(),
_subscription: node.create_subscription(
"in_topic",
rclrs::QOS_PROFILE_DEFAULT,
move |msg: StringMsg| {
*data_cb.lock().unwrap() = Some(msg); // (4)
},
).unwrap(),
};
app.insert_resource(string_node)
.add_systems(Update, spin_node)
.insert_resource(Time::<Fixed>::from_hz(1.0));
}
}
fn spin_node(string_node: ResMut<NodeSetting>){
eprintln!("spinning node ");
rclrs::spin_once(string_node.node.clone(),None).unwrap();
eprintln!("exit node ");
}
from ros2_rust.
@Yadunund thanks for the support.
I tried to create a simple test code to try out what you suggested.
Not sure did I understood the recommendation correctly but my Bevy still gets stuck after the node was spun once.
from ros2_rust.
Is it stuck inside the spin_once
or elsewhere? I'd recommend putting a sensible timeout in the spin_once
.
from ros2_rust.
Instead of transferring the subscription data using an Arc<Mutex<Option<T>>>
I would recommend creating a mpsc channel. Give the sender to your subscription callback and store the receiver in your resource.
Your subscription callback would simply pass the messages into the sender. Your print_string
system would drain the receiver using try_recv
.
from ros2_rust.
use bevy::prelude::*;
use std::{sync::{Arc, Mutex}, time::Duration};
use std_msgs::msg::String as StringMsg;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(NodePlugin)
.add_systems(Startup, setup)
.add_systems(Update,print_string)
.run();
}
fn setup() {
eprintln!("Bevy initialized.");
}
fn print_string(
string_node: ResMut<NodeSetting>,
) {
let guard = string_node.data.lock().unwrap();
if guard.as_ref() != None{
let info = guard.as_ref().unwrap();
eprintln!("Bevy got message: {}",&info.data);
}
}
pub struct NodePlugin;
#[derive(Resource)]
struct NodeSetting {
node: Arc<rclrs::Node>,
_subscription: Arc<rclrs::Subscription<StringMsg>>,
data: Arc<Mutex<Option<StringMsg>>>,
}
impl Plugin for NodePlugin {
fn build (&self, app: &mut App){
let context = rclrs::Context::new(std::env::args()).unwrap();
let node = rclrs::Node::new(&context, "republisher").unwrap();
let data = Arc::new(Mutex::new(None));
let data_cb = Arc::clone(&data);
let string_node = NodeSetting {
node: node.clone(),
data: data.clone(),
_subscription: node.create_subscription(
"in_topic",
rclrs::QOS_PROFILE_DEFAULT,
move |msg: StringMsg| {
eprintln!("Node received message: {}",msg.data);
*data_cb.lock().unwrap() = Some(msg); // (4)
},
).unwrap(),
};
app.insert_resource(string_node)
.add_systems(Update, spin_node)
.insert_resource(Time::<Fixed>::from_hz(1.0));
}
}
fn spin_node(string_node: ResMut<NodeSetting>){
eprintln!("Entering node ");
let _action = rclrs::spin_once(string_node.node.clone(),Some(Duration::new(1, 0)));
eprintln!("Exiting node ");
}
from ros2_rust.
@mxgrey @Yadunund Awesome guys.
Thank you so much for the help.
I managed to get the message on the bevy resource struct and bevy can print the string as it receives it.
from ros2_rust.
Related Issues (20)
- Check if our CI configuration is potentially causing our intermittent failures HOT 1
- Move rclrs_test into rclrs
- Investigate the rcl struct drop order HOT 4
- Failed to build depends on `builtin_interfaces` HOT 10
- Cargo can't find `Std_msgs` HOT 6
- Your own installation process crashes HOT 2
- Strange Warning by initial rclrs compilation HOT 2
- Audit drop ordering for rcl handles HOT 2
- Your tutorial is actually too complicated for beginners. HOT 5
- How to build subscribers? HOT 1
- `self.node.get_clock().now().to_ros_msg().unwrap()` doesn't work anymore HOT 12
- QoS for Clients and Services HOT 6
- Prevent message packages from crates.io to be included during the build HOT 15
- Crate imports_granularity requires nightly HOT 4
- Action_msgs not findable, because of relocation from `/ros_ws/install/action_msgs/share/action_msgs/rust` to `/ros_ws/install/share/action_msgs/rust/` HOT 3
- Upgrade to Rust 1.78 HOT 2
- Begin Jazzy Testing HOT 2
- Improve Message Generation Documentation
- Investigate proposed alternatives to the existing message generation pipeline.
- Panic occurs when publish sequence types for Rust 1.78 HOT 7
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ros2_rust.