"""emotion.launch.py — Launch emotion_node for facial expression recognition (Issue #161).""" from launch import LaunchDescription from launch.actions import DeclareLaunchArgument from launch.substitutions import LaunchConfiguration, PathJoinSubstitution from launch_ros.actions import Node from launch_ros.substitutions import FindPackageShare def generate_launch_description() -> LaunchDescription: pkg = FindPackageShare("saltybot_social") params_file = PathJoinSubstitution([pkg, "config", "emotion_params.yaml"]) return LaunchDescription([ DeclareLaunchArgument( "params_file", default_value=params_file, description="Path to emotion_node parameter YAML", ), DeclareLaunchArgument( "engine_path", default_value="/models/emotion_fp16.trt", description="Path to TensorRT FP16 emotion engine (empty = landmark heuristic)", ), DeclareLaunchArgument( "min_confidence", default_value="0.40", description="Minimum detection confidence to publish an expression", ), DeclareLaunchArgument( "smoothing_alpha", default_value="0.30", description="EMA smoothing weight (0=frozen, 1=no smoothing)", ), DeclareLaunchArgument( "opt_out_persons", default_value="", description="Comma-separated person_ids that opted out", ), DeclareLaunchArgument( "landmark_fallback", default_value="true", description="Use landmark heuristic when TRT engine unavailable", ), DeclareLaunchArgument( "publish_context", default_value="true", description="Publish /social/emotion/context JSON for LLM context", ), Node( package="saltybot_social", executable="emotion_node", name="emotion_node", output="screen", parameters=[ LaunchConfiguration("params_file"), { "engine_path": LaunchConfiguration("engine_path"), "min_confidence": LaunchConfiguration("min_confidence"), "smoothing_alpha": LaunchConfiguration("smoothing_alpha"), "opt_out_persons": LaunchConfiguration("opt_out_persons"), "landmark_fallback": LaunchConfiguration("landmark_fallback"), "publish_context": LaunchConfiguration("publish_context"), }, ], ), ])