ros2_rust icon indicating copy to clipboard operation
ros2_rust copied to clipboard

Missing functions in rclrs

Open montmejat opened this issue 9 months ago • 14 comments

I'm simply trying to run the example from writing-your-first-rclrs-node.md but I'm getting the following errors:

error[E0425]: cannot find function `spin` in crate `rclrs`
  --> src/main.rs:29:12
   |
29 |     rclrs::spin(republisher.node)
   |            ^^^^ not found in `rclrs`

error[E0599]: no function or associated item named `new` found for struct `Node` in the current scope
   --> src/main.rs:12:33
    |
12  |         let node = rclrs::Node::new(context, "republisher")?;
    |                                 ^^^ function or associated item not found in `Node`
    |
help: there is a method `ne` with a similar name, but with different arguments
   --> /home/aurelien.montmejat/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/cmp.rs:261:5
    |
261 |     fn ne(&self, other: &Rhs) -> bool {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0061]: this function takes 2 arguments but 1 argument was supplied
   --> src/main.rs:27:19
    |
27  |     let context = rclrs::Context::new(std::env::args())?;
    |                   ^^^^^^^^^^^^^^^^^^^------------------ argument #2 of type `InitOptions` is missing
    |
note: associated function defined here
   --> /home/aurelien.montmejat/ROS/workspaces/volvo/install/rclrs/share/rclrs/rust/src/context.rs:121:12
    |
121 |     pub fn new(
    |            ^^^
help: provide the argument
    |
27  |     let context = rclrs::Context::new(std::env::args(), /* InitOptions */)?;
    |                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Here's what I have:

use std::sync::Arc;
use std_msgs::msg::String as StringMsg;

struct RepublisherNode {
    node: Arc<rclrs::Node>,
    _subscription: Arc<rclrs::Subscription<StringMsg>>,
    data: Option<StringMsg>,
}

impl RepublisherNode {
    fn new(context: &rclrs::Context) -> Result<Self, rclrs::RclrsError> {
        let node = rclrs::Node::new(context, "republisher")?;
        let data = None;
        let _subscription =
            node.create_subscription("in_topic", rclrs::QOS_PROFILE_DEFAULT, |msg: StringMsg| {
                todo!("Assign msg to self.data")
            })?;
        Ok(Self {
            node,
            _subscription,
            data,
        })
    }
}

fn main() -> Result<(), rclrs::RclrsError> {
    let context = rclrs::Context::new(std::env::args())?;
    let republisher = RepublisherNode::new(&context)?;
    rclrs::spin(republisher.node)
}

and:

[package]
name = "..."
version = "0.1.0"
edition = "2021"

[dependencies]
rclrs = "0.4.1"
std_msgs = "*"

What could I have missed? 😅 Thanks!

montmejat avatar Mar 17 '25 15:03 montmejat

Sorry you haven't missed anything, the tutorial is out of date.

Maybe we should consider moving the tutorial into in-module documentation instead of a separate markdown file. That way we can run doctests on it and ensure it doesn't drift from the API.

Any thoughts on that @esteve @maspe36 @jhdcs ?

Feel free to assign this ticket to me. I'll either update the docs as-is or move it into the module depending on what people prefer.

mxgrey avatar Mar 17 '25 15:03 mxgrey

In the meantime @montmejat you can refer to the examples here which are up to date.

mxgrey avatar Mar 17 '25 15:03 mxgrey

Thanks for your suuper quick answer! I will look into that :)

I'd also be very interested if there are any examples on using custom .srv service file (and making them accessible to C++ or Python nodes)

montmejat avatar Mar 17 '25 15:03 montmejat

Let's reopen the issue to keep it tracked. This is something we should get fixed.

mxgrey avatar Mar 17 '25 15:03 mxgrey

Client and service examples can be found here. We might want to consider consolidating all the examples.

mxgrey avatar Mar 17 '25 15:03 mxgrey

Maybe we should consider moving the tutorial into in-module documentation instead of a separate markdown file. That way we can run doctests on it and ensure it doesn't drift from the API.

I like the idea of moving the tutorial into in-module documentation, we can always automate generating the examples as standalone applications from the documentation and at the same time having the doctests run on them. Do you want to give it a try @mxgrey ?

esteve avatar Mar 20 '25 10:03 esteve

Hello, I was rewriting the same tutorial (just trying to help), do not know how proceed into in-module documentation @esteve, but if I you give me 5 cents maybe I could help. Don't worry if @esteve or @mxgrey you would like to go through this I can look through other PR/tasks.

roboticswithjulia avatar Mar 20 '25 10:03 roboticswithjulia

@roboticswithjulia cool! I've assigned the ticket to @mxgrey, but if you want to work on something else, that'd be awesome 🙂

esteve avatar Mar 20 '25 12:03 esteve

Help is always appreciated, thanks for offering @roboticswithjulia !

This page provides a quick overview of how documentation works in Rust. The key thing is that when you use

//!
//!
//! 

inside a Rust "module" (a source file that ends with .rs), then cargo's doc generator will render that content inside the documentation for that module. Then when you do cargo doc --open you'll be able to see that documentation in the section for that module. All cargo documentation uses markdown, so it should be pretty straightforward to move it from the markdown files that we already have.

There are two reasons that I'm suggesting we move the documentation into the module:

  • It should be more visible for both users who are looking at the code and users who are looking at crates.io
  • Any code that we put inside triple tick blocks ``` ... ``` will be compiled and run as a "doctest". That way if an API ever changes in a way that breaks the documentation we'll see a CI failure.

mxgrey avatar Mar 20 '25 13:03 mxgrey

Thank you for the detailed explanation @mxgrey, it has helped me a lot and I think that's the good way to proceed. After looking through the overall examples, there's two things we could do:

  1. [Option A] Add new docstrings in the multiple examples (for example minimal_publisher.rs, minimal_subscriber...) and remove the writing-your-first-rclrs-node.md file.
  2. [Option B] Create a new writing_your_first_rclrs_node.rs example inside the examples/minimal_pub_sub:

Which is the best way to proceed?

Thank you for your help!

roboticswithjulia avatar Mar 21 '25 08:03 roboticswithjulia

@mxgrey I just added a first implementation after looking through your super useful indications. You can find the PR here https://github.com/ros2-rust/ros2_rust/pull/467, please let me know if there is other indications that should be considered or any improvements. Thank you!

roboticswithjulia avatar Mar 25 '25 23:03 roboticswithjulia

@mxgrey do you have any idea why the pipelines fails due to Warning: can't set imports_granularity = Crate, unstable features are only available in nightly channel. ? https://github.com/ros2-rust/ros2_rust/actions/runs/14072368975/job/39409032878#step:9:5632 Thank you! Could it be something related to this point? Any code that we put inside triple tick blocks ``` ... ``` will be compiled and run as a "doctest". That way if an API ever changes in a way that breaks the documentation we'll see a CI failure.

roboticswithjulia avatar Mar 26 '25 00:03 roboticswithjulia

@roboticswithjulia that's just a warning, it shouldn't make the CI fail. However, the CI seems to fail because the new example is not properly formatted (see cargo fmt). In any case, it's best to ask question about PR in the PR itself, I'll reply with more detail there. Thanks for submitting the PR!

esteve avatar Mar 26 '25 10:03 esteve

@esteve thank you for the explanation. I see, I just tried to fix it and it seems that there were a few spaces that cargo fmt didn't like :) Totally agree on the best is to ask the question about PR in the PR itself!! Will do from now on there :) Thank you!!!

roboticswithjulia avatar Mar 26 '25 15:03 roboticswithjulia