Repository navigation
feat(autotune): draw the plots with pyqtgraph - #59
Merged
Merged
Conversation
A gain change took about 1.4 s: matplotlib redrew the general figure twice per update and recomputed its constrained layout each time. The general tab now creates its pyqtgraph items once and only updates their data, which brings an update down to about 0.8 s; the rest is the robustness tab, still on matplotlib, and the control math. The plots use the light dataviz palette and keep the user's zoom across updates; a double-click restores the default range. The Bode magnitude and phase share their frequency axis and are drawn with 500 points instead of 40. Time and frequency plots show a crosshair readout. The fit metrics and PID gain tests were never added to the repository: add them along with tests of the plotted data. Windows left open segfault when garbage collected during a later paint, so the tests now close them.
The robustness figure was cleared, replotted and laid out again on every gain change. Its pyqtgraph items are now created once, which brings a gain change from about 0.8 s down to about 0.3 s; what is left is the computation of the margins and of the root locus. The sensitivity plot shares its frequency range with the Bode plots of the general tab. The views are kept equal by range rather than with setXLink, which lines views up by screen position and would offset plots that sit in different tabs over the same area.
Input and output were drawn on twin y-axes of one matplotlib plot. They are now two stacked plots sharing the time axis, each with its own scale. A left drag draws the selected range as SpanSelector did, and the selection band on either plot can then be moved or resized; the two bands stay in sync. The wheel zooms time only, within the log span, as the custom matplotlib zoom did.
The step responses of all the windows are drawn as a single curve broken between windows, instead of one matplotlib line per window. plot_step_responses, whose only caller passed its own axes, is folded into the window.
Document the plot helpers, the new plot tests and the reason for the window-closing test fixture. The isort command now passes the Black profile, as the pre-commit hook does: without it, isort rewraps imports in a style the hook rejects.
The main window was a dialog box, and GNOME does not let a dialog maximize: snapping it to the top of the screen, double-clicking the title bar and Super+Up did nothing, and it had no maximize button. It is now shown as a normal top-level window.
Show the pyqtgraph windows: the main window, the robustness tab and the data selection, taken on quadrotor_sitl_jmavsim.ulg between 54 s and 62 s with the default preset. List pyqtgraph in the install commands.
ubuntu-latest moved to Ubuntu 26.04, which has no build of Python 3.10.12, so the job failed before checking anything. Take the latest 3.10 release instead, as the test workflows already do.
bresch
force-pushed
the
feat/autotune-pyqtgraph
branch
from
October 28, 2026 08:29
6830c37 to
df0a97b
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The GUI windows now draw their plots with pyqtgraph instead of matplotlib: the main window (General and Robustness tabs), the data selection and the PID analysis window. The command-line scripts (
closed_loop_sim.py,simulated_autotune.py) keep matplotlib.Display speed
Each tick of a gain slider recomputes the closed loop and redraws the plots. Median time per tick, measured on screen with the same model and window size:
Drawing now takes about 30 ms per tick, down from about 575 ms. The matplotlib version cleared and redrew every axes on each change. The pyqtgraph plots are built once, and a tick only replaces their data. The remaining ~166 ms is the control computation (stability, delay and disk margins, root locus), which this PR does not change.
Screenshots
Taken on
quadrotor_sitl_jmavsim.ulgbetween 54 s and 62 s, with the default preset (Rollrate).Other changes
Testing
test_plots.py,test_data_selection.pyandtest_pid_analysis.pycheck the data the plots show: curves, margins, legends, kept zoom, linked axes and range selection.test_fit_metrics.pyandtest_pid_gains.pyalready existed but were never committed. They are now part of the suite.