If you have done Ardupilot or Arduino source code development, the first thing you do when you clone source code from Github is probably looking for the main function. This is exactly what I did. I spent about 2 weeks looking for a main function, hoping to stumble across something that initializes everything, execute commands in a loop. But nothing in the source code looks even close to this. PX4 has a much more powerful architecture, it doesn’t rely on a single main function. And here is how it works.

Note: Since this is a first look at PX4 architecture, everything will be very high level. For lower level architecture, please wait…


A quick summary:

  1. The example code
  2. A very high level overview
  3. uORB
  4. NSH initializing script

1. The example code

The “writing an application” tutorial on the official PX4 development guide is actually very useful, and it is definitely the first thing anybody should do. Follow the instructions on this page: Writing an Application

I will make extensive references to this example application in this and future logs.


2. A very high level overview

The best explanation is, PX4 works just like a Linux operating system. The system initializes according to the rules in a NSH script. The script will start all essential applications at boot, which I will talk about in section 4. Once the system is initialized, you can run many different small applications that are each dedicated for a small task. All of these applications are included in the “Firmware/src/modules” directory.

For a multicopter, some significant applications are “mc_att_control” (multicopter attitude control), “mc_pos_control” (multicopter position control), “attitude_estimator_q” (q stands for quaternion based). If you have a quick scan at the source code of each application, you will see they all use these functions somewhere in the code:
orb_copy(ORB_ID(xxx))
orb_subscribe(ORB_ID(xxx))
orb_advertise(ORB_ID(xxx),&xxx)

This is the definitive feature that makes PX4 different to Ardupilot. The “orb” is actually “uORB”, which itself deserves a new section, in section 3. “uORB” will handle all the communications between applications, the communication messages are called “topics“, each topic usually contains relevant data in a structure. Applications can subscribe a topic from uORB, copy data within the topic, and use these data. The application can also modify these data and advertise to a topic, the data can then be published for other applications to subscribe and copy.


3. uORB

uORB stands for “micro Object Request Broker”. uORB handles messaging API used for inter-thread/inter-process communication. In simple words, if an application wants to communicate with another application, it has to go through uORB.

PX4 uORB

PX4 uORB

Using the “px4_simple_app” application as an example. The application wants to use some sensor data, hence on line 60, the application subscribes to the topic “sensor_combined”:

uorb_subscribe to topic sensor_combined

“orb_subscribe” to topic “sensor_combined”

Once the topic is subscribed, the application can use the “orb_copy” function to access the data. On line 103, the application copies sensor_combined topic data sensor_sub_fd  into a structure called raw:

orb_copy

“orb_copy” function to copy “sensor_sub_fd” within topic “sensor_combined” into a variable called “raw”

The application proceeds to print the accelerometer raw data on lines 104-107, which you can check if you connect your PX4 hardware to serial and run the example application.

For demonstration purpose, the example application then tries to overwrite the attitude roll, pitch and yaw with accelerometer raw data. Since attitude data exists in a different topic called “vehicle_attitude”, the application needs to first use “orb_advertise” function to let the uORB know it is trying to publish some new data into “vehicle_attitude”, on line 66:

"orb_advertise" topic "vehicle_attitude" and data in "att"

“orb_advertise” topic “vehicle_attitude” and data in “att”

Next, the application overwrites the attitude with raw accelerometer reading and publish these wrong attitudes to the topic “vehicle_attitude” on line 113:

"orb_publish" topic "vehicle_attitude" with data in "att"

“orb_publish” topic “vehicle_attitude” with data in “att”

If you run this application and watch the data analyzer plot in your ground station, you will see the attitude changes to accelerometer reading while the application is running.

A list of all available topics can be found in “Firmware/msg”.


4. NSH initializing script

The initializing script in PX4 can be considered the “main” function, as it initializes most of the parameters and starts all the essential applications when the system is booting up. You can find this script in “Firmware/ROMFS/px4fmu_common/init.d/rcS”.

The script is very well commented so you should figure out what each line is doing quite easily. For example, on line 65, the script starts uORB; on line 760, the script calls another script “rc,mc_apps” to start all multicopter related applications.

It is not necessary to understand what every line of the script is doing, but it is important to know that if you decide to write your own flight control application, you will need to tell PX4 to start your application here.