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


import asyncio
import json
import struct
from pynput import keyboard
import websockets

ROBOT_IP = "10.10.10.10"
WS_URL = f"ws://{ROBOT_IP}:8765"

# Если в Шаге 1 топик называется иначе — замените здесь:
CMD_TOPIC = "/cmd_vel"

LINEAR_SPEED = 0.2
ANGULAR_SPEED = 0.5

keys_pressed = set()
ws = None
channel_id = 1

async def advertise_channel():
    """Объявляем для Foxglove Bridge, что мы будем публиковать geometry_msgs/msg/Twist"""
    # Сообщение регистрации канала по протоколу Foxglove WebSocket
    advertise_msg = {
        "op": "advertise",
        "channels": [
            {
                "id": channel_id,
                "topic": CMD_TOPIC,
                "encoding": "json",
                "schemaName": "geometry_msgs/msg/Twist"
            }
        ]
    }
    await ws.send(json.dumps(advertise_msg))
    print(f"Канал публикации в {CMD_TOPIC} зарегистрирован!")

async def send_twist(vx, wz):
    if ws is None:
        return
    
    twist_data = {
        "linear": {"x": float(vx), "y": 0.0, "z": 0.0},
        "angular": {"x": 0.0, "y": 0.0, "z": float(wz)}
    }
    
    # Foxglove WebSocket binary publish message:
    # Байт 1: op code (1 = Client Publish)
    # Байты 2-5: uint32 channel_id (little-endian)
    # Остальные байты: payload (JSON-строка)
    payload = json.dumps(twist_data).encode('utf-8')
    header = struct.pack("<BI", 1, channel_id)
    binary_msg = header + payload

    try:
        await ws.send(binary_msg)
    except Exception as e:
        print(f"Ошибка отправки: {e}")

def on_press(key):
    try:
        if hasattr(key, 'char') and key.char:
            keys_pressed.add(key.char.lower())
    except AttributeError:
        pass

def on_release(key):
    try:
        if hasattr(key, 'char') and key.char:
            keys_pressed.discard(key.char.lower())
    except AttributeError:
        pass
    if key == keyboard.Key.esc:
        return False

async def main():
    global ws
    print(f"Подключение к {WS_URL}...")
    async with websockets.connect(WS_URL, subprotocols=["foxglove.websocket.v1"]) as websocket:
        ws = websocket
        await advertise_channel()
        
        print("\n--- Управление готово! ---")
        print("Зажмите W для движения вперед, A/D для поворота, ESC для выхода.")

        listener = keyboard.Listener(on_press=on_press, on_release=on_release)
        listener.start()

        try:
            while listener.is_alive():
                vx, wz = 0.0, 0.0
                if 'w' in keys_pressed:
                    vx += LINEAR_SPEED
                if 's' in keys_pressed:
                    vx -= LINEAR_SPEED
                if 'a' in keys_pressed:
                    wz += ANGULAR_SPEED
                if 'd' in keys_pressed:
                    wz -= ANGULAR_SPEED

                await send_twist(vx, wz)
                await asyncio.sleep(0.05)  # 20 Гц
        finally:
            await send_twist(0.0, 0.0)
            print("Остановлено.")

if __name__ == "__main__":
    asyncio.run(main())