Загрузка данных


def display_loop():
    cv2.namedWindow("Камера робота")
    cv2.namedWindow("Сонар")

    print("""
w — вперёд      s — назад
a — влево       d — вправо
пробел — стоп
1 — расстояние до ближайшей стенки
+ — быстрее вращение сонара    - — медленнее вращение сонара
q — выход
(окно с видео или сонаром должно быть в фокусе, клавишу нужно УДЕРЖИВАТЬ)
""")

    current_cmd["sweep_speed"] = 0.02

    # время последнего "подтверждения" каждой зажатой клавиши
    held_keys = {}   # char -> last_seen_time

    def press(ch):
        held_keys[ch] = time.time()

    def is_held(ch):
        t = held_keys.get(ch)
        return t is not None and (time.time() - t) <= KEY_TIMEOUT

    # запоминаем предыдущее состояние команд, чтобы не спамить одинаковыми значениями
    last_sent = {"linear_x": None, "angular_z": None}

    while True:
        with display_lock:
            video_frame = latest_frames["video"]
            sonar_frame = latest_frames["sonar"]
        if video_frame is not None:
            cv2.imshow("Камера робота", video_frame)
        if sonar_frame is not None:
            cv2.imshow("Сонар", sonar_frame)

        # --- 1. Читаем события клавиатуры ---
        # waitKey вызываем несколько раз с малым интервалом, чтобы ловить
        # повторяющиеся события удержания клавиши (key repeat от ОС).
        for _ in range(10):
            k = cv2.waitKey(1) & 0xFF
            if k == 255:
                continue
            ch = chr(k) if k < 128 else ''

            if ch == 'q':
                cv2.destroyAllWindows()
                with cmd_lock:
                    current_cmd["linear_x"] = 0.0
                    current_cmd["angular_z"] = 0.0
                return

            if ch == '1':
                request_distance()
                continue

            if ch in ('w', 'a', 's', 'd', ' '):
                press(ch)
            elif ch == '+':
                with cmd_lock:
                    current_cmd["sweep_speed"] = min(1.0, current_cmd["sweep_speed"] + SWEEP_STEP)
                    print(f"скорость вращения сонара: {current_cmd['sweep_speed']:.2f}")
            elif ch == '-':
                with cmd_lock:
                    current_cmd["sweep_speed"] = max(0.0, current_cmd["sweep_speed"] - SWEEP_STEP)
                    print(f"скорость вращения сонара: {current_cmd['sweep_speed']:.2f}")

        # --- 2. Вычисляем команду из зажатых клавиш ---
        lin = 0.0
        ang = 0.0
        if is_held('w'):
            lin = SPEED
        elif is_held('s'):
            lin = -SPEED
        if is_held('a'):
            ang = TURN
        elif is_held('d'):
            ang = -TURN
        if is_held(' '):
            lin = 0.0
            ang = 0.0

        # если зажато что-то одно из w/a/d/s — едем/поворачиваем; если ничего — стоим
        if lin != last_sent["linear_x"] or ang != last_sent["angular_z"]:
            with cmd_lock:
                current_cmd["linear_x"] = lin
                current_cmd["angular_z"] = ang
            last_sent["linear_x"] = lin
            last_sent["angular_z"] = ang

        # небольшая пауза, чтобы не грузить CPU
        time.sleep(0.01)