22import pytest
33import rclpy
44from ament_index_python .packages import get_package_share_directory
5+ import launch
6+ from launch .substitutions import (
7+ Command ,
8+ FindExecutable ,
9+ LaunchConfiguration ,
10+ NotSubstitution ,
11+ AndSubstitution ,
12+ )
513from launch import LaunchDescription
614from launch .actions import IncludeLaunchDescription , ExecuteProcess , DeclareLaunchArgument
715from launch .substitutions import LaunchConfiguration
816from launch .launch_description_sources import PythonLaunchDescriptionSource
917from launch_ros .actions import Node
1018import launch_pytest
19+ import launch_ros
1120from launch_pytest .tools import process as process_tools
21+ from launch .substitutions import PathJoinSubstitution
22+ from launch .actions import (
23+ ExecuteProcess ,
24+ DeclareLaunchArgument ,
25+ RegisterEventHandler ,
26+ SetEnvironmentVariable ,
27+ )
1228from artefacts_toolkit .config import get_artefacts_param
1329import sys
1430import os
@@ -89,10 +105,6 @@ def launch_description(reach_goal_proc):
89105 )
90106
91107
92- topics = ["/odom" ]
93- metrics = ["/distance_from_start_gt" , "/distance_from_start_est" , "/odometry_error" ]
94- camera_topics = ["/sky_cam" ]
95- sim_topics = ["/world/dynamic_pose/info" ]
96108
97109 # Gazebo ros bridge
98110 gz_bridge = Node (
@@ -108,30 +120,110 @@ def launch_description(reach_goal_proc):
108120 output = "screen" ,
109121 )
110122
111- test_odometry_node = ExecuteProcess (
112- cmd = [
113- "python3" ,
114- os .path .join (
115- "src" ,
116- "sam_bot_nav2_gz" ,
117- "test" ,
118- "test_odometry_node.py"
119- ),
120- ]
123+ gz_env = {'GZ_SIM_SYSTEM_PLUGIN_PATH' :
124+ ':' .join ([os .environ .get ('GZ_SIM_SYSTEM_PLUGIN_PATH' , default = '' ),
125+ os .environ .get ('LD_LIBRARY_PATH' , default = '' )]),
126+ 'IGN_GAZEBO_SYSTEM_PLUGIN_PATH' : # TODO(CH3): To support pre-garden. Deprecated.
127+ ':' .join ([os .environ .get ('IGN_GAZEBO_SYSTEM_PLUGIN_PATH' , default = '' ),
128+ os .environ .get ('LD_LIBRARY_PATH' , default = '' )])}
129+ log_level = LaunchConfiguration ("log_level" )
130+ use_sim_time = LaunchConfiguration ("use_sim_time" )
131+ gz_verbosity = LaunchConfiguration ("gz_verbosity" )
132+ pkg_share = launch_ros .substitutions .FindPackageShare (
133+ package = "sam_bot_nav2_gz"
134+ ).find ("sam_bot_nav2_gz" )
135+ default_model_path = os .path .join (
136+ pkg_share , "src/description/sam_bot_description.urdf"
137+ )
138+ run_headless = LaunchConfiguration ("run_headless" )
139+ world_file_name = LaunchConfiguration ("world_file" )
140+ gz_models_path = ":" .join ([pkg_share , os .path .join (pkg_share , "models" )])
141+ #gz_models_path = os.path.join(pkg_share, "models")
142+ world_path = PathJoinSubstitution ([pkg_share , "world" , world_file_name ])
143+ gazebo = [
144+ ExecuteProcess (
145+ condition = launch .conditions .IfCondition (run_headless ),
146+ cmd = ['ruby' , FindExecutable (name = "ign" ), 'gazebo' , '-r' , '-v' , gz_verbosity , '-s' , '--headless-rendering' , world_path ],
147+ output = 'screen' ,
148+ additional_env = gz_env , # type: ignore
149+ shell = False ,
150+ ),
151+ ExecuteProcess (
152+ condition = launch .conditions .UnlessCondition (run_headless ),
153+ cmd = ['ruby' , FindExecutable (name = "ign" ), 'gazebo' , '-r' , '-v' , gz_verbosity , world_path ],
154+ output = 'screen' ,
155+ additional_env = gz_env , # type: ignore
156+ shell = False ,
157+ )
158+ ]
159+
160+ spawn_entity = Node (
161+ package = "ros_gz_sim" ,
162+ executable = "create" ,
163+ output = "screen" ,
164+ arguments = [
165+ "-name" ,
166+ "sam_bot" ,
167+ "-topic" ,
168+ "robot_description" ,
169+ "-z" ,
170+ "1.0" ,
171+ "-x" ,
172+ "-2.0" ,
173+ "--ros-args" ,
174+ "--log-level" ,
175+ log_level ,
176+ ],
177+ parameters = [{"use_sim_time" : use_sim_time }],
121178 )
122179
180+
123181 return LaunchDescription (
124182 [
183+ SetEnvironmentVariable (
184+ name = "IGN_GAZEBO_RESOURCE_PATH" ,
185+ value = gz_models_path ,
186+ ),
187+ DeclareLaunchArgument (
188+ "gz_verbosity" ,
189+ default_value = "3" ,
190+ description = "Verbosity level for Ignition Gazebo (0~4)." ,
191+ ),
192+ DeclareLaunchArgument (
193+ "gz_args" ,
194+ default_value = "" ,
195+ description = "Extra args for Gazebo (ie. '-s' for running headless)" ,
196+ ),
197+ DeclareLaunchArgument (
198+ name = "world_file" ,
199+ default_value = "empty.sdf" ,
200+ ),
125201 DeclareLaunchArgument (
126202 name = "run_headless" ,
127203 default_value = "False" ,
128- description = "Start GZ in headless mode and don't start RViz (overrides use_rviz)" ,
204+ description = "Start GZ in hedless mode and don't start RViz (overrides use_rviz)" ,
205+ ),
206+ DeclareLaunchArgument (
207+ name = "use_sim_time" ,
208+ default_value = "True" ,
209+ description = "Flag to enable use_sim_time" ,
210+ ),
211+ DeclareLaunchArgument (
212+ name = "log_level" ,
213+ default_value = "warn" ,
214+ description = "The level of logging that is applied to all ROS 2 nodes launched by this script." ,
129215 ),
130- launch_navigation_stack ,
131- reach_goal_proc ,
132- test_odometry_node ,
216+ #DeclareLaunchArgument(
217+ # name="run_headless",
218+ # default_value="False",
219+ # description="Start GZ in headless mode and don't start RViz (overrides use_rviz)",
220+ #),
221+ #launch_navigation_stack,
222+ * gazebo ,
223+ spawn_entity ,
224+ #reach_goal_proc,
133225 gz_bridge ,
134- #bag_recorder,
226+ launch_pytest . actions . ReadyToTest ()
135227 ]
136228 )
137229
@@ -168,7 +260,7 @@ def validate_goal_output(output):
168260
169261 # Get the reach_goal process from the launch context
170262 process_tools .wait_for_output_sync (
171- launch_context , reach_goal_proc , validate_goal_output , timeout = 40 )
263+ launch_context , reach_goal_proc , validate_goal_output , timeout = 10 )
172264
173265 # Additional assertion using simulation state
174266 goal_coordinates = (2.0 , 3.0 ) # Example goal coordinates - adjust as needed
0 commit comments