You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python语音控制车辆应用:实现连续移动功能求助

解决语音控制车辆持续移动问题

问题根源

  1. 语音监听阻塞主循环:recognizer.listen(source)会阻塞程序,直到收到语音命令,导致车辆只有在命令下达后才会移动一次,之后又进入等待状态,无法持续更新位置。
  2. 方向被强制覆盖:原主循环中if self.engine_running: self.direction = (0, -self.speed)这行代码会强制将方向设为前进,覆盖之前通过语音命令设置的左转/右转/后退方向。
  3. 移动逻辑重复:代码中重复执行了两次位置更新,导致移动距离计算错误。

修复步骤

  • 将语音监听放到单独线程中,避免阻塞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()

关键修改说明

  1. 线程分离语音监听:将语音命令处理放到单独线程,避免阻塞Pygame主循环,保证车辆位置能持续更新
  2. 添加监听超时:设置timeout和phrase_time_limit,避免语音监听一直阻塞程序
  3. 拆分主循环:main_loop专注处理Pygame事件和画面渲染,持续更新车辆位置
  4. 清理冗余代码:移除强制覆盖方向的代码,删除重复的位置更新逻辑

内容的提问来源于stack exchange,提问作者Mike

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 05:24:56