From 5f5a75158ef2444b5d3a6fe448966835dae07c4d Mon Sep 17 00:00:00 2001 From: Roni Kreinin <59886299+roni-kreinin@users.noreply.github.com> Date: Fri, 31 Jan 2025 11:31:08 -0500 Subject: [PATCH] Wait for interface to be up before launching node (#7) * Wait for interface to be UP before starting node --- launch/receiver.launch.py | 22 +++++++++++++++++++--- launch/sender.launch.py | 22 +++++++++++++++++++--- package.xml | 2 ++ 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/launch/receiver.launch.py b/launch/receiver.launch.py index 805c581..5c5c57a 100644 --- a/launch/receiver.launch.py +++ b/launch/receiver.launch.py @@ -29,11 +29,12 @@ from launch.actions import ( DeclareLaunchArgument, EmitEvent, + ExecuteProcess, RegisterEventHandler) from launch.conditions import IfCondition -from launch.event_handlers import OnProcessStart +from launch.event_handlers import OnProcessExit, OnProcessStart from launch.events import matches_action -from launch.substitutions import LaunchConfiguration +from launch.substitutions import FindExecutable, LaunchConfiguration from launch_ros.actions import LifecycleNode from launch_ros.event_handlers import OnStateTransition from launch_ros.events.lifecycle import ChangeState @@ -102,6 +103,20 @@ def generate_launch_description(): remappings=[('from_can_bus', from_can_bus_topic)], output='screen') + # Wait for interface to be up + wait_for_can_interface_proc = ExecuteProcess( + cmd=[['until ', FindExecutable(name='ip'), ' link show ', interface, ' | ', + FindExecutable(name='grep'), ' \"state UP\"', '; do sleep 1; done']], + shell=True + ) + + launch_node = RegisterEventHandler( + event_handler=OnProcessExit( + target_action=wait_for_can_interface_proc, + on_exit=node + ) + ) + configure_event = RegisterEventHandler( event_handler=OnProcessStart( target_action=node, @@ -144,7 +159,8 @@ def generate_launch_description(): ld.add_action(arg_auto_configure) ld.add_action(arg_auto_activate) ld.add_action(arg_from_can_bus_topic) - ld.add_action(node) + ld.add_action(wait_for_can_interface_proc) + ld.add_action(launch_node) ld.add_action(configure_event) ld.add_action(activate_event) return ld diff --git a/launch/sender.launch.py b/launch/sender.launch.py index d2b0181..7fa795a 100644 --- a/launch/sender.launch.py +++ b/launch/sender.launch.py @@ -29,11 +29,12 @@ from launch.actions import ( DeclareLaunchArgument, EmitEvent, + ExecuteProcess, RegisterEventHandler) from launch.conditions import IfCondition -from launch.event_handlers import OnProcessStart +from launch.event_handlers import OnProcessExit, OnProcessStart from launch.events import matches_action -from launch.substitutions import LaunchConfiguration +from launch.substitutions import FindExecutable, LaunchConfiguration from launch_ros.actions import LifecycleNode from launch_ros.event_handlers import OnStateTransition from launch_ros.events.lifecycle import ChangeState @@ -90,6 +91,20 @@ def generate_launch_description(): remappings=[('to_can_bus', to_can_bus_topic)], output='screen') + # Wait for interface to be up + wait_for_can_interface_proc = ExecuteProcess( + cmd=[['until ', FindExecutable(name='ip'), ' link show ', interface, ' | ', + FindExecutable(name='grep'), ' \"state UP\"', '; do sleep 1; done']], + shell=True + ) + + launch_node = RegisterEventHandler( + event_handler=OnProcessExit( + target_action=wait_for_can_interface_proc, + on_exit=node + ) + ) + configure_event = RegisterEventHandler( event_handler=OnProcessStart( target_action=node, @@ -130,7 +145,8 @@ def generate_launch_description(): ld.add_action(arg_auto_configure) ld.add_action(arg_auto_activate) ld.add_action(arg_to_can_bus_topic) - ld.add_action(node) + ld.add_action(wait_for_can_interface_proc) + ld.add_action(launch_node) ld.add_action(configure_event) ld.add_action(activate_event) return ld diff --git a/package.xml b/package.xml index 18ff13d..e87f9a0 100644 --- a/package.xml +++ b/package.xml @@ -18,6 +18,8 @@ rclcpp can_msgs + iproute2 + ament_lint_auto ament_lint_common