Create Mavlink message to inject in Cockpit

Hi All,

I’m trying to display a custom value in Cockpit as a NAMED_VALUE_FLOAT message sent from my surface computer with a Python script, but Cockpit never shows it in the MAVLink Inspector.

Is there any guide or reference to do it?

Thanks in advance

There’s a chance the message is arriving but as there are many other NAMED_VALUE_FLOAT messages incoming, you never see yours.

An easier way to debug that is opening Menu>Tools>DataLake, searching for NAMED_VALUE_FLOAT and checking if your variable is there.

Please consider the python script is located on the topside PC . So i’m attempting to inject it directly into Cockpit. The Test script is the following but after i tried i’m unable to locate the paramenter inside the datalake:

#!/usr/bin/env python3
from pymavlink import mavutil
import time

# Try sending directly to BlueOS telemetry ports
TARGET_IPS = [
    ("udpout:192.168.2.2:14550", "Main Cockpit port"),
    ("udpout:192.168.2.2:14552", "Alternate telemetry"),
    ("udpout:192.168.2.2:14600", "Extra test port")
]

for conn, label in TARGET_IPS:
    print(f"\n[TRY] Sending to {conn} ({label})")
    try:
        m = mavutil.mavlink_connection(conn, source_system=245, source_component=191)
        for i in range(5):
            value = -0.812 + 0.001 * i
            m.mav.heartbeat_send(18, 8, 0, 0, 4)
            m.mav.named_value_float_send(int(time.time()), b"CP_VOLT\x00\x00\x00", value)
            print(f" → Sent CP_VOLT={value:.3f}")
            time.sleep(1)
        m.close()
    except Exception as e:
        print(f"[ERR] {e}")

Oh, ok, this changes things a little bit!

We didn’t merge yet the consumption from MAVLink sources other than the main vehicle. Coincidently I was working on that during last week and the PR is open for review. I would ask you to test it from those binaries, which also includes some modifications on Menu>Tools>DataLake to make it easier to find your data.

To enable it, go to Menu>Settings>General on Cockpit and click “Enable Pirate Mode”. After that go to Menu>Settings>MAVLink and click “Enable DataLake variables from other systems”. Than you can use Menu>Tools>DataLake to find your data. It should be under /mavlink/system=X/component=Y being X and Y the MAVLink SystemID and ComponentID of your script.

1 Like

Hi Rafael,

thanks for the quick reply.

I’ll have a look asap and come back on it.

I’ve downloaded and installed the Version 1.17.0-beta.7 . Can you confirm the “Enable DataLake variables from other systems” is something that need to be enabled somewhere? I’ve not found anything related on it.

It’s not on Beta7. It’s in the binaries from the PR (not merged yet) that I mentioned in my previous comment: Improve reading names on the DataLake tools menu · bluerobotics/cockpit@cbd71a8 · GitHub

Hi Rafael,

can you confirm the Named_value_float should be injected to the cockpit PC address or to the blueos address? Here’s a simple demo script to inject a value but i’m not able to discover under the datalake inspector in cockpit. I confirm i’ve enabled the “Datalake variables from other systems” and added the NAMED_VALUE_FLOAT

#!/usr/bin/env python3
import time
from pymavlink import mavutil

# ---- CONFIG ----
TARGET_IP = "192.168.2.1"   
TARGET_PORT = 14550

SYSID = 251
COMPID = 191

NAME = "KP"                 
SEND_HZ = 2                 

# ----------------

def main():
    mav = mavutil.mavlink_connection(
        f"udpout:{TARGET_IP}:{TARGET_PORT}",
        source_system=SYSID,
        source_component=COMPID
    )

    print(f"Injecting {NAME} → system-{SYSID}-component-{COMPID}/{NAME}")

    t0 = time.monotonic()

    while True:
        now = time.monotonic()
        time_boot_ms = int((now - t0) * 1000)

        # DEMO VALUE: increasing counter
        kp = now - t0

        mav.mav.named_value_float_send(
            time_boot_ms,
            NAME.encode("ascii"),
            float(kp),
        )

        print(f"{NAME} = {kp:.2f}")
        time.sleep(1.0 / SEND_HZ)

if __name__ == "__main__":
    main()

Cockpit usually gets its MAVLink messages through a MAVLink2REST interface provided by BlueOS. It is technically possible to switch it over to using a UDP MAVLink connection, but doing so requires the whole connection to be switched to that (so you would also need to change where/how your vehicle is trying to connect, or lose access to it).

The easiest way to get messages to Cockpit is to send them through the existing MAVLink routing functionality on the vehicle, which you can do either by

  1. Connecting to a MAVLink Endpoint in BlueOS with your code, using a library like Pymavlink
    • This is closest to your current code
    • You may need to set up a new endpoint, if the others are already in use by other services
  2. Directly sending the message to the BlueOS MAVLink2REST interface, via a HTTP request
    • This avoids needing a MAVLink library, and the connections to and handling of data streams
    • There are several BlueOS services and Extensions that do this, because it uses substantially fewer resources if your program doesn’t actually need access to all the data in the MAVLink stream

For future reference, we’re also in the process of adding a means to just directly send data to Cockpit via HTTP requests, without MAVLink required at all.

Connecting to a MAVLink Endpoint in BlueOS with your code, using a library like Pymavlink.

Greetings!

Can you please help me with how to exactly use pymavlink to send a custom value from a python script running on the terminal of my Pi to Cockpit.
I am getting confused here with which IP and port to use.

i am very sorry if I sound dumb, I am a newbie :slight_smile: