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

Revision history [back]

There's a few options.

  • If this thing you'd like to do is on a regular interval (e.g. do this operation every N seconds), then the best option is to make the on_demand_foo (or something wrapping it) a timer callback. Timers are added to the same waitset that the ROS interfaces are so the spin will execute it.

  • If you want this to run at some irregular interval or as the result of another event or want to continue doing things outside of that node class, you should spin up another thread - or more compactly - have the example node provided spin up its own thread so it doesn't block when spinning the main thread to do other things. Typically though, we use OOP for ROS programs so that there is 1 main spin in the main() function and otherwise things are handled as the composition of objects within a node class (which itself may contain objects that are also node objects). In C++, this is a much more natural pattern because you can create / manage executors directly, but Python3's Pythonic API currently doesn't have that same capability (though from other discussions I've had recently, it seems to be just an oversight and may be added). As the result, for now in Python3, you may have nodes composed with other objects which are 'nodes' basically just to have a separate executor processing those requests.

  • If you want to run this at some irregular interval but not necessarily as the result of an event (e.g. instead you need to poll if you should run it), I'd recommend the timer option and have the timer callback do that polling and then call the on_demand_foo as required. Run the timer on a pretty frequent basis.

There's a few options.

  • If this thing you'd like to do is on a regular interval (e.g. do this operation every N seconds), then the best option is to make the on_demand_foo (or something wrapping it) a timer callback. Timers are added to the same waitset that the ROS interfaces are so the spin will execute it.

  • If you want this to run at some irregular interval or as the result of another event or want to continue doing things outside of that node class, you should spin up another thread - or more compactly - have the example node provided spin up its own thread so it doesn't block when spinning the main thread to do other things. Typically though, we use OOP for ROS programs so that there is 1 main spin in the main() function and otherwise things are handled as the composition of objects within a node class (which itself may contain objects that are also node objects). In C++, this is a much more natural pattern because you can create / manage executors directly, but Python3's Pythonic API currently doesn't have that same capability (though from other discussions I've had recently, it seems to be just an oversight and may be added). As the result, for now in Python3, you may have nodes composed with other objects which are 'nodes' basically just to have a separate executor processing those requests. But in general (because giving general advise has never bit me in the ass before), in the main() function after the node is instantiated, it is poor design to interact with the main node again. That would preclude natural composition with other systems and/or the more formal Composition Component Containers to make them dynamically loadable - should that be available in Python3 in the future (probably).

  • If you want to run this at some irregular interval but not necessarily as the result of an event (e.g. instead you need to poll if you should run it), I'd recommend the timer option and have the timer callback do that polling and then call the on_demand_foo as required. Run the timer on a pretty frequent basis. basis.

There's a few options.

  • If this thing you'd like to do is on a regular interval (e.g. do this operation every N seconds), then the best option is to make the on_demand_foo (or something wrapping it) a timer callback. Timers are added to the same waitset that the ROS interfaces are so the spin will execute it.

  • If you want this to run at some irregular interval or as the result of another event or want to continue doing things outside of that node class, you should spin up another thread - or more compactly - have the example node provided spin up its own thread so it doesn't block when spinning the main thread to do other things. Typically though, we use OOP for ROS programs so that there is 1 main spin in the main() function and otherwise things are handled as the composition of objects within a node class (which itself may contain objects that are also node objects). In C++, this is a much more natural pattern because you can create / manage executors directly, but Python3's Pythonic API currently doesn't have that same capability (though from other discussions I've had recently, it seems to be just an oversight and may be added). As the result, for now in Python3, you may have nodes composed with other objects which are 'nodes' basically just to have a separate executor processing those requests. But in general (because giving general advise has never bit me in the ass before), in the main() function after the node is instantiated, it is poor design to interact with the main node again. That would preclude natural composition with other systems and/or the more formal Composition Component Containers to make them dynamically loadable - should that be available in Python3 in the future (probably).

The design of ROS nodes are to make "small, sharp tools" (e.g. read the design section of https://www.science.org/doi/10.1126/scirobotics.abm6074) so more, small, reusable node components are desirable and assembled to create your end-application. That's also generally helps to create good software design with small testable and reused units.

  • If you want to run this at some irregular interval but not necessarily as the result of an event (e.g. instead you need to poll if you should run it), I'd recommend the timer option and have the timer callback do that polling and then call the on_demand_foo as required. Run the timer on a pretty frequent basis.

There's a few options.

  • If this thing you'd like to do is on a regular interval (e.g. do this operation every N seconds), then the best option is to make the on_demand_foo (or something wrapping it) a timer callback. Timers are added to the same waitset that the ROS interfaces are so the spin will execute it.

  • If you want this to run at some irregular interval or as the result of another event or want to continue doing things outside of that node class, you should spin up another thread - or more compactly - have the example node provided spin up its own thread so it doesn't block when spinning the main thread to do other things. Typically though, we use OOP for ROS programs so that there is 1 main spin in the main() function and otherwise things are handled as the composition of objects within a node class (which itself may contain objects that are also node objects). In C++, this is a much more natural pattern because you can create / manage executors directly, but Python3's Pythonic API currently doesn't have that same capability (though from other discussions I've had recently, it seems to be just an oversight and may be added). As the result, for now in Python3, you may have nodes composed with other objects which are 'nodes' basically just to have a separate executor processing those requests. But in general (because giving general advise has never bit me in the ass before), in the main() function after the node is instantiated, it is poor design to interact with the main node again. That would preclude natural composition with other systems and/or the more formal Composition Component Containers to make them dynamically loadable - should that be available in Python3 in the future (probably).

The design of ROS nodes are to make "small, sharp tools" (e.g. read the design section of https://www.science.org/doi/10.1126/scirobotics.abm6074) so more, small, reusable node components are desirable and assembled to create your end-application. That's also generally helps to create good software design with small testable and reused units.

  • If you want to run this at some irregular interval but not necessarily as the result of an event (e.g. instead you need to poll something if you should run it), I'd recommend the timer option and have the timer callback do that polling and then call the on_demand_foo as required. Run the timer on a pretty frequent basis.