How to reduce CPU usage of Mavproxy

Hello to all,
I was using Mavproxy in a raspberry pi 2 just to send the telemetry from the pixhawk serial port to the groundstation using UDP and a WiFi link. The only other process running in the raspberry pi was gstreamer for FPV, and everything was working fine.
Now, I have moved to a raspberry pi Zero due to weight constraints, and have noticed a huge increase in the video latency (up to 7 seconds in the Zero, was less than 200ms before) due to the Mavproxy process using about 70% of CPU time.. When I kill the Mavproxy process, the latency goes to normal again. 
The thing is that I need Mavproxy for just relaying the telemetry. I have read in other forums that most of the CPU time is spent in parsing the mavlink packets, but I guess that I don't need parsing for this application. 
I would like to know if the parsing (or any other cpu intensive code) could be disabled with an easy modification of the Python code, which I haven't been able to figure it out. 
I found easy to disable the code to log the mavlink stream on disk, just putting a "return" in the first line of the "log_writer" function, and the CPU usage reduced to about 60%, but not enough.
Any help with this issue will be highly appreciated.

I have also tried using netcat or socat linux command to just connect the serial port to UDP packets, but for some reason, the telemetry is received but many mavlink messages are lost (the quality of the UDP link is about 30% according to mission planner when using netcat or socat, but 100% with no packet loss when using mavproxy).

Thankyou in advance for your help. Best regards!
Adolfo.

You need to be a member of diydrones to add comments!

Join diydrones

Email me when people reply –

Replies

  • Hi Adolfo,

    I have added the sleep in rc.local. In my case I put the 20 in sleep. The serial2udp.py worked well.

    Thanks.

    Best regards,

    Robert

    Adolfo Cobo said:

    Hi Robert,

     you cannot remove the "python" part because both mavproxy.py  and serial2udp.py are python scripts and need to be parsed by the python interpreter. If you remove "python", the script is interpreted by the shell and that is the reason for al the errors.

    In my case, I needed to add a "sleep 30" in rc.local before the call to serial2udp.py, because network stack and wifi connection was not ready and the script ended with error. That could be also your problem, that the network is not yet ready. a delay of about 30 seconds could solve it.

    good luck

  • Check out cmavnode or mavlink-router, both are c or c++ programs that use far less cpu than mavproxy, if all you want is simple relaying of mavlink messages.

  • Hi Robert,

     you cannot remove the "python" part because both mavproxy.py  and serial2udp.py are python scripts and need to be parsed by the python interpreter. If you remove "python", the script is interpreted by the shell and that is the reason for al the errors.

    In my case, I needed to add a "sleep 30" in rc.local before the call to serial2udp.py, because network stack and wifi connection was not ready and the script ended with error. That could be also your problem, that the network is not yet ready. a delay of about 30 seconds could solve it.

    good luck!

    Robert Shen said:

    Hi Adolfo,

    When I run serial2udp.py by manual, the program run better with pi zero. the command is following:

    pi@raspberrypi_z0:~ $ screen -d -m -s /bin/bash python /home/pi/serial2udp.py /dev/ttyAMA0 172.16.1.55 14550

    Reading from serial port: /dev/ttyAMA0 to...

    ['172.16.1.55']

    But when I put this line in the rc.local ( like mavproxy.py for auto run ), it was fail to run so that I could not find it in the task list. How do you make it auto run? I added the following line to the rc.local file:

    (
    date
    echo $PATH
    export PATH
    cd /home/pi
    tvservice -o
    raspivid -n -w 1080 -h 720 -b 10000000 -fps 30 -t 0 -o - | gst-launch-1.0 -v fdsrc ! h264parse ! rtph264pay config-interval=10 pt=96 ! udpsink host=172.16.1.55 port=5600 &
    #screen -d -m -s /bin/bash mavproxy.py --master tcp:172.16.1.62:5760 --out=udp:172.16.1.70:14550 --out=udp:172.16.1.55:14550
    screen -d -m -s /bin/bash python /home/pi/serial2udp.py /dev/ttyAMA0 172.16.1.55 14550
    ) > /tmp/gstreamer.log 2>&1

    And I do not know the Python in detail. Like Mavproxy.py, when I run the serial2udp.py drectly ( not add python in head ) I got the error:

    pi@raspberrypi_z0:~ $ ./serial2udp.py /dev/ttyAMA0 172.16.1.55 14550
    ./serial2udp.py: line 6: $'\r': command not found
    ./serial2udp.py: line 7: import: command not found
    ./serial2udp.py: line 8: import: command not found
    ./serial2udp.py: line 9: import: command not found
    ./serial2udp.py: line 10: import: command not found
    ./serial2udp.py: line 11: import: command not found
    ./serial2udp.py: line 12: $'\r': command not found
    ./serial2udp.py: line 13: syntax error near unexpected token `('
    '/serial2udp.py: line 13: `so = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    pi@raspberrypi_z0:~ $

    Any way I appreciate your share!

    Best regards,

    Robert 

  • Hi Adolfo,

    When I run serial2udp.py by manual, the program run better with pi zero. the command is following:

    pi@raspberrypi_z0:~ $ screen -d -m -s /bin/bash python /home/pi/serial2udp.py /dev/ttyAMA0 172.16.1.55 14550

    Reading from serial port: /dev/ttyAMA0 to...

    ['172.16.1.55']

    But when I put this line in the rc.local ( like mavproxy.py for auto run ), it was fail to run so that I could not find it in the task list. How do you make it auto run? I added the following line to the rc.local file:

    (
    date
    echo $PATH
    export PATH
    cd /home/pi
    tvservice -o
    raspivid -n -w 1080 -h 720 -b 10000000 -fps 30 -t 0 -o - | gst-launch-1.0 -v fdsrc ! h264parse ! rtph264pay config-interval=10 pt=96 ! udpsink host=172.16.1.55 port=5600 &
    #screen -d -m -s /bin/bash mavproxy.py --master tcp:172.16.1.62:5760 --out=udp:172.16.1.70:14550 --out=udp:172.16.1.55:14550
    screen -d -m -s /bin/bash python /home/pi/serial2udp.py /dev/ttyAMA0 172.16.1.55 14550
    ) > /tmp/gstreamer.log 2>&1

    And I do not know the Python in detail. Like Mavproxy.py, when I run the serial2udp.py drectly ( not add python in head ) I got the error:

    pi@raspberrypi_z0:~ $ ./serial2udp.py /dev/ttyAMA0 172.16.1.55 14550
    ./serial2udp.py: line 6: $'\r': command not found
    ./serial2udp.py: line 7: import: command not found
    ./serial2udp.py: line 8: import: command not found
    ./serial2udp.py: line 9: import: command not found
    ./serial2udp.py: line 10: import: command not found
    ./serial2udp.py: line 11: import: command not found
    ./serial2udp.py: line 12: $'\r': command not found
    ./serial2udp.py: line 13: syntax error near unexpected token `('
    '/serial2udp.py: line 13: `so = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    pi@raspberrypi_z0:~ $

    Any way I appreciate your share!

    Best regards,

    Robert 

  • Hi Adolfo,

    My usage of Mavproxy is the same as yours. Thank you for your share. I will test it and give the feedback.

    Best regards!

    Robert
  • Hi Robert,

      I am replying from memory, but I think that I just put a "return" in this piece of code of mavproxy.py:

    def log_writer():
    '''log writing thread'''
    return
    while True:

    However, CPU usage reduction was small.

    At the end, instead of using mavproxy, I adapted a piece of python code to relay the serial input from the autopilot to a UPD client, parsing the mavlink serial stream to send only one mavlink packet in every UDP packet. _I discovered that this was needed for the ground station to receive Ok the mavlink stream from an UDP port.

    You can find attached the python code to this message. I am using it sucesfully in a raspberry pi zero with les than 20% CPU usage.

    Regards!

     Adolfo.

    serial2udp.py

  • Hi Adolfo,

    I met the same problem. Could you advise me how to put "return", which file involved.

    Many thanks.

    Robert
This reply was deleted.

Activity