1313# limitations under the License.
1414
1515import os
16+ from datetime import datetime
1617from launch import LaunchDescription
1718from launch .actions import DeclareLaunchArgument , OpaqueFunction
1819from launch .substitutions import LaunchConfiguration , PathJoinSubstitution
2223from moveit_configs_utils import MoveItConfigsBuilder
2324
2425
26+ def setup_log_directory ():
27+ """
28+ Creates timestamped log directory with error handling.
29+ Returns: (log_dir_path, timestamp) tuple
30+ """
31+ timestamp = datetime .now ().strftime ('%Y-%m-%d-%H-%M-%S' )
32+
33+ # Primary log directory location
34+ log_dir = os .path .join (
35+ os .path .expanduser ('~' ),
36+ '.ros' ,
37+ 'log' ,
38+ timestamp
39+ )
40+
41+ try :
42+ os .makedirs (log_dir , mode = 0o755 , exist_ok = True )
43+ print (f"[Launch] Log directory created: { log_dir } " )
44+ return log_dir , timestamp
45+ except PermissionError as e :
46+ # Fallback to /tmp if ~/.ros is not writable
47+ fallback_dir = os .path .join ('/tmp' , 'sm_panda_moveit2z_cb_inventory_logs' , timestamp )
48+ print (f"[Launch] WARNING: Cannot create log directory at { log_dir } " )
49+ print (f"[Launch] Permission denied: { e } " )
50+ print (f"[Launch] Using fallback directory: { fallback_dir } " )
51+ try :
52+ os .makedirs (fallback_dir , mode = 0o755 , exist_ok = True )
53+ return fallback_dir , timestamp
54+ except Exception as fallback_error :
55+ print (f"[Launch] ERROR: Cannot create fallback directory: { fallback_error } " )
56+ print (f"[Launch] Logs will only be displayed in konsole terminals" )
57+ return None , timestamp
58+ except OSError as e :
59+ print (f"[Launch] ERROR: Failed to create log directory: { e } " )
60+ print (f"[Launch] Logs will only be displayed in konsole terminals" )
61+ return None , timestamp
62+
63+
2564def generate_launch_description ():
2665
2766 declared_arguments = []
@@ -38,6 +77,9 @@ def generate_launch_description():
3877
3978def launch_setup (context , * args , ** kwargs ):
4079
80+ # Setup logging directory
81+ log_dir , timestamp = setup_log_directory ()
82+
4183 moveit_config = (
4284 MoveItConfigsBuilder ("moveit_resources_panda" )
4385 .robot_description (file_path = "config/panda.urdf.xacro" )
@@ -50,12 +92,19 @@ def launch_setup(context, *args, **kwargs):
5092 )
5193
5294 # Start the actual move_group node/action server
95+ # Construct logging prefix
96+ if log_dir :
97+ move_group_log = os .path .join (log_dir , f"move_group_{ timestamp } .log" )
98+ move_group_prefix = f"konsole --hold -p tabtitle='Move Group' -e bash -c '\" $@\" 2>&1 | tee { move_group_log } ; exec bash' -- "
99+ else :
100+ move_group_prefix = "konsole --hold -p tabtitle='Move Group' -e"
101+
53102 run_move_group_node = Node (
54103 package = "moveit_ros_move_group" ,
55104 executable = "move_group" ,
56105 output = "screen" ,
57106 parameters = [moveit_config .to_dict ()],
58- prefix = "konsole --hold -e" ,
107+ prefix = move_group_prefix ,
59108 )
60109
61110 rviz_base = LaunchConfiguration ("rviz_config" )
@@ -128,19 +177,33 @@ def launch_setup(context, *args, **kwargs):
128177 arguments = ["panda_arm_controller" , "-c" , "/controller_manager" ],
129178 )
130179
180+ # Construct logging prefix for state machine node
181+ if log_dir :
182+ state_machine_log = os .path .join (log_dir , f"state_machine_{ timestamp } .log" )
183+ state_machine_prefix = f"konsole --hold -p tabtitle='State Machine' -e bash -c '\" $@\" 2>&1 | tee { state_machine_log } ; exec bash' -- "
184+ else :
185+ state_machine_prefix = "konsole --hold -p tabtitle='State Machine' -e"
186+
131187 smacc_state_machine_spawner = Node (
132188 package = "sm_panda_moveit2z_cb_inventory" ,
133189 executable = "sm_panda_moveit2z_cb_inventory_node" ,
134- prefix = "konsole --hold -e" ,
190+ prefix = state_machine_prefix ,
135191 output = "screen" ,
136192 )
137193
194+ # Construct logging prefix for keyboard client node
195+ if log_dir :
196+ keyboard_log = os .path .join (log_dir , f"keyboard_client_{ timestamp } .log" )
197+ keyboard_prefix = f"konsole --hold -p tabtitle='Keyboard Client' -e bash -c '\" $@\" 2>&1 | tee { keyboard_log } ; exec bash' -- "
198+ else :
199+ keyboard_prefix = "konsole --hold -p tabtitle='Keyboard Client' -e"
200+
138201 keyboard_client_node = Node (
139202 package = "keyboard_client" ,
140203 executable = "keyboard_server_node.py" ,
141204 name = "keyboard_client" ,
142205 output = "screen" ,
143- prefix = "konsole --hold -e" ,
206+ prefix = keyboard_prefix ,
144207 arguments = ["--ros-args" , "--log-level" , "INFO" ],
145208 )
146209
0 commit comments