Request data from FC with pymavlink doesn't work properly

Hi
I used pymavlink and DISTANCE_SENSOR(I have LiDAR Lite V3 I2C version sensor) and GLOBAL_POSITION_INT packets to receive altitude from FC in my companion computer(Jetson Nano).
I used that for while and it works Great! But today it don’t work and I stuck in that!!!

This is the code I used to receive the altitude:

import argparse
import time
import serial
from pymavlink import mavutil
import time
# sudo chmod a+rw /dev/ttyUSB0

myport = '/dev/ttyUSB0'
mybaudrate = 115200

print('before')

# Start a connection listening on a USB port
the_connection = mavutil.mavlink_connection(myport,mybaudrate)

# Wait for the first heartbeat 
# This sets the system and component ID of remote system for the link
the_connection.wait_heartbeat()
print("Heartbeat from system (system %u component %u)" % (the_connection.target_system, the_connection.target_component))

# Once connected, use 'the_connection' to get and send messages
the_connection.mav.request_data_stream_send(the_connection.target_system, the_connection.target_component, mavutil.mavlink.MAV_DATA_STREAM_ALL,
    10, # Hz
    1,   # enable
    )

start_time=time.time()
while 1:
    #tic = time.time()
    if time.time()-start_time>1:
        start_time=time.time()
        
        msg = the_connection.recv_match(type='DISTANCE_SENSOR', blocking=True)
        altitude = msg.current_distance
        #toc = time.time() - tic
        #print(toc)
        print(altitude)

The problem is Altitude data isn’t real time and has a different delay(for example when I change the altitude can visible for LiDAR It shown in my code after 20~40 seconds). I changed the frequency of request_data_stream in code from 0 to 10 Hz and in Full parameter list in SR2_ params as same. When I reduce the frequency, delay reduced and when increase the frequency, also delay increase.
This delay is a cumulative delay. That is, as more time passes since the execution of the code, the time to get the correct data also increases. I think and it seems the Altitude data saved in a buffer and when I request the data, It doesn’t give a real time data and send the data from buffer!
As I mentioned, I used this code for a while(more than 1 year!!!) but now, it doesn’t work. I guess this is params change or something like that.
Can anyone help?

Regards, Joe

@rmackay9 @stephendade @amilcarlucas

So you’re reuqesting data at 10Hz:

the_connection.mav.request_data_stream_send(the_connection.target_system, the_connection.target_component, mavutil.mavlink.MAV_DATA_STREAM_ALL,
    10, # Hz
    1,   # enable
    )

But only reading it at 1 Hz:

    if time.time()-start_time>1:
        start_time=time.time()

So you’ll get a buffer buildup in your script, as you’re reading the data far more slowly than it’s being produced.

A better way to design your read loop would be something like:

while True:
    msg = the_connection.recv_match(type='DISTANCE_SENSOR', blocking=False)
    if msg:
        # process message here
    else:
        time.sleep(0.05)
3 Likes

This code is snip of the main code and it is necessary to use
if time.time()-start_time>1: start_time=time.time()
because I have a scheduling, and I can’t use sleep in main code because it completely breaks the timing of my code!
So I should give real time altitude every 1 second from FC without any delay or lag! my main idea for scheduling is using time.time and time flag.
Is there anyway to receive real altitude data every second in a loop with time.time for scheduling?

@stephendade

The way pymavlink works is that recv_match (and similar functions) will return the next received message from the buffer. This ensures that no messages are missed.

If you have specific timing requirements, you’ll have to figure out a way to separate out the message receiving and timing. Possibly a separate thread for pymavlink receiving …

2 Likes

I had a similar issue, but it was due to the fact that I couldn’t get the data in real time because I was using communication with the single-board computer through GPIO. After setting up a connection via FTDI, the problem disappeared. As for the issue of not being able to read the data more frequently than once per second, the solution might be to create a daemon process that will quickly fetch the data and store the latest values in a shared memory variable. You can then retrieve the data from this variable whenever it’s convenient for you.

1 Like