forked from zbw/yiliao2026
with '#' will be ignored, and an empty message aborts the commit. On branch master Your branch is ahead of 'origin/master' by 24 commits. (use "git push" to publish your local commits) Changes to be committed: modified: src/my_robot_bringup/launch/master_launch.py deleted: src/obs.zip modified: src/vlm_detect/launch/vlm_detect.launch.py
173 lines
6.3 KiB
Python
173 lines
6.3 KiB
Python
#!/usr/bin/env python3
|
||
# -*- coding: utf-8 -*-
|
||
"""
|
||
vlm_detect 启动文件
|
||
同时启动 vlm_node (图生文) + tts_server (语音播报服务)
|
||
|
||
用法:
|
||
ros2 launch vlm_detect vlm_detect.launch.py # 默认全部
|
||
ros2 launch vlm_detect vlm_detect.launch.py vlm_host:=http://... # 指定 VLM 服务地址
|
||
ros2 launch vlm_detect vlm_detect.launch.py use_tts:=false # 关闭语音播报
|
||
ros2 launch vlm_detect vlm_detect.launch.py use_qr_tts:=true # 兼容旧二维码播报桥接
|
||
ros2 launch vlm_detect vlm_detect.launch.py use_vlm:=false # 只启动语音服务
|
||
"""
|
||
|
||
import os
|
||
from ament_index_python.packages import get_package_share_directory
|
||
|
||
from launch import LaunchDescription
|
||
from launch.actions import DeclareLaunchArgument, LogInfo
|
||
from launch.conditions import IfCondition
|
||
from launch.substitutions import LaunchConfiguration, PathJoinSubstitution
|
||
from launch_ros.actions import Node
|
||
|
||
|
||
def generate_launch_description():
|
||
|
||
# ==================== Launch 参数 ====================
|
||
use_vlm = LaunchConfiguration('use_vlm')
|
||
use_tts = LaunchConfiguration('use_tts')
|
||
use_qr_tts = LaunchConfiguration('use_qr_tts')
|
||
|
||
config_file = LaunchConfiguration('config_file')
|
||
|
||
# vlm_node 可覆盖参数
|
||
vlm_host = LaunchConfiguration('vlm_host')
|
||
vlm_model = LaunchConfiguration('vlm_model')
|
||
image_topic = LaunchConfiguration('image_topic')
|
||
trigger_topic = LaunchConfiguration('trigger_topic')
|
||
trigger_sign = LaunchConfiguration('trigger_sign')
|
||
result_topic = LaunchConfiguration('result_topic')
|
||
prompt_text = LaunchConfiguration('prompt_text')
|
||
max_tokens = LaunchConfiguration('max_tokens')
|
||
|
||
# tts_server 可覆盖参数
|
||
audio_sink = LaunchConfiguration('audio_sink')
|
||
tts_speed = LaunchConfiguration('tts_speed')
|
||
|
||
# ==================== 参数声明 ====================
|
||
declare_use_vlm = DeclareLaunchArgument(
|
||
'use_vlm', default_value='true',
|
||
description='启动 VLM 图生文节点')
|
||
|
||
declare_use_tts = DeclareLaunchArgument(
|
||
'use_tts', default_value='true',
|
||
description='启动 TTS 语音播报服务')
|
||
|
||
declare_use_qr_tts = DeclareLaunchArgument(
|
||
'use_qr_tts', default_value='false',
|
||
description='启动旧二维码 → TTS 桥接节点')
|
||
|
||
declare_config_file = DeclareLaunchArgument(
|
||
'config_file',
|
||
default_value=PathJoinSubstitution([
|
||
get_package_share_directory('vlm_detect'), 'config', 'vlm_detect.yaml'
|
||
]),
|
||
description='YAML 配置文件路径')
|
||
|
||
# vlm_node 参数
|
||
declare_vlm_host = DeclareLaunchArgument(
|
||
'vlm_host', default_value='http://192.168.10.189:8000',
|
||
description='VLM 服务器地址')
|
||
declare_vlm_model = DeclareLaunchArgument(
|
||
'vlm_model', default_value='./OpenGVLab/InternVL3-1B/',
|
||
description='VLM 模型名称')
|
||
declare_image_topic = DeclareLaunchArgument(
|
||
'image_topic', default_value='/image_mjpeg',
|
||
description='输入的压缩图像话题')
|
||
declare_trigger_topic = DeclareLaunchArgument(
|
||
'trigger_topic', default_value='/sign4return',
|
||
description='输入的触发信号话题')
|
||
declare_trigger_sign = DeclareLaunchArgument(
|
||
'trigger_sign', default_value='9',
|
||
description='触发信号值 (Int32)')
|
||
declare_result_topic = DeclareLaunchArgument(
|
||
'result_topic', default_value='/vlm_result',
|
||
description='输出 VLM 结果的话题')
|
||
declare_prompt_text = DeclareLaunchArgument(
|
||
'prompt_text', default_value='请描述这张图片的内容,用一句简短的话概括,不超过20个字。',
|
||
description='发送给 VLM 的提示词')
|
||
declare_max_tokens = DeclareLaunchArgument(
|
||
'max_tokens', default_value='100',
|
||
description='最大生成 token 数')
|
||
|
||
# tts_server 参数
|
||
declare_audio_sink = DeclareLaunchArgument(
|
||
'audio_sink',
|
||
default_value='alsa_output.usb-C-Media_Electronics_Inc._USB_Audio_Device-00.analog-stereo',
|
||
description='音频输出设备 (PulseAudio sink)')
|
||
declare_tts_speed = DeclareLaunchArgument(
|
||
'tts_speed', default_value='1.5',
|
||
description='语速倍率 (0.5~2.0)')
|
||
|
||
# ==================== 节点 ====================
|
||
# VLM 图生文节点 (内部自带 TTS 服务客户端)
|
||
vlm_node = Node(
|
||
package='vlm_detect',
|
||
executable='vlm_node',
|
||
name='vlm_detect',
|
||
output='screen',
|
||
condition=IfCondition(use_vlm),
|
||
parameters=[config_file,
|
||
{
|
||
'vlm_host': vlm_host,
|
||
'vlm_model': vlm_model,
|
||
'image_topic': image_topic,
|
||
'trigger_topic': trigger_topic,
|
||
'trigger_sign': trigger_sign,
|
||
'result_topic': result_topic,
|
||
'prompt_text': prompt_text,
|
||
'max_tokens': max_tokens,
|
||
}],
|
||
)
|
||
|
||
# TTS 语音播报服务端
|
||
tts_server = Node(
|
||
package='vlm_detect',
|
||
executable='tts_server',
|
||
name='tts_server',
|
||
output='screen',
|
||
condition=IfCondition(use_tts),
|
||
parameters=[config_file,
|
||
{
|
||
'audio_sink': audio_sink,
|
||
'tts_speed': tts_speed,
|
||
}],
|
||
)
|
||
|
||
# 二维码 → TTS 桥接 (订阅 qr_results,调用 /tts/speak)
|
||
qr_tts_bridge = Node(
|
||
package='vlm_detect',
|
||
executable='qr_tts_bridge',
|
||
name='qr_tts_bridge',
|
||
output='screen',
|
||
condition=IfCondition(use_qr_tts),
|
||
)
|
||
|
||
# ==================== 组装 ====================
|
||
return LaunchDescription([
|
||
# 参数声明
|
||
declare_use_vlm,
|
||
declare_use_tts,
|
||
declare_use_qr_tts,
|
||
declare_config_file,
|
||
declare_vlm_host,
|
||
declare_vlm_model,
|
||
declare_image_topic,
|
||
declare_trigger_topic,
|
||
declare_trigger_sign,
|
||
declare_result_topic,
|
||
declare_prompt_text,
|
||
declare_max_tokens,
|
||
declare_audio_sink,
|
||
declare_tts_speed,
|
||
# 节点
|
||
LogInfo(msg=['配置文件: ', config_file]),
|
||
LogInfo(msg=['VLM 服务: ', vlm_host]),
|
||
LogInfo(msg=['TTS 服务: ', use_tts]),
|
||
LogInfo(msg=['QR-TTS 桥接: ', use_qr_tts]),
|
||
vlm_node,
|
||
tts_server,
|
||
qr_tts_bridge,
|
||
])
|