diff --git a/rclpy/actions/minimal_action_client/examples_rclpy_minimal_action_client/client.py b/rclpy/actions/minimal_action_client/examples_rclpy_minimal_action_client/client.py index 384672d5..f7a5d292 100644 --- a/rclpy/actions/minimal_action_client/examples_rclpy_minimal_action_client/client.py +++ b/rclpy/actions/minimal_action_client/examples_rclpy_minimal_action_client/client.py @@ -12,8 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import sys - from action_msgs.msg import GoalStatus from example_interfaces.action import Fibonacci @@ -71,18 +69,15 @@ def send_goal(self): def main(args=None): - rclpy.init(args=args) - try: - action_client = MinimalActionClient() + with rclpy.init(args=args): + action_client = MinimalActionClient() - action_client.send_goal() + action_client.send_goal() - rclpy.spin(action_client) - except KeyboardInterrupt: + rclpy.spin(action_client) + except (KeyboardInterrupt, ExternalShutdownException): pass - except ExternalShutdownException: - sys.exit(1) if __name__ == '__main__': diff --git a/rclpy/actions/minimal_action_client/examples_rclpy_minimal_action_client/client_asyncio.py b/rclpy/actions/minimal_action_client/examples_rclpy_minimal_action_client/client_asyncio.py index 9af6bcbe..88781b2e 100644 --- a/rclpy/actions/minimal_action_client/examples_rclpy_minimal_action_client/client_asyncio.py +++ b/rclpy/actions/minimal_action_client/examples_rclpy_minimal_action_client/client_asyncio.py @@ -19,6 +19,7 @@ import rclpy from rclpy.action import ActionClient +from rclpy.executors import ExternalShutdownException from rclpy.node import Node @@ -69,48 +70,49 @@ async def spinning(node): async def run(args, loop): - logger = rclpy.logging.get_logger('minimal_action_client') + # init ROS 2 + with rclpy.init(args=args): + logger = rclpy.logging.get_logger('minimal_action_client') - # init ros2 - rclpy.init(args=args) + # create node + action_client = MinimalActionClientAsyncIO() - # create node - action_client = MinimalActionClientAsyncIO() + # start spinning + spin_task = loop.create_task(spinning(action_client)) - # start spinning - spin_task = loop.create_task(spinning(action_client)) + # Parallel example + # execute goal request and schedule in loop + my_task1 = loop.create_task(action_client.send_goal()) + my_task2 = loop.create_task(action_client.send_goal()) - # Parallel example - # execute goal request and schedule in loop - my_task1 = loop.create_task(action_client.send_goal()) - my_task2 = loop.create_task(action_client.send_goal()) + # glue futures together and wait + wait_future = asyncio.wait([my_task1, my_task2]) + # run event loop + finished, unfinished = await wait_future + logger.info(f'unfinished: {len(unfinished)}') + for task in finished: + logger.info('result {} and status flag {}'.format(*task.result())) - # glue futures together and wait - wait_future = asyncio.wait([my_task1, my_task2]) - # run event loop - finished, unfinished = await wait_future - logger.info(f'unfinished: {len(unfinished)}') - for task in finished: - logger.info('result {} and status flag {}'.format(*task.result())) + # Sequence + result, status = await loop.create_task(action_client.send_goal()) + logger.info(f'A) result {result} and status flag {status}') + result, status = await loop.create_task(action_client.send_goal()) + logger.info(f'B) result {result} and status flag {status}') - # Sequence - result, status = await loop.create_task(action_client.send_goal()) - logger.info(f'A) result {result} and status flag {status}') - result, status = await loop.create_task(action_client.send_goal()) - logger.info(f'B) result {result} and status flag {status}') - - # cancel spinning task - spin_task.cancel() - try: - await spin_task - except asyncio.exceptions.CancelledError: - pass - rclpy.shutdown() + # cancel spinning task + spin_task.cancel() + try: + await spin_task + except asyncio.exceptions.CancelledError: + pass def main(args=None): - loop = asyncio.get_event_loop() - loop.run_until_complete(run(args, loop=loop)) + try: + loop = asyncio.get_event_loop() + loop.run_until_complete(run(args, loop=loop)) + except (KeyboardInterrupt, ExternalShutdownException): + pass if __name__ == '__main__': diff --git a/rclpy/actions/minimal_action_client/examples_rclpy_minimal_action_client/client_cancel.py b/rclpy/actions/minimal_action_client/examples_rclpy_minimal_action_client/client_cancel.py index 35e3bd6f..53bcc573 100644 --- a/rclpy/actions/minimal_action_client/examples_rclpy_minimal_action_client/client_cancel.py +++ b/rclpy/actions/minimal_action_client/examples_rclpy_minimal_action_client/client_cancel.py @@ -12,8 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import sys - from example_interfaces.action import Fibonacci import rclpy @@ -79,18 +77,15 @@ def send_goal(self): def main(args=None): - rclpy.init(args=args) - try: - action_client = MinimalActionClient() + with rclpy.init(args=args): + action_client = MinimalActionClient() - action_client.send_goal() + action_client.send_goal() - rclpy.spin(action_client) - except KeyboardInterrupt: + rclpy.spin(action_client) + except (KeyboardInterrupt, ExternalShutdownException): pass - except ExternalShutdownException: - sys.exit(1) if __name__ == '__main__': diff --git a/rclpy/actions/minimal_action_client/examples_rclpy_minimal_action_client/client_not_composable.py b/rclpy/actions/minimal_action_client/examples_rclpy_minimal_action_client/client_not_composable.py index e1ddbe89..1eef86fd 100644 --- a/rclpy/actions/minimal_action_client/examples_rclpy_minimal_action_client/client_not_composable.py +++ b/rclpy/actions/minimal_action_client/examples_rclpy_minimal_action_client/client_not_composable.py @@ -12,8 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import sys - from action_msgs.msg import GoalStatus from example_interfaces.action import Fibonacci @@ -28,53 +26,48 @@ def feedback_cb(logger, feedback): def main(args=None): - rclpy.init(args=args) - try: - node = rclpy.create_node('minimal_action_client') + with rclpy.init(args=args): + node = rclpy.create_node('minimal_action_client') - action_client = ActionClient(node, Fibonacci, 'fibonacci') + action_client = ActionClient(node, Fibonacci, 'fibonacci') - node.get_logger().info('Waiting for action server...') + node.get_logger().info('Waiting for action server...') - action_client.wait_for_server() + action_client.wait_for_server() - goal_msg = Fibonacci.Goal() - goal_msg.order = 10 + goal_msg = Fibonacci.Goal() + goal_msg.order = 10 - node.get_logger().info('Sending goal request...') + node.get_logger().info('Sending goal request...') - send_goal_future = action_client.send_goal_async( - goal_msg, feedback_callback=lambda feedback: feedback_cb(node.get_logger(), feedback)) + send_goal_future = action_client.send_goal_async( + goal_msg, + feedback_callback=lambda feedback: feedback_cb(node.get_logger(), feedback)) - rclpy.spin_until_future_complete(node, send_goal_future) + rclpy.spin_until_future_complete(node, send_goal_future) - goal_handle = send_goal_future.result() + goal_handle = send_goal_future.result() - if not goal_handle.accepted: - node.get_logger().info('Goal rejected :(') - action_client.destroy() - node.destroy_node() - rclpy.shutdown() - return + if not goal_handle.accepted: + node.get_logger().info('Goal rejected :(') + return - node.get_logger().info('Goal accepted :)') + node.get_logger().info('Goal accepted :)') - get_result_future = goal_handle.get_result_async() + get_result_future = goal_handle.get_result_async() - rclpy.spin_until_future_complete(node, get_result_future) + rclpy.spin_until_future_complete(node, get_result_future) - result = get_result_future.result().result - status = get_result_future.result().status - if status == GoalStatus.STATUS_SUCCEEDED: - node.get_logger().info( - 'Goal succeeded! Result: {0}'.format(result.sequence)) - else: - node.get_logger().info('Goal failed with status code: {0}'.format(status)) - except KeyboardInterrupt: + result = get_result_future.result().result + status = get_result_future.result().status + if status == GoalStatus.STATUS_SUCCEEDED: + node.get_logger().info( + 'Goal succeeded! Result: {0}'.format(result.sequence)) + else: + node.get_logger().info('Goal failed with status code: {0}'.format(status)) + except (KeyboardInterrupt, ExternalShutdownException): pass - except ExternalShutdownException: - sys.exit(1) if __name__ == '__main__': diff --git a/rclpy/actions/minimal_action_server/examples_rclpy_minimal_action_server/server.py b/rclpy/actions/minimal_action_server/examples_rclpy_minimal_action_server/server.py index 599a367a..b5ba8438 100644 --- a/rclpy/actions/minimal_action_server/examples_rclpy_minimal_action_server/server.py +++ b/rclpy/actions/minimal_action_server/examples_rclpy_minimal_action_server/server.py @@ -12,7 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import sys import time from example_interfaces.action import Fibonacci @@ -92,19 +91,16 @@ async def execute_callback(self, goal_handle): def main(args=None): - rclpy.init(args=args) - try: - minimal_action_server = MinimalActionServer() + with rclpy.init(args=args): + minimal_action_server = MinimalActionServer() - # Use a MultiThreadedExecutor to enable processing goals concurrently - executor = MultiThreadedExecutor() + # Use a MultiThreadedExecutor to enable processing goals concurrently + executor = MultiThreadedExecutor() - rclpy.spin(minimal_action_server, executor=executor) - except KeyboardInterrupt: + rclpy.spin(minimal_action_server, executor=executor) + except (KeyboardInterrupt, ExternalShutdownException): pass - except ExternalShutdownException: - sys.exit(1) if __name__ == '__main__': diff --git a/rclpy/actions/minimal_action_server/examples_rclpy_minimal_action_server/server_defer.py b/rclpy/actions/minimal_action_server/examples_rclpy_minimal_action_server/server_defer.py index b6abcb01..53a4872c 100644 --- a/rclpy/actions/minimal_action_server/examples_rclpy_minimal_action_server/server_defer.py +++ b/rclpy/actions/minimal_action_server/examples_rclpy_minimal_action_server/server_defer.py @@ -12,7 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import sys import time from example_interfaces.action import Fibonacci @@ -106,19 +105,16 @@ async def execute_callback(self, goal_handle): def main(args=None): - rclpy.init(args=args) - try: - minimal_action_server = MinimalActionServer() + with rclpy.init(args=args): + minimal_action_server = MinimalActionServer() - # Use a MultiThreadedExecutor to enable processing goals concurrently - executor = MultiThreadedExecutor() + # Use a MultiThreadedExecutor to enable processing goals concurrently + executor = MultiThreadedExecutor() - rclpy.spin(minimal_action_server, executor=executor) - except KeyboardInterrupt: + rclpy.spin(minimal_action_server, executor=executor) + except (KeyboardInterrupt, ExternalShutdownException): pass - except ExternalShutdownException: - sys.exit(1) if __name__ == '__main__': diff --git a/rclpy/actions/minimal_action_server/examples_rclpy_minimal_action_server/server_not_composable.py b/rclpy/actions/minimal_action_server/examples_rclpy_minimal_action_server/server_not_composable.py index 60bb3705..796a6cca 100644 --- a/rclpy/actions/minimal_action_server/examples_rclpy_minimal_action_server/server_not_composable.py +++ b/rclpy/actions/minimal_action_server/examples_rclpy_minimal_action_server/server_not_composable.py @@ -12,7 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import sys import time from example_interfaces.action import Fibonacci @@ -71,32 +70,30 @@ async def execute_callback(goal_handle): def main(args=None): global logger - rclpy.init(args=args) try: - node = rclpy.create_node('minimal_action_server') - logger = node.get_logger() - - # Use a ReentrantCallbackGroup to enable processing multiple goals concurrently - # Default goal callback accepts all goals - # Default cancel callback rejects cancel requests - action_server = ActionServer( - node, - Fibonacci, - 'fibonacci', - execute_callback=execute_callback, - cancel_callback=cancel_callback, - callback_group=ReentrantCallbackGroup()) - action_server # Quiet flake8 warnings about unused variable - - # Use a MultiThreadedExecutor to enable processing goals concurrently - executor = MultiThreadedExecutor() - - rclpy.spin(node, executor=executor) - except KeyboardInterrupt: + with rclpy.init(args=args): + node = rclpy.create_node('minimal_action_server') + logger = node.get_logger() + + # Use a ReentrantCallbackGroup to enable processing multiple goals concurrently + # Default goal callback accepts all goals + # Default cancel callback rejects cancel requests + action_server = ActionServer( + node, + Fibonacci, + 'fibonacci', + execute_callback=execute_callback, + cancel_callback=cancel_callback, + callback_group=ReentrantCallbackGroup()) + action_server # Quiet flake8 warnings about unused variable + + # Use a MultiThreadedExecutor to enable processing goals concurrently + executor = MultiThreadedExecutor() + + rclpy.spin(node, executor=executor) + except (KeyboardInterrupt, ExternalShutdownException): pass - except ExternalShutdownException: - sys.exit(1) if __name__ == '__main__': diff --git a/rclpy/actions/minimal_action_server/examples_rclpy_minimal_action_server/server_queue_goals.py b/rclpy/actions/minimal_action_server/examples_rclpy_minimal_action_server/server_queue_goals.py index eae970fb..0c910e06 100644 --- a/rclpy/actions/minimal_action_server/examples_rclpy_minimal_action_server/server_queue_goals.py +++ b/rclpy/actions/minimal_action_server/examples_rclpy_minimal_action_server/server_queue_goals.py @@ -13,7 +13,6 @@ # limitations under the License. import collections -import sys import threading import time @@ -123,18 +122,15 @@ def execute_callback(self, goal_handle): def main(args=None): - rclpy.init(args=args) - try: - minimal_action_server = MinimalActionServer() + with rclpy.init(args=args): + minimal_action_server = MinimalActionServer() - executor = MultiThreadedExecutor() + executor = MultiThreadedExecutor() - rclpy.spin(minimal_action_server, executor=executor) - except KeyboardInterrupt: + rclpy.spin(minimal_action_server, executor=executor) + except (KeyboardInterrupt, ExternalShutdownException): pass - except ExternalShutdownException: - sys.exit(1) if __name__ == '__main__': diff --git a/rclpy/actions/minimal_action_server/examples_rclpy_minimal_action_server/server_single_goal.py b/rclpy/actions/minimal_action_server/examples_rclpy_minimal_action_server/server_single_goal.py index a172963c..c3a398c1 100644 --- a/rclpy/actions/minimal_action_server/examples_rclpy_minimal_action_server/server_single_goal.py +++ b/rclpy/actions/minimal_action_server/examples_rclpy_minimal_action_server/server_single_goal.py @@ -12,7 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import sys import threading import time @@ -117,18 +116,15 @@ def execute_callback(self, goal_handle): def main(args=None): - rclpy.init(args=args) - try: - action_server = MinimalActionServer() + with rclpy.init(args=args): + action_server = MinimalActionServer() - # We use a MultiThreadedExecutor to handle incoming goal requests concurrently - executor = MultiThreadedExecutor() - rclpy.spin(action_server, executor=executor) - except KeyboardInterrupt: + # We use a MultiThreadedExecutor to handle incoming goal requests concurrently + executor = MultiThreadedExecutor() + rclpy.spin(action_server, executor=executor) + except (KeyboardInterrupt, ExternalShutdownException): pass - except ExternalShutdownException: - sys.exit(1) if __name__ == '__main__': diff --git a/rclpy/executors/examples_rclpy_executors/callback_group.py b/rclpy/executors/examples_rclpy_executors/callback_group.py index 3a71a894..084dcd80 100644 --- a/rclpy/executors/examples_rclpy_executors/callback_group.py +++ b/rclpy/executors/examples_rclpy_executors/callback_group.py @@ -12,8 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import sys - from examples_rclpy_executors.listener import Listener import rclpy from rclpy.callback_groups import MutuallyExclusiveCallbackGroup @@ -47,25 +45,23 @@ def timer_callback(self): def main(args=None): - rclpy.init(args=args) try: - talker = DoubleTalker() - listener = Listener() - # MultiThreadedExecutor executes callbacks with a thread pool. If num_threads is not - # specified then num_threads will be multiprocessing.cpu_count() if it is implemented. - # Otherwise it will use a single thread. This executor will allow callbacks to happen in - # parallel, however the MutuallyExclusiveCallbackGroup in DoubleTalker will only allow its - # callbacks to be executed one at a time. The callbacks in Listener are free to execute in - # parallel to the ones in DoubleTalker however. - executor = MultiThreadedExecutor(num_threads=4) - executor.add_node(talker) - executor.add_node(listener) + with rclpy.init(args=args): + talker = DoubleTalker() + listener = Listener() + # MultiThreadedExecutor executes callbacks with a thread pool. If num_threads is not + # specified then num_threads will be multiprocessing.cpu_count() if it is implemented. + # Otherwise it will use a single thread. This executor will allow callbacks to happen + # in parallel, however the MutuallyExclusiveCallbackGroup in DoubleTalker will only + # allow its callbacks to be executed one at a time. The callbacks in Listener are free + # to execute in parallel to the ones in DoubleTalker however. + executor = MultiThreadedExecutor(num_threads=4) + executor.add_node(talker) + executor.add_node(listener) - executor.spin() - except KeyboardInterrupt: + executor.spin() + except (KeyboardInterrupt, ExternalShutdownException): pass - except ExternalShutdownException: - sys.exit(1) if __name__ == '__main__': diff --git a/rclpy/executors/examples_rclpy_executors/composed.py b/rclpy/executors/examples_rclpy_executors/composed.py index c88fa6e0..77c395d7 100644 --- a/rclpy/executors/examples_rclpy_executors/composed.py +++ b/rclpy/executors/examples_rclpy_executors/composed.py @@ -12,8 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import sys - from examples_rclpy_executors.listener import Listener from examples_rclpy_executors.talker import Talker import rclpy @@ -22,23 +20,21 @@ def main(args=None): - rclpy.init(args=args) try: - talker = Talker() - listener = Listener() - - # Runs all callbacks in the main thread - executor = SingleThreadedExecutor() - # Add imported nodes to this executor - executor.add_node(talker) - executor.add_node(listener) - - # Execute callbacks for both nodes as they become ready - executor.spin() - except KeyboardInterrupt: + with rclpy.init(args=args): + talker = Talker() + listener = Listener() + + # Runs all callbacks in the main thread + executor = SingleThreadedExecutor() + # Add imported nodes to this executor + executor.add_node(talker) + executor.add_node(listener) + + # Execute callbacks for both nodes as they become ready + executor.spin() + except (KeyboardInterrupt, ExternalShutdownException): pass - except ExternalShutdownException: - sys.exit(1) if __name__ == '__main__': diff --git a/rclpy/executors/examples_rclpy_executors/custom_callback_group.py b/rclpy/executors/examples_rclpy_executors/custom_callback_group.py index 056ce3a2..75d7276a 100644 --- a/rclpy/executors/examples_rclpy_executors/custom_callback_group.py +++ b/rclpy/executors/examples_rclpy_executors/custom_callback_group.py @@ -12,7 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import sys import threading import rclpy @@ -99,14 +98,12 @@ def timer_callback(self): def main(args=None): - rclpy.init(args=args) try: - talker = ThrottledTalker() - rclpy.spin(talker) - except KeyboardInterrupt: + with rclpy.init(args=args): + talker = ThrottledTalker() + rclpy.spin(talker) + except (KeyboardInterrupt, ExternalShutdownException): pass - except ExternalShutdownException: - sys.exit(1) if __name__ == '__main__': diff --git a/rclpy/executors/examples_rclpy_executors/custom_executor.py b/rclpy/executors/examples_rclpy_executors/custom_executor.py index c6048abd..c47ff2df 100644 --- a/rclpy/executors/examples_rclpy_executors/custom_executor.py +++ b/rclpy/executors/examples_rclpy_executors/custom_executor.py @@ -80,17 +80,17 @@ def spin_once(self, timeout_sec=None): def main(args=None): - rclpy.init(args=args) try: - listener = Listener() - talker = Talker() - estopper = Estopper() - - executor = PriorityExecutor() - executor.add_high_priority_node(estopper) - executor.add_node(listener) - executor.add_node(talker) - executor.spin() + with rclpy.init(args=args): + listener = Listener() + talker = Talker() + estopper = Estopper() + + executor = PriorityExecutor() + executor.add_high_priority_node(estopper) + executor.add_node(listener) + executor.add_node(talker) + executor.spin() except KeyboardInterrupt: pass except ExternalShutdownException: diff --git a/rclpy/executors/examples_rclpy_executors/listener.py b/rclpy/executors/examples_rclpy_executors/listener.py index 4db789e7..5989a101 100644 --- a/rclpy/executors/examples_rclpy_executors/listener.py +++ b/rclpy/executors/examples_rclpy_executors/listener.py @@ -12,8 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import sys - import rclpy from rclpy.executors import ExternalShutdownException from rclpy.node import Node @@ -48,14 +46,12 @@ def main(args=None): :param args: Arguments passed in from the command line. """ - rclpy.init(args=args) try: - listener = Listener() - rclpy.spin(listener) - except KeyboardInterrupt: + with rclpy.init(args=args): + listener = Listener() + rclpy.spin(listener) + except (KeyboardInterrupt, ExternalShutdownException): pass - except ExternalShutdownException: - sys.exit(1) if __name__ == '__main__': diff --git a/rclpy/executors/examples_rclpy_executors/talker.py b/rclpy/executors/examples_rclpy_executors/talker.py index c2951f34..0c0a8893 100644 --- a/rclpy/executors/examples_rclpy_executors/talker.py +++ b/rclpy/executors/examples_rclpy_executors/talker.py @@ -12,8 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import sys - import rclpy from rclpy.executors import ExternalShutdownException from rclpy.node import Node @@ -58,14 +56,12 @@ def main(args=None): :param args: Arguments passed in from the command line. """ # Run standalone - rclpy.init(args=args) try: - talker = Talker() - rclpy.spin(talker) - except KeyboardInterrupt: + with rclpy.init(args=args): + talker = Talker() + rclpy.spin(talker) + except (KeyboardInterrupt, ExternalShutdownException): pass - except ExternalShutdownException: - sys.exit(1) if __name__ == '__main__': diff --git a/rclpy/guard_conditions/examples_rclpy_guard_conditions/trigger_guard_condition.py b/rclpy/guard_conditions/examples_rclpy_guard_conditions/trigger_guard_condition.py index 1f839221..0abe0e47 100644 --- a/rclpy/guard_conditions/examples_rclpy_guard_conditions/trigger_guard_condition.py +++ b/rclpy/guard_conditions/examples_rclpy_guard_conditions/trigger_guard_condition.py @@ -12,43 +12,39 @@ # See the License for the specific language governing permissions and # limitations under the License. -import sys - import rclpy from rclpy.executors import ExternalShutdownException def main(args=None): - rclpy.init(args=args) try: - node = rclpy.create_node('demo_guard_condition') - executor = rclpy.executors.SingleThreadedExecutor() - executor.add_node(node) - - def guard_condition_callback(): - rclpy.shutdown() - node.get_logger().info('guard callback called shutdown') - - def timer_callback(): - guard_condition.trigger() - node.get_logger().info('timer callback triggered guard condition') - - node.create_timer(timer_period_sec=2, callback=timer_callback) - guard_condition = node.create_guard_condition(guard_condition_callback) - - while rclpy.ok(): - # First loop: `spin_once` waits for timer to be ready, then calls - # the timer's callback, which triggers the guard condition. - # Second loop: The guard condition is ready so it's callback is - # called. The callback calls shutdown, so the loop doesn't run - # again and the program exits. - node.get_logger().info("waiting for 'spin_once' to finish...") - executor.spin_once() - node.get_logger().info("...'spin_once' finished!\n") - except KeyboardInterrupt: + with rclpy.init(args=args): + node = rclpy.create_node('demo_guard_condition') + executor = rclpy.executors.SingleThreadedExecutor() + executor.add_node(node) + + def guard_condition_callback(): + rclpy.shutdown() + node.get_logger().info('guard callback called shutdown') + + def timer_callback(): + guard_condition.trigger() + node.get_logger().info('timer callback triggered guard condition') + + node.create_timer(timer_period_sec=2, callback=timer_callback) + guard_condition = node.create_guard_condition(guard_condition_callback) + + while rclpy.ok(): + # First loop: `spin_once` waits for timer to be ready, then calls + # the timer's callback, which triggers the guard condition. + # Second loop: The guard condition is ready so it's callback is + # called. The callback calls shutdown, so the loop doesn't run + # again and the program exits. + node.get_logger().info("waiting for 'spin_once' to finish...") + executor.spin_once() + node.get_logger().info("...'spin_once' finished!\n") + except (KeyboardInterrupt, ExternalShutdownException): pass - except ExternalShutdownException: - sys.exit(1) if __name__ == '__main__': diff --git a/rclpy/services/minimal_client/examples_rclpy_minimal_client/client.py b/rclpy/services/minimal_client/examples_rclpy_minimal_client/client.py index db81dd22..a5b278a5 100644 --- a/rclpy/services/minimal_client/examples_rclpy_minimal_client/client.py +++ b/rclpy/services/minimal_client/examples_rclpy_minimal_client/client.py @@ -12,8 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import sys - from example_interfaces.srv import AddTwoInts import rclpy @@ -21,29 +19,26 @@ def main(args=None): - rclpy.init(args=args) - try: - node = rclpy.create_node('minimal_client') - cli = node.create_client(AddTwoInts, 'add_two_ints') - - req = AddTwoInts.Request() - req.a = 41 - req.b = 1 - while not cli.wait_for_service(timeout_sec=1.0): - node.get_logger().info('service not available, waiting again...') - - future = cli.call_async(req) - rclpy.spin_until_future_complete(node, future) - - result = future.result() - node.get_logger().info( - 'Result of add_two_ints: for %d + %d = %d' % - (req.a, req.b, result.sum)) - except KeyboardInterrupt: + with rclpy.init(args=args): + node = rclpy.create_node('minimal_client') + cli = node.create_client(AddTwoInts, 'add_two_ints') + + req = AddTwoInts.Request() + req.a = 41 + req.b = 1 + while not cli.wait_for_service(timeout_sec=1.0): + node.get_logger().info('service not available, waiting again...') + + future = cli.call_async(req) + rclpy.spin_until_future_complete(node, future) + + result = future.result() + node.get_logger().info( + 'Result of add_two_ints: for %d + %d = %d' % + (req.a, req.b, result.sum)) + except (KeyboardInterrupt, ExternalShutdownException): pass - except ExternalShutdownException: - sys.exit(1) if __name__ == '__main__': diff --git a/rclpy/services/minimal_client/examples_rclpy_minimal_client/client_async.py b/rclpy/services/minimal_client/examples_rclpy_minimal_client/client_async.py index 6d19a58d..a1cfbea1 100644 --- a/rclpy/services/minimal_client/examples_rclpy_minimal_client/client_async.py +++ b/rclpy/services/minimal_client/examples_rclpy_minimal_client/client_async.py @@ -12,8 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import sys - from example_interfaces.srv import AddTwoInts import rclpy @@ -21,32 +19,29 @@ def main(args=None): - rclpy.init(args=args) - try: - node = rclpy.create_node('minimal_client_async') - - cli = node.create_client(AddTwoInts, 'add_two_ints') - - req = AddTwoInts.Request() - req.a = 41 - req.b = 1 - while not cli.wait_for_service(timeout_sec=1.0): - node.get_logger().info('service not available, waiting again...') - - future = cli.call_async(req) - while rclpy.ok(): - rclpy.spin_once(node) - if future.done(): - result = future.result() - node.get_logger().info( - 'Result of add_two_ints: for %d + %d = %d' % - (req.a, req.b, result.sum)) - break - except KeyboardInterrupt: + with rclpy.init(args=args): + node = rclpy.create_node('minimal_client_async') + + cli = node.create_client(AddTwoInts, 'add_two_ints') + + req = AddTwoInts.Request() + req.a = 41 + req.b = 1 + while not cli.wait_for_service(timeout_sec=1.0): + node.get_logger().info('service not available, waiting again...') + + future = cli.call_async(req) + while rclpy.ok(): + rclpy.spin_once(node) + if future.done(): + result = future.result() + node.get_logger().info( + 'Result of add_two_ints: for %d + %d = %d' % + (req.a, req.b, result.sum)) + break + except (KeyboardInterrupt, ExternalShutdownException): pass - except ExternalShutdownException: - sys.exit(1) if __name__ == '__main__': diff --git a/rclpy/services/minimal_client/examples_rclpy_minimal_client/client_async_callback.py b/rclpy/services/minimal_client/examples_rclpy_minimal_client/client_async_callback.py index 03f3a2b6..53b13ef9 100644 --- a/rclpy/services/minimal_client/examples_rclpy_minimal_client/client_async_callback.py +++ b/rclpy/services/minimal_client/examples_rclpy_minimal_client/client_async_callback.py @@ -12,8 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import sys - from example_interfaces.srv import AddTwoInts import rclpy @@ -22,55 +20,52 @@ def main(args=None): - rclpy.init(args=args) - try: - node = rclpy.create_node('minimal_client') - - executor = rclpy.executors.SingleThreadedExecutor() - executor.add_node(node) - - # Node's default callback group is mutually exclusive. This would prevent the client - # response from being processed until the timer callback finished, but the timer callback - # in this example is waiting for the client response - cb_group = ReentrantCallbackGroup() - cli = node.create_client(AddTwoInts, 'add_two_ints', callback_group=cb_group) - did_run = False - did_get_result = False - - async def call_service(): - nonlocal cli, node, did_run, did_get_result - did_run = True - try: - req = AddTwoInts.Request() - req.a = 41 - req.b = 1 - future = cli.call_async(req) - result = await future - node.get_logger().info( - 'Result of add_two_ints: for %d + %d = %d' % - (req.a, req.b, result.sum)) - finally: - did_get_result = True - - while not cli.wait_for_service(timeout_sec=1.0): - node.get_logger().info('service not available, waiting again...') - - timer = node.create_timer(0.5, call_service, callback_group=cb_group) - - while rclpy.ok() and not did_run: - executor.spin_once() - - if did_run: - # call timer callback only once - timer.cancel() - - while rclpy.ok() and not did_get_result: - executor.spin_once() - except KeyboardInterrupt: + with rclpy.init(args=args): + node = rclpy.create_node('minimal_client') + + executor = rclpy.executors.SingleThreadedExecutor() + executor.add_node(node) + + # Node's default callback group is mutually exclusive. This would prevent the client + # response from being processed until the timer callback finished, but the timer + # callback in this example is waiting for the client response + cb_group = ReentrantCallbackGroup() + cli = node.create_client(AddTwoInts, 'add_two_ints', callback_group=cb_group) + did_run = False + did_get_result = False + + async def call_service(): + nonlocal cli, node, did_run, did_get_result + did_run = True + try: + req = AddTwoInts.Request() + req.a = 41 + req.b = 1 + future = cli.call_async(req) + result = await future + node.get_logger().info( + 'Result of add_two_ints: for %d + %d = %d' % + (req.a, req.b, result.sum)) + finally: + did_get_result = True + + while not cli.wait_for_service(timeout_sec=1.0): + node.get_logger().info('service not available, waiting again...') + + timer = node.create_timer(0.5, call_service, callback_group=cb_group) + + while rclpy.ok() and not did_run: + executor.spin_once() + + if did_run: + # call timer callback only once + timer.cancel() + + while rclpy.ok() and not did_get_result: + executor.spin_once() + except (KeyboardInterrupt, ExternalShutdownException): pass - except ExternalShutdownException: - sys.exit(1) if __name__ == '__main__': diff --git a/rclpy/services/minimal_client/examples_rclpy_minimal_client/client_async_member_function.py b/rclpy/services/minimal_client/examples_rclpy_minimal_client/client_async_member_function.py index a23ef8bf..49dea516 100644 --- a/rclpy/services/minimal_client/examples_rclpy_minimal_client/client_async_member_function.py +++ b/rclpy/services/minimal_client/examples_rclpy_minimal_client/client_async_member_function.py @@ -12,8 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import sys - from example_interfaces.srv import AddTwoInts import rclpy @@ -33,28 +31,21 @@ def __init__(self): def send_request(self): self.req.a = 41 self.req.b = 1 - self.future = self.cli.call_async(self.req) + return self.cli.call_async(self.req) def main(args=None): - rclpy.init(args=args) - try: - minimal_client = MinimalClientAsync() - minimal_client.send_request() - - while rclpy.ok(): - rclpy.spin_once(minimal_client) - if minimal_client.future.done(): - response = minimal_client.future.result() - minimal_client.get_logger().info( - 'Result of add_two_ints: for %d + %d = %d' % - (minimal_client.req.a, minimal_client.req.b, response.sum)) - break - except KeyboardInterrupt: + with rclpy.init(args=args): + minimal_client = MinimalClientAsync() + future = minimal_client.send_request() + rclpy.spin_until_future_complete(minimal_client, future) + response = future.result() + minimal_client.get_logger().info( + 'Result of add_two_ints: for %d + %d = %d' % + (minimal_client.req.a, minimal_client.req.b, response.sum)) + except (KeyboardInterrupt, ExternalShutdownException): pass - except ExternalShutdownException: - sys.exit(1) if __name__ == '__main__': diff --git a/rclpy/services/minimal_service/examples_rclpy_minimal_service/service.py b/rclpy/services/minimal_service/examples_rclpy_minimal_service/service.py index 5ade5c50..bb3058b0 100644 --- a/rclpy/services/minimal_service/examples_rclpy_minimal_service/service.py +++ b/rclpy/services/minimal_service/examples_rclpy_minimal_service/service.py @@ -12,8 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import sys - from example_interfaces.srv import AddTwoInts import rclpy @@ -33,20 +31,17 @@ def add_two_ints_callback(request, response): def main(args=None): global g_node - rclpy.init(args=args) try: - g_node = rclpy.create_node('minimal_service') - - srv = g_node.create_service(AddTwoInts, 'add_two_ints', add_two_ints_callback) - srv # Quiet flake8 warnings about unused variable - while rclpy.ok(): - rclpy.spin_once(g_node) - - except KeyboardInterrupt: + with rclpy.init(args=args): + g_node = rclpy.create_node('minimal_service') + + srv = g_node.create_service(AddTwoInts, 'add_two_ints', add_two_ints_callback) + srv # Quiet flake8 warnings about unused variable + while rclpy.ok(): + rclpy.spin_once(g_node) + except (KeyboardInterrupt, ExternalShutdownException): pass - except ExternalShutdownException: - sys.exit(1) if __name__ == '__main__': diff --git a/rclpy/services/minimal_service/examples_rclpy_minimal_service/service_member_function.py b/rclpy/services/minimal_service/examples_rclpy_minimal_service/service_member_function.py index 6eedd736..82d5a0a8 100644 --- a/rclpy/services/minimal_service/examples_rclpy_minimal_service/service_member_function.py +++ b/rclpy/services/minimal_service/examples_rclpy_minimal_service/service_member_function.py @@ -12,8 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import sys - from example_interfaces.srv import AddTwoInts import rclpy @@ -35,16 +33,13 @@ def add_two_ints_callback(self, request, response): def main(args=None): - rclpy.init(args=args) - try: - minimal_service = MinimalService() + with rclpy.init(args=args): + minimal_service = MinimalService() - rclpy.spin(minimal_service) - except KeyboardInterrupt: + rclpy.spin(minimal_service) + except (KeyboardInterrupt, ExternalShutdownException): pass - except ExternalShutdownException: - sys.exit(1) if __name__ == '__main__': diff --git a/rclpy/topics/minimal_publisher/examples_rclpy_minimal_publisher/publisher_local_function.py b/rclpy/topics/minimal_publisher/examples_rclpy_minimal_publisher/publisher_local_function.py index 88f3c942..d02345e8 100644 --- a/rclpy/topics/minimal_publisher/examples_rclpy_minimal_publisher/publisher_local_function.py +++ b/rclpy/topics/minimal_publisher/examples_rclpy_minimal_publisher/publisher_local_function.py @@ -12,8 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import sys - import rclpy from rclpy.executors import ExternalShutdownException @@ -21,31 +19,28 @@ def main(args=None): - rclpy.init(args=args) - try: - node = rclpy.create_node('minimal_publisher') - publisher = node.create_publisher(String, 'topic', 10) - - msg = String() - i = 0 - - def timer_callback(): - nonlocal i - msg.data = 'Hello World: %d' % i - i += 1 - node.get_logger().info('Publishing: "%s"' % msg.data) - publisher.publish(msg) - - timer_period = 0.5 # seconds - timer = node.create_timer(timer_period, timer_callback) - timer # Quiet flake8 warnings about unused variable - - rclpy.spin(node) - except KeyboardInterrupt: + with rclpy.init(args=args): + node = rclpy.create_node('minimal_publisher') + publisher = node.create_publisher(String, 'topic', 10) + + msg = String() + i = 0 + + def timer_callback(): + nonlocal i + msg.data = 'Hello World: %d' % i + i += 1 + node.get_logger().info('Publishing: "%s"' % msg.data) + publisher.publish(msg) + + timer_period = 0.5 # seconds + timer = node.create_timer(timer_period, timer_callback) + timer # Quiet flake8 warnings about unused variable + + rclpy.spin(node) + except (KeyboardInterrupt, ExternalShutdownException): pass - except ExternalShutdownException: - sys.exit(1) if __name__ == '__main__': diff --git a/rclpy/topics/minimal_publisher/examples_rclpy_minimal_publisher/publisher_member_function.py b/rclpy/topics/minimal_publisher/examples_rclpy_minimal_publisher/publisher_member_function.py index 45ae3f5b..5ea61a5d 100644 --- a/rclpy/topics/minimal_publisher/examples_rclpy_minimal_publisher/publisher_member_function.py +++ b/rclpy/topics/minimal_publisher/examples_rclpy_minimal_publisher/publisher_member_function.py @@ -12,8 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import sys - import rclpy from rclpy.executors import ExternalShutdownException from rclpy.node import Node @@ -39,16 +37,13 @@ def timer_callback(self): def main(args=None): - rclpy.init(args=args) - try: - minimal_publisher = MinimalPublisher() + with rclpy.init(args=args): + minimal_publisher = MinimalPublisher() - rclpy.spin(minimal_publisher) - except KeyboardInterrupt: + rclpy.spin(minimal_publisher) + except (KeyboardInterrupt, ExternalShutdownException): pass - except ExternalShutdownException: - sys.exit(1) if __name__ == '__main__': diff --git a/rclpy/topics/minimal_publisher/examples_rclpy_minimal_publisher/publisher_old_school.py b/rclpy/topics/minimal_publisher/examples_rclpy_minimal_publisher/publisher_old_school.py index 8873fad9..b4594e49 100644 --- a/rclpy/topics/minimal_publisher/examples_rclpy_minimal_publisher/publisher_old_school.py +++ b/rclpy/topics/minimal_publisher/examples_rclpy_minimal_publisher/publisher_old_school.py @@ -12,7 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import sys from time import sleep import rclpy @@ -27,26 +26,23 @@ def main(args=None): - rclpy.init(args=args) - try: - node = rclpy.create_node('minimal_publisher') + with rclpy.init(args=args): + node = rclpy.create_node('minimal_publisher') - publisher = node.create_publisher(String, 'topic', 10) + publisher = node.create_publisher(String, 'topic', 10) - msg = String() + msg = String() - i = 0 - while rclpy.ok(): - msg.data = 'Hello World: %d' % i - i += 1 - node.get_logger().info('Publishing: "%s"' % msg.data) - publisher.publish(msg) - sleep(0.5) # seconds - except KeyboardInterrupt: + i = 0 + while rclpy.ok(): + msg.data = 'Hello World: %d' % i + i += 1 + node.get_logger().info('Publishing: "%s"' % msg.data) + publisher.publish(msg) + sleep(0.5) # seconds + except (KeyboardInterrupt, ExternalShutdownException): pass - except ExternalShutdownException: - sys.exit(1) if __name__ == '__main__': diff --git a/rclpy/topics/minimal_subscriber/examples_rclpy_minimal_subscriber/subscriber_lambda.py b/rclpy/topics/minimal_subscriber/examples_rclpy_minimal_subscriber/subscriber_lambda.py index 83331f1c..72f1be92 100644 --- a/rclpy/topics/minimal_subscriber/examples_rclpy_minimal_subscriber/subscriber_lambda.py +++ b/rclpy/topics/minimal_subscriber/examples_rclpy_minimal_subscriber/subscriber_lambda.py @@ -12,8 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import sys - import rclpy from rclpy.executors import ExternalShutdownException @@ -21,20 +19,18 @@ def main(args=None): - rclpy.init(args=args) - try: - node = rclpy.create_node('minimal_subscriber') + with rclpy.init(args=args): + node = rclpy.create_node('minimal_subscriber') - subscription = node.create_subscription( - String, 'topic', lambda msg: node.get_logger().info('I heard: "%s"' % msg.data), 10) - subscription # prevent unused variable warning + subscription = node.create_subscription( + String, 'topic', + lambda msg: node.get_logger().info('I heard: "%s"' % msg.data), 10) + subscription # prevent unused variable warning - rclpy.spin(node) - except KeyboardInterrupt: + rclpy.spin(node) + except (KeyboardInterrupt, ExternalShutdownException): pass - except ExternalShutdownException: - sys.exit(1) if __name__ == '__main__': diff --git a/rclpy/topics/minimal_subscriber/examples_rclpy_minimal_subscriber/subscriber_member_function.py b/rclpy/topics/minimal_subscriber/examples_rclpy_minimal_subscriber/subscriber_member_function.py index 4346f4ce..ffd5c92e 100644 --- a/rclpy/topics/minimal_subscriber/examples_rclpy_minimal_subscriber/subscriber_member_function.py +++ b/rclpy/topics/minimal_subscriber/examples_rclpy_minimal_subscriber/subscriber_member_function.py @@ -12,8 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import sys - import rclpy from rclpy.executors import ExternalShutdownException from rclpy.node import Node @@ -37,16 +35,13 @@ def listener_callback(self, msg): def main(args=None): - rclpy.init(args=args) - try: - minimal_subscriber = MinimalSubscriber() + with rclpy.init(args=args): + minimal_subscriber = MinimalSubscriber() - rclpy.spin(minimal_subscriber) - except KeyboardInterrupt: + rclpy.spin(minimal_subscriber) + except (KeyboardInterrupt, ExternalShutdownException): pass - except ExternalShutdownException: - sys.exit(1) if __name__ == '__main__': diff --git a/rclpy/topics/minimal_subscriber/examples_rclpy_minimal_subscriber/subscriber_old_school.py b/rclpy/topics/minimal_subscriber/examples_rclpy_minimal_subscriber/subscriber_old_school.py index 06bda5fd..70c2376e 100644 --- a/rclpy/topics/minimal_subscriber/examples_rclpy_minimal_subscriber/subscriber_old_school.py +++ b/rclpy/topics/minimal_subscriber/examples_rclpy_minimal_subscriber/subscriber_old_school.py @@ -12,8 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import sys - import rclpy from rclpy.executors import ExternalShutdownException @@ -30,20 +28,18 @@ def chatter_callback(msg): def main(args=None): global g_node - rclpy.init(args=args) try: - g_node = rclpy.create_node('minimal_subscriber') + with rclpy.init(args=args): + g_node = rclpy.create_node('minimal_subscriber') - subscription = g_node.create_subscription(String, 'topic', chatter_callback, 10) - subscription # prevent unused variable warning + subscription = g_node.create_subscription(String, 'topic', chatter_callback, 10) + subscription # prevent unused variable warning - while rclpy.ok(): - rclpy.spin_once(g_node) - except KeyboardInterrupt: + while rclpy.ok(): + rclpy.spin_once(g_node) + except (KeyboardInterrupt, ExternalShutdownException): pass - except ExternalShutdownException: - sys.exit(1) if __name__ == '__main__': diff --git a/rclpy/topics/pointcloud_publisher/examples_rclpy_pointcloud_publisher/pointcloud_publisher.py b/rclpy/topics/pointcloud_publisher/examples_rclpy_pointcloud_publisher/pointcloud_publisher.py index 8638a51e..b67b9a34 100644 --- a/rclpy/topics/pointcloud_publisher/examples_rclpy_pointcloud_publisher/pointcloud_publisher.py +++ b/rclpy/topics/pointcloud_publisher/examples_rclpy_pointcloud_publisher/pointcloud_publisher.py @@ -12,8 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import sys - import numpy as np import rclpy @@ -62,14 +60,12 @@ def timer_callback(self): def main(args=None): - rclpy.init(args=args) try: - pc_publisher = PointCloudPublisher() - rclpy.spin(pc_publisher) - except KeyboardInterrupt: + with rclpy.init(args=args): + pc_publisher = PointCloudPublisher() + rclpy.spin(pc_publisher) + except (KeyboardInterrupt, ExternalShutdownException): pass - except ExternalShutdownException: - sys.exit(1) if __name__ == '__main__':