|
|
@@ -0,0 +1,74 @@
|
|
|
+import os
|
|
|
+
|
|
|
+import yaml
|
|
|
+from ament_index_python.packages import get_package_share_directory
|
|
|
+from launch import LaunchDescription
|
|
|
+from launch.actions import DeclareLaunchArgument, LogInfo
|
|
|
+from launch.substitutions import LaunchConfiguration
|
|
|
+from launch_ros.actions import Node
|
|
|
+
|
|
|
+
|
|
|
+DEFAULT_DEV = "/dev/voiceModule"
|
|
|
+
|
|
|
+
|
|
|
+def _load_serial_dev(config_file: str) -> str:
|
|
|
+ """从 YAML 中读取串口设备路径。"""
|
|
|
+ # 这里单独做一个函数,是为了把“读取配置”和“生成启动描述”两个职责拆开,
|
|
|
+ # 后面如果你想继续从 YAML 中读取更多字段,这里会比较容易扩展。
|
|
|
+ if not os.path.exists(config_file):
|
|
|
+ raise FileNotFoundError(f"未找到配置文件: {config_file}")
|
|
|
+
|
|
|
+ with open(config_file, "r", encoding="utf-8") as file:
|
|
|
+ config = yaml.safe_load(file) or {}
|
|
|
+
|
|
|
+ # 配置层级设计成 offline_voice_module -> micro_ros_agent -> serial -> dev,
|
|
|
+ # 这样和原命令 `micro_ros_agent serial --dev ...` 的语义是一一对应的。
|
|
|
+ dev = (
|
|
|
+ config.get("offline_voice_module", {})
|
|
|
+ .get("micro_ros_agent", {})
|
|
|
+ .get("serial", {})
|
|
|
+ .get("dev", DEFAULT_DEV)
|
|
|
+ )
|
|
|
+
|
|
|
+ if not isinstance(dev, str) or not dev.strip():
|
|
|
+ raise ValueError("配置文件中的 dev 必须是非空字符串。")
|
|
|
+
|
|
|
+ return dev
|
|
|
+
|
|
|
+
|
|
|
+def generate_launch_description() -> LaunchDescription:
|
|
|
+ # 先定位安装后的包共享目录,这样无论你是在源码目录还是 install 目录启动,
|
|
|
+ # 都能稳定找到配置文件。
|
|
|
+ package_share_directory = get_package_share_directory("offline_voice_module")
|
|
|
+ config_file = os.path.join(
|
|
|
+ package_share_directory, "config", "offline_voice_module.yaml"
|
|
|
+ )
|
|
|
+
|
|
|
+ default_dev = _load_serial_dev(config_file)
|
|
|
+
|
|
|
+ # 将 YAML 中的 dev 暴露成 launch 参数,保留“配置默认值 + 命令行可覆盖”的灵活性。
|
|
|
+ declare_dev_argument = DeclareLaunchArgument(
|
|
|
+ "dev",
|
|
|
+ default_value=default_dev,
|
|
|
+ description="micro_ros_agent 使用的串口设备路径",
|
|
|
+ )
|
|
|
+
|
|
|
+ micro_ros_agent_node = Node(
|
|
|
+ package="micro_ros_agent",
|
|
|
+ executable="micro_ros_agent",
|
|
|
+ output="screen",
|
|
|
+ emulate_tty=True,
|
|
|
+ # 这里等价替代原命令:
|
|
|
+ # ros2 run micro_ros_agent micro_ros_agent serial --dev /dev/voiceModule
|
|
|
+ # 不同点在于 dev 会优先从 YAML 读取,并且也支持通过 launch 参数临时覆盖。
|
|
|
+ arguments=["serial", "--dev", LaunchConfiguration("dev")],
|
|
|
+ )
|
|
|
+
|
|
|
+ return LaunchDescription(
|
|
|
+ [
|
|
|
+ declare_dev_argument,
|
|
|
+ LogInfo(msg=["加载配置文件: ", config_file]),
|
|
|
+ LogInfo(msg=["当前串口设备: ", LaunchConfiguration("dev")]),
|
|
|
+ micro_ros_agent_node,
|
|
|
+ ]
|
|
|
+ )
|