Ask Your Question
0

Cannot create a rclcpp::spin function

asked 2019-08-08 13:57:50 -0500

EdwardNur gravatar image

Hi all,

I am having a trouble in publishing and subscribing the node at the same time. More specifically, I am having an issue to pass the shared_ptr to the rclcpp::spin function. Here is my function inside my class:

void OdomNode::update()
{
    //std::shared_ptr<rclcpp::Node> _for_spin = std::make_shared<rclcpp::Node>(*this);
    while(rclcpp::ok())
    {
        this->loop();
        this->_loop_rate.sleep();
        rclcpp::spin(*this);
    }
}

As you can see, the object itself inherits from rclcpp::Node class and this is a node instance. I have tried to use the first (uncommented) choice but it would not compile saying that the variable is private in this context (not sure what private there exactly). I have also tried to pass shared_from_this but during the runtime it crashes saying that it is a bad_weak_ptr.

edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted
1

answered 2019-09-07 23:41:46 -0500

jdlangs gravatar image

Using shared_from_this() is the correct way to obtain a rclcpp::Node::SharedPtr. But note that it only works if there already exists a shared_ptr that has ownership of the node. If you had only created a local OdomNode object instead of using std::make_shared, you would get that bad_weak_ptr error.

edit flag offensive delete link more
0

answered 2019-09-10 16:24:28 -0500

jacobperron gravatar image

updated 2019-09-10 16:25:31 -0500

@jdlangs is correct that shared_from_this() is the correct way to get a shared pointer to the node.

Besides the compilation issue, your code looks troublesome. rclcpp::spin() is a blocking function, so this->loop() will only be called once. You could try using rclcpp::spin_some() instead, but I suggest that you call rclcpp::spin() from outside your node, for example in a main function like this:

int main(int argc, char ** argv)
{
  rclcpp::init(argc, argv);

  auto odom_node = std::make_shared<OdomNode>();
  rclcpp::spin(odom_node);

  rclcpp::shutdown();
  return 0;
}

And perhaps start a timer to replace your update method, for example in the constructor:

OdomNode::OdomNode(rclcpp::Duration & loop_rate)
{
  timer_ = this->create_wall_timer(loop_rate.to_chrono(), std::bind(&OdomNode::loop, this));
}

This is the pattern you'll find in many of the examples and demos. This helps make your node more flexible. For example, it leaves open the possibility to compose your node with others into a single process, or easily change the type of executor or callback group.

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

2 followers

Stats

Asked: 2019-08-08 13:57:50 -0500

Seen: 42 times

Last updated: Sep 10