ArduPilot Quadplane System Identification

Introduction and Inspiration:

System Identification is a quick and efficient way to create high fidelity models of an aircraft. It is a black box method that uses chirp injections into the control loop at various points to analyze the discrepancy between the input and output signal. When this data is collected, a transfer function can be derived through spectral analysis. This transfer function is an accurate representation of the plant portion of the control loop, so it will account for all of the aircraft dynamics. The process of system identification has been employed by fellow members of the ArduPilot community to create these high fidelity models. Specifically, these can be found here and here. We conducted a similar analysis as the aforementioned blog posts using Lua scripting to perform the chirp injections. Since System Identification mode is only available on copter and not quadplane this was a low development time effort for initial tests. This post will discuss the SITL test results, real flight test results, analysis procedures, and results.

Simulation:

The Lua script was tested using SITL before it was tested on a physical vehicle. It was working in SITL as expected. The injected chirp can be seen below.

Figure: Chirp Injection

It then had to be verified that the desired roll rate target matched the chirp injection. As seen below, the desired angular rate matched the setpoint.

Figure: Desired Rate versus Setpoint

Finally, it needed to be verified that the setpoint and the measured angular rate were similar. As seen in the figure below, there is a good correlation between the angular rate and the setpoint.

Figure: Measured Rate vs Setpoint

Flight Testing:

With strong results from SITL, we moved onto flight testing. All the flight tests were performed on a quadcopter running ArduPlane firmware, as a quadplane. Multiple trials were done along each axis of the inner loop controller each of which contained 8 independent injections. Optimal flight parameters were determined through flight testing. Also, the feedforward was disabled and the rate integrators were nearly zero prior to system identification beginning. The setpoint and desired roll were similar to the SITL testing shown above; the Lua script was working effectively. This can be seen in the following figure.

Figure: Desired Roll Rate versus Setpoint

However, the roll rate did not match the setpoint well. There is little correlation between the two. This can be seen in the following figure. This can be attributed to noise within the system or improper PID tuning.

Figure: Measured Roll Rate versus Setpoint

Analysis Methods:

Although we did not do this, it is suggested that only flights with a coherence of 0.6 or higher are used. Instead, all successful injections were utilized. These different injections were averaged to eliminate noise or interference in the system. Additionally, each of these tests were run through a low pass filter. Next, a fourth order transfer function was fitted to the data. We used both PyAircraftIden and Scipy curve fitting for transfer function determination. Each of the options were validated using simulated data of a spring mass damper system. Scipy curve fitting was more accurate with the spring transfer function; however, there was high amounts of variability in the flight test transfer function between the various trials. PyAircraftIden was selected for our final product because the variability across multiple trials was much lower. Only the trials with a cost function of less than 50 were used for averaging. The data was then validated in the time domain through a forced response comparison of the transfer function to the flight data. The PID controller was tuned using this transfer function and step responses of the new and old PID values were compared.

Results:

For the areas of high coherence (>=0.6), the transfer function fit the flight data highly accurately, but when the coherence was lower than the threshold the transfer function is very different from the flight data. This can be seen in the plot below. It should be noted that the top plot is the amplitude, the middle plot is the phase, and the bottom plot is the coherence.

Figure: Results of Pitch Rate Flight Test Data

As mentioned above, we also accepted the regions in which the coherence was not greater than 0.6. This lead to unstable transfer functions with real poles in the positive plane. This unstable transfer function was detrimental to the PID tuning discussed in the analysis section. When a closed loop PID controller was added to the derived transfer function, the system was unstable regardless of the gains. This can be seen in the following figure. This can be avoided by only using flight tests that possess a coherence of 0.6 or greater. We opted not to do this because more emphasis was placed on developing a modular system identification tool than deriving an actual transfer function.

Figure: Step Response with PID Controller

6 Likes

A great effort! Hopefully you’ll manage to condition your inputs and outputs to match well and root out any delay sources.

Very nice!

I’ve edited your post to place a copy of one of the chirp plots up top, as blog topics display better on the homepage when there is a leading image. If you wish to replace it with a graphic you feel is more representative of the content, edit the post to include it before the text.

hello @Ncolasan. I’m working on a creating a web-based system identification toolkit for GSoC 2024. Its based on pyaircraftiden and can be used to find statespace or tf models from flight logs. You can check it out here GSoC24: All in one system identification toolkit for ardupilot (Update). I’d love if you can try it out and suggest changes that can be made to make it more user friendly