Skip to the content
FixTheRobot Explore Robotics / UAV / Module 6 / M6-T4

UAV Systems Engineering · Module 6

M6-T4: PX4 modules and communication

uORB is the nervous system of PX4. Learn to read it and you can see what every module believes.

  • Lesson 4 of 16
  • UAV Software and Flight-Controller Integration
  • Implementation-specific
  • About 6 minutes to read

Every signal in PX4 is a uORB topic: sensor data, estimates, setpoints, status flags, actuator outputs. Understanding publish/subscribe semantics (latest value, queues, update rates) explains a surprising number of subtle bugs, such as missed events and stale data.

Learning objectives

After this lesson, you should be able to:

  • Explain publish/subscribe semantics in uORB, including the latest-value model and queued topics.
  • Read a topic definition (.msg file) and map it to ROS 2 messages.
  • Use listener, uorb top and the logger to inspect a running vehicle.
  • Identify topics that carry events, and why their queue depth matters.

Conceptual explanation

Implementation-specific uORB semantics are described in the PX4 documentation. Topic names, fields and queue depths vary between releases; the message definitions live in the msg/ directory of the PX4 repository for your version.

uORB (micro Object Request Broker) is PX4’s internal publish/subscribe middleware. A topic has a typed definition (a .msg file), any number of publishers (usually one) and any number of subscribers. Key semantics:

  • Latest value: by default a subscriber reads the most recent message; if the publisher wrote twice between reads, the first is overwritten and lost.
  • Independent subscribers: each tracks its own “last seen” position and can check for updates or block until one arrives.
  • Queues: topics that carry events (for example commands) are declared with a queue depth greater than one so that bursts are not lost.
  • Timestamps: every message carries a microsecond timestamp in the vehicle’s time base; some also carry a sample timestamp for the underlying measurement.
uORB publish and subscribeA publisher writes the latest message to a topic; every subscriber has its own read position and can be woken on new data or poll. Topics can have a queue depth greater than one for events that must not be lost.Publisherekf2uORB topicvehicle_local_positionSubscriber Amc_pos_controlSubscriber BloggerSubscriber Cmavlink / ddsOne publisher, many independent subscribers, no direct coupling.
One topic, many subscribers.

Modules are started by the startup scripts (the airframe configuration and rc scripts), run as tasks or work-queue items, and can be inspected with the console (module status for most modules, top for task load).

Animation of publish and subscribe semantics. A publisher emits messages in bursts on a timeline; a subscriber reads at fixed intervals. On a topic with latest-value semantics the subscriber only sees the newest message of each burst and the earlier ones are lost, shown by crossed-out markers; on a topic with a queue of depth four it receives every message of a burst. Counters show the messages lost on each.
A uORB subscriber reads the latest message; messages published between two reads overwrite each other. Topics carrying events (commands) are declared with a queue depth greater than one so that bursts survive. Toy model with random bursts, not PX4 code; reads every 0.5 s. (Looping, about 6 seconds; drawn and computed for this course with illustrative values.)

Engineering intuition

uORB is a bulletin board, not a mailbox. A bulletin board shows the latest notice; people reading it twice see the same notice. If two notices are pinned between visits, the earlier is gone. That is perfect for states (the current position) and dangerous for events (a command to disarm). Events therefore use a queue.

The corollary for companion-computer integration: the ROS 2 side sees topics through the DDS bridge, which applies its own QoS. A “reliable, keep-last-1” subscription has the bulletin-board semantics too; ask whether each topic you use is a state or an event.

Mathematical formulation

For a topic published at rate fpf_{p} and a subscriber that samples at fsf_{s} (polling), the fraction of messages seen by a latest-value subscriber is min⁡(1, fs/fp)\min (1,\,f_{s}/f_{p}), and for an uncorrelated sample time the data age at read time is uniformly distributed on [0, 1/fp][0,\,1/f_{p}]:

Latest-value sampling
seen fraction=min⁡ ⁣(1, fsfp)\text{seen fraction} = \min\!\left(1,\ \frac{f_s}{f_p}\right)
mean age=12fp,max age=1fp\text{mean age} = \frac{1}{2 f_p}, \qquad \text{max age} = \frac{1}{f_p}

With a queue of depth qq a burst of up to qq messages between reads is preserved. If events arrive as a Poisson process with rate λ\lambda and the subscriber reads every TT seconds, the probability of losing at least one event with q=1q=1 is 1−e−λT−λT e−λT1-e^{-\lambda T}-\lambda T\,e^{-\lambda T} (more than one arrival in an interval) which for λT=0.5\lambda T=0.5 is about 9 %; with q=4q=4 it falls below 0.02 %. This is a toy model of why events use queues; the real depths are set per topic in the definition.

fpf_{p}, fsf_{s}
publish and sample rates (Hz).
qq
queue depth of the topic.
λ\lambda
event arrival rate (1/s).

Architecture and data flow

Within PX4: drivers and modules publish; the logger subscribes to a configured set of topics and writes the ULog; the MAVLink module subscribes to topics to build telemetry messages and publishes topics from received messages (for example commands); the uXRCE-DDS client subscribes to or publishes the topics listed in its configuration. The set of topics visible to ROS 2 is therefore a configuration, not automatic. See the uXRCE-DDS lesson for the mapping.

Real-world UAV applications

  • Inspecting internal state during bench tests with listener and uorb top.
  • Choosing the topics to log for an experiment.
  • Writing a custom PX4 module that publishes diagnostics.
  • Diagnosing missed commands and stale data between modules.

Implementation example

This runs as shown. A toy model of latest-value and queued topics, not PX4 code, that reproduces the loss probability from the maths section by simulation and shows the benefit of a queue.

import numpy as np
rng = np.random.default_rng(3)

def lost_fraction(lam, T, q, trials=200000):
    # events arrive as a Poisson process; the subscriber reads every T seconds and sees at most q events per interval
    n = rng.poisson(lam * T, trials)
    lost = np.maximum(n - q, 0).sum(); return lost / max(n.sum(), 1)
def p_more_than_one(lam, T): return 1 - np.exp(-lam * T) * (1 + lam * T)
print(f"P(more than 1 event in an interval), lambda T = 0.5: {p_more_than_one(1.0, 0.5):.3f}")
for q in (1, 2, 4, 8): print(f"queue depth {q}: fraction of events lost {lost_fraction(1.0, 0.5, q):.5f}")
assert abs(p_more_than_one(1.0, 0.5) - 0.0902) < 1e-3
assert lost_fraction(1.0, 0.5, 1) > 10 * max(lost_fraction(1.0, 0.5, 4), 1e-6)
Latest-value (q = 1) loses events that a queue preserves. A toy model, not PX4 code.

On a real vehicle, the console commands are the tools:

uorb top -1                  # one snapshot of topic rates
listener sensor_combined -n 3 # three messages
listener vehicle_status       # a state topic
param show SDLOG_*            # what the logger records and when
Console commands to inspect topics (output format varies by release).

Common engineering mistakes

Using a state topic as an event

An overwritten message is lost; use a queued topic for events.

Assuming a topic is published at a constant rate

Some topics publish on change only; check with uorb top.

Confusing timestamp and timestamp_sample

The latter is the measurement time; use it for fusion.

Logging too few topics

The cause of a failure is often in a topic nobody logged.

Logging everything at full rate on a slow card

Dropouts in the log; select profiles and check log health.

Failure modes

Failure modes, symptoms and causes
Failure modeHow it shows upLikely cause
Missed commandA one-time command never acted onOverwritten in a queue-1 topic or not subscribed during the burst
Stale data usedController reacts to old stateSubscriber checks update flag incorrectly or publisher stopped
Log gapsHoles in the flight logLogging bandwidth exceeds card write rate
No data on the companionROS 2 topic emptyTopic not in the uXRCE-DDS configuration

Debugging approach

  1. Use uorb top to see whether a topic is publishing and at what rate.
  2. Check logger status for dropouts.
  3. Look at the .msg definition for queue depth and fields.
  4. Compare timestamps between topics to find stale or delayed data.

Practical exercises

  1. List five topics in your PX4 version and classify each as state or event, from its definition.
  2. Compute the sampling age for a 100 Hz topic polled at 30 Hz.
  3. Decide which topics to log for a VIO integration test and justify each.
  4. In SITL, measure the rate of ten topics with uorb top and tabulate them.

Interview questions

Write an answer in your own words, then reveal the model answer. Nothing is sent anywhere.

Question 1

What are the semantics of a uORB topic?

Model answer

Typed publish/subscribe with latest-value semantics by default: subscribers track their own position, and unread messages are overwritten unless the topic has a queue depth above one.

Question 2

Why do events need queued topics?

Model answer

With latest-value semantics a burst between reads overwrites earlier messages and events are silently lost; a queue preserves up to qq.

Question 3

How would you find out what the estimator publishes and how fast?

Model answer

Use uorb top for the rates, listener to view messages, and the .msg definition for fields; the logger records them for post-flight analysis.

References and further reading

Primary papers, official documentation and standards. Each claim above that is specific to a tool or version points here.

What’s next

Mark this lesson

Saved in this browser and synced to your account when you are signed in.

Next lesson

M6-T5: PX4 state estimation and EKF2

Describe PX4's EKF2 estimator, its fusion sources and the parameters that select them, and read its status and innovation outputs.