I’m working on a project where I have a Python script running on my Ground Control Station (GCS) and I need to send the results of this script to my ArduPilot flight controller. I’m currently using Mission Planner as my GCS software.
After researching different methods, I believe using pymavlink is the most suitable approach. I’ve started with code similar to this:
import time
from pymavlink import mavutil
# Connect to the autopilot
master = mavutil.mavlink_connection("com5", 115200)
master.wait_heartbeat()
# Data to send
data = [5, 30, 80, 120]
names = ['value6', 'value7', 'value8', 'value9']
while 1:
# Send data using NAMED_VALUE_FLOAT
for i in range(len(data)):
master.mav.named_value_float_send(10, names[i].encode("utf-8"),data[i])
time.sleep(1)
print("Hi")
master.close()
where COM5 represents the serial port connected to the Autopilot, which is also used by Mission Planner.
However, I’m facing an issue: I can’t seem to connect both Mission Planner and my Python script to the Autopilot simultaneously.
The primary objective of this project is to establish a real-time data link between the PC running Mission Planner and the Autopilot using python script. This involves transmitting a few integer variables from the PC to the Autopilot while maintaining an active connection between Mission Planner and the Autopilot.
I would greatly appreciate any advice or suggestions on how to achieve this integration effectively.
I am working on something similar, but I am not an expert. I believe it is not possible to have a simultaneous connection for both using just one UART channel or one modem.
It depends what you want to achieve, in my case I want the MP just to display the position of the drone on map, and all other data would be displayed on a dedicated GS written in python.
Basically, what you have to do is in your python program is to collect all the data you want to be displayed on the MP (you have to send command which requests that cerrtain data like GPS, ATTITUDE, etc, are broadcast by the FC at certain intervals, then read that data using python, and then create a connection with MP through which the data will be forwarded to MP.
Now if you want unlimited connectivity, i.e. all the functions of the MP, and bidirectional communication, like for reading logs, setting the waypoints, etc, you would have to program explicitly forwarding of each of these commands and the data. It is not too complicated, but not too easy.
In the PC, alongside the mission planner GCS. I have a Python script that implements image processing to detect targets and calculate their coordinates within the frame.
The Autopilot has a LUA script that will handle the received data and convert it into control commands. I have no issues with the LUA script; its functionality is clear to me.
The data frame consists of approximately 8 integer variables. I aim to send this data at a rate of 5 times per second without affecting Mission Planner data transmission.
Basically, the same as I said. You have to program a data passthrough hub in your python program. FC <> Your python <> MP. It could be easier than I think, because you do not really to decode the data coming from FC. So everything you get fro FC, you resend to MP. Everything which comes from MP is resend to FC. AND You inject in that stream your data.
The other way of doing it is to set two serial channels, with two modems. One modem would be connected to MP, and the other to your python program.
you can use mavproxy to connect with FC and send out 2 ports: 1 for Mission Planner, 1 for pymavlink
e.g. mavproxy --master=/dev/ttyUSB0 --baudrate=57600 --out=udp:127.0.0.1:14550 --out=udp:127.0.0.1:14551
After successfully connecting Mission Planner to the autopilot via one UDP port, I proceeded to attempt to transmit data from my Python script to the autopilot utilizing the second UDP port. While the variable ‘MAV_torna7’ appears in Mission Planner’s Quick Panel, its value consistently remains at 0. However I can see the correct value in Mavlink inspector.
the python code:
from pymavlink import mavutil
import time
mavlink_connection_string = "udpout:127.0.0.1:14551"
mav = mavutil.mavlink_connection(mavlink_connection_string)
def send_named_value_float(mav_, name, value):
# Get the time_boot_ms as the time difference since the first heartbeat received
time_boot_ms = int((time.time() - mav_.start_time) * 1000)
# Ensure the name is exactly 10 bytes long
encoded_name = name.encode('ascii').ljust(10, b'\0')
mav_.mav.named_value_float_send(time_boot_ms, encoded_name, value)
def main():
try:
while (1):
# Send the NAMED_VALUE_FLOAT message
send_named_value_float(mav, 'torna7', 7)
print("send ")
time.sleep(0.2) # Wait for 0.5 seconds before sending the next message
except KeyboardInterrupt:
# Handle any cleanup or resource releasing if necessary
print("Interrupted by user, stopping message sending.")
main()