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:
- The example code
- A very high level overview
- uORB
- 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.
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”:
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:
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:
Next, the application overwrites the attitude with raw accelerometer reading and publish these wrong attitudes to the topic “vehicle_attitude” on line 113:
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.
Incredible! Thank you Zihao !
Thank you Saif! I will post some more interesting tutorial soon, stay tuned.
Thank you! Your posts are very useful!
Hi Leo
Thanks for showing interests, more posts are on the way.
Amazing! I’ve been struggling to understand. Thanks a lot.
Thank you! I am glad my posts are useful.
Thank you very much. That was a very useful post. However, I am facing problem to follow the initial tutorial ”Writing an application”. I use Windows and when I try to do ”make px4fmu-v2_default”, I get some errors. Could someone help me?
Did you follow the official PX4 documentation on how to set up the environment? You need to install all of the packages, try follow the instructions again and try building the firmware again, if it still fails, post what error messages you get here. I don’t have experience with Windows but someone here must have.
I cannot make QGroundControl Plotting the data.
Do you know how to solve the issue?