ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
2

ros2 publisher without node and spinning

asked 2019-11-20 06:54:15 -0500

gdebrecz gravatar image

Hi !

I have a ROS2 system up and running and from an external (C++) process I'd like to occasionally, randomly, asynchronously publish some data to an existing topic, without spinning a node at fixed frequency. (I'd like to publish the data when an event is triggered, but then I'd like to publish that immediately instead of waiting for some spin invocation.)

Using spin_once one can make a workaround to make this work, however according to the docs there is no spin_once available in the C++ API.

Found no way to do this in ROS2 C++. Is it doable ?

G

edit retag flag offensive close merge delete

Comments

1

If I dive into rclcpp and look in executor.cpp I am able to find

void
Executor::spin_once(std::chrono::nanoseconds timeout)
{

So it seems that you should be able to do something like this

rclcpp::executors::StaticSingleThreadedExecutor exec
auto node = std::make_shared<rclcpp::Node>("node_name");
auto pub = node->create_publisher<String>("existing_topic"), qos);
auto timer = node->create_wall_timer(interval, [=]() {
  String msg;
  msg.data = "abcdefg";
  pub->publish(msg);
});
exec.add_node(node);
exec.spin_once();

Haven't tried this, but you can have a look if this is the way to do what you want.

MCornelis gravatar image MCornelis  ( 2019-11-21 04:18:20 -0500 )edit

Depending on what exactly you are trying to do you could probably also look into using the other abstraction layers, i.e. sending directly through DDS, creating a custom waitable that achieves what you want or writing a custom executor/workaround at rclcpp level. This however requires you to look deeper into rclcpp, rcl and rmw (I don't expect your use-case requires you to go this deep though).

MCornelis gravatar image MCornelis  ( 2019-11-21 04:30:19 -0500 )edit

You have already asked a similar question here: https://answers.ros.org/question/3380... Please follow up on the previous question rather than just posting new ones and not replying on the previous ones.

Dirk Thomas gravatar image Dirk Thomas  ( 2019-11-21 10:20:26 -0500 )edit

Though the two question is similar they are not the same (!) and might have different solutions, that is why I posted this second one. (Low latency does not neceserly means no spinning.) In the meantime I found a solution to the other question and also posted as an answer.

gdebrecz gravatar image gdebrecz  ( 2019-11-22 09:33:50 -0500 )edit
1

You do need a node to publish messages. But you don't need to spin at all if the only thing your node does is publishing - spinning is needed for incoming messages so subscribing, offering/using services etc.

Dirk Thomas gravatar image Dirk Thomas  ( 2019-11-22 10:54:57 -0500 )edit

1 Answer

Sort by ยป oldest newest most voted
1

answered 2019-11-26 05:12:06 -0500

gdebrecz gravatar image

updated 2019-11-26 05:14:12 -0500

Found the following which seems to work, i.e. using spin_some insted of spin_once (which is available only in the Python API).

.
.
.
 rmw_qos_profile_t custom_qos_profile = rmw_qos_profile_default;
 custom_qos_profile.depth = 7;

 auto node           = rclcpp::Node::make_shared("IMU_node");
 auto imu_publisher  = node->create_publisher<sensor_msgs::msg::Imu>("Imu_topic", custom_qos_profile.depth);
 auto imu_msg_       = std::make_shared<sensor_msgs::msg::Imu>();

 while(rclcpp::ok())
 {
     std::string buf = imu.SerialReadLine();

     // Do some conversion of data from buf to parsed_val vector
     // .
     // .
     // Fill the imu_msg
     imu_msg_->orientation.x = parsed_val_[0];
     imu_msg_->orientation.y = parsed_val_[1];
     imu_msg_->orientation.z = parsed_val_[2];
     imu_msg_->orientation.w = parsed_val_[3];

     // Publish the msg
     imu_publisher->publish(*imu_msg_);
     rclcpp::spin_some(node);
  }

So there is no continuously spinning node, publish method called only when an input arrived.

edit flag offensive delete link more

Comments

Your code should work just the same without the call to rclcpp::spin_some (as Dirk pointed out in a previous comment).

jacobperron gravatar image jacobperron  ( 2019-11-27 15:22:43 -0500 )edit

Question Tools

3 followers

Stats

Asked: 2019-11-20 06:54:15 -0500

Seen: 4,840 times

Last updated: Nov 26 '19