ArduPilot / ArduPilot/pymavlink
Significant processing delays when receiving data
- Dominant language
- Python
- Stars
- 728
- Forks
- 739
- Avg merge
- 4d 10h
- Merged PRs (30d)
- 7
Description
I recently started using MAVLink in a robotics project, and I was passing IMU data using MAVLink over a direct Ethernet from a Teensy 4.1 to an NVIDIA Jetson Orin nano.
I ran some tests, and the results show that on the receiving end (the Jetson Orin Nano) there are processing delays of ~30ms
To run the test, I connected one of the Teensy's GPIO pins to the Jetson's GPIO, and used the following code to send a heartbeat message while pulsing the GPIO line:
```cpp
ml->heartbeat();
Serial.println("Sent heartbeat");
digitalWrite(5, LOW);
Serial.println("Toggled GPIO");
```
The heartbeat() method is just a small wrapper:
```cpp
void MAVLink::heartbeat() {
mavlink_message_t msg;
uint8_t buf[MAVLINK_MAX_PACKET_LEN];
mavlink_msg_heartbeat_pack(this->system_id,
this->component_id,
&msg,
MAV_TYPE_GROUND_ROVER,
MAV_AUTOPILOT_GENERIC,
0,
0,
MAV_STATE_ACTIVE);
uint16_t len = mavlink_msg_to_send_buffer(buf, &msg);
this->send_buffer(buf, len);
}
```
The send_buffer function is also just a simple wrapper around Arduino's built-in UDP functionality
On the Jetson side, I wrote a Python script that waits for the GPIO falling edge, then measures the time until the MAVLink message is received:
```python
#!/usr/bin/env python3
import Jetson.GPIO as GPIO
import time
import socket
from pymavlink import mavutil
GPIO_PIN = 21
GPIO.setmode(GPIO.BCM)
GPIO.setup(GPIO_PIN, GPIO.IN)
mavlink_connection = mavutil.mavlink_connection('udpin:0.0.0.0:14550')
#sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
#sock.bind(("", 14550))
def wait_for_heartbeat():
while True:
msg = mavlink_connection.recv_match(blocking=False)
# msg, addr = sock.recvfrom(1024)
if msg:
return time.time()
try:
# Wait for GPIO to go LOW
GPIO.wait_for_edge(GPIO_PIN, GPIO.FALLING)
start_time = time.time()
# Measure time to first MAVLink heartbeat
heartbeat_time = wait_for_heartbeat()
elapsed_time = heartbeat_time - start_time
print(f"Time from GPIO LOW to MAVLink heartbeat: {elapsed_time * 1000:.4f}ms")
except KeyboardInterrupt:
pass
finally:
GPIO.cleanup()
```
When commenting out the MAVLink code and uncommenting the raw UDP code in this script, the time drops from ~30ms to ~0.5ms. Am I doing something wrong on the receive code that causes such a massive delay? Or is this an fundamental limitation of pymavlink?
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with the Jetson Python script, especially mavutil.mavlink_connection(...), recv_match(blocking=False), and wait_for_heartbeat(), and compare that path with the raw UDP socket shown. Reproduce the ~30 ms versus ~0.5 ms measurements and determine whether the delay is in pymavlink reception or the polling loop; done means the cause and a supported correction or limitation are established.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- networking
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100