Drone and Rover System Debugging Guide
无人机与无人车系统调试手册 · 现场故障排查
无人机
无人车
MAVLink
LQ3 网络
故障排查
1. Purpose
This document explains how to debug the drone and rover system in the field. It focuses on the actual vehicle system:
- Windows ground station
- LQ3 communication network
- Raspberry Pi 4B on rover
- Pixhawk flight controller
- ArduPilot / ArduCopter / ArduRover
- MAVProxy or MAVLink bridge
- Rover UDP motor agent
- STM32 motor controller
- GPS and EKF readiness
- Camera video stream
Use this guide when a drone does not arm, a rover does not move, GPS is missing, MAVLink heartbeat is missing, or video/network is unstable.
2. System Architecture
Drone Path
Windows PC mission script
|
| MAVLink UDP
|
LQ3 / network
|
|
Pixhawk on drone
|
|
ArduCopter
|
|
Drone motors
Typical drone mission flow:
Heartbeat → GPS OK → EKF OK → GUIDED mode → Arm → Takeoff → Velocity forward command → Land
Heartbeat → GPS OK → EKF OK → GUIDED mode → Arm → Takeoff → Velocity forward command → Land
Rover Path
Windows PC mission script
|
| MAVLink UDP
|
Rover Pixhawk
|
|
GPS / EKF status only
Windows PC mission script
|
| UDP command, port 15000
|
Raspberry Pi 4B rover_agent.py
|
| USB serial
|
STM32 motor controller
|
|
Rover motors
Rover Pixhawk: Used for heartbeat, GPS, and EKF readiness.
Rover motors: Not driven by Pixhawk. Command goes through Raspberry Pi UDP to STM32 motor controller.
Typical rover mission flow:
Pixhawk heartbeat → GPS OK → EKF OK → Rover agent UDP ping OK → Mission start sync → UDP move command → STM32 serial motor command → Stop command
Rover motors: Not driven by Pixhawk. Command goes through Raspberry Pi UDP to STM32 motor controller.
Typical rover mission flow:
Pixhawk heartbeat → GPS OK → EKF OK → Rover agent UDP ping OK → Mission start sync → UDP move command → STM32 serial motor command → Stop command
3. Important IP Addresses and Ports
Common Network
Windows PC LQ3-side IP: 192.168.1.234
Mac debug IP: 192.168.1.10
Typical subnet: 192.168.1.0/24
Gateway: 192.168.1.1
Mac debug IP: 192.168.1.10
Typical subnet: 192.168.1.0/24
Gateway: 192.168.1.1
Rover Examples
ROVER_1 Raspberry Pi IP: 192.168.1.101
ROVER_2 Raspberry Pi IP: 192.168.1.102
ROVER_3 Raspberry Pi IP: 192.168.1.103
Rover UDP motor port: 15000
ROVER_2 Raspberry Pi IP: 192.168.1.102
ROVER_3 Raspberry Pi IP: 192.168.1.103
Rover UDP motor port: 15000
MAVLink Ports
DRONE_1: UDP 14501, sysid 1
DRONE_2: UDP 14502, sysid 2
DRONE_3: UDP 14503, sysid 3
ROVER_1: UDP 14511, sysid 11
ROVER_2: UDP 14512, sysid 12
ROVER_3: UDP 14513, sysid 13
DRONE_2: UDP 14502, sysid 2
DRONE_3: UDP 14503, sysid 3
ROVER_1: UDP 14511, sysid 11
ROVER_2: UDP 14512, sysid 12
ROVER_3: UDP 14513, sysid 13
The UDP port and the vehicle SYSID must match the script configuration.
4. Field Debug Order
Power
|
Network
|
SSH
|
MAVLink heartbeat
|
GPS / EKF
|
Rover agent
|
Motor movement
|
Full mission
警告 Do not start with the full mission script. Test each layer first.
5. Power Checks
Drone
- Flight battery connected
- Pixhawk powered
- GPS module LED active
- Telemetry / LQ3 link powered
- ESCs powered
- Propellers removed for indoor tests
- Propellers installed only for outdoor flight tests
Rover
- Raspberry Pi powered
- Pixhawk powered
- STM32 motor controller powered
- Motor battery connected
- USB cable from Raspberry Pi to STM32 connected
- USB cable from Raspberry Pi to Pixhawk connected if MAVProxy bridge is running on Pi
- Rover wheels lifted for first motor test
6. Network Debugging
Check IP Address on Raspberry Pi
ip addr
hostname -I
ip route
Expected: eth0 has 192.168.1.xxx, default route uses eth0 if LQ3 is the main link.
If
hostname -I is empty, the Pi has no active IP address. Check Netplan
cat /etc/netplan/01-uav.yaml
network:
version: 2
ethernets:
eth0:
optional: true
dhcp4: no
addresses:
- 192.168.1.102/24
gateway4: 192.168.1.1
nameservers:
addresses: [8.8.8.8, 1.1.1.1]
wifis:
wlan0:
optional: true
dhcp4: no
sudo netplan generate
sudo netplan apply
ip addr
ip route
警告 Important:
•
•
• Do not put
•
addresses must be indented correctly•
gateway4 should line up with addresses• Do not put
gateway4 inside the address list
Ping Test
# From Windows
ping 192.168.1.102
# From Raspberry Pi
ping -c 3 192.168.1.234
If ping fails: Check LQ3 power · Ethernet cable · IP address · Subnet · Windows firewall · Duplicate IP addresses
7. SSH Debugging
# From Windows
ssh ubuntu@192.168.1.102
# If password login is disabled
ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no ubuntu@192.168.1.102
# On Raspberry Pi
sudo vim /etc/ssh/sshd_config
Useful settings:
PasswordAuthentication yesPubkeyAuthentication yesKbdInteractiveAuthentication yes
sudo systemctl restart ssh
8. MAVLink Heartbeat Debugging
py -c "from pymavlink import mavutil; m=mavutil.mavlink_connection('udpin:0.0.0.0:14512'); print('waiting heartbeat'); m.wait_heartbeat(); print('sysid', m.target_system, 'compid', m.target_component)"
Expected:
waiting heartbeat → sysid 12 compid 0If no heartbeat: Confirm MAVProxy service · UDP output IP · Windows IP · Port · Pixhawk USB · Pixhawk powered · ArduPilot booted
9. MAVProxy Bridge Debugging
sudo systemctl status mavlink-router.service
sudo systemctl status mavproxy.service
journalctl -u mavlink-router.service -n 50 --no-pager
mavproxy.py \
--master=/dev/serial/by-id/usb-ArduPilot_fmuv2_xxxxx-if00 \
--baudrate=115200 \
--out=udp:192.168.1.234:14512
ls -l /dev/serial/by-id/
Use stable USB paths. Do not rely on
/dev/ttyACM0 or /dev/ttyACM1 if multiple USB devices are connected. 10. GPS Debugging
py -c "from pymavlink import mavutil; m=mavutil.mavlink_connection('udpin:0.0.0.0:14512'); m.wait_heartbeat(); print('heartbeat', m.target_system);
while True:
msg=m.recv_match(type='GPS_RAW_INT', blocking=True, timeout=2)
if msg:
print('fix', msg.fix_type, 'sats', msg.satellites_visible, 'eph', msg.eph)"
Good GPS:
fix_type >= 3 · sats >= 8 · HDOP low, preferably below 2.0
If GPS is not detected: Check GPS cable · GPS port · Baud rate · Serial protocol · GPS module power LED · Move outdoors · Wait several minutes for first lock
For Pixhawk 2.4.8, common GPS serial settings:
SERIAL3_PROTOCOL = GPSSERIAL3_BAUD = 115200 or 38400GPS_TYPE = Auto
If compass is detected but GPS is not, I2C compass works while UART GPS does not. Check GPS UART wires, port, baud, or GPS protocol.
11. EKF Debugging
The mission waits for EKF position by checking
GLOBAL_POSITION_INT.
If GPS has fix but EKF is not ready: Wait longer outdoors · Check compass calibration · Accelerometer calibration · EKF origin · Vehicle not indoors · ArduPilot pre-arm warnings
In Mission Planner: Messages tab · Status tab · EKF flags · PreArm messages
12. Drone Debugging
Drone Heartbeat Test
py -c "from pymavlink import mavutil; m=mavutil.mavlink_connection('udpin:0.0.0.0:14503'); m.wait_heartbeat(); print('connected sysid', m.target_system)"
Drone Mode Test
master.set_mode_apm("GUIDED")
master.set_mode_apm("STABILIZE") # Indoor motor tests without props
Drone Arm Test
master.mav.command_long_send(
master.target_system,
master.target_component,
mavutil.mavlink.MAV_CMD_COMPONENT_ARM_DISARM,
0, 1, 0, 0, 0, 0, 0, 0
)
If drone does not arm: Pre-arm message · GPS if GUIDED · Safety switch · RC calibration · Accelerometer calibration · Compass calibration · Battery failsafe · Valid mode
Drone Forward Movement
distance = speed × time
Examples:
0.2 m/s × 30 sec = ~6 m
0.2 m/s × 50 sec = ~10 m
0.5 m/s × 20 sec = ~10 m
Examples:
0.2 m/s × 30 sec = ~6 m
0.2 m/s × 50 sec = ~10 m
0.5 m/s × 20 sec = ~10 m
send_velocity(master, 0.2, 0, 0)
This is a body-frame velocity command, not a true GPS waypoint mission.
13. Rover Debugging
The rover has two independent systems:
Pixhawk: GPS / EKF / heartbeat
Raspberry Pi + STM32: Motor control
Both must work.
Pixhawk: GPS / EKF / heartbeat
Raspberry Pi + STM32: Motor control
Both must work.
Rover Pixhawk Heartbeat
py -c "from pymavlink import mavutil; m=mavutil.mavlink_connection('udpin:0.0.0.0:14512'); m.wait_heartbeat(); print('rover sysid', m.target_system)"
Rover Agent Service
sudo systemctl status acker-rover.service
journalctl -u acker-rover.service -n 50 --no-pager
Rover Agent Manual Run
sudo systemctl stop acker-rover.service
python3 ~/acker_rover/rover_agent.py
[ROVER] Connecting STM32...
[ROVER] STM32 OK
[ROVER] STOP
[ROVER] UDP listening on 0.0.0.0:15000
[ROVER] STM32 OK
[ROVER] STOP
[ROVER] UDP listening on 0.0.0.0:15000
Rover UDP Ping
py -c "import socket,json; s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM); s.settimeout(2); s.sendto(json.dumps(dict(cmd='ping')).encode(),('192.168.1.102',15000)); print(s.recvfrom(4096))"
Expected:
{"ok": true, "status": "alive"} Rover Move Test
py -c "import socket,json; s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM); s.settimeout(2); s.sendto(json.dumps(dict(cmd='move',x=200,z=0,duration=2)).encode(),('192.168.1.102',15000)); print(s.recvfrom(4096))"
py -c "import socket,json; s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM); s.settimeout(2); s.sendto(json.dumps(dict(cmd='stop')).encode(),('192.168.1.102',15000)); print(s.recvfrom(4096))"
If UDP reply says moving but wheels do not spin: STM32 USB path wrong · STM32 firmware stuck · Motor battery off · Motor controller needs reboot · Wrong serial command format · Wrong USB serial device
14. STM32 Serial Debugging
ls -l /dev/serial/by-id/
Expected motor controller path:
or
usb-1a86_USB_Single_Serial_xxxxx-if00or
usb-WCH.CN_USB_Single_Serial_xxxxx-if00
python3 -c 'import serial,time; ser=serial.Serial("/dev/serial/by-id/usb-1a86_USB_Single_Serial_5C2C061781-if00",115200,timeout=1); f=bytes.fromhex("7B 00 00 00 64 00 00 00 00 1F 7D"); s=bytes.fromhex("7B 00 00 00 00 00 00 00 00 7B 7D"); print("forward"); ser.write(f); ser.flush(); time.sleep(2); print("stop"); ser.write(s); ser.flush(); ser.close()'
If no movement: Reboot STM32 · Replug USB · Check power · Check correct /dev/serial/by-id · Check if another process is holding the serial port
sudo lsof /dev/ttyACM0
15. Camera Stream Debugging
lsusb
ls -l /dev/video*
python3 -c "import cv2; cap=cv2.VideoCapture('/dev/video0'); print('opened', cap.isOpened()); ret, frame=cap.read(); print('ret', ret, 'shape', None if frame is None else frame.shape); cap.release()"
Expected:
opened True · ret True · shape (480, 640, 3)python3 -m pip install --user flask opencv-python-headless
python3 capture_video.py
Open:
http://PI_IP:8080/videoFor LQ3 low bandwidth:
WIDTH=128 · HEIGHT=96 · FPS=3 · JPEG_QUALITY=20 16. Emergency Stop
# Stop Rover Agent Mission
py -c "import socket,json; s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM); s.settimeout(2); s.sendto(json.dumps(dict(cmd='stop')).encode(),('192.168.1.102',15000)); print(s.recvfrom(4096))"
# Stop Rover Service
sudo systemctl stop acker-rover.service
# Disarm Drone by MAVLink
master.mav.command_long_send(... 0, 0, 0, 0, 0, 0, 0, 0)
# Kill Python mission
pkill -f mission_script_name.py
# Kill camera stream
pkill -SIGTERM -f capture_video.py
17. Common Problems and Fixes
| Problem | Fix |
|---|---|
| MAVLink heartbeat missing | Check UDP port, Windows IP, Pixhawk USB, MAVProxy service, LQ3 link, firewall |
| SYSID mismatch | Change expected_sysid in script or SYSID_THISMAV parameter
|
| GPS fix_type 1, sats 0 | Move outdoors, wait longer, check antenna direction, GPS wiring |
| Compass detected but GPS not detected | Check GPS UART cable, serial port, baud rate, SERIALx_PROTOCOL = GPS
|
| Rover UDP says moving but wheels don't move | Check STM32 power, motor battery, USB serial path, rover agent logs, reboot STM32 |
| Ctrl+C does not stop script | Use STOP_EVENT, timeout loops, signal handler, disarm all MAVLink masters |
| Drone does not arm | Check pre-arm message: GPS, compass, accelerometer, safety switch, RC calibration, battery failsafe, mode |
| LQ3 video freezes | Reduce resolution, FPS, JPEG quality; use one high-resolution stream; use low-resolution thumbnails |
通过 18. Pre-Mission Checklist
[ ] All vehicle batteries charged
[ ] Drone props installed only outdoors
[ ] Rover wheels clear
[ ] LQ3 connected
[ ] Windows has correct LQ3 IP
[ ] All Pixhawks powered
[ ] MAVProxy services running
[ ] MAVLink heartbeat confirmed
[ ] GPS fix confirmed
[ ] EKF/global position confirmed
[ ] Rover agents running
[ ] Rover UDP ping works
[ ] Rover move test works
[ ] Emergency stop tested
19. Recommended Debug Commands Summary
# Pi Network
ip addr; ip route; hostname -I; cat /etc/netplan/01-uav.yaml
# Pi USB Devices
lsusb; ls -l /dev/serial/by-id/; ls -l /dev/video*
# Pi Services
sudo systemctl status acker-rover.service
sudo systemctl status mavlink-router.service
journalctl -u acker-rover.service -n 50 --no-pager
journalctl -u mavlink-router.service -n 50 --no-pager
# Windows Ping
ping 192.168.1.102
# Windows MAVLink Heartbeat
py -c "from pymavlink import mavutil; m=mavutil.mavlink_connection('udpin:0.0.0.0:14512'); print('waiting'); m.wait_heartbeat(); print(m.target_system, m.target_component)"
# Windows Rover UDP Ping
py -c "import socket,json; s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM); s.settimeout(2); s.sendto(json.dumps(dict(cmd='ping')).encode(),('192.168.1.102',15000)); print(s.recvfrom(4096))"
# Windows Rover Move
py -c "import socket,json; s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM); s.settimeout(2); s.sendto(json.dumps(dict(cmd='move',x=200,z=0,duration=2)).encode(),('192.168.1.102',15000)); print(s.recvfrom(4096))"
20. Final Notes
The most important idea is to debug one layer at a time.
For drones, MAVLink controls the vehicle directly.
For rovers, MAVLink checks GPS/EKF, but Raspberry Pi UDP controls motors.
Because of this, a rover can have good GPS and still not move if the rover agent, STM32, motor battery, or serial path is not working.
Likewise, a rover can move manually but still fail a GPS mission if Pixhawk GPS or EKF is not ready.
For rovers, MAVLink checks GPS/EKF, but Raspberry Pi UDP controls motors.
Because of this, a rover can have good GPS and still not move if the rover agent, STM32, motor battery, or serial path is not working.
Likewise, a rover can move manually but still fail a GPS mission if Pixhawk GPS or EKF is not ready.
平台:Windows · LQ3 · Raspberry Pi 4B · Pixhawk · ArduPilot · MAVLink
(c) 卓博泰科技 · Drone and Rover System Debugging Guide
(c) 卓博泰科技 · Drone and Rover System Debugging Guide