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)