ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | Q&A answers.ros.org
Ask Your Question
0

[ROS2][c++][boost][asio] How to continously read the serial port inside a Node.

asked 2020-12-21 11:09:05 -0600

Honolulu gravatar image

Hi:

I'm currently trying to implement a Serial server. I would like to implement it this way.

Create a Class : rclcpp::Node("my_node");

Inside of it, make a function which will be continuously checking the serial port (using the boost/asio library). When something arrives ,the node will parse it and change it's state and do something according the received cmd. The same node will also be capable of writing the Serial port with commands.

What I cannot figure is how to run this inside my class. I read about not using threads inside Nodes and use Executors instead. So I tried creating two callback groups and run a service containing a while(true) statement. But what comes into my mind is that if somehow the service get called it will hang.

Is there any different approach to this ?. The tool I'm getting serial information from is activated manually so I would like to read and process the data when needed and not using a timer to constantly poll from it.

Best Regards. Honolulu

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
1

answered 2020-12-21 16:34:15 -0600

billy gravatar image

If you have a node who's sole job is to read and process data from the serial port, then blocking on boost::asio::read in a while(1) loop should not be an issue - no 2nd thread. Using boost::asio::async_read will do the callback for you, but maybe that's the extra thread you're trying to avoid. BTW: who told you not to use threads? I'd like to read more about that.

If you're trying to read data from the serial port in a node that is doing something else not related to serial port, then a logical step would be to break out the serial port to a different node and write that node to do the serial port data processing really well, and let your current node do what it wants to do, really well.

I'm not saying you can't work out callbacks to handle a character arriving at the serialport but boost has an efficient solution worked out already. You should use it unless there is a compelling reason you must implement something new.

Also ask yourself if it's really required that a single node do both the reading and the wiring to the serialport or if maybe you can split that into separate nodes.

Of course I'm not familiar with your use case, so my answer should be applied only if it makes sense. I see you're on ROS2, my references all dealing with experience on ROS1. YMMV.

edit flag offensive delete link more

Comments

Thanks for the response !. I will search the post where they said threads were not recommended inside a Node. Say for example I want to implement it the way you said, using the while(1). Should I implement it inside the class for example:

Class
void reader()
   while(1)
      //do stuff

what's the way to launch this function inside ROS?. If I do it in the constructor, it wont return and I would not be able to add the node to the spinner later. Or should I use a approach of the type:

while(rclcpp::ok()){
   spin_some();
}

I'm confused about where to call the function in order to be able to spin the node later.

Honolulu gravatar image Honolulu  ( 2020-12-22 07:37:36 -0600 )edit

I think most appropriate to put it in a function that get called from program post constructor. You're asking about spinning, so the node you're working on must have subscribers you need to deal with. This goes back to my comment about setting up your nodes so the scope of each node is limited and can functioned well on it's assign task. As an example of serial port monitoring for a continuous data stream, see this code for a simple laser scanner that uses serial porting polling using boost::asio::read. But this node doesn't need to spin as it doesn't have any subscribers. It would still be easy to put a spinonce at end of loop. Since you know the frequency of the loop. http://wiki.ros.org/xv_11_laser_driver

billy gravatar image billy  ( 2020-12-22 11:52:41 -0600 )edit

Your Answer

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

Add Answer

Question Tools

1 follower

Stats

Asked: 2020-12-21 11:09:05 -0600

Seen: 1,206 times

Last updated: Dec 21 '20