Python语音控制车辆应用:实现连续移动功能求助
解决语音控制车辆持续移动问题
问题根源
- 语音监听阻塞主循环:
recognizer.listen(source)会阻塞程序,直到收到语音命令,导致车辆只有在命令下达后才会移动一次,之后又进入等待状态,无法持续更新位置。 - 方向被强制覆盖:原主循环中
if self.engine_running: self.direction = (0, -self.speed)这行代码会强制将方向设为前进,覆盖之前通过语音命令设置的左转/右转/后退方向。 - 移动逻辑重复:代码中重复执行了两次位置更新,导致移动距离计算错误。
修复步骤
- 将语音监听放到单独线程中,避免阻塞Pygame的主渲染循环
- 移除强制覆盖方向的代码,保留语音命令设置的方向
- 清理重复的移动逻辑,只保留一次位置更新操作
修改后的完整代码
import sys import speech_recognition as sr import pygame import time from pygame.locals import QUIT import threading class CarControl: def __init__(self): pygame.init() self.screen = pygame.display.set_mode((1000, 900)) self.clock = pygame.time.Clock() self.engine_running = False self.direction = (0, 0) # Initially, the car is not moving self.speed = 5 # Initial speed self.car_image = pygame.image.load("car.png") self.car_rect = self.car_image.get_rect() self.car_rect.center = (200, 150) # Visual indicators for climate and multimedia control self.climate_indicator = False self.volume_level = 50 # Initial volume # 启动语音监听线程 self.running = True threading.Thread(target=self.handle_voice_commands, daemon=True).start() self.main_loop() def start_engine(self): if not self.engine_running: self.engine_running = True print("Engine has started.") def stop_engine(self): if self.engine_running: self.engine_running = False self.direction = (0, 0) # Stop the car when the engine is off print("Engine has stopped.") def turn_left(self): if self.engine_running: self.direction = (-self.speed, 0) # Set left movement print("Car is turning left.") else: print("Engine must be started to turn.") def turn_right(self): if self.engine_running: self.direction = (self.speed, 0) # Set right movement print("Car is turning right.") else: print("Engine must be started to turn.") def go_forward(self): if self.engine_running: self.direction = (0, -self.speed) # Set forward movement print("Car is moving forward.") else: print("Engine must be started to move forward.") def go_backward(self): if self.engine_running: self.direction = (0, self.speed) # Set backward movement print("Car is moving backward.") else: print("Engine must be started to move backward.") def set_speed(self, speed): self.speed = speed print(f"Speed has been set to {speed}.") def draw_climate_indicator(self): # Draw visual indicator for climate control pygame.draw.circle(self.screen, (0, 255, 0) if self.climate_indicator else (255, 0, 0), (50, 50), 20) def draw_volume_indicator(self): # Draw visual indicator for volume pygame.draw.rect(self.screen, (255, 255, 255), pygame.Rect(800, 50, 20, 100)) pygame.draw.rect(self.screen, (0, 0, 255), pygame.Rect(800, 150 - self.volume_level, 20, self.volume_level)) def control_volume(self, direction): if direction == "increase": self.volume_level = min(self.volume_level + 10, 100) print("Volume has been increased.") elif direction == "decrease": self.volume_level = max(self.volume_level - 10, 0) print("Volume has been decreased.") def control_climate(self, command): if "turn on climate" in command: self.climate_indicator = True print("Climate control has been turned on.") elif "turn off climate" in command: self.climate_indicator = False print("Climate control has been turned off.") def handle_voice_commands(self): recognizer = sr.Recognizer() while self.running: with sr.Microphone() as source: print("Listening...") recognizer.adjust_for_ambient_noise(source) try: # 添加超时设置,避免一直阻塞等待语音 audio = recognizer.listen(source, timeout=1, phrase_time_limit=2) text = recognizer.recognize_google(audio, language='en-US') print(f"Received command: {text}") if "start" in text: self.start_engine() elif "stop" in text: self.stop_engine() elif "left" in text: self.turn_left() elif "right" in text: self.turn_right() elif "forward" in text: self.go_forward() elif "backward" in text: self.go_backward() elif "speed" in text: words = text.split() for word in words: if word.isdigit(): self.set_speed(int(word)) elif "increase volume" in text: self.control_volume("increase") elif "decrease volume" in text: self.control_volume("decrease") elif "turn on climate" in text or "turn off climate" in text: self.control_climate(text) except sr.UnknownValueError: print("Unknown command") except sr.RequestError: print("Failed to recognize speech.") except sr.WaitTimeoutError: # 超时未收到命令,继续监听 pass time.sleep(0.1) def main_loop(self): while self.running: for event in pygame.event.get(): if event.type == QUIT: self.running = False pygame.quit() sys.exit() # 更新车辆位置 if self.engine_running: self.car_rect.x += self.direction[0] self.car_rect.y += self.direction[1] # 绘制界面 self.screen.fill((0, 0, 0)) self.screen.blit(self.car_image, self.car_rect) self.draw_climate_indicator() self.draw_volume_indicator() pygame.display.flip() self.clock.tick(60) if __name__ == "__main__": car_control = CarControl()
关键修改说明
- 线程分离语音监听:将语音命令处理放到单独线程,避免阻塞Pygame主循环,保证车辆位置能持续更新
- 添加监听超时:设置
timeout和phrase_time_limit,避免语音监听一直阻塞程序 - 拆分主循环:
main_loop专注处理Pygame事件和画面渲染,持续更新车辆位置 - 清理冗余代码:移除强制覆盖方向的代码,删除重复的位置更新逻辑
内容的提问来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

