.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "api/gallery/control_systems/feedback/plot_01_watt_centrifugal_governor.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code or to run this example in your browser via JupyterLite. .. rst-class:: sphx-glr-example-title .. _sphx_glr_api_gallery_control_systems_feedback_plot_01_watt_centrifugal_governor.py: Watt's centrifugal governor and proportional droop ================================================== James Watt's flyball governor (1788) closed the steam valve as the engine sped up: the throttle moved *in proportion* to the speed error. Model the engine as :math:`J\dot\omega = \tau - b\omega - \tau_{load}` and the governor as :math:`\tau = K_p(\omega_{ref} - \omega)`, a proportional :class:`~engineeringkit.control_systems.PID`. A proportional governor holds speed far better than an open throttle, but it always leaves a steady *droop*, :math:`\Delta\omega = \tau_{load}/(b + K_p)`, which shrinks with gain but never vanishes. .. GENERATED FROM PYTHON SOURCE LINES 16-24 .. code-block:: Python import matplotlib.pyplot as plt import numpy as np from engineeringkit.control_systems import PID, dc_gain, feedback, step_response, transfer_function J, b = 2.0, 0.5 # inertia [kg m^2], friction [N m s] engine = transfer_function([1], [J, b]) # speed per unit torque .. GENERATED FROM PYTHON SOURCE LINES 25-30 Response to a sudden load ------------------------- The load torque enters at the plant input, so the speed disturbance is :math:`G/(1 + GC)`. .. GENERATED FROM PYTHON SOURCE LINES 30-46 .. code-block:: Python t = np.linspace(0, 40, 1601) load = 1.0 fig, ax = plt.subplots() for kp in [0.0, 2.0, 8.0, 32.0]: to_speed = feedback(engine, PID(kp).transfer_function()) if kp else engine _, dw = step_response(to_speed, t) droop = -load * dc_gain(to_speed) assert np.isclose(droop, -load / (b + kp)) assert np.isclose(-load * dw[-1], droop, rtol=1e-3) ax.plot(t, -load * dw, label=f"$K_p$ = {kp:g}: droop {droop:.3f} rad/s") print(f"K_p = {kp:5.1f}: steady speed change {droop:.4f} rad/s") ax.set(xlabel="time [s]", ylabel="speed change [rad/s]", title="Engine speed after a 1 N m load step") ax.legend() plt.show() .. image-sg:: /api/gallery/control_systems/feedback/images/sphx_glr_plot_01_watt_centrifugal_governor_001.png :alt: Engine speed after a 1 N m load step :srcset: /api/gallery/control_systems/feedback/images/sphx_glr_plot_01_watt_centrifugal_governor_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none K_p = 0.0: steady speed change -2.0000 rad/s K_p = 2.0: steady speed change -0.4000 rad/s K_p = 8.0: steady speed change -0.1176 rad/s K_p = 32.0: steady speed change -0.0308 rad/s .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.145 seconds) .. _sphx_glr_download_api_gallery_control_systems_feedback_plot_01_watt_centrifugal_governor.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: lite-badge .. image:: images/jupyterlite_badge_logo.svg :target: ../../../../lite/lab/index.html?path=api/gallery/control_systems/feedback/plot_01_watt_centrifugal_governor.ipynb :alt: Launch JupyterLite :width: 150 px .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_01_watt_centrifugal_governor.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_01_watt_centrifugal_governor.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_01_watt_centrifugal_governor.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_