diff --git a/package.xml b/package.xml new file mode 100644 index 0000000..84aa0e6 --- /dev/null +++ b/package.xml @@ -0,0 +1,21 @@ + + + + robot_speaker + 0.0.0 + TODO: Package description + mzebra + Apache-2.0 + + rclpy + example_interfaces + + ament_copyright + ament_flake8 + ament_pep257 + python3-pytest + + + ament_python + + diff --git a/resource/robot_speaker b/resource/robot_speaker new file mode 100644 index 0000000..e69de29 diff --git a/robot_speaker/__init__.py b/robot_speaker/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/robot_speaker/robot_speaker_node.py b/robot_speaker/robot_speaker_node.py new file mode 100644 index 0000000..9be64cc --- /dev/null +++ b/robot_speaker/robot_speaker_node.py @@ -0,0 +1,55 @@ +import rclpy +from rclpy.node import Node +from example_interfaces.msg import String +import threading +from queue import Queue +import time +import espeakng +import pyttsx3 + + +class RobotSpeakerNode(Node): + def __init__(self, node_name): + super().__init__(node_name) + self.novels_queue_ = Queue() + self.novel_subscriber_ = self.create_subscription( + String, 'robot_msg', self.novel_callback, 10) + self.speech_thread_ = threading.Thread(target=self.speak_thread) + self.speech_thread_.start() + + def novel_callback(self, msg): + self.novels_queue_.put(msg.data) + + def speak_thread(self): + # 初始化引擎 + engine = pyttsx3.init() + # 调整参数 + engine.setProperty('rate', 150) # 语速(150更自然) + engine.setProperty('volume', 1.0) # 音量(0.0-1.0) + + # 选择中文音色(修正:使用 languages 属性,且是列表) + voices = engine.getProperty('voices') + for voice in voices: + # 检查语音支持的语言列表中是否包含中文('zh' 或 'zh-CN' 等) + if any('zh' in lang for lang in voice.languages): + engine.setProperty('voice', voice.id) + self.get_logger().info(f'已选择中文语音:{voice.id}') + break + else: + self.get_logger().warning('未找到中文语音库,将使用默认语音') + + while rclpy.ok(): + if self.novels_queue_.qsize() > 0: + text = self.novels_queue_.get() + engine.say(text) + engine.runAndWait() # 等待语音播放完成 + else: + time.sleep(0.5) + + + +def main(args=None): + rclpy.init(args=args) + node = RobotSpeakerNode("robot_speaker_node") + rclpy.spin(node) + rclpy.shutdown() diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..a631b4c --- /dev/null +++ b/setup.cfg @@ -0,0 +1,4 @@ +[develop] +script_dir=$base/lib/robot_speaker +[install] +install_scripts=$base/lib/robot_speaker diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..3f2d00e --- /dev/null +++ b/setup.py @@ -0,0 +1,26 @@ +from setuptools import find_packages, setup + +package_name = 'robot_speaker' + +setup( + name=package_name, + version='0.0.0', + packages=[package_name], + data_files=[ + ('share/ament_index/resource_index/packages', + ['resource/' + package_name]), + ('share/' + package_name, ['package.xml']), + ], + install_requires=['setuptools'], + zip_safe=True, + maintainer='mzebra', + maintainer_email='mzebra@foxmail.com', + description='TODO: Package description', + license='Apache-2.0', + tests_require=['pytest'], + entry_points={ + 'console_scripts': [ + 'robot_speaker_node=robot_speaker.robot_speaker_node:main' + ], + }, +)