Troubleshooting - LLUAV SDK Docs

# LLUAV SDK Troubleshooting Guide

## Connection Issues

### "Failed to connect to ws://:53001"

Symptoms: `LLUAVConnectionError` immediately on `connect()`.

Causes & Fixes: 1. Drone not reachable — Verify network connectivity: `bash ping <host> telnet <host> 53001` 2. Firewall blocking port 53001 — Ensure the drone's firewall allows inbound WebSocket connections. 3. Wrong host/port — Double-check the IP and port. Some firmware builds use a non-default port. 4. Password mismatch — If password protection is enabled but no password is provided, the server may immediately close the connection after the login failure.

### "Connection timeout"

Symptoms: `connect()` hangs and then raises timeout.

Causes & Fixes: 1. High latency link (e.g., 4G/5G telemetry) — Increase `timeout`: `python client = LLUAVClient("192.168.1.100", timeout=30.0)` 2. Drone CPU overloaded — The WebSocket server may be slow to respond if the flight controller is under heavy load. Check `sysinfo` after connecting.

### Continuous reconnection loop

Symptoms: Log shows "Reconnecting..." repeatedly every few seconds.

Causes & Fixes: 1. Unstable network — Check wireless signal strength. Consider using a dedicated ground-station radio instead of WiFi. 2. Heartbeat too aggressive — If the heartbeat command itself causes timeouts, increase `heartbeat_interval`: `python client = LLUAVClient(..., heartbeat_interval=15.0)` 3. Server crashed — The drone firmware may have restarted. Verify via ping.

### "Login first!"

Symptoms: Every command returns `ret=-1, msg="Login first!"`.

Fix: Provide the password in the constructor or call `login()` explicitly after connecting:

    client = LLUAVClient("192.168.1.100", password="your_password")
    client.connect()  # auto-login happens here

## Command Queue & Timeout

### "Command timeout"

Symptoms: `LLUAVCommandError: Command timeout`.

Causes & Fixes: 1. Command blocked by server — Some commands (e.g., `savemap`, `preflight_check`) can take several seconds. Increase the per-command timeout: `python client.save_map("/big_map", timeout=60.0)` 2. Queue congestion — If many periodic tasks are registered with short intervals, the queue may grow faster than the drone can process. Reduce task frequency or remove unnecessary tasks. 3. Server busy — Check `get_statics()` for high CPU load or communication latency.

### "Max retries exceeded"

Symptoms: Command fails after 3 retries.

Causes & Fixes: 1. Connection drops mid-flight — The command was sent but the response was lost. The SDK retries automatically. If this happens frequently, check network stability. 2. Command rejected by server — If the server consistently returns `ret != 0`, the SDK does not retry (only network failures trigger retry). Check the error message. 3. Too few retries — Increase `max_retries`: `python client = LLUAVClient(..., max_retries=5)`

### Queue growing indefinitely

Symptoms: Memory usage increases over time; commands take longer and longer to complete.

Causes & Fixes: 1. Periodic tasks too frequent — Tasks are enqueued faster than the drone can respond. Increase interval or remove tasks. 2. Blocking the caller — In the sync Python client, calling `send_cmd(block=True)` from a tight loop without consuming the response can back up if the caller thread is slower than the queue drain. Use `block=False` and check the Future status.

## Flight Control Issues

### "Not allow when vehicle is ARMED!"

Symptoms: Command returns `ret=-1` with this message.

Explanation: The drone firmware blocks certain commands while the motors are armed. This is a safety feature.

Affected commands: `reboot_node`, `set_maplocate`, `set_mappath`, `disarm` (actually allowed), `savemap`, etc. See the `runOnArm` column in the firmware command table.

Fix: Only send these commands when disarmed, or use `land()` / `rtl()` first, then wait for disarm.

### "CMD not permitted to run in LOCK mode!"

Symptoms: Command rejected with this message.

Explanation: The server is in admin lock mode. Only commands marked `runInLock=true` are allowed for non-admin users.

Fix: Log in with admin password (`"1025"`) and call `admin_unlock()`.

## Language-Specific Issues

### Python: `ImportError: websocket-client is required`

Fix:

    pip install websocket-client
    # For async support:
    pip install websockets

### Python Async: `RuntimeError: Event loop is closed`

Cause: Creating an `LLUAVAsyncClient` after the event loop has already been closed.

Fix: Ensure `asyncio.run()` or equivalent is active before calling `connect()`.

### C++: `websocketpp not found`

Fix (Ubuntu/Debian):

    sudo apt install libwebsocketpp-dev nlohmann-json3-dev

### C++: Link errors mentioning `pthread`

Fix: Ensure CMake links Threads::Threads (already included in provided CMakeLists.txt).

### JavaScript: `WebSocket implementation not found`

Fix:

    npm install ws

### Browser: `WebSocket connection failed`

Cause: Browsers enforce same-origin and mixed-content policies. Connecting to `ws://` from an `https://` page may be blocked.

Fix: Serve the page over `http://` or configure the drone with a TLS terminator for `wss://`.

## Performance Tuning

### Reducing command latency

1. Disable heartbeat if not needed behind a stable LAN: `python client = LLUAVClient(..., heartbeat_interval=0)`
2. Shorten timeout for fast commands on a reliable link: `python client = LLUAVClient(..., timeout=3.0)`

### Handling high-latency links (satellite / 4G)

1. Increase timeout to 30–60 seconds.
2. Increase reconnect interval to avoid flooding the network: `python client = LLUAVClient( ..., timeout=30.0, reconnect_interval=5.0, max_reconnect_interval=120.0, )`
3. Reduce periodic task frequency to avoid queue backlog.

## Logging & Debugging

### Enable SDK debug output

Python:

    import logging
    logging.basicConfig(level=logging.DEBUG)

C++: Rebuild with `DCMAKE_BUILD_TYPE=Debug` and add print statements in the callback handlers.

JavaScript:

    // Patch _processQueue to log
    const orig = client._processQueue.bind(client);
    client._processQueue = function() {
        console.log("Queue length:", client._queue.length);
        return orig();
    };

### Capture raw protocol traffic

Use a WebSocket proxy or packet capture:

    # Using wscat for manual inspection
    npm install -g wscat
    wscat -c ws://192.168.1.100:53001
    > login your_password
    > state