0
$\begingroup$

Rosanswers logo

Hi Everyone,

I'm trying to design ROS nodes using best practice... the problem is I'm still trying to figure out what best practice is.

Let's say I've made a complex C++ class that does image recognition using OpenCV, Poco, and whatever libraries I could get my hands on.

Question #1:

Would it make more sense to keep the contents of a given ROS node to a minimum - just the boiler plate code - and then instantiate an object of this complex class inside the node (this way I could just use the class's interface and reduce the complexity)? Or would it make more sense to expand the logic of the class into one or more ROS nodes?

Question #2:

How efficient is it to use ROS node services to perform complex computation? For example, let's say I have an image that will get processed in a FOR loop 100 times, each time with a different set of parameters. Should I:

  1. Keep this looped process within one class within a single node and have it do all the work.
  2. Make a node that does the computation once, but instantiate 100 nodes to do the job?

Is there a latency between nodes that would not make this computationally practical? Does the communication between nodes suffer if the data being sent is large?

Thank you for your help!


Originally posted by trianta2 on ROS Answers with karma: 293 on 2013-11-01

Post score: 3

$\endgroup$

2 Answers 2

0
$\begingroup$

Rosanswers logo

  1. Your first question is a general software engineering/software architecture design problem and applies to more than just ROS. There are both costs and benefits to any abstraction you choose to solve a problem. Nodes provide encapsulation, isolation, modularity, robustness, the ability to run across a network -- but they come at the cost of spawning an OS-level process plus the cost of serializing/transport/deserializing messages. In general, if an idea is "big enough" (you be the judge of that), make it into a node. If you run into a problem where the interprocess communication overhead of ROS is too much on the same host...then you can always refactor and aggregate nodes together. If you're using C++, you also have the option of using nodelets which runs a node as a thread within a single process.

  2. For your second question, option 1 makes more sense. Nodes are operating system processes...it's not "free" to create one in terms of resources. Also you have to send the image information to each node via ROS publishers/subscribers...again not free. You're serializing messages, sending them over TCP, deserializing them. This is contrast to spawning 100 threads within your process and having them share pointers. With the case of image processing, it would be a very bad idea to have 100 nodes subscribed to an image stream! Each node would have a P2P connection to the camera driver -- image streams are usually in the 10s of MB/s or higher then * 100.

I'm kind of getting the gut feeling that you're thinking of ROS nodes as primarily a means to parallelize computation. It is used for that in a sense, but high performance concurrent computing is not the point. Rather the point is to break down various aspects of a robot's software stack into modular components that can be reused, easily reasoned about, and isolated from each other. You could just write your software as one giant process with a single thread for each "node"...but if one thread segfaults, the entire thing goes down. As ROS nodes are processes, if one crashes, it won't bring down another node and can just start itself back up. Also ROS nodes allow multi-programming language development. You can write your image processor in C++ and I can then write a visualizer in Python to view your output -- I'll be able to talk to your C++ program through ROS topics. If you're interesting in computational node graphs, check out another cool project that came out of Willow Garage called "ecto" -- http://wiki.ros.org/ecto

To give you an understanding of how many nodes are usually running on a system...a PR2 runs in the ballpark of 150 nodes. These nodes include camera drivers, servo drivers, navigation algorithms, laser drivers. A Turtlebot2 runs around half that. Not saying there's a target number for a given robot or application, but trying to give you a feel of the granularity of nodes.

In the end, there's no wrong way as long as your computer and application can handle it. Today 100 nodes for a task like you're describing is a bad idea, but in 10 years when we have thousands of cores per processor it might be standard practice. ROS topics/publishers/subscribers are implemented very efficiently...it's just a P2P TCP connection streaming a packed binary representation of the respective ROS message (.msg) files. Unless you're dealing with large data streams (like image streams off cameras, big point clouds) or hard real time control...ROS topics are very very very fast. The Linux kernel also has optimizations when data is being sent over TCP on the same machine...though de/serialization routines will still be run.

Also, ROS services are built on top of topics/publishers/subscribers. The cost is essentially double that of publishing a message (send to service provider request, provider sends back result to client).

Hope that helps.


Originally posted by mirzashah with karma: 1209 on 2013-11-01

This answer was ACCEPTED on the original site

Post score: 12

$\endgroup$
0
$\begingroup$

Rosanswers logo

To know what granularity is good for your nodes, keep in mind that a ROS node first job is to make processes communicate together. Having multiple processes allow you to have several independent algorithms running in parallel. However, processes are heavy objects and you cannot have a lot of them at the same time. To run thousands of tasks in parallel alternative techniques such as threading or coroutine are more suitable.

On top of that there is an overhead when you are communicating data from one node to another. ROS relies on the network to do this. This induces additional computation compared to a single-process algorithm.

To reduce this overhead and reduce the number of concurrent processes running, ROS supports nodelets. Nodelets are a way to aggregate several ROS nodes into one single process. This allow you to run as many nodes as you want into one process while removing the communication overhead.

However, using this model still has a cost as implementing nodelets is more challenging than challenging a normal node. In this case, think about the development cost of your application, the additional feature that ROS may or may not provide you and try to avoid over-engineer your solution.


Originally posted by Thomas with karma: 4478 on 2013-11-01

This answer was NOT ACCEPTED on the original site

Post score: 2

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.