The application responsible for multicopter position control exists in “Firmware/src/modules/mc_pos_control”. I will describe what I understand about this application as much as I can in this blog.
Start
The application is started by the script “rc.mc_apps” in “Firmware/ROMFS/px4fmu_common/init.d”. The script itself is called by the main starting script “rcS” at line 761. Since “rc.mc_apps” is a very short script, I will paste it here for convenience:
As can be seen, the “mc_pos_control” application is started by the script at line 34. Interestingly, there are three attitude and position estimator group, the first one is INAV (inertial navigation); second one is LPE (local position estimator); thrid one is EKF (extended Kalman filter). The script sets “SYS_MC_EST_GROUP” 0 by default, (in “Firmware/src/modules/systemlib/system_params.c” at line 107), hence the INAV estimator group will be used.
Call Hierarchy
Here is an overview of how the function “mc_pos_control_main.cpp” flows, all functions have “MulticopterPositionControl::” prefix:
- line 2095: function “start()” is called when the application is started
- line 2104: function “task_main_trampoline()” is called by “start()”
- line 714: seems like “task_main_trampoline()” is only used to access the function “:task_main()”
- line 1184: function “task_main()” begins, subscribes a bunch of topics, enter a while loop on line 1233
- line 1344: function “control_manual()” is called by function “task_main()” if in manual modes
- line 797: function “control_manual()” starts
- line 1349: function “control_offboard()” is called by function “task_main()” if in offboard modes
- line 896: function “control_offboard()” starts
- line 1354: function “control_auto()” is called by function”task_main()” if in auto modes
- line 975″ function “control_auto()” starts
- line 1344: function “control_manual()” is called by function “task_main()” if in manual modes
- line 1577-1582: function “task_main()” publishes and advertises “vehicle_global_velocity_setpoint”*
- line 1934-1940: function “task_main()” publishes and advertises “vehicle_local_position_setpoint”
- line 2076-2081: function “task_main()” publishes and advertises “_attitude_setpoint_id”*
*No mathematical manipulations on these topics.
- poll_subscriptions(): called every loop to update topics
- update_ref(): called every loop to update position reference
- reset_pos_sp(): reset position setpoint to current position, called when position controller is disabled, or when landed, or on arming etc.
- reset_alt_sp(): reset altitude setpoint to current altitude, called in similar fashion as “reset_pos_sp”
- limit_pos_sp_offset(): if position setpoint is too far from current position, this function will scale the setpoint so that it is closer
Interestingly, “control_update” and “select_alt” are declared but never used in this application, need further investigation.
Appendix
What is going on in task_main?
If you see ?? it means I don’t know what this line is doing, please fill in.
- 1187-1201: subscribe to topics
- 1204: update parameters
- 1207: make sure you are telling PX4 vehicle is not armed
- 1210: orb_copy vehicle status if orb subscriptions are updated
- 1212-1216: initialize some boolean variables
- 1218: hrt_abstime is a high-resolution timer object (src/drivers/drv_hrt.h), set t_prev =0, used on 1253
- 1220-1221: ??
- 1224-1225: ??
- 1228-1231: set up poll topic, fd stands for file descriptor
- 1233: enter while loop, while _task_should_exit is false, this will be set false when the destructor is called
- 1234-1250: getting data and parameters
- 1252: hrt_abstime again, this time it is setting t = hrt_absolute time(), an absolute time after system startup
- 1253: calculate dt, is equal to a millionth of a loop run time, or 0 for the first loop, declared on 1218
- 1259-1267: reset all setpoints as the vehicle gets armed
- 1269-1275: VTOL stuff
- 1278: change was_armed to the arming state now, will be used on 1259 in the next loop
- 1285-1316:
- 1287-1298: put current local xyz position into _pos
- 1300-1311: put current local xyz velocity into _vel
- 1313-1315: calculate velocity derivative error using object _vel_x_deriv.update(negative _vel), put into _vel_err_d
- 1320-1326: if flight mode does not require position/altitude hold, set the corresponding flags to false
- 1328-1942: if you need any position control, run these
- 1342-1355: control source switch, can be manual, offboard or auto
- 1357-1364: vtol stuff
- 1366-1940: ??
- 1942-1953: if you don’t need position or altitude control, skip 1328-1942, and reset all setpoints, and store last velocity
- 1955-2056: this part of the code generate attitude setpoint from manual controls
- 1958-1962: reset yaw setpoints to current position if needed
- 1964-1984: if on the ground, yaw is untouched
- 1986-1990: control roll and pitch directly if no aiding velocity controller is active
- 1992-2001: control throttle directly if no climb rate controller is active
- 2005-2049: ??
- 2051-2055: copy quaternion setpoint to attitude setpoint topic
- 2057-2060: if manual control and attitude control are not enabled, skip 1955-2056, and reset yaw setpoints
- 2065-2082: publish attitude setpoints
- 2092: while loop ends