From 0be5fef3c2155ea6878e19cca5368266516b6624 Mon Sep 17 00:00:00 2001 From: obaidmm Date: Mon, 8 Dec 2025 23:29:35 +0000 Subject: [PATCH] ap1 launch file pnc --- src/ap1_launch/launch/ap1.launch.py | 91 +++++++++++++++++++++ src/ap1_launch/launch/pnc_backend.launch.py | 42 ++++++---- src/ap1_launch/launch/ui_setup.launch.py | 18 ---- 3 files changed, 118 insertions(+), 33 deletions(-) create mode 100644 src/ap1_launch/launch/ap1.launch.py delete mode 100644 src/ap1_launch/launch/ui_setup.launch.py diff --git a/src/ap1_launch/launch/ap1.launch.py b/src/ap1_launch/launch/ap1.launch.py new file mode 100644 index 0000000..4dec6c5 --- /dev/null +++ b/src/ap1_launch/launch/ap1.launch.py @@ -0,0 +1,91 @@ +import os + +from ament_index_python.packages import get_package_share_directory + +from launch import LaunchDescription +from launch.actions import DeclareLaunchArgument, TimerAction +from launch.substitutions import LaunchConfiguration, TextSubstitution +from launch.conditions import IfCondition +from launch_ros.actions import Node + +''' +Official P&C Launch File + +Example usage: + + ros2 launch ap1_launch ap1.launch.py \ + control_cfg:=/path/to/control_node_cfg.csv \ + map_file_path:=/path/to/MyMap.osm \ + use_sim:=true + t +By default, control_cfg points to the installed: + share/ap1_control/config/control_node_cfg.csv + +pnc_sim is optional via the use_sim argument. + +''' + + +def generate_launch_description(): + + # this is gonna go crazy and find the csv file within the control directory + default_cfg = os.path.join( + get_package_share_directory('ap1_control'), + 'config', + 'control_node_cfg.csv', + ) + + map_file_arg = DeclareLaunchArgument( + 'map_file_path', + default_value='', + description='Path to Lanelet2 map file (OSM). Leave empty for mock road.' + ) + + use_sim_arg = DeclareLaunchArgument( + 'use_sim', + default_value='false', + description='Whether to start ap1_pnc_sim (true/false)' + ) + + control_cfg_arg = DeclareLaunchArgument( + 'control_cfg', + default_value=TextSubstitution(text=default_cfg), + description='Path to control_node CSV config file' + ) + + # ===== Nodes ===== + control = Node( + package='ap1_control', + executable='control_node', + name='ap1_control', + output='log', + arguments=[LaunchConfiguration('control_cfg')], + ) + + planner = Node( + package='ap1_planning', + executable='planner_node', + name='ap1_planning', + output='log', + parameters=[{ + 'map_file_path': LaunchConfiguration('map_file_path') + }], + ) + + sim = Node( + package='ap1_pnc_sim', + executable='pnc_sim_node', + name='sim_node', + output='log', + condition=IfCondition(LaunchConfiguration('use_sim')), + ) + + return LaunchDescription([ + control_cfg_arg, + map_file_arg, + use_sim_arg, + + control, + TimerAction(period=2.0, actions=[planner]), + TimerAction(period=4.0, actions=[sim]), + ]) diff --git a/src/ap1_launch/launch/pnc_backend.launch.py b/src/ap1_launch/launch/pnc_backend.launch.py index 4eced4f..c3549ef 100644 --- a/src/ap1_launch/launch/pnc_backend.launch.py +++ b/src/ap1_launch/launch/pnc_backend.launch.py @@ -1,5 +1,6 @@ from launch import LaunchDescription -from launch.actions import TimerAction +from launch.actions import DeclareLaunchArgument, TimerAction +from launch.substitutions import LaunchConfiguration from launch_ros.actions import Node ''' @@ -8,34 +9,45 @@ it will get planning, control and the sim up and running ''' +import os + +from launch import LaunchDescription +from launch.actions import DeclareLaunchArgument, TimerAction +from launch.substitutions import LaunchConfiguration, TextSubstitution +from launch_ros.actions import Node +from ament_index_python.packages import get_package_share_directory + + def generate_launch_description(): + default_cfg = os.path.join( + get_package_share_directory('ap1_control'), + 'config', + 'control_node_cfg.csv', + ) + + control_cfg_arg = DeclareLaunchArgument( + 'control_cfg', + default_value=TextSubstitution(text=default_cfg), + description='Path to control_node CSV config file' + ) + control = Node( package='ap1_control', executable='control_node', name='ap1_control', - output='screen', - arguments=[ - # should be removed down the line, using a filler for now - '/home/obaidmm/Repo/ap1/src/planning_and_control/control/control_node_cfg.csv', - ], + output='log', + arguments=[LaunchConfiguration('control_cfg')], ) planner = Node( package='ap1_planning', executable='planner_node', name='ap1_planning', - output='screen', - ) - - sim = Node( - package='ap1_pnc_sim', - executable='pnc_sim_node', - name='sim_node', - output='screen', + output='log', ) return LaunchDescription([ + control_cfg_arg, control, TimerAction(period=2.0, actions=[planner]), - TimerAction(period=4.0, actions=[sim]), ]) diff --git a/src/ap1_launch/launch/ui_setup.launch.py b/src/ap1_launch/launch/ui_setup.launch.py deleted file mode 100644 index 9de9c44..0000000 --- a/src/ap1_launch/launch/ui_setup.launch.py +++ /dev/null @@ -1,18 +0,0 @@ -from launch import LaunchDescription -from launch_ros.actions import Node - -''' -honestly unnecessary because you can just use a ros command to run the interface now using this launch command: - ros2 launch ap1_launch ui_only.launch.py - if you want to run through regularly just run in another terminal: - ros2 run ap1_control_interface system_interface -''' -def generate_launch_description(): - ui = Node( - package='ap1_control_interface', - executable='system_interface', - name='ap1_control_interface', - output='screen', - ) - - return LaunchDescription([ui])