-
Notifications
You must be signed in to change notification settings - Fork 127
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
Find a better way of interacting with nodes #243
Comments
I did an internship in the company Pollen Robotics about transcription of Python ROS code to Rust ROS code. Here is the result with its Python equivalent inside of it. It may not be the best but in the end it worked as intended. I was using the client-service branch just before its merge with the main branch. I made some things to allow an easier usage of the ros2-rust crate, resolving partially the locking issue and the transcription from Python. For the locking issue I resolved it by making the macro ameis (Arc Mutex Edit Inner Safely). The arc_mutex macro can be simplified, as it spam in debug profile but only for user friendliness purpose (to backtrack the usage of locks and therefore data) : #[allow(unused_mut)]
macro_rules! arc_mutex {
($name_arc:ident => $name_var:ident) => {
#[cfg(not(debug_assertions))]
{
$name_var = $name_arc.lock().unwrap();
}
#[cfg(debug_assertions)]
loop {
if let Ok(some) = $name_arc.try_lock() {
$name_var = some;
println!(
"macro getting lock of {}: {:?} at {:?}",
stringify!($name_arc),
line!(),
std::time::Instant::now()
);
break;
} else {
std::thread::sleep(std::time::Duration::from_millis(100));
println!("macro {}: {:?}", stringify!($name_var), line!());
}
}
};
}
macro_rules! ameis {
($am_var:ident => $var:ident; $some:block ) => {
{
#[allow(unused_mut)]
let mut $var;
arc_mutex!($am_var=>$var);
$some
}
};
} Simplified version with an example : use std::sync::{Arc, Mutex};
macro_rules! ameis {
($am_var:ident => $var:ident; $some:block ) => {
{
#[allow(unused_mut)]
let mut $var;
$var = $am_var.lock().unwrap();
$some
}
};
}
fn main() {
println!("Hello, ArcMutex!");
let var = Arc::new(Mutex::new(String::from("init")));
println!("{:?}", var);
ameis!(var=>temp_var;{*temp_var = String::from("inner")});
println!("{:?}", var);
ameis!(var => temp_var ; {
println!("{}", temp_var);
*temp_var = String::from("second");
});
println!("{:?}", var);
} But this simplified version needs a correct usage of mutex to be safe to use as it wont help otherwise and could lock the code. It may imply some repetition in the code but allow a easier usage of the parameters, especially with a struct where you need to keep the Mutex alive. It may need another place to be but in my internship I also made the crate cargo-rost which skips most of the boring stuff of the transcription of Python ROS to Rust ROS but it is currently oriented to be used on a class structured Python code (if it is how it is called) to work properly (tests were made on initials python codes of the intern ship ex: this one by running the following command It may not resolve the issue but adding a struct to contain Data that implement the Deref/DerefMut trait with the target type being a MutexGuard to the data (or maybe as the MutexGuard never drop after, the only easy way is the ameis macro). It would simplify the user experience but it may be something totally new for the ROS environment (I have not that much experience in ROS so I can not really say anything) but it may not be appreciated to be implemented as being a Rust only thing. |
As the tutorial shows, implementing a node with
rclrs
is currently very different fromrclcpp
/rclpy
and comparatively difficult: In particular, a lot of locking is going on.There probably is room for an abstraction that, at the very least, hides this from the user. For instance, perhaps callbacks could receive a mutable reference to the "node state" along with the message itself, which would correspond to the members of your
Node
class in C++.The text was updated successfully, but these errors were encountered: