HW Arm HW Pendulum HW Satellite HW Mass HW Blockbeam HW VTOL

Introduction to Feedback Control

Using Design Studies

Randal W. Beard
with
Timothy W. McLain
Cammy Peterson
Marc Killpack

Revised: August 2025

© 2016 Randal W. Beard
All rights reserved.

This work may not be distributed and/or modified without written consent of the authors.

Preface

Does the world really need another introductory textbook on feedback control? For many years we have felt that the many high-quality textbooks that currently exist are more than sufficient. However, several years ago I, the first author (RWB), had an experience that changed my mind and the minds of my colleagues. I had just finished teaching the introductory feedback control course at BYU. I had a need for a new master’s student in my research group and hired one of the top students in the class. We had designed a gimbal system for a small unmanned air vehicle, and we needed a control system implemented on a microcontroller for the gimbal. I tasked this new master’s student to model the gimbal and design the control system. I was surprised by how much the student struggled with this task, especially understanding where to begin and how to model the gimbal. If I had given him a transfer function and asked him to design a PID controller, or if I had given him a state-space model and asked him to design an observer and controller for the system, he would not have had any difficulty. But he did not know how to do an end-to-end design that required developing models for the system, including physical constraints. It was this experience that convinced me that my current approach to teaching feedback control was inadequate.

The next time that I taught the course, rather than focusing on the theory of feedback design, I focused the lectures on the end-to-end design process. Accordingly, I spent significantly more time talking about the modeling process, adding several lectures on the Euler-Lagrange method. I also added several lectures on linearization about set points, and on developing linear models. When I taught feedback design methods, I focused on design specifications and the need to account for saturation, sensor noise, model uncertainty, and external disturbances on the system. Over the next several years, we developed several complete design studies and then used these design studies throughout the course to illustrate the material. That course reorganization and the realization that existing textbooks on feedback control did not fit the pedagogy were the genesis of this textbook.

Therefore, this textbook is unique in several ways. Most importantly, it is focused, in its organization, in its examples, and in its homework problems, on a particular, but fairly general, end-to-end design strategy and methodology. Topics were included in the book only if they aided in the design process. For example, the book does not include a chapter on the root locus (although it is discussed in an appendix). The second unique feature is that the examples and homework problems follow a small set of design studies throughout the book. The text provides complete worked examples for three design studies: a single-link robot arm, a pendulum on a cart, and a satellite attitude control problem. The homework problems parallel the examples with three additional design studies: a mass-spring-damper, a block sliding on a beam, and a planar vertical take-off and landing aircraft, similar to a quadrotor. A third unique feature of the book is that complete solutions to the three example design studies are provided in MATLAB/Simulink and Python at http://controlbook.byu.edu.

The design methodology culminates in computer code that implements the controllers. In the examples provided in the book, the computer code interacts with a simulation model of the plant composed of coupled nonlinear differential equations, rather than the physical plant. However, the example computer code is written in a way that can be directly implemented on a microcontroller, or other computing devices. We have used MATLAB/Simulink because many students are already familiar with these tools. But we also provide Python examples because Python is free of charge and therefore accessible to everyone, and because for many applications, Python can be used to implement the controller in hardware.

One criticism of the book might be that all of the design problems are mechanical systems, and that they are fairly similar to each other. The student may come away with the impression that feedback control and the design methods discussed in the book are only applicable to mechanical systems. Of course this is not true. The tools taught in the book are widely used in many applications including electrical power systems, disk drives, aerospace systems, chemical processing, biological systems, queueing systems, and many more. Although this book is focused on mechanical systems, we believe that the student who masters the material will be able to easily transition to other application domains. Mechanical systems, like those covered in this book, have a compelling pedagogical advantage because the control objectives are intuitive, and the behavior of the system can be easily visualized. Therefore, we feel that they offer the best setting for developing intuition behind feedback design.

We had two other motivations for writing this textbook. The first is the exorbitant prices currently being charged for textbooks. Accordingly, we are providing an electronic version of this book to students free of charge at http://controlbook.byu.edu. The book has required significant time and energy to develop, and so we hope that “free” does not equate to “low quality.” An Amazon version of the book is also available for those desiring a hard copy. Given the amount of high-quality open-source software, students may get the wrong impression about monetary compensation for technical work. Good work should be compensated. However, since our day jobs provide adequate financial remuneration, we ask to be compensated by your feedback about your educational experience with the book, including typos and other errors. This will allow us to update and improve the book. We also hope that you will understand that we will probably not be very responsive to email asking for help with the homework problems. Another motivation for writing the book is our observation that this generation of students seems to prefer learning through electronic resources. The book has therefore been written with the assumption that it will be studied electronically. Therefore, hyperlinks and other electronic aids are embedded throughout the text. We hope that these enhance the educational experience.

1 Introduction

Introduction

Overview

The objective of this book is to prepare the reader to design feedback control systems for dynamic systems and to lay the groundwork for further studies in the area. The design philosophy that we follow throughout the book is illustrated schematically in Fig. 1.1. The objective is to design a control system for the “Physical System” shown in Fig. 1.1. The physical system includes actuators like motors and propellers, and sensors like accelerometers, gyros, GPS, cameras, and pressure sensors. The first step in the design process is to model the physical system using nonlinear differential equations. While approximations and simplifications will be necessary at this step, the hope is to capture, in mathematics, all of the important characteristics of the physical system. While there are many different methods for developing the equations of motion of the physical systems, in this book we will introduce one specific method, the Euler-Lagrange method, that is applicable to a wide variety of mechanical systems. We will, for the most part, abstract the actuators to applied forces and torques on the system. Similarly, the sensors will be abstracted to general measurements of certain physical quantities like position and velocity. The resulting model is called the Simulation Model as shown in Fig. 1.1. In the design process, the simulation model is used for the high fidelity computer simulation of the physical system. Every control design will be tested thoroughly on the simulation model. However, the simulation model is only a mathematical approximation of the physical system, and simply because a design is effective on the simulation model, we should not assume that it will function properly on the physical system. Part I of the book introduces the Euler-Lagrange method and demonstrates how to derive simulation models for mechanical systems using this method.

The design process. Using principles of physics, the physical system is modeled mathematically, resulting in the simulation model. The simulation model is simplified to create design models that are used for the control design. The control design is then tested and debugged in simulation and finally implemented on the physical system.

1.1 Interactive Control Workflow

Click Figure 1.1

The diagram below is the same design-process figure, but the major regions are clickable. Select a region to see how that part of the workflow will be developed later in the book.

Control
design process diagram with physical system, simulation model, design
models, controller methods, testing, and implementation paths.

Disturbance experiment

Open-loop and feedback response to a disturbance

Choose when the disturbance appears and how large it is. The curves use a simple first-order plant model: open loop has no current output measurement, while feedback uses the measured output to drive the response back toward the desired value. The role of integral action in removing steady-state disturbance error is developed in Chapter 9, the PID system-type section.

A first-order plant comparison showing that open-loop operation remains shifted after a disturbance while feedback with integral action returns the output to the desired value. Disturbance response Open loop: command does not use the measured output Feedback: measured output helps reject the disturbance model: dy/dt = -a y + u + d; integral action is explained in the PID system-type section disturbance at t = 0.55 output remains shifted feedback returns to target

First-order disturbance comparison for dy/dt = -a y + u + d. Open-loop operation cannot correct the offset caused by a constant disturbance. The feedback curve includes the kind of accumulated-error effect discussed later in Chapter 9, the PID system-type section, so the output returns to the desired value after the transient.

The simulation model is typically nonlinear and high order and is too mathematically complex to be useful for control design. Therefore, to facilitate design, the simulation model is simplified and usually linearized to create lower-order design models. For any physical system, there may be multiple design models that capture certain aspects of the system that are important for a particular design. In this book we will introduce the two most common design models used for control systems analysis and design: transfer-function models and state-space models. In both cases we will linearize the system about a particular operating condition. The advantage of transfer function models is that they capture the frequency dependence of the input-output relationship in dynamic systems. The advantage of state-space models is that they are more intuitive and are better adapted to numerical implementation. Part II of the book shows how to linearize the equations of motion and how to create transfer function and state-space design models.

The next three parts, Part III–V, introduce three different control design methods. Part III shows how to design Proportional-Integral-Derivative (PID) controllers for second-order systems. The PID method is the most common control technique used in industry. It can be understood from both a time-domain and frequency-domain perspective. The advantage of PID is its simplicity in design and implementation and the fact that it can be used to achieve high performance for a surprising variety of systems. However, the disadvantage of PID control is that stability and performance can typically only be guaranteed for second-order systems. Therefore, Part III is focused exclusively on second-order systems.

In Part IV we introduce the observer-based control method. Observer-based methods can be thought of as a natural extension of PID controllers to higher-order systems. However, observer-based methods are much more general than PID and can be used to obtain higher performance. In addition, most observer-based techniques extend to nonlinear and time-varying systems. The disadvantages of observer-based methods are that they require a higher level of mathematical sophistication to understand and use, and they are primarily time-domain methods.

The final design technique, which is covered in Part V, is the loop shaping control design method. The loop shaping method is a frequency domain technique that explicitly addresses robustness of the system. The loop shaping method is also a natural extension of PID control to higher-order systems. One of the advantages of loop shaping techniques is that they can be used when only a frequency response model of the system is available.

The book is organized around several design studies. For each new concept that is introduced, we will apply that concept to three specific design problems. The design problems are introduced in the following three sections and include a single-link robot arm, a pendulum on a cart, and a simple satellite attitude control problem. The homework problems, which are provided in Part VI, will follow the same format with problems that are identical to those worked in the book, but they will be applied to different physical systems. Our hope is to illustrate the control design process with specific, easy-to-understand problems. We note, however, that the concepts introduced in this book are applicable to a much wider variety of problems than those illustrated in the book. We focus on mechanical systems, but a similar process (with the exception of the modeling section) can be followed for any system that can be modeled using ordinary differential equations. Examples include aerodynamic systems, electrical systems, chemical processes, large structures like buildings and bridges, biological feedback systems, economic systems, queuing systems, and many more.

1.2 Design-Study Preview

Choose a system and identify what control will need

These cards are a preview. At this point, focus only on the physical system: what can be actuated, what can be measured, and what limitation could matter later.

A. Single-link arm
Likely actuator
Motor torque at the joint.
Likely measurement
Arm angle and possibly angular velocity.
Physical limitation
Motor torque limits and gravity loading.
B. Pendulum on a cart
Likely actuator
Horizontal force on the cart.
Likely measurement
Cart position and pendulum angle.
Physical limitation
Limited track length and unstable pendulum motion.
C. Satellite attitude
Likely actuator
Applied torque from thrusters or reaction wheels.
Likely measurement
Attitude angle and angular rate.
Physical limitation
Flexible modes, actuator limits, and fuel or energy use.
D. Mass-spring-damper
Likely actuator
Applied force on the mass.
Likely measurement
Position and possibly velocity.
Physical limitation
Oscillation, damping, and force limits.
E. Block on beam
Likely actuator
Beam angle or torque applied to the beam.
Likely measurement
Block position and beam angle.
Physical limitation
Beam angle limits and rolling/sliding assumptions.
F. Planar VTOL
Likely actuator
Left and right rotor thrusts.
Likely measurement
Position, altitude, pitch angle, and rates.
Physical limitation
Rotor saturation, coupling between pitch and lateral motion, and gravity.

1.3 Design Studies

image

Figure 1.2 shows a single-link robot arm system. The robot arm has mass \(m\) and length \(\ell\). The angle of the robot is given by \(\theta\) as measured from horizontal to the ground. The angular speed of the arm is \(\dot{\theta}\). There is an applied torque \(\tau\) at the joint. There is also a damping (or viscous friction) torque that opposes the rotation of the joint and which can be modeled as \(-b\dot{\theta}\).

The actual physical parameters of the system are \(m=0.5\) kg, \(\ell=0.3\) m, \(g=9.8\) m/s\(^2\), \(b=0.01\) Nms. The torque is limited by \(\left|\tau\right|\leq 1\) Nm.

Design Study A orientation

Identify the robot-arm variables before starting the design sequence

This check is not a worked solution gate. It is a quick orientation to the coordinate, measured output, actuator, and physical limitation that appear throughout the single-link robot-arm design study.

Step 1. Configuration variable

Enter the generalized coordinate used for the configuration.

Step 2. Full state versus measured output

For later state-space chapters, identify the two state variables and the measured output used for this design study.

Step 3. Actuation and limitation

Identify the actuator input and one physical limitation that will matter during control design.

A.2 Kinetic energy.

A.3 Equations of motion.

A.4 Linearize equations of motion.

A.5 Transfer function model.

A.6 State-space model.

A.7 Pole placement using PD.

A.8 Second-order design.

A.9 Integrators and system type.

A.P.6 Root locus.

A.10 Digital PID.

A.11 Full state feedback.

A.12 Full state with integrator.

A.13 Observer based control.

A.14 Disturbance observer.

A.15 Frequency response.

A.16 Loop gain.

A.17 Stability margins.

A.18 Loopshaping design.

Note: The notation identifies the design configuration and the chapter in which it is used: Example A.4 refers to the application of approximations in Chapter 4 to linearize design configuration A. Similarly, Example A.P.6 refers to the root locus assignment associated with Appendix A.P.6.

1.3.2 Design Study: Pendulum on a Cart

image

Figure 1.3 shows the pendulum on a cart system, also called an inverted pendulum. The position of the cart measured from the origin is \(z\) and the linear speed of the cart is \(\dot{z}\). The angle of the pendulum from straight up is given by \(\theta\), and the angular velocity is \(\dot{\theta}\). The rod is of length \(\ell\), and has mass \(m_1\), and is approximated as being infinitely thin. The cart has mass \(m_2\). Gravity acts in the down direction. The only applied force is \(F\), which acts in the direction of \(z\). The cart slides on a frictionless surface, but air friction produces a damping force equal to \(-b\dot{z}\).

The physical constants are \(m_1=0.25\) kg, \(m_2=1.0\) kg, \(\ell=1.0\) m, \(g=9.8\) m/s\(^2\), \(b=0.05\) Ns. The force is limited by \(\left|F\right|\leq 5\) N.

Design Study B orientation

Identify the pendulum variables before starting the design sequence

This check is not a worked solution gate. It is a quick orientation to the variables, measurements, and limitations that appear throughout the pendulum-on-cart design study.

Step 1. Configuration variables

Enter the two generalized coordinates used for the configuration.

Step 2. Full state versus measured output

For later state-space chapters, identify the four state variables and the two measured outputs described in the design study.

Step 3. Actuation and limitation

Identify the single actuator and one physical limitation that will matter during control design.

B.2 Kinetic energy.

B.3 Equations of Motion.

B.4 Linearize equations of motion.

B.5 Transfer function model.

B.6 State-space model.

B.8 Successive loop closure.

B.9 Integrators and system type.

B.P.6 Root locus.

B.10 Digital PID.

B.11 Full state feedback.

B.12 Full state with integrator.

B.13 Observer based control.

B.14 Disturbance observer.

B.15 Frequency Response.

B.16 Loop gain.

B.17 Stability margins.

B.18 Loopshaping design.

1.3.3 Design Study: Satellite Attitude Control

Satellite with flexible solar panels.

Figure 1.4 shows a simplified version of a satellite with flexible solar panels. We will model the flexible panels using a rigid sheet with moment of inertia \(J_p\) connected to the main satellite body by a torsional compliant element with spring constant \(k\) and damping constant \(b\). The moment of inertia of the satellite is \(J_s\). The angle of the satellite body from the inertial reference is \(\theta\) and the angle of the panel from the inertial reference is denoted as \(\phi\). Thrusters are used to command an external torque of \(\tau\) about the axis of the satellite body.

The physical constants are \(J_s=5\) kg m\(^2\), \(J_p=1\) kg m\(^2\), \(k=0.1\) N m, \(b=0.05\) Nms. The torque is limited by \(\left|\tau\right|\leq 5\) Nm.

Design Study C guided orientation

Identify the satellite variables before starting the worked examples

The satellite has a rigid body and flexible panel. Before using the study in later chapters, check that you can distinguish the body attitude, panel attitude, relative panel deflection, and torque input.

Step 1: Configuration variables

Identify the three variables that fully describe the satellite and its deflection.

Step 2. Identify what the actuator directly changes

Step 3. Interpret no flexure

C.2 Kinetic energy.

C.3 Equations of motion.

C.4 Equilibria.

C.5 Transfer function model.

C.6 State-space model.

C.8 Successive loop closure.

C.9 Integrators and system type.

C.P.6 Root locus.

C.10 Digital PID.

C.11 Full state feedback.

C.12 Full state with integrator.

C.13 Observer based control.

C.14 Disturbance observer.

C.15 Frequency Response.

C.16 Loop gain.

C.17 Stability margins.

C.18 Loopshaping design.

1.4 Knowledge Check

Use these quick checks to test the Chapter 1 workflow vocabulary before moving on. The short-answer checks are intentionally limited to terms that can be graded reliably.

Q1. Design model

Which item best describes the role of a design model?

Q2. Value of feedback

Why is feedback useful?

Q3. Implementation

Which item is usually closest to implementation?

Q4. Disturbance response

A disturbance pushes the output away from the desired behavior. What information does a feedback system need in order to react?

Q5. Vocabulary

What is the name for using measured output to react to error?

Show solution

Answer: Feedback. Feedback uses measured output information to respond to error.

Q6. Model vocabulary

What kind of model is simplified for controller design?

Show solution

Answer: Design model. The simulation model is simplified into one or more design models.

Reflection Prompt

In one or two sentences, explain why the book separates modeling, design, implementation, and validation.

Show guidance

Guidance: A strong answer should mention that each step serves a different purpose and that success in simulation does not guarantee success on the physical system.

Q7. Model roles

A team has a detailed nonlinear simulator and a simpler linear model used to choose feedback gains. Which artifact is the design model?

Q8. Feedback information

A wind gust pushes an aircraft away from the commanded attitude. What information is essential for feedback to correct the error?

Part I

Simulation Models

To design efficient feedback control systems, we use mathematical models to understand the system, and then we design controllers that achieve the desired specifications. Developing suitable mathematical models is problem-specific and can be very complicated, requiring specialized knowledge. However, there are some well-known techniques for certain classes of systems. This book covers one general technique that is useful for a large class of rigid-body mechanical systems. The technique is known as the Euler-Lagrange method and requires a mathematical description of the kinetic and potential energy of the system, given its generalized position and velocity. The theory behind the Euler-Lagrange method is deep and well beyond the scope of this book. However, we will give a brief introduction that will enable the reader to apply Euler-Lagrange methods to a surprisingly large class of problems.

As motivation for the Euler-Lagrange equations, consider a particle of mass \(m\) in a gravity field, as shown in Fig. 1.5, where \(g\) is the force of gravity at sea level, \(f_a\) is an externally applied force, and the friction due to air resistance is modeled by a gain \(b\) times the velocity \(\dot{y}\).

Point mass in a gravity field.

Since all of the forces are in the vertical direction, the motion of the vehicle can be completely described by the vertical position of particle \(y(t)\). From Newton’s law, the equations of motion are \[\tag{1.1} m\ddot{y} = f_a-mg-b\dot{y},\] where dots over the variable will be used throughout the book to denote differentiation with respect to time, i.e., \(\dot{y}\stackrel{\triangle}{=}\frac{dy}{dt}\) and \(\ddot{y}\stackrel{\triangle}{=}\frac{d^2y}{dt^2}\). Rearranging 1.1 gives \[\tag{1.2} m\ddot{y} + mg = f_a -b\dot{y}.\] The kinetic energy for the particle is given by \(K(\dot{y})=\frac{1}{2}mv^2=\frac{1}{2}m\dot{y}^2\). The potential energy, which is induced by gravitational pull proportional to the distance from the center of the earth, is given by \(P(y)=P_0+mgy\), where \(P_0\) is the potential energy of the particle when \(y=0\). Note that if the velocity \(\dot{y}\) is thought of as independent of \(y\), then \[\frac{\partial K(\dot{y})}{\partial \dot{y}} = m\dot{y}\] and \[\frac{d}{dt}\left(\frac{\partial K(\dot{y})}{\partial \dot{y}}\right) = m\ddot{y}.\] Also note that \[\frac{\partial P(y)}{\partial y} = mg.\] Therefore, Equation 1.2 can be written as \[\tag{1.3} \frac{d}{dt}\left(\frac{\partial K(\dot{y})}{\partial \dot{y}}\right) + \frac{\partial P(y)}{\partial y} = f_a-b\dot{y}.\] Equation 1.3 is a particular form of the so-called Euler-Lagrange equation. The generalization to a more complicated system takes the form \[\tag{1.4} \frac{d}{dt}\left(\frac{\partial K(y,\dot{y})}{\partial \dot{y}}-\frac{\partial P(y)}{\partial \dot{y}}\right) - \left(\frac{\partial K(y,\dot{y})}{\partial y} - \frac{\partial P(y)}{\partial y}\right) = f_a-b\dot{y},\] which reduces to Equation 1.3 for our particular case since \(K\) is only a function of \(\dot{y}\). To simplify the notation, we define the so-called Lagrangian as \[L(y,\dot{y})\stackrel{\triangle}{=}K(y,\dot{y})-P(y),\] and write Equation 1.4 as \[\tag{1.5} \frac{d}{dt}\left(\frac{\partial L(y,\dot{y})}{\partial \dot{y}}\right) - \left(\frac{\partial L(y,\dot{y})}{\partial y}\right) = f_a-b\dot{y}.\] The position of the system can be generalized to both positions and angles, and the velocity can be generalized to both linear and angular velocities. Throughout the book we will use the notation \(\mathbf{q} = (q_1, q_2, \dots, q_n)^\top\) to denote the general configuration of the mechanical system that we are modeling. The vector \(\mathbf{q}\) is called the generalized-coordinate vector. The kinetic energy of the system is generally a function of both the generalized coordinates \(\mathbf{q}\) and the generalized velocity \(\dot{\mathbf{q}}\). Therefore, we denote the kinetic energy as \(K(\mathbf{q},\dot{\mathbf{q}})\). On the other hand, in this book we will only consider potential fields that are conservative and depend only on the configuration variable \(\mathbf{q}\). Under these assumptions, the general form of the Euler-Lagrange equations is given by \begin{align} \frac{d}{dt}\left(\frac{\partial L(\mathbf{q},\dot{\mathbf{q}})}{\partial \dot{q}_1}\right) - \frac{\partial L(\mathbf{q},\dot{\mathbf{q}})}{\partial q_1} &= \tau_1-b_{11} \dot{q}_1 - \cdots - b_{1n}\dot{q}_n \notag \\ \frac{d}{dt}\left(\frac{\partial L(\mathbf{q},\dot{\mathbf{q}})}{\partial \dot{q}_2}\right) - \frac{\partial L(\mathbf{q},\dot{\mathbf{q}})}{\partial q_2} &= \tau_2-b_{21} \dot{q}_1 - \cdots - b_{2n}\dot{q}_n \tag{1.6} \\ \vdots \\ \frac{d}{dt}\left(\frac{\partial L(\mathbf{q},\dot{\mathbf{q}})}{\partial \dot{q}_n}\right) - \frac{\partial L(\mathbf{q},\dot{\mathbf{q}})}{\partial q_n} &= \tau_n-b_{n1} \dot{q}_1 - \cdots - b_{nn}\dot{q}_n, \notag \end{align} where \(\tau_i\) are the generalized forces and torques that are applied to the system. Or in vector form we can write \[\tag{1.8} \frac{d}{dt}\left(\frac{\partial L(\mathbf{q},\dot{\mathbf{q}})}{\partial \dot{\mathbf{q}}}\right) - \frac{\partial L(\mathbf{q},\dot{\mathbf{q}})}{\partial \mathbf{q}} = \boldsymbol{\tau} -B \dot{\mathbf{q}},\] where \(B\) is a matrix with positive elements and \(\boldsymbol{\tau}=(\tau_1,\dots,\tau_n)^\top\) are the generalized forces. The Euler-Lagrange equation will be discussed in more detail in Chapter 6. However, before showing how to use Equation 1.8 to derive the equations of motion for practical systems, we need to show how to compute the kinetic and potential energy for general (holonomic) rigid body systems.

2 Kinetic Energy of Mechanical Systems

2.1 Theory

Consider a point mass with mass \(m\), traveling at velocity \(\mathbf{v}\), as shown in Fig. 2.1. If the velocity is resolved with respect to a coordinate axis, then \(\mathbf{v}=(v_x, v_y, v_z)^\top\). The kinetic energy of the point mass is given by \[\begin{aligned} K &= \frac{1}{2} m \left|\mathbf{v}\right|^2 \\ &= \frac{1}{2} m \mathbf{v}^\top \mathbf{v} \\ & = \frac{1}{2} m (v_x^2 + v_y^2 + v_z^2). \end{aligned}\]

Point mass moving at velocity \mathbf{v}.

Now consider two point masses as shown in Fig. 2.2.

Two constrained point masses spinning about a point on an adjoining axis.

The total kinetic energy of the system is given by summing the kinetic energy of each of the point masses as \[\tag{2.1} K = \frac{1}{2} m_1 \mathbf{v}_1^\top \mathbf{v}_1 + \frac{1}{2} m_2 \mathbf{v}_2^\top \mathbf{v}_2.\] If the two masses are connected by a massless rod and the particles are spinning about a point on the rod, as shown in Fig. 2.2, where the angular velocity vector \(\boldsymbol{\omega}\) points out of the page, and the magnitude is given by \(\dot{\theta}\), i.e., \(\boldsymbol{\omega}=(0, 0, \dot{\theta})^\top\), then from elementary physics, the velocity of point \(i\) is given by \[\mathbf{v}_i = \boldsymbol{\omega}\times\mathbf{p}_i,\] where in our case \(\mathbf{p}_1 = (L_1\cos\theta, L_1\sin\theta, 0)^\top\), and \(\mathbf{p}_2 = (-L_2\cos\theta, -L_2\sin\theta, 0)^\top\). Therefore \[\begin{aligned} \mathbf{v}_1 &= \begin{pmatrix} 0 \\ 0 \\ \dot{\theta}\end{pmatrix}\times\begin{pmatrix}L_1\cos\theta \\ L_1\sin\theta \\ 0\end{pmatrix} = \begin{pmatrix} -L_1\dot{\theta}\sin\theta \\ L_1\dot{\theta}\cos\theta \\ 0 \end{pmatrix} \\ \mathbf{v}_2 &= \begin{pmatrix} 0 \\ 0 \\ \dot{\theta} \end{pmatrix}\times\begin{pmatrix}-L_2\cos\theta \\ -L_2\sin\theta \\ 0\end{pmatrix} = \begin{pmatrix} L_2\dot{\theta}\sin\theta \\ -L_2\dot{\theta}\cos\theta \\ 0 \end{pmatrix}. \end{aligned}\] An alternative method for computing the velocities \(\mathbf{v}_1\) and \(\mathbf{v}_2\) is to differentiate \(\mathbf{p}_1\) and \(\mathbf{p}_2\) with respect to time to obtain \[\begin{aligned} \mathbf{v}_1 &\stackrel{\triangle}{=}\dot{\mathbf{p}}_1 = \frac{d\mathbf{p}_1}{dt} = \frac{d}{dt}(L_1\cos\theta, L_1\sin\theta, 0)^\top \\ &= \begin{pmatrix}-L_1\left(\frac{d\theta}{dt}\right)\sin\theta, & L_1\left(\frac{d\theta}{dt}\right)\cos\theta, & 0 \end{pmatrix}^\top \\ &= \begin{pmatrix}-L_1\dot{\theta}\sin\theta, & L_1\dot{\theta}\cos\theta, & 0 \end{pmatrix}^\top \\ \mathbf{v}_2 &\stackrel{\triangle}{=}\dot{\mathbf{p}}_2 = \frac{d\mathbf{p}_2}{dt} = \frac{d}{dt}(-L_2\cos\theta, -L_2\sin\theta, 0)^\top \\ &= \begin{pmatrix}L_2\left(\frac{d\theta}{dt}\right)\sin\theta, & -L_2\left(\frac{d\theta}{dt}\right)\cos\theta, & 0 \end{pmatrix}^\top \\ &= \begin{pmatrix}L_2\dot{\theta}\sin\theta, & -L_2\dot{\theta}\cos\theta, & 0 \end{pmatrix}^\top. \end{aligned}\]

Therefore, using Equation 2.1 the kinetic energy is \[\begin{aligned} K &= \frac{1}{2} m_1 \mathbf{v}_1^\top \mathbf{v}_1 + \frac{1}{2} m_2 \mathbf{v}_2^\top \mathbf{v}_2 \\ &= \frac{1}{2} m_1 \left[ (-L_1\dot{\theta}\sin\theta)^2 + (L_1\dot{\theta}\cos\theta)^2 \right] \\ &\qquad + \frac{1}{2} m_2 \left[ (L_2\dot{\theta}\sin\theta)^2 + (-L_2\dot{\theta}\cos\theta)^2 \right] \\ &= \frac{1}{2} m_1 \left[ L_1^2\dot{\theta}^2\sin^2\theta + L_1^2\dot{\theta}^2\cos^2\theta \right] % + \frac{1}{2} m_2 \left[ L_2^2\dot{\theta}^2\sin^2\theta + L_2^2\dot{\theta}^2\cos^2\theta \right] \\ &= \frac{1}{2} (m_1 L_1^2 + m_2 L_2^2)\dot{\theta}^2. \end{aligned}\]

Now consider the case where there are \(N\) point masses spinning about a general angular velocity vector \(\boldsymbol{\omega}\), where the position of the \(i^{th}\) point mass, \(i=1,\dots,N\), in a specified coordinate system is given by \(\mathbf{p}_i\), as shown in Fig. 2.3.

Many masses in a rigid body spinning about a common axis and moving at velocity \mathbf{v}.

We will see in the discussion below that it is most convenient to pick the coordinate system to be at the center of mass. The kinetic energy of the \(i^{th}\) particle is \(K_i = \frac{1}{2}m_i\mathbf{v}_i^\top\mathbf{v}_i\). Therefore, the kinetic energy of the total system is given by \[K = \sum_{i=1}^N \frac{1}{2}m_i\mathbf{v}_i^\top\mathbf{v}_i.\] Using the fact that \(\mathbf{v}_i = \boldsymbol{\omega}\times\mathbf{p}_i\) gives \[K = \sum_{i=1}^N \frac{1}{2}m_i\left(\boldsymbol{\omega}\times\mathbf{p}_i\right)^\top\left(\boldsymbol{\omega}\times\mathbf{p}_i\right).\] Recalling the cross product rule \[(\mathbf{a}\times\mathbf{b})^\top(\mathbf{c}\times\mathbf{d}) = (\mathbf{a}^\top\mathbf{c})(\mathbf{b}^\top\mathbf{d})-(\mathbf{a}^\top\mathbf{d})(\mathbf{b}^\top\mathbf{c})\] gives \[\begin{aligned} K &= \frac{1}{2} \sum_{i=1}^N m_i \left[ (\boldsymbol{\omega}^\top\boldsymbol{\omega})(\mathbf{p}_i^\top\mathbf{p}_i)-(\boldsymbol{\omega}^\top\mathbf{p}_i)(\mathbf{p}_i^\top\boldsymbol{\omega})\right] \\ &= \frac{1}{2} \sum_{i=1}^N m_i \boldsymbol{\omega}^\top \left[ (\mathbf{p}_i^\top\mathbf{p}_i) I_3 - \mathbf{p}_i \mathbf{p}_i^\top \right] \boldsymbol{\omega} \\ &= \frac{1}{2} \boldsymbol{\omega}^\top \left[ \sum_{i=1}^N m_i \left((\mathbf{p}_i^\top\mathbf{p}_i) I_3 - \mathbf{p}_i \mathbf{p}_i^\top \right) \right] \boldsymbol{\omega} \\ &\stackrel{\triangle}{=}\frac{1}{2} \boldsymbol{\omega}^\top J \boldsymbol{\omega}. \end{aligned}\] where \(I_3\) is the \(3 \times 3\) identity matrix. The matrix \[J = \sum_{i=1}^N m_i \left((\mathbf{p}_i^\top\mathbf{p}_i) I_3 - \mathbf{p}_i \mathbf{p}_i^\top \right)\] is called the inertia matrix of the mass system. If the mass system is solid then there is an infinite number of particles, and the sum becomes an integral resulting in \[J = \int_{\mathbf{p}\in\text{body}} \left((\mathbf{p}^\top\mathbf{p}) I_3 - \mathbf{p} \mathbf{p}^\top \right)dm(\mathbf{p}),\] where \(dm(\mathbf{p})\) is the elemental mass located at position \(\mathbf{p}\) and the integral is over all elemental masses in the system.

Suppose that \(\mathbf{p}=(x, y, z)^\top\) is expressed with respect to a coordinate system fixed in a rigid body. Then \[\begin{aligned} J &= \int_{(x,y,z)\in\text{body}} \Bigg[ \begin{pmatrix} x & y & z \end{pmatrix}\begin{pmatrix} x \\ y \\ z \end{pmatrix} \begin{pmatrix} 1 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{pmatrix} % - \begin{pmatrix} x \\ y \\ z \end{pmatrix} \begin{pmatrix} x & y & z \end{pmatrix} \Bigg] dm(x,y,z) \\ &= \int_{(x,y,z)\in\text{body}} \Bigg[ (x^2 + y^2 + z^2)\begin{pmatrix} 1 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{pmatrix} % - \begin{pmatrix} x^2 & xy & x z \\ yx & y^2 & yz \\ zx & zy & z^2 \end{pmatrix} \Bigg] dm(x,y,z) \\ &= \int_{(x,y,z)\in\text{body}} \begin{pmatrix} y^2 + z^2 & -xy & -x z \\ -yx & x^2+z^2 & -yz \\ -zx & -zy & x^2+y^2 \end{pmatrix} dm(x,y,z). \end{aligned}\]

As an example, to compute the inertia matrix of the thin rod of mass \(m\) about its center of mass, as shown in Fig. 2.4, the first step is to define a coordinate system at the center of mass, as shown in Fig. 2.4, where \(\hat{i}\) and \(\hat{j}\) are orthogonal unit vectors pointing parallel and perpendicular to the rod, respectively. The unit vector \(\hat{k}\) forms a right-handed coordinate system and points out of the page.

Computing the inertia of a thin rod.

Assuming that the rod is infinitely thin and that the mass is evenly distributed throughout the rod, then the elemental mass is given by \[dm(x) = \frac{m}{\ell}dx.\] Since the rod is infinitely thin in the \(\hat{j}\) and \(\hat{k}\) directions, the inertia matrix is given by \begin{align} J &= \int_{x=-\ell/2}^{\ell/2}\int_{y=0}^0\int_{z=0}^0 \begin{pmatrix} y^2 + z^2 & -xy & -x z \\ -yx & x^2+z^2 & -yz \\ -zx & -zy & x^2+y^2 \end{pmatrix} dz \, dy \, \frac{m}{\ell}dx \notag\\ &= \frac{m}{\ell} \int_{x=-\ell/2}^{\ell/2} \begin{pmatrix} 0 & 0 & 0 \\ 0 & x^2 & 0 \\ 0 & 0 & x^2 \end{pmatrix} dx \notag\\ &= \frac{m}{\ell} \begin{pmatrix} 0 & 0 & 0 \\ 0 & \frac{x^3}{3}\big|_{x=-\frac{\ell}{2}}^{\frac{\ell}{2}} & 0 \\ 0 & 0 & \frac{x^3}{3}\big|_{x=-\frac{\ell}{2}}^{\frac{\ell}{2}} \end{pmatrix} = \begin{pmatrix} 0 & 0 & 0 \\ 0 & \frac{m\ell^2}{12} & 0 \\ 0 & 0 & \frac{m\ell^2}{12} \end{pmatrix}. \tag{2.2} \end{align} Note that the infinitely thin rod assumption implies that there is only inertia, or rotational mass, about the \(\hat{j}\) and \(\hat{k}\) axes.

As another example, to compute the inertia matrix of the thin plate of mass \(m\) about its center of mass, as shown in Fig. 2.5, the first step is to define a coordinate system at the center of mass, as shown in Fig. 2.5, where \(\hat{i}\) and \(\hat{j}\) are orthogonal unit vectors pointing along the length and width of the plate, respectively, and \(\hat{k}\) forms a right-handed coordinate system and points perpendicular to the plate.

Computing the inertia of a thin plate.

Assuming that the plate is infinitely thin, and that the mass is evenly distributed throughout the plate, then the elemental mass is given by \[dm(x,y) = \frac{m}{\ell w}dx\,dy.\] Since the plate is infinitely thin in the \(\hat{k}\) direction, the inertia matrix is given by \[\begin{aligned} J &= \int_{x=-\ell/2}^{\ell/2}\int_{y=-w/2}^{w/2}\int_{z=0}^0 \begin{pmatrix} y^2 + z^2 & -xy & -x z \\ -yx & x^2+z^2 & -yz \\ -zx & -zy & x^2+y^2 \end{pmatrix} dz \, dy \, \frac{m}{\ell w}\,dx \\ &= \frac{m}{\ell w} \int_{x=-\ell/2}^{\ell/2} \int_{y=-w/2}^{w/2} \begin{pmatrix} y^2 & -xy & 0 \\ -yx & x^2 & 0 \\ 0 & 0 & x^2 +y^2\end{pmatrix} dy\,dx \\ % &= \frac{m}{\ell w} \int_{x=-\ell/2}^{\ell/2} \begin{pmatrix} \frac{w^3}{12} & 0 & 0 \\ 0 & x^2 w & 0 \\ 0 & 0 & x^2 w +\frac{w^3}{12}\end{pmatrix} dx \\ % &= \frac{m}{\ell w} \begin{pmatrix} \frac{w^3}{12}\ell & 0 & 0 \\ 0 & \frac{\ell^3}{12} w & 0 \\ 0 & 0 & \frac{\ell^3}{12}w +\frac{w^3}{12}\ell\end{pmatrix} = \begin{pmatrix} \frac{mw^2}{12} & 0 & 0 \\ 0 & \frac{m\ell^2}{12} & 0 \\ 0 & 0 & \frac{m\ell^2}{12} +\frac{mw^2}{12}\end{pmatrix}. \end{aligned}\]

The diagonal elements of \(J\) are called the moments of inertia and represent the rotational mass about the \(\hat{i}\), \(\hat{j}\), and \(\hat{k}\) axes respectively.

We have shown that if the motion of the system of \(N\) masses is caused purely by spinning about the angular velocity vector \(\boldsymbol{\omega}\), then the kinetic energy is given by \(K=\frac{1}{2}\boldsymbol{\omega}^\top J \boldsymbol{\omega}\). If the system of masses is also translating with velocity \(\mathbf{v}\), then the velocity of the \(i^{th}\) particle is given by \(\mathbf{v}_i = \mathbf{v} + \boldsymbol{\omega}\times\mathbf{p}_i.\) In that case, the kinetic energy is given by \[\begin{aligned} K &= \frac{1}{2}\sum_{i=1}^N m_i \mathbf{v}_i^\top\mathbf{v}_i = \frac{1}{2}\sum_{i=1}^N m_i (\mathbf{v} + \boldsymbol{\omega}\times\mathbf{p}_i)^\top(\mathbf{v} + \boldsymbol{\omega}\times\mathbf{p}_i) \\ &= \frac{1}{2}\sum_{i=1}^N m_i \Big(\mathbf{v}^\top\mathbf{v} + \mathbf{v}^\top(\boldsymbol{\omega}\times\mathbf{p}_i)+(\boldsymbol{\omega}\times\mathbf{p}_i)^\top\mathbf{v} % + (\boldsymbol{\omega}\times\mathbf{p}_i)^\top(\boldsymbol{\omega}\times\mathbf{p}_i) \Big) \\ &= \frac{1}{2}\left(\sum_{i=1}^N m_i\right)\mathbf{v}^\top\mathbf{v} + \frac{1}{2} \sum_{i=1}^N m_i (\boldsymbol{\omega}\times\mathbf{p}_i)^\top(\boldsymbol{\omega}\times\mathbf{p}_i) \\ &\qquad\qquad + \frac{1}{2}\sum_{i=1}^N m_i\left[\mathbf{v}^\top(\boldsymbol{\omega}\times\mathbf{p}_i) + (\boldsymbol{\omega}\times\mathbf{p}_i)^\top\mathbf{v}\right]. \end{aligned}\] Using the cross product property \[\mathbf{a}^\top(\mathbf{b}\times\mathbf{c}) = \mathbf{b}^\top(\mathbf{c}\times\mathbf{a}) = \mathbf{c}^\top(\mathbf{a}\times\mathbf{b})\] we get that \[\begin{gathered} \sum_{i=1}^N m_i\left[\mathbf{v}^\top(\boldsymbol{\omega}\times\mathbf{p}_i) + (\boldsymbol{\omega}\times\mathbf{p}_i)^\top\mathbf{v}\right] = \\ (\sum_{i=1}^N m_i\mathbf{p}_i)^\top(\mathbf{v}\times\boldsymbol{\omega}) + (\sum_{i=1}^N m_i\mathbf{p}_i)^\top(\mathbf{v}\times\boldsymbol{\omega}). \end{gathered}\] If we choose the center of the coordinate system to be the center of mass, then \(\sum_{i=1}^N m_i\mathbf{p}_i=0\). Defining the total mass as \(m=\sum_{i=1}^N m_i\), the kinetic energy is given by \[\begin{aligned} K&= \frac{1}{2}\left(\sum_{i=1}^N m_i\right)\mathbf{v}_{cm}^\top\mathbf{v}_{cm} + \frac{1}{2} \sum_{i=1}^N m_i (\boldsymbol{\omega}\times\mathbf{p}_i)^\top(\boldsymbol{\omega}\times\mathbf{p}_i) \notag \\ &= \frac{1}{2}m\mathbf{v}_{cm}^\top\mathbf{v}_{cm} + \frac{1}{2} \boldsymbol{\omega}^\top J_{cm} \boldsymbol{\omega}. \end{aligned}\]

Therefore, the kinetic energy of a rigid body moving with velocity \(\mathbf{v}_{cm}\) and spinning at angular velocity \(\boldsymbol{\omega}\) is \[\tag{2.3} K=\frac{1}{2}m\mathbf{v}_{cm}^\top\mathbf{v}_{cm} + \frac{1}{2} \boldsymbol{\omega}^\top J_{cm} \boldsymbol{\omega}.\] If the system consists of \(n\) rigid bodies, then the total kinetic energy is computed by summing the kinetic energy for each body as \[K = \sum_{j=1}^n \left[\frac{1}{2}m_j\mathbf{v}_{cm,j}^\top\mathbf{v}_{cm,j} + \frac{1}{2} \boldsymbol{\omega}_j^\top J_{cm,j} \boldsymbol{\omega}_j\right].\]

2.1.1 Example: Mass Spring System

As an example, consider the mass spring system shown in Fig. 2.6 where two masses are moving along a surface and are connected by springs with constants \(k_1\) and \(k_2\) and dampers with constants \(b_1\) and \(b_2\). The kinetic energy of the system is determined by the velocity of the two masses and is therefore given by \[K = \frac{1}{2} m_1 \dot{z}_1^2 + \frac{1}{2} m_2 \dot{z}_2^2.\]

Mass spring system with two masses connected by springs and dampers.

2.1.2 Example: Spinning Dumbbell

As another simple example, consider the spinning dumbbell system shown in Fig. 2.7, where two masses are spinning about a point on the adjoining line between the masses. The angular velocity vector is pointing out of the page with magnitude \(\dot{\theta}\) and the dumbbell system is moving to the right at velocity \(\dot{z}\).

Spinning dumbbell. The system is spinning about the axis pointing out of the page and moving to the right at velocity \dot{z}.

The first step in computing the kinetic energy is to define an inertial coordinate system as shown in Fig. 2.7 where \(\hat{i}\) is a unit vector along the direction of travel, \(\hat{j}\) is perpendicular to the direction of travel, and where \(\hat{k}\) forms a right-handed coordinate system and points out of the page. In this coordinate system, the position of the point of rotation is given by \(\mathbf{p}(t)=(z(t), 0, 0)^\top\). Accordingly, the positions of \(m_1\) and \(m_2\) are given by \[\begin{aligned} \mathbf{p}_1(t) &= (z(t)+\ell_1\cos\theta(t), \ell_1\sin\theta(t), 0)^\top, \\ \mathbf{p}_2(t) &= (z(t)-\ell_2\cos\theta(t), -\ell_2\sin\theta(t), 0)^\top. \end{aligned}\] Since \(z\) and \(\theta\) are functions of time, using the chain rule \[\frac{d}{dt}f(g(t)) = \frac{\partial f}{\partial g}\frac{d g}{dt}\] and differentiating with respect to time, we get the velocities of the masses as \[\begin{aligned} \mathbf{v}_1 &= (\dot{z} - \ell_1\dot{\theta}\sin\theta, \ell_1\dot{\theta}\cos\theta, 0)^\top,\\ \mathbf{v}_2 &= (\dot{z} + \ell_2\dot{\theta}\sin\theta, -\ell_2\dot{\theta}\cos\theta, 0)^\top. \end{aligned}\] The kinetic energy is therefore given by \[\begin{aligned} K &= \frac{1}{2}m_1\mathbf{v}_1^\top \mathbf{v}_1 + \frac{1}{2}m_2\mathbf{v}_2^\top \mathbf{v}_2 \\ &= \frac{1}{2}m_1 \left[(\dot{z} - \ell_1\dot{\theta}\sin\theta)^2 + (\ell_1\dot{\theta}\cos\theta)^2 \right] \\&\qquad + \frac{1}{2}m_2\left[(\dot{z} + \ell_2\dot{\theta}\sin\theta)^2 + (-\ell_2\dot{\theta}\cos\theta)^2 \right] \\ &= \frac{1}{2}m_1 \left[\dot{z}^2 - 2\ell_1\dot{z}\dot{\theta}\sin\theta + \ell_1^2\dot{\theta}^2\sin^2\theta+\ell_1^2\dot{\theta}^2\cos^2\theta \right] \\ &\quad + \frac{1}{2}m_2\left[\dot{z}^2 + 2\ell_2\dot{z}\dot{\theta}\sin\theta + \ell_2^2\dot{\theta}^2\sin^2\theta+\ell_2^2\dot{\theta}^2\cos^2\theta \right] \\ &= \frac{1}{2}(m_1+m_2)\dot{z}^2 + \frac{1}{2} (m_1\ell_1^2+m_2\ell_2^2)\dot{\theta}^2 + (m_2\ell_2-m_1\ell_1)\dot{z}\dot{\theta}\sin\theta. \end{aligned}\] Note that if the pivot point is located at the center of mass, then \(m_1\ell_1=m_2\ell_2\), and the kinetic energy is simply given by \[K = \frac{1}{2}(m_1+m_2)\dot{z}^2 + \frac{1}{2} (m_1\ell_1^2+m_2\ell_2^2)\dot{\theta}^2,\] which is in the form \[K = \frac{1}{2}m\mathbf{v}_{cm}^\top\mathbf{v}_{cm} + \frac{1}{2}\boldsymbol{\omega}^\top J \boldsymbol{\omega},\] where the total mass is \(m=m_1+m_2\), the velocity of the center of mass is \(\mathbf{v}_{cm}=(\dot{z}, 0, 0)^\top\), the angular velocity vector is \(\boldsymbol{\omega} = (0, 0, \dot{\theta})^\top\) and the \((3,3)\) element of \(J\) is given by \(J_z = m_1\ell_1^2 + m_2\ell_2^2\).

A definition of the single-link robot arm is given in Design Study A.

2.2.1 image Example Problem 3.1.2

(a) Using the configuration variable \(\theta\), write an expression for the kinetic energy of the system.

(b) Referring to Appendices P.1, P.2, and P.3, write a Python or MATLAB class, or a MATLAB function that creates an animation of the single-link robot arm. Simulate the animation to display a sinusoidal variation on the configuration variable \(q=\theta\).

Design Study A guided exercise

Derive the arm kinetic energy

Work from the center-of-mass motion and the rotational inertia of the slender link.

Single
link robot arm with center of mass and angular velocity labels.

Use this geometry to identify the center-of-mass position and the angular velocity before deriving kinetic energy.

Step 1. Center-of-mass position

Enter the horizontal and vertical components of \(p_{cm}\).

Step 2. Link inertia

Enter the moment of inertia about the center of mass for the slender link.

Step 3. Total kinetic energy

Enter the multiplier on \(\dot{\theta}^2\) in the final kinetic energy expression.

Pseudocode

The complete solution includes an animation class and a simulation script. Before opening it, outline each component separately.

These prompts are ungraded. They are intended to connect the derivation to the implementation code in the complete solution.

2.3 Design Study B. Pendulum on Cart

A definition of the pendulum on a cart (or inverted pendulum) is given in Design Study 3.2.

2.3.1 image Example Problem 3.2.2

(a) Using the configuration variables \(z\) and \(\theta\), write an expression for the kinetic energy of the system.

(b) Referring to Appendices P.1, P.2, and P.3, write a Python or MATLAB class, or a MATLAB function that creates an animation of the inverted pendulum. Simulate the animation to display sinusoidal variations on the configuration variables \(q=(z, \theta)^\top\).

Design Study B guided exercise

Build the pendulum kinetic energy

Use the geometry to identify positions, velocities, and energy terms for the cart and rod.

Pendulum on a cart kinetic-energy geometry.

Use this geometry to identify the cart position, rod center-of-mass position, and pendulum angular velocity.

Step 1. Position variables

Step 2. Velocity variables

Step 3. Energy terms

Pseudocode

The complete solution includes an animation class and a simulation script. Before opening it, outline each component separately.

These prompts are ungraded. They are intended to connect the derivation to the implementation code in the complete solution.

2.4 Design Study C. Satellite Attitude Control

A definition of the satellite attitude control problem is given in Design Study C.

2.4.1 image Example Problem 3.3.2

(a) Using the configuration variables \(\theta\) and \(\phi\), write an expression for the kinetic energy of the system.

(b) Referring to Appendices P.1, P.2, and P.3, write a Python or MATLAB class, or a MATLAB function that creates an animation of the satellite. Simulate the animation to display sinusoidal variations on the configuration variables \(q=(\theta, \phi)^\top\).

Design Study C guided exercise

Build the satellite kinetic energy

The satellite model has two rotational inertias: the body inertia \(J_s\) associated with \(\theta\), and the panel inertia \(J_p\) associated with \(\phi\).

Satellite
with flexible solar panels.

Use inertial angular rates for kinetic energy. The relative deflection \(\phi-\theta\) appears in spring and damping terms later.

Step 1. Match inertias to coordinates

Step 2. Identify the kinetic-energy terms

Step 3. Enter the total kinetic-energy structure

Pseudocode

The complete solution includes satellite animation code. Before opening it, outline how an animation should update the body and panel orientations from \(\theta(t)\) and \(\phi(t)\).

This prompt is ungraded. It connects the energy model to the animation code in the complete solution.

2.5 Interactive Inertia Check

Chapter 2 activity

Mass distribution and kinetic energy

Move two equal point masses away from the rotation axis. The moment of inertia and rotational kinetic energy increase even when the total mass stays fixed.

rotation axis r d ω v
Figure 1.1. The sliders control two point masses, their radius from the center, the offset rotation axis, translational velocity, and angular velocity.

Computed values

Each mass: kg; radius: m; offset: m

I = 2 m r2 = kg m2

Ioffset = I + 2 m d2 = kg m2

Ktrans = ½ (2m) v2 = J

Krot = ½ Ioffset ω2 = J

The parallel-axis theorem adds md2 for each point mass when the axis is shifted by distance d.

2.6 Knowledge Check

Q1. Mass distribution

Moving mass farther from a rotation axis usually does what to moment of inertia?

Q2. Translational energy

Translational kinetic energy depends directly on:

Q3. Point-mass inertia

A point mass m = 2 kg is 1.414 m from an axis. Enter the inertia of this point mass.

Show solution

Answer: Approximately 4 kg m2, since 2(1.414)2 is about 4.

Q4. Rotational kinetic energy

If I = 2 kg m2 and ω = 3 rad/s, enter the rotational kinetic energy.

Show solution

Answer: 9 J because ½(2)(32) = 9.

Q5. Toy system: warehouse cart and flywheel

A 6 kg cart moves at 1.5 m/s while a flywheel with I = 0.8 kg m2 spins at ω = 5 rad/s. Enter the total kinetic energy.

cart mass = 6 kg I = 0.8 kg m2 ω = 5 rad/s v = 1.5 m/s

Compute the total kinetic energy, by computing both the cart’s translational kinetic energy and the flywheel’s rotational kinetic energy.

Show solution

Answer: 16.75 J because ½(6)(1.52) + ½(0.8)(52) = 6.75 + 10.

Q6. Toy system: puck and rotor

A 0.4 kg puck slides at 3 m/s while a small rotor sitting on top of the puck spins at ω = 20 rad/s. The rotor has a moment of inertia of I = 0.05 kg m2. Enter the total kinetic energy.

puck v = 3 m/s ω = 20 rad/s puck mass m = 0.4 kg rotor inertia I = 0.05 kg m2 puck: ½ m v2 rotor: ½ I ω2

The puck translates to the right, while the rotor spins about its own vertical axle. Add the puck’s translational energy and the rotor’s rotational energy.

Show solution

Answer: 11.8 J because ½(0.4)(32) + ½(0.05)(202) = 1.8 + 10.

Q7. Mass distribution

Two equal point masses rotate with the same angular velocity. Which change most directly increases rotational kinetic energy?

Q8. Combined kinetic energy

A cart of mass m translates at speed v while a disk on the cart spins with inertia J and angular speed ω. Which kinetic energy expression includes both effects?

Q9. Parallel-axis theorem

When is the parallel-axis theorem needed?

Q10. Inertia matrix meaning

What does a diagonal entry of an inertia matrix represent?

2.7 Notes and References

The inertia matrix in Equation 2.3 is computed about the center of mass of the object. When an object is composed of several connected rigid bodies and the inertia matrix is known for each body, the parallel axis theorem provides a convenient way to find the total inertia about the center of mass. The theorem states that if \(J_{cm}\) is the inertia matrix about the center of mass, then the inertia matrix about a point located at vector \(\mathbf{r}\) from the center of mass is \[J(\mathbf{r}) = J_{cm} + m\left(\mathbf{r}^\top\mathbf{r} I_3 - \mathbf{r}\mathbf{r}^\top\right).\] For the moment of inertia about a single axis, where the axis is shifted from the center of mass by distance \(d\), the parallel axis theorem implies that \[I(d) = I_{cm} + md^2.\]

3 The Euler-Lagrange Equations

3.1 Theory

In this chapter we show how to define the potential energy for simple mechanical systems and how to define the generalized forces. The Euler-Lagrange equations given in Equation 1.8 can then be used to derive the equations of motion for the system.

3.1.1 Potential Energy

In this book we will be concerned with two sources of potential energy: potential energy due to gravity and potential energy due to springs.

The potential energy of a unit mass m in gravity is given by P=mgy.

Consider a point mass \(m\) in a gravity field that is at position \(y\) as shown in Fig. 3.1. The potential energy is given by \[P = mgy + P_0,\] where \(P_0\) is the potential energy when \(y=0\). Typically, we desire an expression for potential energy that is zero when the configuration variables are zero.

The second source of potential energy is from translational and rotational springs.

A spring stretched by distance z stores potential energy.

The spring shown in Fig. 3.2 is stretched from rest by a distance of \(z\). The potential energy of a linear stretched/compressed spring is given by \[P = \frac{1}{2}k z^2,\] where \(k\) is the spring constant. Similarly, for a rotational spring, the potential energy is given by \(P=\frac{1}{2}k \theta^2\), where \(\theta\) is the rotational angle and \(\theta=0\) is the angle at which the rotational spring is at rest.

3.1.2 Generalized Coordinates and Generalized Forces

The generalized coordinates are the minimum set of configuration variables. For example, for the mass-spring-damper system shown in Fig. 2.6, the generalized coordinates are \(\mathbf{q}=(z_1, z_2)^\top\). For the single-link robot arm shown in Fig. 2.8, the generalized coordinate is \(\mathbf{q}=\theta\). For the spinning dumbbell system shown in Fig. 2.7, and the pendulum on a cart system shown in Fig. 2.9, the generalized coordinates are \(\mathbf{q}=(z, \theta)^\top\). Finally, for the satellite system shown in Fig. 1.4, the generalized coordinates are \(\mathbf{q}=(\theta,\phi)^\top\).

The generalized forces are the nonconservative forces and torques acting along each generalized coordinate. In other words, they are the applied forces and torques on the system. For example, for the mass-spring-damper system shown in Fig. 2.6, the generalized force acting along \(z_1\) is zero and the generalized force acting along \(z_2\) is the applied force \(F\). Therefore, the generalized force is \(\boldsymbol{\tau} = (0, F)^\top\).

3.1.3 Damping Forces and Torques

Friction and applied dampers also exert forces on the system. Damping forces are externally applied forces that are proportional to the velocity or angular velocity of the system. For example, in the mass-spring-damper system shown in Fig. 2.6, the damping force acting along \(z_1\) is due to the first damper and the damper between the two masses and is given by \(-b_1\dot{z}_1-b_2(\dot{z}_1-\dot{z}_2)\). The damping acting along \(z_2\) is given by \(-b_2(\dot{z}_2-\dot{z}_1)\). Therefore, the damping force on the system is given by \[-B\dot{\mathbf{q}} = -\begin{pmatrix} b_1+b_2 & -b_2 \\ -b_2 & b_2 \end{pmatrix} \begin{pmatrix} \dot{z}_1 \\ \dot{z}_2 \end{pmatrix} = \begin{pmatrix} -b_1\dot{z}_1-b_2(\dot{z}_1-\dot{z}_2) \\ -b_2(\dot{z}_2-\dot{z}_1) \end{pmatrix}.\]

3.1.4 Euler-Lagrange Equations

The equations of motion are given by the Euler-Lagrange equations. Let the Lagrangian be given by \[L(\mathbf{q},\dot{\mathbf{q}}) = K(\mathbf{q},\dot{\mathbf{q}}) - P(\mathbf{q}),\] where \(K(\mathbf{q},\dot{\mathbf{q}})\) is the kinetic energy of the system and is, in general, a function of the generalized coordinates and the generalized velocities, and \(P(\mathbf{q})\) is the potential energy which is, in general, a function of the generalized coordinates. As shown in Equation 1.8 the Euler-Lagrange equations are given in vector form as \[\frac{d}{dt}\left(\frac{\partial L(\mathbf{q},\dot{\mathbf{q}})}{\partial \dot{\mathbf{q}}}\right) - \frac{\partial L(\mathbf{q},\dot{\mathbf{q}})}{\partial \mathbf{q}} = \boldsymbol{\tau}-B \dot{\mathbf{q}}.\]

3.2.1 image Example Problem 3.1.6

Find the potential energy for the system.

Define the generalized coordinates.

Find the generalized forces and damping forces.

Derive the equations of motion using the Euler-Lagrange equations.

Referring to Appendices P.1, P.2, and P.3, write a class or s-function that implements the equations of motion. Simulate the system using a variable torque input. The output should connect to the animation function developed in homework A.2.

Design Study A guided exercise

Build the arm equation of motion

Use the kinetic energy from Chapter 2 and gravity potential energy for the center of mass.

Single link robot arm geometry for potential energy.

Use this geometry to relate the center-of-mass height to \(\theta\) before applying Euler-Lagrange.

Step 1. Potential energy

Step 2. Generalized coordinate and force

Step 3. Equation of motion

Enter the multiplier on \(\ddot{\theta}\) in the final equation.

Pseudocode

The complete solution includes a dynamics class and a simulation script. Before opening it, outline each component separately.

These prompts are ungraded. They are intended to connect the Euler-Lagrange equation to the implementation code in the complete solution.

3.3 Design Study B. Inverted Pendulum

3.3.1 image Example Problem 3.2.6

Find the potential energy for the system.

Define the generalized coordinates.

Find the generalized forces and damping forces.

Derive the equations of motion using the Euler-Lagrange equations.

Referring to Appendices P.1, P.2, and P.3, write a class for s-function that implements the equations of motion. Simulate the system using a variable force on the cart as an input. The output should connect to the animation function developed in homework B.2.

Design Study B guided exercise

Assemble the pendulum equations of motion

Use energy, generalized coordinates, and generalized forces to form the coupled nonlinear equations.

Pendulum on
a cart definition figure.

Use this setup to connect gravity, force, cart motion, and pendulum angle before applying Euler-Lagrange.

Step 1. Potential energy

Step 2. Generalized coordinates

Step 3. Coupled dynamics structure

Pseudocode

The complete solution includes a dynamics class and a simulation script. Before opening it, outline each component separately.

These prompts are ungraded. They are intended to connect the derivation to the implementation code in the complete solution.

3.4 Design Study C. Satellite Attitude Control

3.4.1 image Example Problem 3.3.6

Find the potential energy for the system.

Define the generalized coordinates.

Find the generalized forces and damping forces.

Derive the equations of motion using the Euler-Lagrange equations.

Referring to Appendices P.1, P.2, and P.3, write a class or s-function that implements the equations of motion. Simulate the system using a variable torque on the body as an input. The output should connect to the animation function developed in homework C.2.

Design Study C guided exercise

Assemble the satellite equations of motion

Use the torsional spring, relative damping, body torque, and two angular coordinates to form the coupled satellite-panel equations.

Satellite
with flexible solar panels.

The spring and damper act on relative motion between the body and panel, while the actuator torque is applied only to the body.

Step 1. Potential energy

Step 2. Generalized coordinates and input

Step 3. Relative damping

Step 4. Coupled equation structure

Pseudocode

The complete solution includes dynamics code. Before opening it, outline how the code should compute \(\ddot{\theta}\) and \(\ddot{\phi}\) from state and torque.

This prompt is ungraded. It connects the Euler-Lagrange equations to the implementation code in the complete solution.

3.5 Interactive Euler-Lagrange Check

Chapter 3 activity

From energy to Lagrangian terms

Use a one-coordinate mass-spring example to connect kinetic energy, potential energy, the Lagrangian L = K - P, and the spring force term.

q q . k m
Figure 1.2. A one-coordinate mass-spring system with generalized coordinate q and generalized velocity q.

Live equations

P(q) = ½ k q2 = ½()()2 = J

K(q) = ½ m q2 = ½()()2 = J

L(q,q) = K - P = J

dP⁄dq = k q = N

3.6 Knowledge Check

Q1. Lagrangian definition

The Lagrangian is:

Q2. Generalized coordinates

Generalized coordinates should be:

Q3. Spring potential

For k = 4 and displacement q = 2, enter the potential energy P.

Show solution

Answer: 8 because P = ½kq2 = ½(4)(22) = 8.

Q4. Potential derivative

For P = ½kq2, with k = 3 and q = 2, enter dP⁄dq.

Show solution

Answer: 6 because dP⁄dq = kq = (3)(2).

Q5. Toy system: warehouse cart and flywheel

Consider the warehouse cart and flywheel system from Chapter 2 Q5. The cart translates horizontally, and the flywheel rotates relative to the cart. For this Chapter 3 version, assume the cart is attached to a linear spring with displacement z from its relaxed position, and the flywheel is attached to a torsional spring with angle θ from its relaxed angle. Which potential energy expression is correct?




Q6. Toy system: puck and rotor

Consider the puck-and-rotor system from Chapter 2 Q6. The puck slides along a horizontal surface, and the rotor spins on top of the puck. To describe the configuration, use x for the puck's horizontal position and θ for the rotor's angular position. Which set is the best choice of generalized coordinates?

Q7. Toy system: Lagrangian form

For either toy system with translation and rotation, which Lagrangian form is correct?

Q8. Coordinate choice

A slider moves horizontally while a rigid link rotates relative to the slider. Which generalized coordinates are most appropriate?

Q9. Potential energy structure

A point mass has height y and stretches a spring by x from its relaxed length. Which potential-energy structure is correct?

Q10. Generalized force

For q = (θ, x), a positive torque τ is applied directly in the positive θ direction and no direct force is applied in x. What generalized-force vector is consistent with this description?

Q11. Euler-Lagrange term

Which term most directly comes from d/dt(partial L / partial qdot) in a one-coordinate mass-spring model?

Q12. Coupled motion

Why can products such as xdot times thetadot appear in Euler-Lagrange equations for a multi-coordinate mechanical system?

3.7 Notes and References

Derivations of the Euler-Lagrange equations can be found in many sources, including [1, 2]. A simple derivation using only calculus can be found in [3].

Part II

Design Models

The equations of motion that we derived in the previous section are often too complicated to facilitate effective engineering design. Accordingly, the standard approach is to simplify the models into so-called design models that capture the essential features of the system. The design techniques studied in this class will require that the design models are linear and time-invariant. In addition, the PID method described in Part III will require that the design models are second-order systems.

Our approach to developing linear time-invariant design models will be to linearize the simulation models developed in Part I and then to convert the linearized models into two standard forms, namely

  • Transfer function models and

  • State-space models.

Both forms will have advantages and disadvantages that will be explained throughout the remaining parts of the book. In Chapter 7 we will define the important concept of equilibrium and show how the equations of motion can be linearized about the equilibrium. Chapter 8 will show how to transform the linearized equations of motion into transfer function models, and Chapter 9 will show how to put the equations of motion in state-space form.

The remaining parts of the book will use the design models to develop feedback controllers for the system of interest. In Part III we will describe the
Proportional-Integral-Derivative (PID) controllers based on second-order transfer function models. Part IV derives observer-based controllers using state-space models. Finally, Part V describes loopshaping design strategies using general transfer function models.

4 Equilibria and Linearization

4.1 Theory

In this chapter we will describe two methods for linearizing the system, namely Jacobian linearization and feedback linearization. Jacobian linearization is based on the idea of approximating the nonlinear terms in the equations of motion by the first two terms in their Taylor series expansion. Feedback linearization is based on the idea of using the input signal to artificially remove the nonlinear terms.

4.1.1 Jacobian Linearization

If the function \(g:\mathbb{R}\to\mathbb{R}\) is a nonlinear function that can be differentiated an infinite number of times, then its Taylor series expansion about the point \(w_0\) is given by \[g(w) = g(w_0) + \left.\frac{\partial g}{\partial w}\right|_{w_0} (w-w_0) + \frac{1}{2!}\left.\frac{\partial^2 g}{\partial w^2}\right|_{w_0}(w-w_0)^2 + \cdots.\] A pictorial representation of Taylor series expansion is shown in Fig. 4.1, where it can be seen that in a small neighborhood around \(w=w_0\), the function \(g(w)\) is well approximated by the first two terms in the Taylor series expansion, namely \[g(w)\approx g(w_0) + \left.\frac{\partial g}{\partial w}\right|_{w_0} (w-w_0).\]

Interactive Figure 4.1

Taylor series expansion about ω0

Choose a nonlinear function, move the expansion point, and change the Taylor polynomial degree. Degree 1 is the linearized model used in Jacobian linearization.

Figure 4.1. The blue curve is the nonlinear function. The orange curve is the selected Taylor polynomial about ω0. The dashed black line shows the first-order term used for linearization.

Taylor representation

Status:

Symbolic:

Numerical:

Point value:

If \(g\) is a scalar function of several variables, then the Taylor series about \(w_1=w_{10}, w_2=w_{20}, \cdots, w_m=w_{m0}\) is given by \[\begin{gathered} g(w_1,w_2,\dots,w_m) = g(w_{10}, w_{20}, \dots, w_{m0}) + \left.\frac{\partial g}{\partial w_1}\right|_{w_{10},w_{20},\dots,w_{m0}} (w_1-w_{10}) \\ + \left.\frac{\partial g}{\partial w_2}\right|_{w_{10},w_{20},\dots,w_{m0}} (w_2-w_{20}) + \cdots + \left.\frac{\partial g}{\partial w_m}\right|_{w_{10},w_{20},\dots,w_{m0}} (w_m-w_{m0}) + \cdots. \end{gathered}\] For example, given the function \(g(v,w)=v\cos w\), the constant and linear terms in the Taylor series, expanded around \(v_0\) and \(w_0\) are \[\begin{aligned} g(v,w) &\approx g(v_0, w_0) + \left.\frac{\partial g}{\partial v}\right|_{v_{0},w_{0}}(v-v_{0}) + \left.\frac{\partial g}{\partial w}\right|_{v_{0},w_{0}}(w-w_{0}) \\ &= v_0\cos w_0 + \left.\left(\cos w \right)\right|_{v_0,w_0}(v-v_0) % + \left.\left(-v\sin w\right)\right|_{v_0,w_0}(w-w_0) \\ &= v_0\cos w_0 + (\cos w_0)(v-v_0) - (v_0\sin w_0)(w-w_0). \end{aligned}\]

Since approximating a nonlinear function by the first two terms in its Taylor series is only a good approximation in a small neighborhood of \(w_0\), it is important to select \(w_0\) judiciously. In particular, we will be interested in linearizing about equilibrium points of differential equations.

Given the differential equation \(\dot{x} = f(x,u)\), the pair \((x_e,u_e)\) is an equilibrium point if \[f(x_e,u_e)=0.\] In other words, an equilibrium point is a state-input pair where there is not any motion in the system.

For example, suppose that the nonlinear differential equation of a second-order system is given by \[\tag{4.2} \ddot{y} + a\dot{y} + by + g(y,\dot{y}) = u,\] where \(a\) and \(b\) are constants and \(g(y,\dot{y})\) is a known nonlinear function of \(y\) and \(\dot{y}\), and \(u\) is the input signal. Defining \(x=(y,\dot{y})^\top\), we get \[\dot{x} = \begin{pmatrix} \dot{y} \\ \ddot{y} \end{pmatrix} = \begin{pmatrix} \dot{y} \\ u - a\dot{y} - by - g(y,\dot{y}) \end{pmatrix} \stackrel{\triangle}{=}f(x,u).\] The equilibrium is when \(f(x_e,u_e)=0\) or in other words, when \[y_e = \text{~anything~}, \qquad \dot{y}_e=0, \qquad u_e=by_e+g(y_e,0).\] Equivalently, at equilibrium there is no motion in the system, which implies that \(\ddot{y}_e=\dot{y}_e=0\), which from Equation 4.2 implies that \(u_e = by_e+g(y_e,0)\).

Jacobian linearization then proceeds by replacing each term in the nonlinear differential equations describing the system by the first two terms in the Taylor series expansion about the equilibrium point.

For example, since the first term in Equation 4.2 is already linear, it can be expanded exactly as \[\ddot{y} = \ddot{y}_e + \frac{\partial \ddot{y}}{\partial \ddot{y}}\Big|_e (\ddot{y}-\ddot{y}_e) = \ddot{\tilde{y}},\] where we have defined the linearized quantity \(\tilde{y}\stackrel{\triangle}{=}y-y_e\), and we have used the fact that \(\ddot{y}_e=0\). Similarly, the remaining terms in Equation 4.2 are linearized as \[\begin{aligned} a\dot{y} &= a\dot{y}_e + a\frac{\partial \dot{y}}{\partial \dot{y}}\Big|_e (\dot{y}-\dot{y}_e) = a\dot{\tilde{y}} \\ by &= by_e + b\frac{\partial y}{\partial y}\Big|_e (y-y_e) = by_e + b\tilde{y} \\ g(y,\dot{y}) &\approx g(y_e,\dot{y}_e) + \frac{\partial g}{\partial y}\Big|_e(y-y_e) + \frac{\partial g}{\partial \dot{y}}\Big|_e(\dot{y}-\dot{y}_e) \\ &= g(y_e,0) + \frac{\partial g}{\partial y}\Big|_e\tilde{y} + \frac{\partial g}{\partial \dot{y}}\Big|_e\dot{\tilde{y}} \\ u &= u_e + \frac{\partial u}{\partial u}\Big|_e (u-u_e) = u_e + \tilde{u}. \end{aligned}\] Substituting these expressions into Equation 4.2 the resulting linearized equations of motion are \[[\ddot{\tilde{y}}] + [a\dot{\tilde{y}}] + [by_e + b\tilde{y}] + \left[g(y_e,0) + \frac{\partial g}{\partial y}\Big|_e\tilde{y} + \frac{\partial g}{\partial \dot{y}}\Big|_e\dot{\tilde{y}}\right] = [u_e + \tilde{u}]\] Using the equilibrium \(u_e=by_e+g(y_e,0)\) gives \[\ddot{\tilde{y}} + \left(a+\frac{\partial g}{\partial \dot{y}}\Big|_e\right)\dot{\tilde{y}} + \left(b+\frac{\partial g}{\partial y}\Big|_e\right)\tilde{y} = \tilde{u}.\] A block diagram that shows the design model for Equation 4.2 using Jacobian linearization is shown in Fig. 4.2.

Linear model using Jacobian linearization.

4.1.2 Feedback Linearization

It is often the case that the nonlinearities in the system can be directly canceled by a judicious choice for the input variable. Consider again the nonlinear equations of motion in Equation 4.2. If \(u\) is selected as \[u = g(y,\dot{y}) + \tilde{u}\] then the resulting equation of motion is \[\ddot{y} + a\dot{y} + by = \tilde{u},\] which is linear. This technique is called feedback linearization because the feedback signal \(u\) has been used to linearize the system by directly canceling the nonlinearities. The advantage of this method is that the equations of motion are still globally defined and are not restricted to a small neighborhood of an equilibrium point. The disadvantage is that \(g(y,\dot{y})\) may not be precisely known, and therefore may not be completely canceled by \(u\). A block diagram that shows the design model for Equation 4.2 using feedback linearization is shown in Fig. 4.3.

Linear model using feedback linearization.

4.2.1 image Example Problem 3.1.7

For the single-link robot arm:

(a) Find the equilibria of the system.

(b) Linearize the system about the equilibria using Jacobian linearization.

(c) Linearize the system using feedback linearization.

Design Study A guided exercise

Linearize the arm model

Use the nonlinear arm equation from Chapter 3 and compare Jacobian linearization with feedback linearization.

Step 1. Equilibrium conditions

Step 2. Linearized gravity term

Enter the coefficient multiplying \(\tilde{\theta}\) after linearizing the gravity torque.

Step 3. Feedback-linearizing torque

4.3 Design Study B. Inverted Pendulum

4.3.1 image Example Problem 3.2.7

For the inverted pendulum,

(a) Find the equilibria of the system.

(b) Linearize the system about the equilibria using Jacobian linearization.

Note that for the inverted pendulum, since the nonlinearities are not all contained in the same channel as the control force \(F\), the system cannot be feedback linearized.

Design Study B guided exercise

Find equilibria and linearization facts

Check the equilibrium conditions and the key upright-linearization structure.

Step 1. Equilibrium conditions

Step 2. Upright linearization

Step 3. Feedback linearization

4.4 Design Study C. Satellite Attitude Control

4.4.1 image Example Problem 3.3.7

For the satellite system:

(a) Find the equilibria of the system.

Design Study C guided exercise

Find the satellite equilibria

At equilibrium the body and panel are not accelerating, the relative spring deflection is zero, and the actuator torque is zero.

Step 1. Stop the motion

Step 2. Remove spring torque

Step 3. Decide whether a local approximation is needed

4.5 Interactive Linearization Check

Chapter 4 activity

Local linear model of a nonlinear equation

Use f(x,u)=x2+u to compare the nonlinear surface, the selected operating point, the tangent-plane linearization, and the approximation error.

Interactive Figure 4.I2. The blue mesh is the nonlinear surface f(x,u). The orange mesh is the tangent plane at (x0, u0).

Interactive Figure 4.I3. Heat map of approximation error f(x,u)-flin(x,u). Darker cells indicate larger local linearization error.

Live linearization values

Operating point: \(x_0\) = , \(u_0\) = ; nearby point: \(x\) = , \(u\) =

\(f(x_0,u_0)=x_0^2+u_0\) =

\(A=\frac{\partial f}{\partial x}=2x_0\) = ; \(B=\frac{\partial f}{\partial u}\) =

\(f_{\mathrm{lin}}(x,u)\) at the nearby point = ; true \(f(x,u)\) = ; error =

Notice that the error is small near \(x_0\) and grows as the nearby point moves away from the linearization point.

A linearized perturbation model is most meaningful when the operating point is an equilibrium and the perturbation stays near that point.

4.6 Knowledge Check

Q1. Valid region

When is a Jacobian linearization usually the best approximation?

Q2. Equilibrium condition

For xdot=f(x,u), what condition defines an equilibrium point?

Q3. Jacobian entry

For f(x,u)=x2+u, enter A = ∂f⁄∂x evaluated at xe=2.

Show solution

Answer: 4, because ∂f⁄∂x = 2x and 2(2)=4.

Q4. Equilibrium input

For f(x,u)=x2+u and xe=3, enter the input ue that makes f(xe,ue) = 0.

Show solution

Answer: -9, because 32+ue=0.

Q5. Perturbation variables

In words, what do variables like x-xe represent in a linearized model?

Show solution

Answer: They are deviations, or perturbations, from the equilibrium value.

Q6. Equilibrium pair

For the scalar model xdot = f(x,u) = x2 + u, which pair is an equilibrium?

Q7. Jacobian entry

For f2(x,u)=x22+u, what is A22 = partial f2/partial x2 at x2e = -1?

Q8. Perturbation variable

In a linearized model, what does x - xe represent?

Q9. Local approximation

Which statement about a Jacobian linearization is most accurate?

4.7 Notes and References

Jacobian linearization is a standard technique that is well documented in most introductory textbooks on control. For example, see [4–7]. Feedback linearization is a much deeper topic than can be covered in an introductory textbook on control. A discussion that is similar to ours, that assumes that the nonlinearity is in the input channel, is contained in [5]. Feedback linearization is a fairly standard technique for fully actuated mechanical systems modeled by Euler-Lagrange equations, where the model of the system can be reduced to \[M(q)\ddot{q} + c(q,\dot{q})\dot{q}+g(q) = \tau,\] where \(q\in\mathbb{R}^m\) is the generalized coordinate and \(\tau\in\mathbb{R}^m\) is the generalized force, and where \(M(q)\) is an invertible matrix. In that case we can write \[\ddot{q} = M^{-1}(q)\left(\tau - c(q,\dot{q})\dot{q} - g(q)\right).\] Selecting \(\tau\) as \[\tag{4.16} \tau = c(q,\dot{q})\dot{q} + g(q) + M(q)\nu,\] results in the linear system \[\ddot{q} = \nu,\] where the new control variable \(\nu\) can be designed to stabilize the system. The control law in Equation 4.16 is the feedback linearizing control. This is a standard technique for robot manipulators and is often called the method of computed torque [8–10].

When the nonlinearity is not in the input channel, the system can still often be feedback linearized through a suitable change of variables. A good introduction to the topic is contained in [11]. More advanced coverage of the topic can be found in [12–15].

5 Transfer Function Models

5.1 Theory

The (one-sided) Laplace transform of a time domain signal \(y(t)\) is defined as \[\mathcal{L}\{y(t)\} \stackrel{\triangle}{=}Y(s) = \int_0^\infty y(t) e^{-st}\,dt.\] In essence, the Laplace transform indicates the content of the complex signal \(e^{-st}\) that is contained in \(y(t)\). The Laplace transform of the time derivative of \(y(t)\) is given by \[\mathcal{L}\{\dot{y}\} = \int_0^\infty \dot{y} e^{-st}\,dt.\] Using integration by parts \(\int udv = uv-\int vdu\), where \(u=e^{-st}\) and \(dv = \dot{y}dt\), and assuming that \(\lim_{t\to\infty}y(t)e^{-st}=0\), or that \(s\) is in the region of convergence of the Laplace transform, we get \[\begin{aligned} \mathcal{L}\{\dot{y}\} &= \int_0^\infty \dot{y} e^{-st}\,dt \\ &= y(t)e^{-st}\Big|_0^\infty - \int_0^\infty y(t)\left(-se^{-st}dt\right) \\ &= \lim_{t\to\infty}y(t)e^{-st} - y(0) + s\int_0^\infty y(t)e^{-st}\,dt \\ &= sY(s) - y(0). \end{aligned}\] Similarly, the Laplace transform of the second derivative of \(y(t)\) is given by \[\begin{aligned} \mathcal{L}\{\ddot{y}\} &= s\mathcal{L}\{\dot{y}\} - \dot{y}(0) \\ &= s\left(sY(s)-y(0)\right) - \dot{y}(0) \\ &= s^2 Y(s) - sy(0) - \dot{y}(0). \end{aligned}\]

The transfer function is typically defined as the relationship between the input and the output of the system. In that setting the transfer function is found when all initial conditions are set to zero. This is important to remember in the context of modeling. We will see that state-space models explicitly account for initial conditions, but that transfer functions do not.

Given the \(n^{th}\) order differential equation \[\begin{gathered} y^{(n)} + a_{n-1}y^{(n-1)} + \cdots+ a_1 \dot{y} + a_0 y \\ = b_mu^{(m)} + b_{m-1}u^{(m-1)}+\cdots+b_1\dot{u} + b_0 u, \end{gathered}\] the transfer function from \(u\) to \(y\) is found by taking the Laplace transform of both sides of the equation and setting all initial conditions to zero to obtain \[\begin{gathered} s^nY(s) + a_{n-1}s^{n-1}Y(s) + \cdots+ a_1 sY(s) + a_0 Y(s) \\ = b_ms^{m}U(s) + b_{m-1}s^{m-1}U(s)+\cdots+b_1sU(s) + b_0U(s). \end{gathered}\] Factoring \(Y(s)\) and \(U(s)\) we get \[\begin{gathered} \left(s^n + a_{n-1}s^{n-1} + \cdots+ a_1 s + a_0\right) Y(s) \\ = \left(b_ms^{m}+b_{m-1}s^{m-1}+\cdots+b_1s+b_0\right)U(s). \end{gathered}\] Solving for \(Y(s)\) gives \[Y(s) = \left(\frac{b_ms^{m} + b_{m-1}s^{m-1}+\cdots+b_1s + b_0}{s^n + a_{n-1}s^{n-1} + \cdots+ a_1 s + a_0}\right)U(s),\] where \[H(s)= \frac{b_ms^{m} + b_{m-1}s^{m-1}+\cdots+b_1s + b_0}{s^n + a_{n-1}s^{n-1} + \cdots+ a_1 s + a_0}\] is the transfer function from \(u\) to \(y\).

Given the transfer function \(H(s)\), the poles of the transfer function are the roots of the denominator polynomial \[s^n + a_{n-1}s^{n-1} + \cdots+ a_1 s + a_0 = 0.\] Similarly, the zeros of the transfer function are the roots of the numerator polynomial \[b_ms^{m} + b_{m-1}s^{m-1}+\cdots+b_1s + b_0 = 0.\]

As a concrete example, consider the differential equation given by \[y^{(3)} + 2\ddot{y} + 3\dot{y} + 4y = 5\dot{u} + 6u.\] Taking the Laplace transform of both sides, setting the initial conditions to zero, and factoring \(Y(s)\) and \(U(s)\) gives \[(s^3 + 2s^2 + 3s + 4)Y(s) = (5s+6)U(s).\] Solving for \(Y(s)\) gives \[Y(s) = \frac{5s+6}{s^3+2s^2+3s+4} U(s).\] The transfer function from \(u\) to \(y\) is therefore \[H(s) = \frac{5s+6}{s^3+2s^2+3s+4}.\] The poles of the transfer function are the roots of \(s^3+2s^2+3s+4=0\) or \(p_1=-1.6506\), \(p_2=-0.1747+j1.5469\), and \(p_3=-0.1747-j1.5469\). The zeros of the transfer function are the roots of \(5s+6=0\) or \(z_1 = -6/5\).

5.2.1 image Example Problem 3.1.8

For the single-link robot arm, find the transfer function of the system from the torque \(\tau\) to the angle \(\theta\).

Design Study A guided exercise

Derive the arm transfer function

Start from the feedback-linearized arm equation and solve for \(\Theta(s)/\tilde{\tau}(s)\).

Block diagram of the single-link robot arm transfer function.

The completed transfer function should fit this input-output block diagram from \(\tilde{\tau}\) to \(\theta\).

Step 1. Starting differential equation

Enter the coefficient on \(\ddot{\theta}\).

Step 2. Transfer-function coefficients

Step 3. Pole locations

5.3 SIMO Systems and Cascade Approximations

There are many systems that have multiple inputs and/or multiple outputs. In this case, a transfer function exists from each input to each output. For example, suppose that the system is given by the coupled differential equations \[\begin{aligned} \ddot{y}_1 + a_{11}\dot{y}_1 + \ddot{y}_2 + a_{12}\dot{y}_2 &= b_{11}u_1 + b_{12}u_2 + b_{13}\dot{u}_2 \\ \ddot{y}_2 + a_{22}y_2 &= b_{21}u_2. \end{aligned}\] Taking the Laplace transform and arranging in matrix notation gives \[\left(\begin{array}{c|c} s^2+a_{11}s & s^2+a_{12}s \\ \hline 0 & s^2+a_{22}\end{array}\right) \begin{pmatrix}Y_1(s) \\ Y_2(s)\end{pmatrix} \\ = \left(\begin{array}{c|c} b_{11} & (b_{13}s+b_{12}) \\ \hline0 & b_{21}\end{array}\right) \begin{pmatrix} U_1(s) \\ U_2(s)\end{pmatrix}.\] To find the relevant transfer functions, we need to isolate the outputs on the left-hand side by inverting the matrix on the left. Using the inverse formula for a \(2\times 2\) matrix derived in Appendix 31 \[\begin{pmatrix} a & b \\ c & d \end{pmatrix}^{-1} = \frac{\begin{pmatrix} d & -b \\ -c & a\end{pmatrix}}{ad-bc}\] we get \[\begin{aligned} \begin{pmatrix}Y_1 \\ Y_2\end{pmatrix} &= \left(\begin{array}{c|c} s^2+a_{11}s & s^2+a_{12}s \\ \hline 0 & s^2+a_{22}\end{array}\right)^{-1} \left(\begin{array}{c|c} b_{11} & b_{13}s+b_{12} \\ \hline 0 & b_{21}\end{array}\right) \begin{pmatrix} U_1 \\ U_2\end{pmatrix} \\ &= \frac{\left(\begin{array}{c|c} s^2+a_{22} & -s^2-a_{12}s \\ \hline 0 & s^2+a_{11}s\end{array}\right)}{(s^2+a_{11}s)(s^2+a_{22})} \left(\begin{array}{c|c} b_{11} & b_{13}s+b_{12} \\ \hline 0 & b_{21}\end{array}\right) \begin{pmatrix} U_1 \\ U_2\end{pmatrix} \\ &= \frac{\left(\begin{array}{c|c} b_{11}(s^2+a_{22}) & (s^2+a_{22})(b_{13}s+b_{12})-b_{21}(s^2+a_{12}s) \\ \hline 0 & b_{21}(s^2+a_{11}s)\end{array}\right)}{(s^2+a_{11}s)(s^2+a_{22})} \begin{pmatrix} U_1 \\ U_2\end{pmatrix} \\ &= \left(\begin{array}{c|c} \frac{b_{11}}{s^2+a_{11}s} & \frac{b_{13}s^3+(b_{12}-b_{21})s^2+(b_{13}a_{22}-b_{21}a_{12})s+a_{22}b_{12}}{(s^2+a_{11}s)(s^2+a_{22})} \\ \hline 0 & \frac{b_{21}}{s^2+a_{22}}\end{array}\right) \begin{pmatrix} U_1 \\ U_2\end{pmatrix}. \end{aligned}\] Therefore, the transfer function from \(u_1\) to \(y_1\) is \(\frac{b_{11}}{s^2+a_{11}s}\), the transfer function from \(u_2\) to \(y_1\) is \(\frac{b_{13}s^3+(b_{12}-b_{21})s^2+(b_{13}a_{22}-b_{21}a_{12})s+a_{22}b_{12}}{(s^2+a_{11}s)(s^2+a_{22})}\), the transfer function from \(u_1\) to \(y_2\) is \(0\), and the transfer function from \(u_2\) to \(y_2\) is \(\frac{b_{21}}{s^2+a_{22}}\).

For many of the case studies that we will look at in this book, there is a single input, but we are also interested in controlling two or more measurements or outputs. State-space control techniques are able to create control laws to control multiple outputs in a single design step, as we will see in later chapters. However, we also want to be able to create single-input, multiple-output controllers using more classical transfer-function based approaches. Doing so will require more intuition about the systems we are controlling, as well as a clear understanding of our control objectives so that we can make appropriate design decisions and simplifying assumptions.

The majority of our design studies (specifically studies B, C, E, and F) have coupled, higher-order dynamics (greater than order two) with multiple outputs. Instead of coming up with a single feedback loop to control the multiple outputs of interest, we will form a cascade of two lower-order transfer functions and design two independent control loops. Forming the cascade of lower-order transfer functions requires insights into the dynamic behavior of the system, because it may require simplifying assumptions about the dynamic coupling between the two subsystems. Instead of a two-way coupling, the cascade may make the dynamic coupling one-way. To reduce the complexity of the system, we may make simplifying assumptions about the dynamics of one of the subsystems. It is essential for these simplifications to be justifiable given the parameters of the system and our control objectives. For example, in design study C, we form a cascade of two transfer functions: the first is from the torque input to the satellite angular position and the second is from the satellite angular position to the solar panel angular position. Because the satellite is more massive than the solar panels, we will make a valid assumption that while the satellite significantly influences the dynamic behavior of the solar panels, the solar panels do not significantly influence the dynamic behavior of the satellite. As we will see, this will simplify the design of the control system significantly and result in a viable control design that provides good performance.

In forming cascades of transfer functions, other factors may influence the form of the cascade. Our control priorities may play a significant role. For example, in design study B, the balancing of the inverted pendulum is the highest priority and therefore, we will use the force input to control the angle of the pendulum. Of importance, but lower priority, is controlling the cart. These considerations will lead us to form the cascade using the transfer functions from force to pendulum angle and from pendulum angle to cart position. In other situations, the causality of the dynamic behavior is more transparent. In the block-beam system, the force on the beam causes the beam angle to change and the change in beam angle causes the block to slide. We will form the transfer function cascade for the block-beam system accordingly. In the planar VTOL aircraft system, torque from the differential thrust causes the aircraft to pitch, while thrust combined with non-zero pitch causes the aircraft to translate. It is natural, therefore, to think of torque causing pitch, and pitch causing translational motion. We will thus form a cascade of two transfer functions: from torque to pitch angle and from pitch angle to horizontal position.

In forming a cascade of two (or more) transfer functions to represent the dynamics of a single system, it is critically important that we consider the physics of the system and our control objectives as we make simplifying assumptions. Important questions to consider include:

  • What is the control input to the system?

  • What outputs of the system are to be controlled?

  • What outputs can be measured?

  • What physically justifiable simplifications can be made about the dynamic coupling between subsystems?

  • What physically justifiable simplifying assumptions can be made about the dynamics of the system?

Asking and answering these questions is fundamental to the design of successful control systems. The more insight you have into the physical behavior of the system you are controlling, the better your control system designs will be.

5.4 Design Study B. Inverted Pendulum

5.4.1 image Example Problem 3.2.8

For the inverted pendulum:

(a) Start with the linearized equations and use the Laplace transform to convert the equations of motion to the s-domain.

(b) Find the transfer functions from the input \(\tilde{F}(s)\) to the outputs \(\tilde{Z}(s)\) and \(\tilde{\Theta}(s)\). Assume that the damping constant is negligible. How does this simplify the transfer functions? Is this a reasonable assumption?

(c) From the simplified \(\tilde{Z}(s)/\tilde{F}(s)\) and \(\tilde{\Theta}(s)/\tilde{F}(s)\) transfer functions, compute the \(\tilde{Z}(s)/\tilde{\Theta}(s)\) transfer function. Draw a block diagram of the system as a series of two transfer functions from \(\tilde{F}(s)\) to \(\tilde{\Theta}(s)\) and from \(\tilde{\Theta}(s)\) to \(\tilde{Z}(s)\).

(d) Describe how this transfer-function cascade makes sense physically. How does force influence the pendulum angle? How does the pendulum angle influence the cart position?

Design Study B guided exercise

Build the pendulum transfer-function cascade

Start from the linearized equations and identify the force-to-angle and angle-to-position relationship.

Cascade block diagram for the inverted pendulum.

Use the cascade structure to separate the fast force-to-angle subsystem from the angle-to-position subsystem.

Step 1. Simplifying assumption

Step 2. Force-to-angle subsystem

Step 3. Angle-to-position subsystem

The PID and loopshaping techniques that we will discuss in Parts III and V will use the approximate transfer function models of the plant derived above. The state-space methods discussed in Part IV will use a state-space model, which does not depend on neglecting the coupling between subsystems and does not depend on a separation into fast and slow subsystems.

5.5 Design Study C. Satellite Attitude Control

5.5.1 image Example Problem 3.3.8

For the satellite attitude control problem:

(a) Start with the linearized equations for the satellite attitude problem and use the Laplace transform to convert the equations of motion to the s-domain.

(b) Find the full transfer matrix from the input \(\tau(s)\) to the outputs \(\Phi(s)\) and \(\Theta(s)\).

(c) From the transfer matrix, find the second-order transfer function from \(\Theta(s)\) to \(\Phi(s)\).

(d) Under the assumption that the panel moment of inertia \(J_p\) is significantly smaller than the spacecraft moment of inertia \(J_s\) (specifically, \((J_s+J_p)/J_s \approx 1\)), find the second-order approximation for the transfer function from \(\tau(s)\) to \(\Theta(s)\).

(e) From your results on parts (c) and (d), form the approximate transfer function cascade for the satellite/panel system and justify why it makes sense physically.

Design Study C guided exercise

Build the satellite transfer-function cascade

The transfer-function model separates the body-angle dynamics from the panel-angle dynamics using a physically motivated cascade approximation.

Satellite cascade block diagram.

The approximation lets the body angle drive the panel dynamics while neglecting the panel's back-effect on the massive satellite body.

Step 1. Identify the s-domain outputs

Step 2. Body angle to panel angle

Step 3. Torque to body angle approximation

Step 4. Interpret the approximation

5.6 Interactive Transfer Function Check

Chapter 5 activity

Read a second-order transfer function

Adjust the coefficients in H(s)=b0/(s2+a1s+a0) and watch how the denominator determines poles while b0/a0 sets the DC gain when a0 is nonzero.

Transfer function
Poles
DC gain
System order

Transfer functions describe zero-initial-condition input-output behavior. Poles come from the denominator roots; zeros come from numerator roots.

5.7 Knowledge Check

Q1. Initial conditions

What initial-condition assumption is used when forming a transfer function?

Q2. Poles

Where do the poles of a transfer function come from?

Q3. DC gain

For H(s)=6/(s2+4s+3), enter the DC gain H(0).

Show solution

Answer: 2, because H(0)=6/3.

Q4. First-order pole

For the denominator s+4, enter the pole location.

Show solution

Answer: -4, because s+4=0 gives s=-4.

Q5. Numerator roots

What are the roots of a transfer function numerator called?

Show solution

Answer: They are zeros.

Q6. Transfer-function assumption

Which assumption is used when deriving a transfer function from a differential equation?

Q7. Pole-zero identification

For G(s)=(s+4)/((s+1)(s+3)), which statement is correct?

Q8. DC gain

For stable G(s)=(s+2)/(s2+6s+8), what final value should a unit step input approach?

Q9. Cascade approximation

When is a cascade approximation most useful?

5.8 Notes and References

The Laplace transform can be found in introductory textbooks on signals and systems like [16] and in introductory textbooks on differential equations. The transfer function of a linear time-invariant system is also covered in introductory textbooks on signals and systems, and in most introductory textbooks on control like [4].

6 State-Space Models

6.1 Theory

The transfer function models discussed in the previous chapter are a frequency-domain representation of the system because they describe how the system responds to sinusoidal inputs at specific frequencies. In contrast, differential equation models are time-domain representations of the systems that directly model the time-evolution of the system. The state-space model is also a time-domain representation that is essentially a reformatting of the differential equations. In essence, the state-space model represents the system by an input, an output, and a memory element, called the state. In this book, the input will always be denoted as \(u(t)\), the output as \(y(t)\), and the state as \(x(t)\). The state represents all of the memory elements in the system. For example, the state may represent a storage register, the altitude of an aircraft, the velocity of a car, the voltage across a capacitor, or the current through an inductor.

The state-space model is composed of two equations. The first equation is called the state evolution equation and represents how the memory elements, or states, change as a function of the current state and the inputs to the system. The second equation is called the output equation and describes how the current output of the system depends on the current state and the current input. The general state-space equations for a continuous time system are written as \begin{align} \dot{x} &= f(x,u) \tag{6.1} \\ y &= h(x,u), \tag{6.2} \end{align} where Equation 6.1 is the state evolution equation and Equation 6.2 is the output equation. Note that for continuous time systems the state evolution equation is a system of coupled first order nonlinear differential equations. The general state-space equations for a discrete time system are written as \begin{align} x[k+1] &= f(x[k],u[k]) \tag{6.3} \\ y[k] &= h(x[k],u[k]), \tag{6.4} \end{align} where again Equation 6.3 is the state evolution equation, this time given by a system of coupled first order difference equations, and Equation 6.4 is the output equation.

Any nonlinear \(n^{th}\) order differential equation can be transformed into state-space form. For example, consider the nonlinear differential equation \[\dddot{y} + y^2\ddot{y} + \sin(y\dot{y}) + e^y = u,\] where \(u\) is the input and \(y\) is the output. Define the state as \[x=\begin{pmatrix}x_1 \\ x_2 \\ x_3 \end{pmatrix}\stackrel{\triangle}{=}\begin{pmatrix} y \\ \dot{y} \\ \ddot{y} \end{pmatrix}.\] Then the state evolution equation can be derived as \[\begin{aligned} \dot{x} &= \begin{pmatrix} \dot{x}_1 \\ \dot{x}_2 \\ \dot{x}_3 \end{pmatrix} = \begin{pmatrix} \dot{y} \\ \ddot{y} \\ \dddot{y} \end{pmatrix} = \begin{pmatrix} \dot{y} \\ \ddot{y} \\ -y^2\ddot{y} - \sin(y\dot{y}) - e^y + u \end{pmatrix} \\ &= \begin{pmatrix} x_2 \\ x_3 \\ -x_1^2x_3 - \sin(x_1x_2) - e^{x_1} + u \end{pmatrix} \stackrel{\triangle}{=}f(x,u), \end{aligned}\] and the output equation is \[y = x_1 \stackrel{\triangle}{=}h(x,u).\] As another example, consider the coupled differential equations \[\begin{aligned} \ddot{y}_1 + \dot{y}_1y_2 + y_2 &=u \\ \ddot{y}_2 + \dot{y}_2\cos(y_1)+\dot{y_1} &=0. \end{aligned}\] Defining the output as \(y=(y_1, y_2)^{\top}\) and the state as \[x=\begin{pmatrix} x_1 \\ x_2 \\ x_3 \\ x_4 \end{pmatrix} \stackrel{\triangle}{=}\begin{pmatrix} y_1 \\ y_2 \\ \dot{y}_1 \\ \dot{y}_2 \end{pmatrix},\] the state evolution equation can be derived as \[\begin{aligned} \dot{x} &= \begin{pmatrix} \dot{x}_1 \\ \dot{x}_2 \\ \dot{x}_3 \\ \dot{x}_4 \end{pmatrix} = \begin{pmatrix} \dot{y}_1 \\ \dot{y}_2 \\ \ddot{y}_1 \\ \ddot{y}_2 \end{pmatrix} = \begin{pmatrix} \dot{y}_1 \\ \dot{y}_2 \\ -\dot{y}_1y_2 - y_2 +u \\ -\dot{y}_2\cos(y_1)-\dot{y_1} \end{pmatrix} \\ &= \begin{pmatrix} x_3 \\ x_4 \\ -x_3x_2 - x_2 +u \\ -x_4\cos(x_1)-x_3 \end{pmatrix} \stackrel{\triangle}{=}f(x,u), \end{aligned}\] and the output equation is given by \[y = \begin{pmatrix} x_1 \\ x_2 \end{pmatrix} \stackrel{\triangle}{=}h(x,u).\]

6.1.1 Jacobian Linearization Revisited

Jacobian linearization of the system is more straightforward when the equations are in state-space form. Given the nonlinear state-space equations \begin{align} \dot{x} &= f(x,u) \tag{6.5} \\ y &= h(x,u) \tag{6.6} \end{align} an equilibrium point is defined as any \((x_e,u_e)\) such that \(f(x_e,u_e)=0\). In other words, equilibrium points are combinations of states and inputs where the state stops evolving in time. To linearize about an equilibrium point, Equations 6.5 and 6.6 can be expanded in a Taylor series about \((x_e,u_e)\) as \begin{align} f(x,u) &\approx f(x_e,u_e) + \left.\frac{\partial f}{\partial x}\right|_e (x-x_e) + \left.\frac{\partial f}{\partial u}\right|_e(u-u_e) + H.O.T. \tag{6.7}\\ h(x,u) &\approx h(x_e,u_e) + \left.\frac{\partial h}{\partial x}\right|_e (x-x_e) + \left.\frac{\partial h}{\partial u}\right|_e(u-u_e) + H.O.T., \tag{6.8} \end{align} where the Jacobian matrices are defined as \[\begin{aligned} \frac{\partial f}{\partial x} &\stackrel{\triangle}{=}\begin{pmatrix} \frac{\partial f_1}{\partial x_1} & \dots & \frac{\partial f_1}{\partial x_n} \\ \vdots & & \vdots \\ \frac{\partial f_n}{\partial x_1} & \dots & \frac{\partial f_n}{\partial x_n} \end{pmatrix} \\ \frac{\partial f}{\partial u} &\stackrel{\triangle}{=}\begin{pmatrix} \frac{\partial f_1}{\partial u_1} & \dots & \frac{\partial f_1}{\partial u_m} \\ \vdots & & \vdots \\ \frac{\partial f_n}{\partial u_1} & \dots & \frac{\partial f_n}{\partial u_m} \end{pmatrix} \\ \frac{\partial h}{\partial x} &\stackrel{\triangle}{=}\begin{pmatrix} \frac{\partial h_1}{\partial x_1} & \dots & \frac{\partial h_1}{\partial x_n} \\ \vdots & & \vdots \\ \frac{\partial h_p}{\partial x_1} & \dots & \frac{\partial h_p}{\partial x_n} \end{pmatrix} \\ \frac{\partial h}{\partial u} &\stackrel{\triangle}{=}\begin{pmatrix} \frac{\partial h_1}{\partial u_1} & \dots & \frac{\partial h_1}{\partial u_m} \\ \vdots & & \vdots \\ \frac{\partial h_p}{\partial u_1} & \dots & \frac{\partial h_p}{\partial u_m} \end{pmatrix}. \end{aligned}\] Therefore, \(\frac{\partial f}{\partial x}\) is an \(n\times n\) matrix, \(\frac{\partial f}{\partial u}\) is an \(n\times m\) matrix, \(\frac{\partial h}{\partial x}\) is a \(p\times n\) matrix, and \(\frac{\partial h}{\partial u}\) is a \(p\times m\) matrix.

Defining \(\tilde{x}\stackrel{\triangle}{=}x-x_e\) and \(\tilde{u}=u-u_e\) and letting \(A=\left.\frac{\partial f}{\partial x}\right|_e\) and \(B=\left.\frac{\partial f}{\partial u}\right|_e\), and noting that \(\dot{\tilde{x}}=\dot{x}-\dot{x}_e=\dot{x}\), results in the linearized state evolution equation \[\dot{\tilde{x}}=A\tilde{x} + B\tilde{u}.\] At the equilibria, the output may not necessarily be zero. If we define the equilibrium output to be \(y_e=h(x_e,u_e)\) and the linearized output as \(\tilde{y}=y-y_e\), and define \(C\stackrel{\triangle}{=}\left.\frac{\partial h}{\partial x}\right|_e\) and \(D\stackrel{\triangle}{=}\left.\frac{\partial h}{\partial u}\right|_e\), then using Equation 6.8 in 6.6 gives \[\begin{aligned} \tilde{y} &= y-y_e \\ &\approx h(x_e,u_e)+C\tilde{x} + D\tilde{u} - h(x_e,u_e) \\ &= C\tilde{x} + D\tilde{u}. \end{aligned}\] The linearized state-space equations are therefore \[\begin{aligned} \dot{\tilde{x}} &= A\tilde{x} + B\tilde{u} \\ \tilde{y} &= C\tilde{x} + D\tilde{u}. \end{aligned}\]

6.1.2 Converting State-Space Models to Transfer Function Models

Linear state-space models can be converted to transfer function models using the following technique. Suppose that the linear state-space model is given by \begin{align} \dot{x} &= Ax + Bu \tag{6.9} \\ y &= Cx + Du. \tag{6.10} \end{align} Defining the Laplace transform of a vector to be the Laplace transform of each element, i.e., \[\mathcal{L}\left\{\begin{pmatrix} x_1 \\ \vdots \\ x_n \end{pmatrix}\right\} = \begin{pmatrix} \mathcal{L}\left\{x_1\right\} \\ \vdots \\ \mathcal{L}\left\{x_n\right\}\end{pmatrix},\] and noting that the Laplace transform is a linear operator, which implies that \[\mathcal{L}\{Ax\} = A\mathcal{L}\{x\},\] taking the Laplace transform of Equations 6.9 and 6.10, and setting the initial conditions to zero, gives \begin{align} sX(s) &= AX(s) + BU(s) \tag{6.11} \\ Y(s) &= CX(s) + DU(s). \tag{6.12} \end{align} Solving 6.11 for \(X(s)\) gives \begin{align} & sX(s)-AX(s) = BU(s) \notag \\ \implies & (sI-A)X(s) = BU(s) \notag \\ \implies & X(s) = (sI-A)^{-1}BU(s), \tag{6.13} \end{align} where \(I\) is the \(n\times n\) identity matrix. Substituting 6.13 into 6.12 gives \[\begin{aligned} & Y(s) = C(sI-A)^{-1}BU(s) + DU(s) \\ \implies & Y(s) = \left[ C(sI-A)^{-1}B + D\right]U(s). \end{aligned}\] The transfer function from \(u\) to \(y\) is therefore \[\tag{6.14} H(s) = C(sI-A)^{-1}B + D.\] As an example, suppose that the state-space equations are given by \[\begin{aligned} \dot{x} &= \begin{pmatrix} 0 & 1 \\ -4 & -3 \end{pmatrix} x + \begin{pmatrix} 0 \\ 2 \end{pmatrix} u \\ y &= \begin{pmatrix} 1 & 0 \end{pmatrix} x + (0)u, \end{aligned}\] then the transfer function from \(u\) to \(y\) is given by \[\begin{aligned} H(s) &= C(sI-A)^{-1}B + D \\ &= \begin{pmatrix} 1 & 0\end{pmatrix}\left(s\begin{pmatrix} 1 & 0 \\ 0 & 1\end{pmatrix} - \begin{pmatrix} 0 & 1 \\ -4 & -3 \end{pmatrix}\right)^{-1}\begin{pmatrix} 0 \\ 2\end{pmatrix} + 0 \\ &= \begin{pmatrix} 1 & 0\end{pmatrix}\begin{pmatrix} s & -1 \\ 4 & s+3\end{pmatrix}^{-1}\begin{pmatrix} 0 \\ 2\end{pmatrix}\\ &= \begin{pmatrix} 1 & 0\end{pmatrix}\frac{\begin{pmatrix} s+3 & 1 \\ -4 & s\end{pmatrix}}{s^2+3s+4}\begin{pmatrix} 0 \\ 2\end{pmatrix}\\ &= \frac{\begin{pmatrix} s+3 & 1 \end{pmatrix}}{s^2+3s+4}\begin{pmatrix} 0 \\ 2\end{pmatrix}\\ &= \frac{2}{s^2+3s+4}. \end{aligned}\]

The form of the transfer function in Equation 6.14 allows us to derive a simple relationship between the poles of the transfer function \(H(s)\) and the eigenvalues of \(A\). Recall (see Appendix 31) that for any square invertible matrix \(M\), we have that \[M^{-1} = \frac{\text{adj}(M)}{\text{det}(M)},\] where \(\text{adj}(M)\) is the adjugate of \(M\) defined as the transpose of the cofactors of \(M\), and \(\text{det}(M)\) is the determinant of \(M\). Therefore \[\begin{aligned} H(s) &= C(sI-A)^{-1}B+D \\ &=\frac{C\text{adj}(sI-A)B}{\text{det}(sI-A)}+D \\ &= \frac{C\text{adj}(sI-A)B+D\text{det}(sI-A)}{\text{det}(sI-A)}. \end{aligned}\] This expression implies that the zeros of \(H(s)\) are given by the roots of the polynomial \[C\text{adj}(sI-A)B+D\text{det}(sI-A) = 0,\] and that the poles of \(H(s)\) are given by the roots of the polynomial \[\tag{6.15} \text{det}(sI-A) = 0.\] Recall from linear algebra (see Appendix 31) that Equation 6.15 also defines the eigenvalues of \(A\). Therefore, the poles of \(H(s)\) are equivalent to the eigenvalues of \(A\).

In Chapters 14 and 16 we will show two general techniques for converting SISO transfer function models into state-space models.

6.2.1 image Example Problem 3.1.9

For the feedback linearized equations of motion for the single-link robot arm given in Equation 4.7, define the states as \(x=(\theta,\dot{\theta})^{\top}\), the input as \(\tilde{u}=\tilde{\tau}\), and the measured output as \(y=\theta\). Find the linear state-space equations in the form \[\begin{aligned} \dot{x} &= Ax + B\tilde{u} \\ y &= Cx + D\tilde{u}. \end{aligned}\]

Design Study A guided exercise

Work through the arm state-space model

Use the feedback-linearized arm equation and the state definitions in the problem statement. For compact entry, use \(a = 3b/(m\ell^2)\) and \(\beta = 3/(m\ell^2)\).

Step 1. Convert the second-order equation to state derivatives

With \(x_1 = \theta\) and \(x_2 = \dot{\theta}\), enter the two state derivative equations in coefficient form.

Step 2. Fill in the state-space matrices

Enter the entries of \(A\), \(B\), \(C\), and \(D\). Use \(a\) and \(\beta\) as defined above.

\(A =\)
\(B =\)
\(C =\)

Step 3. Check the transfer function from the state-space model

The transfer function should match the result from Chapter 5. Enter the numerator and denominator coefficients of \(H(s)=C(sI-A)^{-1}B+D\).

6.3 Design Study B. Inverted Pendulum

6.3.1 image Example Problem 3.2.9

Defining the states as \(\tilde{x}=(\tilde{z},\tilde{\theta},\dot{\tilde{z}},\dot{\tilde{\theta}})^{\top}\), the input as \(\tilde{u}=\tilde{F}\), and the measured output as \(\tilde{y}=(\tilde{z},\tilde{\theta})^{\top}\), find the linear state-space equations in the form \[\begin{aligned} \dot{\tilde{x}} &= A\tilde{x} + B\tilde{u} \\ \tilde{y} &= C\tilde{x} + D\tilde{u}. \end{aligned}\]

Design Study B guided exercise

Construct the pendulum state-space model

Confirm the state, output, and key matrix structure for the four-state linear model.

Step 1. State and output definitions

Step 2. Matrix sizes

Step 3. Input channel

6.4 Design Study C. Satellite Attitude Control

6.4.1 image Example Problem 3.3.9

Suppose that a star tracker is used to measure \(\theta\) and a strain gauge is used to approximate \(\phi-\theta\). Defining the states as \(x=(\theta,\phi,\dot{\theta},\dot{\phi})^{\top}\), the input as \(u=\tau\), and the measured output as \(y=(\theta,\phi-\theta)^{\top}\), find the linear state-space equations in the form \[\begin{aligned} \dot{x} &= Ax + Bu \\ y &= Cx + Du. \end{aligned}\]

Design Study C guided exercise

Build the satellite state-space model

The state vector is \(x=(\theta,\phi,\dot{\theta},\dot{\phi})^T\), the input is body torque \(\tau\), and the measured output is \(y=(\theta,\phi-\theta)^T\).

Step 1. Assign the states

Step 2. Fill the kinematic rows of \(A\)

Step 3. Place the torque input

Step 4. Build the measured output

6.5 Interactive State-Space Check

Chapter 6 activity

Build and test a state-space model

Start with y” + a1y’ + a0y = b0u. Define x1=y and x2=y’, then compare the state equation with the separate output equation.

State definitions

State equation

A matrix

B matrix

Current derivative

Output equation

Current output

Key separation: A and B determine how the state moves. C and D determine what is measured as the output. Changing C or D changes y(t), but it does not change the state trajectory.

6.6 Knowledge Check

Q1. State meaning

What role does the state play in a state-space model?

Q2. Output equation

What does y = Cx + Du describe?

Q3. State count

How many first-order state equations are typically needed for a third-order differential equation?

Show solution

Answer: 3, because an nth-order differential equation becomes n first-order state equations.

Q4. State derivative

For the state equation

dx2⁄dt = -2x1 - 3x2 + 4u,

enter dx2⁄dt when x1 = 1, x2 = 0, and u = 1.

Show solution

Answer: 2, because dx2⁄dt = -2(1) - 3(0) + 4(1) = 2.

Q5. Direct input path

In y=Cx+Du, what term names the direct path from input to output?

Show solution

Answer: The D matrix, often called the direct feedthrough term.

Q6. State dimension

A third-order ordinary differential equation is normally represented with how many states?

Q7. Output matrix

If A and B are unchanged but C is changed, what changes most directly?

Q8. Matrix dimensions

For a model with two states, one input, and one output, which dimensions are consistent?

Q9. Transfer function from state-space

Which expression maps a state-space model to its transfer function?

Q10. Stability from A

For A with rows (1, 0) and (2, -3), what can you conclude about the open-loop state dynamics?

6.7 Notes and References

There are numerous resources that derive state-space models from differential equations and transfer functions. For example [4–6, 17].

Part III

PID Control Design

In this part of the book we will introduce feedback control by studying the most commonly used industrial control law, the so-called proportional-integral-derivative control, or PID control. PID controllers are widely used because they are intuitive and easy to understand, they can be designed without any understanding of the underlying physics of the system, and a model of the system is not required, which is especially important in the chemical processing industry. However, the stability and performance of the closed-loop system can only be guaranteed when using PID control on second-order systems. In Part IV on observer-based control and Part V on loopshaping, we will extend the basic ideas covered in this Part to higher-order systems.

Fig. 6.1 shows a basic proportional control strategy. The output \(y\) of the physical system is subtracted from the commanded reference output \(r\) to produce the error \(e=r-y\). Proportional control determines the input to the system \(u\) to be proportional to the error, i.e., \(u=k_P e\). The constant gain \(k_P\) is called the proportional gain.

Proportional Control. The feedback control is a gain k_p multiplied by the error.

Proportional control can be augmented with integral control to produce PI control, as shown in Fig. 6.2. The basic idea is to integrate the error so that the system responds to error accrued in the past. The constant gain \(k_I\) is called the integral gain.

Proportional plus Integral (PI) Control. The feedback control is a linear combination of proportional and integral control.

Alternatively, proportional control can be augmented with a derivative control as shown in Fig. 6.3. The idea is to respond to how fast the error is changing, or the derivative of the error. The constant gain \(k_D\) is called the derivative gain.

Proportional plus Derivative (PD) Control. The feedback control is a linear combination of proportional and derivative control.

When all three elements are used, as shown in Fig. 6.4, the resulting controller is called a PID control. In Part III of this book, we will explore various aspects of PID control. Many of these concepts can be generalized to other control schemes in later chapters, and so our study of PID control will also help to motivate and understand more advanced concepts.

Proportional plus Integral plus Derivative (PID) Control. The feedback control is a linear combination of proportional, integral, and derivative control.

Intuition for PID control can be gained by considering the step response shown in Fig. 6.5. At the beginning of the response, there is a significant error between the current output \(y(t)\) and the reference command \(r(t)\). The proportional control term will tend to push the system so as to reduce the gap between \(y(t)\) and \(r(t)\). As \(y(t)\) begins to change, a fast response may lead to significant overshoot due to the momentum in the system. Therefore, if it is moving too quickly, we may want to slow down the response, or if it is moving too slowly, we may want to speed up the response. Derivative control is used to affect these changes. After the response has settled into steady state, there may be significant steady-state error, as shown in Fig. 6.5. Integral control adds up this steady error and will eventually act to reduce the steady-state error. A good example is an aircraft in a constant crosswind. An integrator can be used to correct the response of the aircraft so that it crabs into the wind to maintain its desired flight path.

Intuitive interpretation of PID control. Proportional control acts on the current error, integral control acts on accrued past error, and derivative control acts on anticipated future error.

Part III of the book is organized as follows. In Chapter 10 we will show how PD control can be used to specify the desired closed-loop poles of a second-order system. In Chapter 11 we introduce the concepts of rise time, natural frequency, and damping ratio for second-order systems and show how these concepts relate to the location of the closed-loop poles. We also show how these quantities can be used to design PD controllers for second-order systems and cascades of second-order systems. In Chapter 12 we use the final value theorem to show the effect of integrators on the closed-loop system. We introduce the notion of system type in the context of reference tracking and disturbance rejection. Finally, in Chapter 13 we show how to write computer code to implement PID controllers.

7 Pole Placement for Second-Order Systems

7.1 Theory

Suppose that the model for a linearized physical system is given by the second-order transfer function \[\tag{7.1} P(s) = \frac{b_0}{s^2 + a_1s + a_0}.\] The open-loop poles of the plant \(P(s)\) are defined to be the roots of the open-loop characteristic polynomial \[\Delta_{ol}(s) = s^2 + a_1 s + a_0,\] which are given by \[p_{ol} = -\frac{a_1}{2} \pm \sqrt{\left(\frac{a_1}{2}\right)^2-a_0}.\] Note that the open-loop poles are determined by the physical parameters and that the poles may be in the right half-plane. If we use PD control to regulate the output \(y\) to the reference command \(r\), then the block diagram is shown in Fig. 7.1.

PD control of a second-order system.

The transfer function for the closed-loop system can be derived by noting from the block diagram that \begin{align} & Y(s) = \left(\frac{b_0}{s^2 + a_1s + a_0}\right)\left(k_P + k_D s\right)\left(R(s)-Y(s)\right) \notag \\ \implies & (s^2 + a_1s + a_0)Y(s) = \left(b_0k_P + b_0k_D s\right)\left(R(s)-Y(s)\right) \notag \\ \implies & \left[(s^2 + a_1s + a_0)+\left(b_0k_P + b_0k_D s\right)\right]Y(s) \\ & = \left(b_0k_P + b_0k_D s\right)R(s) \notag \\ \implies & (s^2 + (a_1 + b_0k_D)s + (a_0+b_0k_P))Y(s) \\ & = \left(b_0k_P + b_0k_D s\right)R(s) \notag \\ \implies & Y(s) = \frac{b_0k_D s + b_0k_P}{s^2 + (a_1 + b_0k_D)s + (a_0+b_0k_P)}R(s). \tag{7.4} \end{align} Equation 7.4 constitutes the closed-loop transfer function for the system under the influence of PD control. The closed-loop poles are given by the roots of the closed-loop characteristic polynomial \[\Delta_{cl}(s) = s^2 + (a_1+b_0k_D) s + (a_0+b_0k_P),\] which are \[p_{cl} = -\frac{a_1 + b_0k_D}{2} \pm \sqrt{\left(\frac{(a_1+b_0k_D)}{2}\right)^2-(a_0+b_0k_P)}.\] Note that the closed-loop poles can be specified by the designer by selecting \(k_P\) and \(k_D\). The basic idea is to select desired closed-loop poles \(-p_1^d\) and \(-p_2^d\) and then to form the desired characteristic polynomial \[\Delta_{cl}^d(s) = (s+p_1^d)(s+p_2^d) \stackrel{\triangle}{=}s^2 + \alpha_1 s + \alpha_0.\] By setting \(\Delta_{cl}(s)=\Delta_{cl}^d(s)\) we can equate the leading coefficients of each term of the polynomial and solve for the gains \(k_P\) and \(k_D\) as \[\begin{aligned} k_P &= \frac{\alpha_0-a_0}{b_0} \\ k_D &= \frac{\alpha_1-a_1}{b_0}. \end{aligned}\]

One of the disadvantages to the PD architecture shown in Fig. 7.1 is the introduction of a zero in the closed-loop transfer function. Note that while the open-loop system 7.1 does not have a zero, the closed-loop system 7.4 has a zero at \[z_{cl} = - \frac{k_P}{k_D}.\] The presence of the zero will modify the closed-loop response of the system. A simple trick that removes the zero is to use the control structure shown in Fig. 7.2. In this particular case, the differentiator acts only on the output \(y\) and not on the error \(e\). Notice the change of sign on the signal coming from the differentiator.

PD control of a second-order system, where the derivative control only differentiates the output y and not the error e.

In this case the closed-loop transfer function is calculated as \begin{align} & Y(s) = \left(\frac{b_0}{s^2 + a_1s + a_0}\right)\left(k_P (R(s)-Y(s)) - k_D s Y(s) \right) \notag \\ \implies & (s^2 + a_1s + a_0)Y(s) = \left(b_0k_P (R(s)-Y(s)) - b_0k_D s Y(s) \right) \notag \\ \implies & \left[(s^2 + a_1s + a_0)+\left(b_0k_P + b_0k_D s\right)\right]Y(s) = b_0k_P R(s) \notag \\ \implies & (s^2 + (a_1 + b_0k_D)s + (a_0+b_0k_P))Y(s) = b_0k_P R(s) \notag \\ \implies & Y(s) = \frac{b_0k_P}{s^2 + (a_1 + b_0k_D)s + (a_0+b_0k_P)}R(s). \tag{7.5} \end{align} Note that the closed-loop transfer function 7.5 has the same poles as Equation 7.4, but that the zero has been removed. An added benefit to the structure shown in Fig. 7.2 is that when \(r(t)\) is a step input, the derivative can introduce a large signal spike in \(u(t)\). These large spikes are removed by only differentiating \(y(t)\) instead of \(e(t)=r(t)-y(t)\).

7.2.1 image Example Problem 3.1.10

(a) Given the open-loop transfer function found in problem 3.1.6, find the open-loop poles of the system, when the equilibrium angle is \(\theta_e=0\).

(b) Using the PD control architecture shown in Fig. 7.2, find the closed-loop transfer function from \(r_{\theta}\) to \(\theta\) and find the closed-loop poles as a function of \(k_P\) and \(k_D\).

(c) Select \(k_P\) and \(k_D\) to place the closed-loop poles at \(p_1=-3\) and \(p_2=-4\).

(d) Using the gains from part (c), implement the PD control for the single-link robot arm in simulation and plot the step response for an amplitude of 30 degrees.

Design Study A guided exercise

Compute the PD gains

Match the closed-loop characteristic polynomial to desired poles at \(-3\) and \(-4\).

PD feedback block diagram for the single-link robot arm.

Use this PD feedback structure to derive the closed-loop characteristic polynomial.

Step 1. Desired characteristic polynomial

Step 2. PD gains

Pseudocode

The complete solution includes a PD controller class and a simulation script. Before opening it, outline each component separately.

These prompts are ungraded. They are intended to connect the gain calculation to the implementation code in the complete solution.

7.3 Interactive PD Pole Placement Check

Chapter 7 activity

Match desired poles to PD gains

For a plant b0/(s2+a1s+a0), choose desired closed-loop poles at -sigma +/- j omegad. The activity computes the desired characteristic equation and the PD gains.

Plant denominator Desired characteristic equation PD gains Closed-loop coefficient check Damping ratio Natural frequency

Derivative gain changes the coefficient on s, while proportional gain changes the constant term in the second-order characteristic equation.

7.4 Knowledge Check

Q1. Transient response

In PD pole placement, what primarily determines the closed-loop transient response?

Q2. Derivative gain

For the chapter's second-order PD design equation, which term does derivative gain directly affect?

Q3. Desired polynomial

For desired poles at -2 +/- j3, enter the constant coefficient of the desired polynomial.

Show solution

Answer: 13, because σ2 + ωd2 = 22 + 32.

Q4. Proportional gain

For the plant and desired closed-loop coefficient

a0 = 1,   b0 = 2,   a0 + b0kP = 13,

enter the proportional gain kP.

Show solution

Answer: 6, because kP = (13 - 1)/2.

Q5. Derivative gain

For the plant and desired coefficient on s,

a1 = 1,   b0 = 2,   a1 + b0kD = 4,

enter the derivative gain kD.

Show solution

Answer: 1.5, because kD = (4 - 1)/2.

Q6. Damping from pole location

Which stable pole pair is the most underdamped?

Q7. Natural frequency trend

If damping ratio is held fixed and natural frequency is increased, what usually happens to rise time?

Q8. Coefficient matching

A closed-loop characteristic polynomial is s2 + 4s + k. To match desired poles at -2 +/- j1, what value of k is needed?

7.5 Notes and References

The concept of using feedback to place the poles of the system at desired locations is a much deeper topic than is covered in this chapter. While the method discussed in this chapter is only applicable to second-order systems, it is usually possible to arbitrarily assign the poles for an \(n^{th}\) order system. In general, to assign \(n\) poles will require \(n\) gains. We will discuss pole placement in more detail in Chapter 14 of this book.

8 Design Strategies for Second-Order Systems

8.1 Theory

In the previous section we saw that for second-order systems, PD control could be used to exactly specify the pole location of the closed-loop system. This chapter examines the design problem of how to select the pole locations to achieve desired behavior. In Section 11.1.1 we derive the relationship between a single pole location and the step response of the system. In Section 11.1.2 we show that the time-domain response for a second-order system can be understood in terms of natural frequency and damping ratio. Finally, in Section 11.1.3 we show the effect that a zero has on the step response of a second-order system.

8.1.1 First Order Response

Consider a first-order system given by \[Y(s) = \frac{p}{s+p} U(s),\] where \(p>0\). The pole location of the first-order system is at \(-p\). If \(U(s)=\frac{A}{s}\) is a step of magnitude \(A\), then \[Y(s) = \frac{Ap}{s(s+p)}.\] As shown in Appendix 29, the inverse Laplace transform is given by \[\tag{8.1} y(t) = \begin{cases} A(1-e^{-pt}), & t\geq 0 \\ 0, & \text{otherwise} \end{cases}.\] The response is shown in Fig. 8.1, which shows the response to steps of size \(A=1\), \(A=2\), and \(A=3\), respectively.

Interactive Figure 8.I1

First-order step response

Adjust the pole location p and the step magnitudes A to see how y(t)=A(1-e-pt) changes. The 90 percent rise time is independent of A, but the initial slope is A p.

Interactive Figure 8.I1. Step response of a first-order system with pole parameter p and step magnitude A. The step magnitude changes the final value and initial slope, while the normalized 90 percent rise time is set by p.

Live response values

Pole Rise time Initial slope

If we define the rise time \(t_r\) of the system to be the time after the step when the response reaches 90% of its final value, then we note from Fig. 8.1 that the rise time is independent of the step size \(A\). Also, by differentiating Equation 8.1 at time \(t=0\), it is straightforward to show that the slope of the response at \(t=0\) is equal to \(Ap\). This is also shown graphically in Fig. 8.1.

When \(A=1\), the step response for different pole locations is shown in Fig. 8.2. Pole locations corresponding to \(p=1\), \(p=2\), and \(p=4\) are shown. Note that as the pole location moves further into the left half of the complex plane, the rise time decreases.

Figure 8.2. Interactive step response of a first-order system. Use the slider to vary pole location (p); larger (p) values move the pole further left and produce a faster rise time.

An important concept for the steady-state response of a system is the DC gain, which is defined as follows.

The DC gain of a transfer function \(H(s)\) is \[\left.H(s)\right|_{\text{DC gain}} = \lim_{s\to 0} H(s).\]

An important fact is that if the poles of \(H(s)\) are in the open left half-plane, then the response of \(H(s)\) to a step of size \(A\) approaches \(A\left.H(s)\right|_{\text{DC gain}}\) as \(t\to\infty\). This is true for first-order systems, as well as general \(H(s)\). For example, the DC gain of the first-order system \(H(s) = \frac{q}{s+p}\) is \(\frac{q}{p}\), as long as \(p>0\).

8.1.2 Second-Order Response

Suppose that the closed-loop system has a second-order transfer function with two real poles and no zeros: \[Y(s) = \frac{K}{(s+p_1)(s+p_2)}R(s).\] To find the output of the system when the input is a step of magnitude \(A\), we find the inverse Laplace transform of \[Y(s) = \frac{K}{(s+p_1)(s+p_2)}\frac{A}{s}.\] Using partial fraction expansion we get \[Y(s) = \frac{\frac{KA}{p_1p_2}}{s} + \frac{\frac{KA}{(-p_1)(p_2-p_1)}}{s+p_1} + \frac{\frac{KA}{(-p_2)(p_1-p_2)}}{s+p_2}.\] Taking the inverse Laplace transform gives \[y(t) = \begin{cases} \frac{KA}{p_1p_2} + \frac{KA}{(-p_1)(p_2-p_1)}e^{-p_1t} + \frac{KA}{(-p_2)(p_1-p_2)} e^{-p_2t}, & t\geq 0 \\ 0, & \text{otherwise} \end{cases}.\] Note that as \(t\to\infty\), \(y(t)\to \frac{KA}{p_1p_2}\), which is equal to the step size \(A\) times the DC gain of the system.

Now suppose that the closed-loop system has two complex poles and no zeros. We will write a generic second-order system with poles in the left half-plane using the notation \[H(s) = \frac{K\omega_n^2}{s^2 + 2\zeta\omega_n s + \omega_n^2},\] where \(K\) is the DC gain of the system (typically \(K=1\)), \(\omega_n>0\) is called the natural frequency, and \(\zeta>0\) is called the damping ratio. The poles are given by the roots of the characteristic polynomial \[\Delta(s) = s^2 + 2\zeta\omega_n s + \omega_n^2=0,\] in other words, the poles are \[\begin{aligned} p_{1,2} &= -\zeta\omega_n \pm \sqrt{(\zeta\omega_n)^2-\omega_n^2} \\ &= -\zeta\omega_n \pm \omega_n\sqrt{\zeta^2-1}. \end{aligned}\] If \(0<\zeta<1\), then the roots are complex and given by \[\tag{8.2} p_{1,2} = -\zeta\omega_n \pm j\omega_n\sqrt{1-\zeta^2}.\] Using the Python code

import control as cnt
import matplotlib.pyplot as plt

#start by varying the natural frequency
plt.figure(1), plt.clf()
zeta = 0.707

for wn in [0.5, 1.0, 2.0, 5.0]:
    G = cnt.tf(wn**2, [1, 2*zeta*wn, wn**2])
    t,y = cnt.step_response(G)
    plt.plot(t, y)

plt.plot([0, 20.0] , [1, 1], 'k--')
plt.xlabel('Time (seconds)')
plt.ylabel('Amplitude')
plt.title('Step Response')
plt.legend(('wn=0.5', 'wn=1.0', 'wn=2.0', 'wn=5.0'))

#now we'll see the effect of varying zeta
plt.figure(2), plt.clf()
wn = 1.0

for zeta in [0.2, 0.4, 0.707, 1.0, 2.0]:
    G = cnt.tf(wn**2, [1, 2*zeta*wn, wn**2])
    t,y = cnt.step_response(G)
    plt.plot(t, y)
    
plt.plot([0, 35.0] , [1, 1], 'k--')
plt.xlabel('Time (seconds)')
plt.ylabel('Amplitude')
plt.title('Step Response')
plt.legend(('zeta=0.2', 'zeta=0.4', 'zeta=0.707',
            'zeta=1.0', 'zeta=2.0'))

plt.show() # necessary to make plots appear

we obtain second-order response plots similar to the ones shown in Figures 8.3 and 8.4. Note from Fig. 8.3 that as the natural frequency increases, the rise time decreases. We should note that a similar phenomenon to Fig. 8.1 also occurs, where the rise time is independent of the size of the step. Note from Fig. 8.4 that the damping ratio affects the amount of ringing in the system. For a small damping ratio, e.g., \(\zeta=0.2\), there is a large overshoot and significant ringing in the system. At the other extreme, when \(\zeta\) is larger than one, the poles are real and the response is highly damped. The sweet spot is when \(\zeta=0.707\), where the rise time is small but the overshoot is minimal.

Figure 8.3. Interactive second-order step response with fixed damping ratio ζ = 0.707. Use the slider to vary natural frequency ω_n; increasing ω_n decreases rise time.
Figure 8.4. Interactive second-order step response with fixed natural frequency ω_n = 1. Use the slider to vary damping ratio ζ; lower ζ increases overshoot and ringing.

Note from Equation 8.2 that when \(\zeta = 0.707 = \frac{1}{\sqrt{2}}\), the poles are at \[p_{1,2} = -\frac{\omega_n}{\sqrt{2}} \pm j\frac{\omega_n}{\sqrt{2}}.\] In the complex plane, the pole locations are shown in Fig. 8.5, where \(\omega_n\) is the distance from the origin to the poles. When \(\zeta=\frac{1}{\sqrt{2}}\) the angle \(\theta\) equals \(45\) degrees.

Complex conjugate poles in the left half-plane.

In rectangular coordinates, the poles are given by \[\tag{8.3} p_{1,2} = -\sigma \pm j\omega_d,\] as shown in Fig. 8.5. Equations 8.2 and 8.3 give \[\begin{aligned} \sigma &= \zeta \omega_n \\ \omega_d &= \omega_n\sqrt{1-\zeta^2}. \end{aligned}\] From Fig. 8.5 it is also clear that \[\sin\theta = \frac{\sigma}{\omega_n} = \zeta.\] Therefore \[\theta = \sin^{-1} \zeta.\]

Since the pole locations are at \(-\zeta\omega_n \pm \omega_n\sqrt{\zeta^2-1}\), the poles are both real if \(\zeta\geq 1\). When \(\zeta=1\) the poles are both located at \(-\omega_n\). When \(0<\zeta<1\) the poles are imaginary and occur in complex conjugate pairs. As shown in Fig. 8.6, we say that the system is overdamped when \(\zeta>1\), we say that the system is critically damped when \(\zeta=1\), and we say that the system is underdamped when \(0<\zeta<1\).

Second-order response as a function of the damping ratio \zeta.
Figure 8.6 (Interactive). Adjust damping ratio zeta to see under-damped, critically-damped, and over-damped regimes.

The response of \(H(s)\) to a step of size \(A\) is the inverse Laplace transform of \[Y(s) = \frac{A\omega_n^2}{s(s^2+2\zeta\omega_n s + \omega_n^2)},\] which, as shown in Appendix 29, when the poles are complex results in \[\tag{8.4} y(t) = A\left[ 1-\frac{1}{\sqrt{1-\zeta^2}}e^{-\sigma t}\cos\left(\omega_d t - \tan^{-1}\left(\frac{\sigma}{\omega_d}\right)\right)\right].\] A plot of this signal is shown in Fig. 8.7.

Second-order response. The steady-state value is A. The response envelope decays exponentially, and the oscillation frequency and phase shift are set by the complex pole locations.

The rise time is defined to be the time that it takes the output to transition from 10% to 90% of its final value \(A\). A suitable approximation is that the rise time is one half of the peak time, which is the time when \(y(t)\) reaches its first peak. To find the peak time \(t_p\), differentiate \(y(t)\) in Equation 8.4 and then solve for the first instance when the derivative is zero. The result is \[t_p = \frac{\pi}{\omega_d} = \frac{\pi}{\omega_n\sqrt{1-\zeta^2}}.\] Therefore, the rise time is approximately \[t_r \approx \frac{1}{2}t_p = \frac{1}{2}\frac{\pi}{\omega_n\sqrt{1-\zeta^2}}.\] When \(\zeta=0.707\) we get \[\tag{8.5} t_r \approx \frac{2.2}{\omega_n}.\]

Specifications for second-order systems are usually given either in terms of the rise time \(t_r\) and the damping ratio \(\zeta\), or in terms of the natural frequency \(\omega_n\) and the damping ratio \(\zeta\).

8.1.3 Effect of a Zero on the Step Response

In the previous section, we looked at the step response when there were two complex poles and no zeros. In this section we will briefly discuss the effect of zeros on the step response of the system. This is a topic that we could treat at a much deeper level.

A transfer function is called rational if it is the ratio of two polynomials in \(s\). For example, \[H(s) = \frac{s+1}{s^3+3s^2+s+4}\] is a rational transfer function, whereas \[H(s) = \frac{(s+1)e^{-s}}{s^3+3s^2+s+4}\] is not. A rational transfer function can be written as \[H(s) = \frac{N(s)}{D(s)},\] where \(N(s)\) is the numerator polynomial and \(D(s)\) is the denominator polynomial. The zeros of the transfer function are roots of the equation \(N(s)=0\), and the poles of the system are the roots of the equation \(D(s)=0\).

One way to understand the effect of zeros is to consider the effect that zeros have on the partial fraction expansion of a transfer function. For a review of partial fraction expansion, see Appendix 29. First consider a two-pole system with characteristic equation given by \(\Delta(s) = (s+2)(s+3)\). The transfer function with DC gain equal to one and without zeros is given by \[H(s) = \frac{6}{(s+2)(s+3)}.\] The response to a unit step is given by \begin{align} y(t) &= \mathcal{L}^{-1}\left\{\frac{6}{s(s+2)(s+3)}\right\} \notag \\ &= \mathcal{L}^{-1}\left\{ \frac{1}{s} + \frac{-3}{s+2} + \frac{2}{s+3}\right\} \notag \\ &= 1 - 3e^{-2t} + 2e^{-3t}, \quad t\geq 0. \tag{8.6} \end{align} Now consider the step response when a zero has been added at \(z=-2.1\) and the gain adjusted so that the DC gain is still one, i.e., when \[H(s) = \frac{\frac{6}{2.1}(s+2.1)}{(s+2)(s+3)}.\] The response to a unit step is given by \[\begin{aligned} y(t) &= \mathcal{L}^{-1}\left\{\frac{\frac{6}{2.1}(s+2.1)}{s(s+2)(s+3)}\right\} \\ &= \mathcal{L}^{-1}\left\{ \frac{1}{s} + \frac{-0.1429}{s+2} + \frac{-0.8571}{s+3}\right\}\\ &= 1 - 0.1429e^{-2t} - 0.8571e^{-3t}, \quad t\geq 0. \end{aligned}\] Note that \(y(t)\) still settles to one, but the response of the pole at \(-2\) has almost been removed. If, however, the zero is far away from the poles, then the effect is much less. Suppose that the zero is at \(z=-60\) and the gain is adjusted so that the DC gain is still one, i.e., \[H(s) = \frac{\frac{6}{60}(s+60)}{(s+2)(s+3)}.\] The response to a unit step is given by \[\begin{aligned} y(t) &= \mathcal{L}^{-1}\left\{\frac{\frac{6}{60}(s+60)}{s(s+2)(s+3)}\right\} \\ &= \mathcal{L}^{-1}\left\{ \frac{1}{s} + \frac{-2.9}{s+2} + \frac{1.9}{s+3}\right\}\\ &= 1 - 2.9e^{-2t} + 1.9e^{-3t}, \quad t\geq 0. \end{aligned}\] In this case, the response is similar to Equation 8.6.

Another way to understand the effect of zeros on the system is to recall that an \(s\) in the numerator is essentially a differentiator. Therefore \[\begin{aligned} H(s) &= \frac{\omega_n^2(\tau s+1)}{s^2 + 2\zeta\omega_n s + \omega_n^2} \\ &= \tau\frac{\omega_n^2 s}{s^2 + 2\zeta\omega_n s + \omega_n^2} + \frac{\omega_n^2}{s^2 + 2\zeta\omega_n s + \omega_n^2}. \end{aligned}\] Therefore, the step response is given by \[\begin{aligned} y(t) &= \mathcal{L}^{-1}\left\{\tau\frac{\omega_n^2s}{s(s^2 + 2\zeta\omega_n s + \omega_n^2)} + \frac{\omega_n^2}{s(s^2 + 2\zeta\omega_n s + \omega_n^2)}\right\} \\ &= \tau\frac{d}{dt}\mathcal{L}^{-1}\left\{\frac{\omega_n^2}{s(s^2 + 2\zeta\omega_n s + \omega_n^2)}\right\} % + \mathcal{L}^{-1}\left\{\frac{\omega_n^2}{s(s^2 + 2\zeta\omega_n s + \omega_n^2)}\right\}. \end{aligned}\] Therefore, the effect of the zero is to add \(\tau\) times the derivative of the step response to what the step response would have been without the zero. Fig. 8.8 shows the step response for different values of \(\tau\), illustrating that adding a zero has a strong effect on the rise time and damping of the response. Note also that when \(\tau<0\), i.e., when zeros are in the right half-plane, the system response first goes negative before going positive. Right-half-plane zeros are often called nonminimum-phase zeros , and the associated response is often called a nonminimum-phase response. Physical systems that have right-half-plane zeros include the inverted pendulum and aircraft altitude-control systems. For the inverted pendulum, to move the cart to the right from a stopped position, the cart must first move left so that the rod leans right before the cart can move to its desired position. Similarly, an aircraft pitches up to climb. However, when the aircraft pitches up, it loses speed, which causes it to lose lift and altitude. As the aircraft loses altitude, it gains speed and produces the lift necessary to climb.

Figure 8.8. Interactive step response of a second-order system with a single zero. Vary tau to see the effect of left-half-plane and right-half-plane zero behavior.

8.1.4 Successive Loop Closure

The natural frequency \(\omega_n\) and the damping ratio \(\zeta\) are only defined for second-order systems, and therefore, the PD design technique based on \(\omega_n\) and \(\zeta\) are only valid for second-order systems. However, these concepts can be extended to higher-order systems through a technique called successive loop closure, or inner-loop, outer-loop design. When we derived the Laplace transform in Chapter 8, we saw that for many systems, the transfer functions can be arranged in cascade form as shown in Fig. 8.9 where the input to the system is \(u_1\) and the output is \(y_2\), but where \(y_1\) and \(u_2\) are intermediary values that represent the natural physical coupling between internal variables. Many physical systems can be represented by a cascade of systems.

Open-loop transfer function modeled as a cascade of two transfer functions.

When the system is represented as a cascade, the control strategy can be designed using successive loop closure. The basic idea is to close feedback loops in succession around the open-loop plant dynamics rather than designing a single control system. To illustrate this approach, consider the open-loop system shown in Fig. 8.9. The open-loop dynamics are given by the product of two transfer functions in series: \(P(s)=P_1(s)P_2(s)\). We assume that each of the transfer functions has an output (\(y_1\), \(y_2\)) that can be measured and used for feedback. Typically, each of the transfer functions, \(P_1(s)\) and \(P_2(s)\), is of relatively low order – usually first or second-order. In this case, we are interested in controlling the output \(y_2\). Instead of closing a single feedback loop around \(y_2\), we will close feedback loops around \(y_1\) and \(y_2\) in succession as shown in Fig. 8.10.

Successive loop closure design.

We will design the compensators \(C_1(s)\) and \(C_2(s)\) in succession. A necessary condition in the design process is that the inner loop must be much faster than each successive loop. As a rule of thumb, if the rise time of the inner loop is \(t_{r_1}\), the rise time of the next loop should be 5 to 10 times longer, i.e., \(t_{r_2}> W_1 t_{r_1}\), where \(W_1\) is a design parameter, usually on the order of \(5-10\). In part V of this book, we will talk about the frequency response of the system. At that time, we will provide a deeper explanation that can be understood in terms of the bandwidth of each successive loop.

Examining the inner loop shown in Fig. 8.10, the goal is to design a closed-loop system from \(r_1\) to \(y_1\) having a rise time of \(t_{r_1}\). If the rise time of the inner loop is significantly faster than the rise time of the outer loop, and if the DC gain of the inner loop is \(k_{DC_1}\), then relative to the outer loop the inner loop can be effectively modeled as the DC gain. This is depicted schematically in Fig. 8.11. With the inner-loop transfer function modeled as its DC gain, design of the outer loop is simplified because it only includes the plant transfer function \(P_2(s)\) and the compensator \(C_2(s)\) and the DC gain \(k_{DC_1}\).

Successive loop closure design with inner loop modeled as a unity gain.

Because both plant models \(P_1(s)\) and \(P_2(s)\) are first or second-order, conventional PID compensators can be employed. The loopshaping techniques discussed in Part V can also be used for successive loop closure of higher-order systems.

8.1.5 Input Saturation and Limits of Performance

A natural question is to ask if the rise time can be made arbitrarily small. Unfortunately, saturation limits on the actuators place a lower bound on the achievable rise time. All physical systems have saturation limits on their actuators. For example, in the robot arm problem, the torque that can be applied to the arm is limited by the motor that is used to apply that torque. Force and torque will always be limited by physical constraints like current limits. Similarly, for an airplane, the rudder command is limited by how far the rudder can physically move, which is typically on the order of \(\pm 40\) degrees. A natural way to model input constraints is to add a saturation block preceding the physical plant. Fig. 8.12 shows a saturation block in conjunction with a PD control scheme.

Control system with input saturation. The input saturation places a lower bound on the achievable rise time.

Mathematically, the saturation block is given by \[u_{sat} = \begin{cases} u_{\max}, & \text{~if~} u\geq u_{\max} \\ u, & \text{~if~} -u_{\max} \leq u \leq u_{\max} \\ -u_{\max}, & \text{~otherwise} \end{cases},\] where the input to the block is \(u\), the output is \(u_{sat}\), and the saturation limit is \(u_{\max}\). Note that the saturation block is non-linear. Therefore, one design strategy is to select the feedback gains so that the system remains linear by keeping the input out of saturation.

To see how this might be done, consider the second-order system shown in Fig. 8.12 with proportional feedback on the output error and derivative feedback on the output. When the input is not saturated, the closed-loop transfer function is \[Y(s) = \left(\frac{b_0 k_p}{s^2 + (a_1 + b_0 k_D)s + (a_0 + b_0 k_p)}\right) R(s). \tag{8.7}\] We can see that the closed-loop poles of the system are defined by the selection of the control gains \(k_p\) and \(k_D\). Note also that the actuator effort \(u\) can be expressed as \(u=k_p e - k_D\dot{y}\). When \(\dot{y}\) is zero or small, the size of the actuator effort \(u\) is primarily governed by the size of the control error \(e\) and the control gain \(k_p\). If the system is stable, the largest control effort in response to a step input will occur immediately after the step when \(\dot{y}=0\). If the system is to be kept just out of saturation, then immediately after the step we have \(\left|u\right|=u_\text{max} = k_p e_\text{max}\). Rearranging this expression, we find that the proportional control gain can be determined from the maximum anticipated output error and the saturation limits of the actuator as \[k_p = \pm \frac{u_\text{max}}{e_\text{max}}, \tag{8.8}\] where \(u_{\max}\) is the maximum control effort the system can provide, \(e_{\max}\) is the step error that results from a step input of nominal size, and the sign of \(k_p\) is determined by the physics of the system.

Suppose that the desired closed-loop characteristic polynomial is given by \[\Delta_{cl}^d(s) = s^2 + 2\zeta\omega_n s + \omega_n^2,\] then by comparing with the actual closed-loop characteristic polynomial \[\Delta_{cl}(s) = s^2 + (a_1 + b_0 k_D)s + (a_0 + b_0 k_p)\] we have that \[\begin{aligned} \omega_n &= \sqrt{a_0 + b_0 k_p} \leq \sqrt{a_0 + b_0 \frac{u_\text{max}}{e_\text{max}}}, \end{aligned}\] which is an upper limit on the natural frequency of the closed-loop system, ensuring that saturation of the actuator is avoided. The corresponding rise time constraint is \[t_r \geq \frac{2.2}{\omega_n} = \frac{2.2}{\sqrt{a_0 + b_0 \frac{u_\text{max}}{e_\text{max}}}},\] which is the smallest possible rise time for an error step of \(e_{\text{max}}\).

If the input has an equilibrium value, then the saturation constraint used in the above calculation must be modified to account for the equilibrium. For example, suppose that \(u=u_e+\tilde{u}\) where \(u_e\) is the equilibrium value and \(\tilde{u}\) is the output of the PID controller. Also suppose that the input saturation constraint is given by \(u_{\min}\leq u\leq u_{\max}\). The objective is to find a value for \(\tilde{u}_{\max}\) where \(\left|\tilde{u}\right|\leq \tilde{u}_{\max}\) guarantees that \(u_{\min}\leq u\leq u_{\max}\). We have that \[\begin{aligned} & u_{\min}\leq u \leq u_{\max} \\ \implies & u_{\min} \leq u_e + \tilde{u} \leq u_{\max} \\ \implies & u_{\min}-u_e \leq \tilde{u} \leq u_{\max}-u_e. \end{aligned}\] The desired value for \(\tilde{u}_{\max}\) is therefore the minimum (in absolute value) of the right and left-hand sides of this expression. The situation is shown in Fig. 8.13, where it is clear that the value for \(\tilde{u}_{\max}\) can be written as \[\tilde{u}_{\max} = \begin{cases} \left|u_{\max}-u_e\right|, & \text{~if~} u_e \geq \frac{u_{\max}+u_{\min}}{2} \\ \left|u_e - u_{\min}\right|, & \text{~if~} u_e \leq \frac{u_{\max}+u_{\min}}{2}. \end{cases}\]

The saturation constraint for \tilde{u} depends on the value of the equilibrium input u_e.

The takeaway from this discussion is that the rise time is limited by the input saturation constraint and cannot be made arbitrarily small. In practice, the control parameters are tuned so that the closed-loop system has the fastest possible rise time without driving the plant input into saturation.

8.2.1 image Example Problem 3.1.11

For the single-link robot arm, do the following:

(a) Suppose that the design requirements are that the rise time is \(t_r \approx 0.8\) seconds, with a damping ratio of \(\zeta=0.707\). Find the desired closed-loop characteristic polynomial \(\Delta_{cl}^d(s)\) and the associated pole locations. Find the proportional and derivative gains \(k_P\) and \(k_D\) to achieve these specifications, and modify the simulation from HW 3.1.8 to verify that the step response satisfies the requirements.

(b) Suppose that the input torque for the robot arm is limited to \(\left|\tau\right|\leq\tau_{\max}=1\) Nm. Modify the simulation to include a saturation on the torque \(\tau\). Using the rise time \(t_r\) and damping ratio \(\zeta\) as tuning parameters, tune the PD control law so that the input just saturates when a step of size \(50\) degrees is placed on \(\tilde{r}_{\theta}\).

Design Study A guided exercise

Use rise time and damping ratio

Translate the time-domain design specifications into a desired second-order polynomial.

Step 1. Natural frequency rule

Step 2. Desired polynomial coefficients

Step 3. Saturation check

Pseudocode

The complete solution includes a PD controller class and a simulation script. Before opening it, outline each component separately.

These prompts are ungraded. They are intended to connect the design specifications to the implementation code in the complete solution.

8.3 Design Study B. Inverted Pendulum

8.3.1 image Example Problem 3.2.11

For the inverted pendulum, do the following:

(a) Using the principle of successive loop closure, draw a block diagram that uses PD control for both inner loop control and outer loop control. The input to the outer loop controller is the desired cart position \(r_z\) and the output of the controller is the desired pendulum angle \(r_{\theta}\). The input to the inner loop controller is the desired pendulum angle \(r_{\theta}\) and the output is the force \(F\) on the cart.

(b) Focusing on the inner loop, find the PD gains \(k_{P_\theta}\) and \(k_{D_\theta}\) so that the rise time of the inner loop is \(t_{r_\theta}=0.5\) seconds, and the damping ratio is \(\zeta_{\theta}=0.707\).

(c) Find the DC gain \(k_{DC_\theta}\) of the inner loop.

(d) Replace the inner loop by its DC gain and consider the outer loop. Add a low-pass filter that cancels the left-half-plane zero, and then design a PD control strategy to stabilize the position of the cart.

(e) Implement the control design to control on the inverted pendulum. Modify the simulation to include saturation on the force \(F\) to limit the size of the input force on the cart to \(F_{\max}=5\) N. Give the pendulum angle an initial condition of 10 deg and simulate the response of the system for 10 seconds to verify that the cart is able to balance the pendulum. You may also tune rise times or damping to improve performance.

Design Study B guided exercise

Organize the successive-loop pendulum controller

Separate the inner angle loop from the outer cart-position loop.

Inner-loop PD control diagram for the pendulum.

The inner loop stabilizes pendulum angle before the outer loop commands cart position.

Step 1. Loop signal order

Step 2. Inner-loop design target

Step 3. Outer-loop design feature

Pseudocode

The complete solution includes a nested PD controller class and a zero-canceling filter class. Before opening it, outline each component separately.

These prompts are ungraded. They are intended to connect the derivation to the implementation code in the complete solution.

8.4 Design Study C. Satellite Attitude Control

8.4.1 image Example Problem 3.3.11

(a) For the simple satellite system, using the principle of successive loop closure, draw a block diagram that uses PD control for the inner and the outer loop control. The input to the outer loop controller is the desired angle of the solar panel \(r_{\phi}\) and the output is the desired angle of the satellite \(r_{\theta}\). The input to the inner loop controller is \(r_{\theta}\) and the output is the torque on the satellite \(\tau\).

(b) Focusing on the inner loop, find the PD gains \(k_{P_\theta}\) and \(k_{D_\theta}\) so that the rise time of the inner loop is \(t_{r_\theta}=1\) second, and the damping ratio is \(\zeta_{\theta}=0.9\).

(c) Find the DC gain \(k_{DC_\theta}\) of the inner loop.

(d) Replacing the inner loop by its DC gain, find the PD gains \(k_{P_\phi}\) and \(k_{D_\phi}\) so that the rise time of the outer loop is \(t_{r_\phi}= 10 t_{r_\theta}\) with damping ratio \(\zeta_{\phi}=0.9\).

(e) Implement the successive loop closure design for the satellite system in simulation where the commanded solar panel angle is given by a square wave with magnitude \(15\) degrees and frequency \(0.015\) Hz.

(f) Suppose that the size of the input torque on the satellite is limited to \(\tau_{\max}=5\) Nm. Modify the simulation to include saturation on the torque \(\tau\). Use rise time as a tuning parameter and tune the PD control law to get the fastest possible response without input saturation when a step of size \(30\) degrees is placed on \(r_\phi\).

Design Study C guided exercise

Plan the satellite successive-loop controller

Use the body loop as the fast inner loop and the flexible-panel loop as the slower outer loop.

Step 1. Signal architecture

Step 2. Inner-loop design target

Step 3. Outer-loop separation

Pseudocode

Before opening the implementation code, outline the nested PD controller and saturation check.

8.5 Coding Lab: PD Controller Implementation

PD Controller u = kₚe + kᴅ ė Plant P(s) ωₙ² / (s² + 2ζωₙs + ωₙ²) Σ + − r(t) e(t) u(t) y(t) feedback d(t)
Figure 8.21. Block-diagram setup for the Chapter 8 coding lab on second-order closed-loop control.

Plant model used in this lab:

ÿ + 2ζωnẏ + ωn2y = ωn2u

Section 8.6 coding lab objective: complete the controller template and use the targeted checks to evaluate step-response performance for the second-order system.

Evaluation criteria: rise time ≤ 1.2 s, overshoot ≤ 20 percent, and steady-state error ≤ 0.03.

Use the code editor to complete the controller class.

Figure 8.22 (Interactive). Chapter 8 coding lab workspace and automated performance checks.

8.6 Knowledge Check

Use these quick checks to test understanding of Chapter 8 concepts before moving on.

Q1. Effect of ωn

If ζ is fixed and ωn increases, what happens to rise time?

Show solution

Answer: B. Larger ωn usually yields a faster response and shorter rise time.

Q2. Damping classification

Which damping range gives an oscillatory step response in a standard second-order system?

Show solution

Answer: C. Complex conjugate poles (underdamped case) produce oscillation and possible overshoot.

Q3. Pole interpretation

A system has poles at s = -0.8 ± j1.5. Enter the damping type.

Show solution

Answer: Underdamped. Nonzero imaginary parts indicate oscillatory behavior.

Q4. Overshoot trend

If ωn is fixed and ζ increases from 0.3 to 0.9, what happens to percent overshoot?

Show solution

Answer: B. Increasing damping ratio reduces oscillation and overshoot.

Q5. Effect of a nonminimum-phase zero

Changing the zero parameter to produce nonminimum-phase behavior most directly causes:

Show solution

Answer: B. A nonminimum-phase zero can produce an inverse initial response.

Q6. PD characteristic equation

For unity negative feedback with \(P(s)=\frac{2}{s^2+3s+1}\) and \(C(s)=k_P+k_Ds\), which characteristic equation should be used for pole placement?

Q7. Matching desired poles

Using the same plant and controller, the desired poles are -2 +/- j2. Which gains match the desired characteristic polynomial?

Q8. Pole-placement tradeoff

Why is it usually not a good design rule to place the closed-loop poles as far left as possible?

8.7 Notes and References

9 System Type and Integrators

9.1 Theory

In the previous chapter we explored design techniques for second-order systems where the feedback controller was a PD-type control. Since second-order systems have two degrees of freedom, their transient response can be completely determined by the proportional and derivative gains. However, from the simulation results it can easily be observed that if there is a disturbance on the system, or if the controller does not know the system parameters exactly, then there will be a steady-state error in the output. The steady-state error can be effectively removed using an integrator in the control law. In this chapter we will explore these ideas in more detail and explain when and how integral control can be used to enhance steady-state tracking and to reduce the effect of disturbances.

9.1.1 Final Value Theorem

The key theoretical tool to understanding the steady-state error and the effect of integrators is the final value theorem, which we state and prove below.

.
Suppose that \(z(t)\) and \(Z(s)\) are Laplace transform pairs, and suppose that \(\lim_{t\to\infty}z(t)\) is finite, then \[\lim_{t\to\infty}z(t) = \lim_{s\to 0} sZ(s).\]

Interactive check

Final value theorem validity explorer

The final value theorem is useful only when the final value exists. Select a transform, predict whether the theorem applies, and then check the poles of sY(s).

Step 1: form sY(s)

Step 2: check poles of sY(s)

Step 3: make a prediction before checking

conceptual response y(t) time

Numeric final-value check

For Y(s) = 3 / (s(s + 4)), enter the final value if the final value theorem applies.

Show solution

Answer: 0.75. Since sY(s) = 3/(s + 4), the pole is at s = -4 and the theorem applies; lims->0 3/(s + 4) = 3/4.

9.1.2 System Type for Reference Tracking

Block diagram for reference tracking.

Consider the closed-loop system shown in Fig. 9.1. The transfer function from the reference \(r\) to the error \(e=r-y\) is computed as \[\begin{aligned} & E(s) = R(s) - P(s)C(s)E(s) \\ \implies & E(s) = \frac{1}{1+P(s)C(s)}R(s) \end{aligned}\]

Suppose that \(r(t)\) is a step of size one, then \(R(s)=\frac{1}{s}\) and \[E(s) = \frac{1}{1+P(s)C(s)}\frac{1}{s}.\] Assuming that the closed-loop system is stable and therefore that \(\lim_{t\to\infty}e(t)\) is finite, then the final value theorem gives \[\begin{aligned} \lim_{t\to\infty}e(t) &= \lim_{s\to 0} sE(s) \\ &= \lim_{s\to 0} s\frac{1}{1+P(s)C(s)}\frac{1}{s} \\ &= \lim_{s\to 0}\frac{1}{1+P(s)C(s)} \\ &= \frac{1}{1+\lim_{s\to 0} P(s)C(s)}. \end{aligned}\] Let \[M_p \stackrel{\triangle}{=}\lim_{s\to 0} P(s)C(s),\] then \[\lim_{t\to\infty}e(t) = \frac{1}{1+M_p}.\]

Now suppose that \[P(s)C(s) = \frac{K(s+z_1)(s+z_2)\cdots(s+z_m)}{(s+p_1)(s+p_2)\cdots(s+p_n)},\] then \[M_p = \lim_{s\to 0} P(s)C(s) = \frac{Kz_1z_2\cdots z_m}{p_1p_2\cdots p_n}.\] In this case, the steady-state error is \(\frac{1}{1+M_p}\) which is finite. Note also that the DC gain of the closed-loop system is \[k_{DC} = \frac{1}{1+M_p}.\]

Now suppose that \(P(s)C(s)\) contains a pole at the origin, or in other words, one free integrator, i.e., \[P(s)C(s) = \frac{K(s+z_1)(s+z_2)\cdots(s+z_m)}{s(s+p_1)(s+p_2)\cdots(s+p_n)}.\] In this case we have \[M_p = \lim_{s\to 0} P(s)C(s) = \infty,\] and the steady-state error is \[\lim_{t\to\infty}e(t) = \frac{1}{1+\infty} = 0.\] Therefore, one free integrator in \(P(s)C(s)\) implies that the steady-state error to a step is zero. Note that multiple free integrators, i.e., \[P(s)C(s) = \frac{K(s+z_1)(s+z_2)\cdots(s+z_m)}{s^q(s+p_1)(s+p_2)\cdots(s+p_n)},\] gives that same result for \(q\geq 1\).

Now suppose that \(r(t)\) is a unit ramp, or in other words that \(R(s)=\frac{1}{s^2}\). In this case the error is given by \[E(s) = \frac{1}{1+P(s)C(s)}\frac{1}{s^2}.\] Again assuming that the closed-loop system is stable, the final value theorem gives \[\begin{aligned} \lim_{t\to\infty} e(t) &= \lim_{s\to 0} sE(s) \\ &= \lim_{s\to 0} s \frac{1}{1+P(s)C(s)}\frac{1}{s^2} \\ &= \lim_{s\to 0} \frac{1}{s+sP(s)C(s)} \\ &= \frac{1}{\lim_{s\to 0} sP(s)C(s)}. \end{aligned}\] Defining \[M_v = \lim_{s\to 0} sP(s)C(s),\] gives \[\lim_{t\to\infty} e(t) = \frac{1}{M_v}.\] If \(P(s)C(s)\) has no free integrators, i.e., \[P(s)C(s) = \frac{K(s+z_1)(s+z_2)\cdots(s+z_m)}{(s+p_1)(s+p_2)\cdots(s+p_n)}\] then \[M_v = \lim_{s\to 0} s\frac{K(s+z_1)(s+z_2)\cdots(s+z_m)}{(s+p_1)(s+p_2)\cdots(s+p_n)} = 0.\] Therefore \[\lim_{t\to\infty} e(t) = \frac{1}{0}=\infty.\] If, on the other hand, \(P(s)C(s)\) has one free integrator, i.e., \[P(s)C(s) = \frac{K(s+z_1)(s+z_2)\cdots(s+z_m)}{s(s+p_1)(s+p_2)\cdots(s+p_n)}\] then \[M_v = \lim_{s\to 0} s \frac{K(s+z_1)(s+z_2)\cdots(s+z_m)}{s(s+p_1)(s+p_2)\cdots(s+p_n)} = \frac{Kz_1z_2\cdots z_m}{p_1p_2\cdots p_n},\] therefore the steady-state error is finite. If \(P(s)C(s)\) has two or more free integrators, then \[M_v = \lim_{s\to 0} s \frac{K(s+z_1)(s+z_2)\cdots(s+z_m)}{s^q(s+p_1)(s+p_2)\cdots(s+p_n)} = \infty,\] when \(q\geq 2\), therefore \[\lim_{t\to\infty} e(t) = \frac{1}{\infty} = 0.\] Therefore, the number of free integrators in \(P(s)C(s)\) is the key parameter for reference tracking with zero steady-state error.

For the reference tracking problem, we say that the system is type \(q\) if the steady-state error to input \(R(s) = \frac{1}{s^{q+1}}\) is finite and if the steady-state error to input \(R(s)=\frac{1}{s^p}\) is zero for \(1\leq p\leq q\). In general, for the feedback system shown in Fig. 9.1, the steady-state tracking error when \(R(s)=\frac{1}{s^{q+1}}\) is given by \[\lim_{t\to\infty}e(t) = \lim_{s\to 0} s E(s) = \lim_{s\to 0} \left(\frac{1}{1+P(s)C(s)}\right)\left(\frac{1}{s^q}\right).\] Table 12.1 summarizes the tracking error for different inputs as a function of system type, where \[\begin{aligned} M_p &= \lim_{s\to 0}P(s)C(s) \\ M_v &= \lim_{s\to 0}sP(s)C(s) \\ M_a &= \lim_{s\to 0}s^2P(s)C(s). \end{aligned}\]

System Type Step (\(\frac{1}{s}\)) Ramp (\(\frac{1}{s^2}\)) Parabola (\(\frac{1}{s^3}\)) \(\cdots\)
\(0\) \(\frac{1}{1+M_p}\) \(\infty\) \(\infty\) \(\cdots\)
\(1\) \(0\) \(\frac{1}{M_v}\) \(\infty\) \(\cdots\)
\(2\) \(0\) \(0\) \(\frac{1}{M_a}\) \(\cdots\)
\(3\) \(0\) \(0\) \(0\) \(\cdots\)
\(\vdots\) \(\vdots\) \(\vdots\) \(\vdots\)

Reference tracking verse system type.

Interactive figure

Reference-tracking system type explorer

Use the controls to connect the table to a visual prediction. The input order is determined by R(s), while the tracking type is determined by the number of free integrators in P(s)C(s).

reference r(t) output y(t) time
Figure 1.3. Reference and output. Finite steady-state error appears as a persistent vertical gap.
tracking error e(t) = r(t) - y(t) time
Figure 1.4. Error response. This is the plot that determines zero, finite, or infinite steady-state error.
Prediction

Why

Error constant effect

As an example, consider the feedback system shown in Fig. 9.2.

The system type for reference tracking for this system is type 1.

The open-loop system \[P(s)C(s) = \frac{k_P}{s(s+2)}\] has one free integrator (pole at zero) and therefore the system is type 1. From Table 12.1 the tracking error when the input is a step is zero, and the tracking error when the input is a ramp of slope one is \[\lim_{t\to\infty}e(t) = \frac{1}{M_v} = \frac{1}{\lim_{s\to 0} sP(s)C(s)} = \frac{1}{\frac{k_P}{2}} = \frac{2}{k_P}.\] The tracking error when the input is a parabola, or higher-order polynomial, is \(\infty\), meaning that \(y(t)\) and \(r(t)\) diverge as \(t\to\infty\).

As another example, consider the system shown in Fig. 9.3.

The system type for reference tracking for this system is type 0.

In this case, the open-loop system \[P(s)C(s) = \frac{k_D s + k_P}{(s+3)(s+4)}\] does not have any free integrators (poles at zero) and therefore the system is type 0. From Table 12.1 the tracking error when the input is a step is \[\lim_{t\to\infty}e(t) = \frac{1}{1+M_p} = \frac{1}{1+\lim_{s\to 0} P(s)C(s)} = \frac{1}{1+\frac{k_P}{12}} = \frac{12}{12+k_P}.\] The tracking error when the input is a ramp, or higher-order polynomial, is \(\infty\), meaning that \(y(t)\) and \(r(t)\) diverge as \(t\to\infty\).

If, on the other hand, a PID controller is used as shown in Fig. 9.4 where \[U(s) = \left(k_P + \frac{k_I}{s} + k_D s\right)E(s) = \left(\frac{k_D s^2 + k_P s + k_I}{s}\right)E(s),\]

The system type for reference tracking for this system is type 1.

then the open-loop system \[P(s)C(s) = \frac{k_D s^2 + k_Ps + k_I}{s(s+3)(s+4)}\] has one free integrator (pole at zero) and therefore the system becomes type 1 by design. From Table 12.1 the tracking error when the input is a step is zero, and the tracking error when the input is a ramp is \[\lim_{t\to\infty}e(t) = \frac{1}{M_v} = \frac{1}{\lim_{s\to 0} sP(s)C(s)} = \frac{1}{\frac{k_I}{12}} = \frac{12}{k_I}.\] The tracking error when the input is a parabola, or higher-order polynomial, is \(\infty\), meaning that \(y(t)\) and \(r(t)\) diverge as \(t\to\infty\).

9.1.3 System Type for Input Disturbances

Consider the general feedback loop shown in Fig. 9.5. There are in general four inputs to the system, namely the reference input \(r(t)\), the input disturbance \(d_{in}(t)\), the output disturbance \(d_{out}(t)\), and the sensor noise \(n(t)\). In general \(r(t)\), \(d_{in}(t)\), and \(d_{out}(t)\) are signals with low frequency content, and the sensor noise \(n(t)\) has high frequency content. The negative sign on the disturbance and noise terms is for notational convenience.

General feedback loop with reference input r(t), input disturbance d_{in}(t), output disturbance d_{out}(t), and sensor noise n(t).

We can compute the transfer function from each input to the error signal by following the signal flow to obtain \[E(s) = R(s) + N(s) + D_{out}(s) + P(s)D_{in}(s) - P(s)C(s)E(s).\] Solving for \(E(s)\) gives \[\begin{gathered} E(s) = \frac{1}{1+P(s)C(s)} R(s) + \frac{1}{1+P(s)C(s)}N(s) \\ + \frac{1}{1+P(s)C(s)}D_{out}(s) + \frac{P(s)}{1+P(s)C(s)}D_{in}(s). \end{gathered}\] Since the transfer function from \(N(s)\) and \(D_{out}(s)\) to \(E(s)\) is identical to the transfer function from \(R(s)\) to \(E(s)\), the system type as defined in the previous section for reference inputs, also characterizes the steady-state response to output disturbances and noise. However, the transfer function from the input disturbance to the error is different, and so we need to further analyze system type with respect to input disturbances.

Suppose that the input disturbance is given by \(D_{in}(s) = \frac{1}{s^{q+1}}\), then by the final value theorem, the steady-state error due to the input disturbance is \[\lim_{t\to\infty} e(t) = \lim_{s\to 0} s\frac{P(s)}{1+P(s)C(s)}D_{in}(s) = \lim_{s\to 0} \left(\frac{P(s)}{1+P(s)C(s)}\right)\left(\frac{1}{s^q}\right).\] The system type with respect to input disturbance is the value of \(q\) such that the steady-state error is finite, and the steady-state error is zero for \(D_{in}(s) = \frac{1}{s^p}\) for \(1\leq p \leq q\).

For example, consider the system shown in Fig. 9.6. Recall from the discussion above, that the system type with respect to the reference input is type 1.

The system type for input disturbances for this system is type 0.

For the input disturbance we have \[\begin{aligned} \lim_{t\to\infty} e(t) &= \lim_{s\to 0} \left(\frac{P(s)}{1+P(s)C(s)}\right)\left(\frac{1}{s^q}\right) \\ &=\lim_{s\to 0} \left(\frac{\frac{1}{s(s+2)}}{1+\left(\frac{1}{s(s+2)}\right)(k_Ds+k_P)}\right)\left(\frac{1}{s^q}\right) \\ &=\lim_{s\to 0} \left(\frac{1}{s(s+2)+(k_Ds+k_P)}\right)\left(\frac{1}{s^q}\right) \\ &=\lim_{s\to 0} \left(\frac{1}{k_P}\right)\left(\frac{1}{s^q}\right) \end{aligned}\] which is finite when \(q=0\). Therefore, the system type with respect to input disturbances is type 0 and the steady-state error to a step input disturbance is \(\frac{1}{k_P}\) whereas the steady-state error with respect to a ramp and higher-order polynomials is infinite.

If, on the other hand, we add an integrator as in Fig. 9.7, then \[\begin{aligned} \lim_{t\to\infty} e(t) &= \lim_{s\to 0} \left(\frac{P(s)}{1+P(s)C(s)}\right)\left(\frac{1}{s^q}\right) \\ &=\lim_{s\to 0} \left(\frac{\frac{1}{s(s+2)}}{1+\left(\frac{1}{s(s+2)}\right)(\frac{k_Ds^2+k_Ps+k_I}{s})}\right)\left(\frac{1}{s^q}\right) \\ &=\lim_{s\to 0} \left(\frac{s}{s^2(s+2)+(k_Ds^2+k_Ps+k_I)}\right)\left(\frac{1}{s^q}\right) \\ &=\lim_{s\to 0} \left(\frac{1}{k_I}\right)\left(\frac{1}{s^{q-1}}\right) \end{aligned}\] which is finite when \(q=1\). Therefore, the system type with respect to input disturbances is type 1 and the steady-state error to a step on the input disturbance is zero. The steady-state error with respect to a ramp on the input disturbance is \(\frac{1}{k_I}\) whereas the steady-state error with respect to a parabola and higher-order polynomials on the input disturbance is infinite.

The system type for input disturbances for this system is type 1.

Therefore, the system type with respect to input disturbances is related to the number of free integrators in the controller \(C(s)\) and not in the open-loop system \(P(s)C(s)\). As a consequence, while an integrator may not be necessary for steady-state tracking, it is often necessary to reject constant input disturbances.

Interactive figure

Disturbance-path explorer

Select a case to highlight where the signal enters the loop and which low-frequency path determines the steady-state error. The key distinction is that an input disturbance passes through P(s), while output disturbance and sensor noise use the same denominator path as reference tracking.

C(s) P(s) + - r d_in d_out n y measured feedback path

The highlighted path shows the signal path being used to compute E(s). First identify the entry point, then use the matching transfer function below.

Error path

System type

Implication

Transfer-path practice

Practice problem: derive the error paths

Use the signs in the block diagram to derive the transfer functions from the external inputs R, D, and N to the error E. Do this before counting free integrators.

R + - Gc(s) - D Gp(s) y N - H(s)
Figure 9.x. Transfer-path diagram for Problem 5. The disturbance D enters with a negative sign before the plant. The sensor noise N is subtracted from the measured output before H(s).

Q1. Transfer functions into the error

Which set gives the transfer functions from R, D, and N to E for the diagram above?

Q2. Intuition for reference input R

For the reference path E/R, which free integrators most directly increase the system type?

Q3. Intuition for disturbance input D

For the disturbance path E/D, which free integrators should you look at first?

Q4. Intuition for sensor noise N(s)

For the low-frequency sensor-noise path E/N, which block or signal has the free integrators that most directly affect the type?

R + - 1 s(s + 1) - D 1 s2(s + 2) y N - s + 2 s(s + 1)
Figure 9.x. Practice problem with specific transfer functions. Use your transfer paths from Q1 and the final value theorem to complete the table.

Final-value computation

For the specific system above, enter the final value of e(t) for each input path and polynomial input. Use infinity for an unbounded error.

Input path Step Ramp Parabola
R to E
D to E
N to E

Show solution

Solution: The loop product is GcGpH = 1/\[s4(s+1)2\]. Therefore, E/R behaves like s4, E/D behaves like s, and E/N behaves like 2s3 near s = 0. Thus, R gives 0 for step, ramp, and parabola; D gives 0 for step, 1 for ramp, and infinity for parabola; N gives 0 for step, ramp, and parabola.

9.2.1 image Example Problem 3.1.12

When the controller for the single-link robot arm is PD control, what is the system type? Characterize the steady-state error when the reference input is a step, a ramp, and a parabola. How does this change if you add an integrator?

Consider the case where a constant disturbance acts at the input to the plant (for example gravity in this case). What is the steady-state error to a constant input disturbance when the integrator is not present and when it is present?

Design Study A guided exercise

Classify tracking and disturbance type

Count free integrators in the relevant loop transfer function before applying the final value theorem.

Closed-loop system diagram for system type analysis.

Use this closed-loop signal map to decide which loop transfer function determines tracking and disturbance error.

Step 1. PD tracking type

Step 2. PID tracking type

Step 3. Error interpretation

9.3 Design Study B. Inverted Pendulum

9.3.1 image Example Problem 3.2.12

When the inner loop controller for the inverted pendulum is PD control, what is the system type with respect to tracking of the inner loop? Characterize the steady-state error when \(\tilde{R}_{\theta}\) is a step, a ramp, and a parabola. What is the system type with respect to an input disturbance?

When the outer loop controller for the inverted pendulum is PD control, what is the system type of the outer loop with respect to tracking? Characterize the steady-state error when \(r_z\) is a step, a ramp, and a parabola. How does this change if you add an integrator? What is the system type with respect to an input disturbance for both PD and PID control?

Design Study B guided exercise

Classify pendulum system type

Count free integrators separately for the inner and outer loops.

Inner-loop system type diagram for pendulum.

Use the inner and outer loop diagrams to decide which loop transfer function determines each steady-state error.

Step 1. Inner-loop tracking type

Step 2. Outer-loop PD tracking type

Step 3. Outer-loop PID tracking type

9.4 Design Study C. Satellite Attitude Control

9.4.1 image Example Problem 3.3.12

When the inner loop controller of the satellite system is PD control, what is the system type of the inner loop with respect to the reference input and with respect to the disturbance input? Characterize the steady-state error when the reference input is a step, a ramp, and a parabola. Characterize the steady-state error when the input disturbance is a step, a ramp, and a parabola.

With PD control for the outer loop, what is the system type of the outer loop with respect to the reference input and with respect to the disturbance input? Characterize the steady-state error when each of the reference and disturbance inputs is a step, a ramp, or a parabola. How does this change if you add an integrator?

Design Study C guided exercise

Classify satellite system type

Separate the reference-tracking and disturbance-rejection paths for the inner and outer loops.

Step 1. Inner loop with PD control

Step 2. Outer loop with PD control

Step 3. Add an integrator

9.5 Knowledge Check

Use these checks to test final-value theorem conditions, reference-tracking type, and disturbance-path type before moving on.

Q1. Final value theorem condition

Before accepting lims->0 sY(s) as the final value, what must be true?

Q2. Type number

For reference tracking, a type 1 system has how many free integrators in P(s)C(s)?

Q3. Tracking consequence

For a stable type 1 reference-tracking system, what steady-state tracking behavior should you expect?

Q4. Input-disturbance type

For input disturbances in the chapter examples, where is the free integrator that most directly improves constant disturbance rejection?

Q5. What integral action most directly helps

Which issue is integral action most directly intended to improve in this chapter?

Q6. Ramp-error calculation

A type 1 reference-tracking system has Mv = 4. For a unit ramp input, enter the steady-state error.

Show solution

Answer: 0.25. For a type 1 system tracking a unit ramp, ess = 1/Mv = 1/4.

Q7. Step-error calculation

For the same type 1 reference-tracking system, enter the steady-state error for a unit step input.

Show solution

Answer: 0. A type 1 system gives zero steady-state error for a step input, assuming the closed loop is stable.

Q8. Classify tracking type

If P(s)C(s) has no free integrators, enter the reference-tracking system type.

Show solution

Answer: Type 0. The type equals the number of free integrators in P(s)C(s) for reference tracking.

Q9. Disturbance-path identification

In one word or expression, where should you look first for the free integrator that improves input-disturbance rejection in the chapter examples?

Show solution

Answer: The controller C(s). For input disturbances, the chapter examples show that adding an integrator to the controller changes the disturbance type.

Q10. Error transfer from reference

For unity negative feedback with plant P(s) and controller C(s), what is the transfer function from R(s) to E(s)?

Q11. Input-disturbance path

For a disturbance D(s) added at the plant input in unity feedback, which closed-loop factor determines the error path magnitude from D(s) to E(s)?

Q12. Count the free integrators

For reference tracking with C(s)P(s)H(s) = 10(s + 2)/(s(s + 5)), what is the system type?

Q13. Disturbance type

When determining the system type for a disturbance input, what should you count?

Q14. Ramp-error constant

A stable type 1 reference-tracking system has Mv = 5. What is the steady-state error for a unit ramp?

9.6 Notes and References

The PID structure analyzed in this chapter uses a differentiator on the error as shown in Fig. 7.1 instead of differentiating the output variable as shown in Fig. 7.2. It is straightforward to show, using the final value theorem, that the system type does not change under the two configurations. However, the value of the steady-state error does change and is not necessarily given by the simple formulas in Table 12.1.

10 Digital Implementation of PID Controllers

10.1 Theory

In this book we work primarily with continuous time systems and continuous time controllers. However, almost all modern control strategies are implemented digitally on a micro-controller or a micro-processor, typically implemented using C-code. In this chapter, we describe how PID controllers can be implemented in a sampled data system using computer code.

A general PID control signal is given by \[u(t) = k_P e(t) + k_I\int_{-\infty}^t e(\tau)d\tau + k_D \frac{de}{dt}(t),\] where \(e(t)=r(t)-y(t)\) is the error between the desired reference output \(r(t)\) and the current output \(y(t)\). Define \(u_P(t) = e(t)\), \(u_I(t) = \int_{-\infty}^t e(\tau)d\tau\), and \(u_D(t) = \frac{de}{dt}(t)\). The PID controller is therefore given by \(u(t) = k_p u_P(t) + k_I u_I(t) + k_D u_D(t)\). In the following paragraphs we will derive discrete sampled-time equivalents for \(u_P(t)\), \(u_I(t)\), and \(u_D(t)\).

First consider a sampled time implementation of \(u_P(t)\). When \(t=nT_s\), where \(T_s\) is the sample period and \(n\) is the sample time, we have \(u_P(nT_s) = e(nT_s)\), or using discrete time notation \[u_P[n] = e[n].\]

To derive the sample-time implementation of an integrator, note that \[\begin{aligned} u_I(nT_s) &= \int_{-\infty}^{nT_s} e(\tau) d\tau \\ &= \int_{-\infty}^{(n-1)T_s} e(\tau)d\tau + \int_{(n-1)T_s}^{nT_s} e(\tau) d\tau \\ &= u_I((n-1)T_s) + \int_{(n-1)T_s}^{nT_s} e(\tau) d\tau. \end{aligned}\] As shown in Fig. 10.1, a trapezoidal approximation of the integral between \((n-1)T_s\) and \(nT_s\) is given by \[\int_{(n-1)T_s}^{n T_s} e(\tau) d\tau \approx \frac{T_s}{2}\left(e(nT_s)+e((n-1)T_s)\right).\]

Trapezoidal rule for digital integration.

Therefore \[u_I(nT_s) \approx u_I((n-1)T_s) + \frac{T_s}{2}\left(e(nT_s)+e((n-1)T_s)\right).\] Taking the z-transform we get \[U_I(z) = z^{-1}U_I(z) + \frac{T_s}{2}(E(z)+z^{-1}E(z)).\] Solving for \(U_I(z)\) gives \[\tag{10.1} U_I(z) = \frac{T_s}{2} \left(\frac{1+z^{-1}}{1-z^{-1}}\right)E(z).\] Since in the Laplace domain we have \[U_I(s) = \frac{1}{s}E(s),\] we have derived the so-called Tustin approximation where \(s\) in the Laplace domain is replaced with the \(z\)-transform approximation \[\tag{10.2} s \mapsto \frac{2}{T_s}\left(\frac{1-z^{-1}}{1+z^{-1}}\right),\] where \(T_s\) is the sample period [18]. Taking the inverse \(z\)-transform of Equation 10.1 gives the discrete time implementation of an integrator as \[\tag{10.3} u_I[n] = u_I[n-1] + \frac{T_s}{2}\left(e[n] + e[n-1]\right).\]

In the Laplace domain, a pure differentiator is given by \(U_D(s) = s E(s)\). However, since a pure differentiator is not causal, the standard approach is to use the band-limited, or dirty derivative \[U_D(s) = \frac{s}{\sigma s + 1}E(s),\] where \(\sigma\) is small, and \(\frac{1}{\sigma}\) defines the bandwidth of the differentiator. In practical terms, the dirty derivative differentiates signals with frequency content less than \(\frac{1}{\sigma}\) radians per second. Using the Tustin approximation 10.2, the dirty derivative in the \(z\)-domain becomes \[\begin{aligned} U_D(z) &= \frac{\frac{2}{T_s}\left(\frac{1-z^{-1}}{1+z^{-1}}\right)}{\frac{2\sigma}{T_s}\left(\frac{1-z^{-1}}{1+z^{-1}}\right)+1}E(z) = \frac{\left(\frac{2}{2\sigma+T_s}\right)(1-z^{-1})}{1-\left(\frac{2\sigma-T_s}{2\sigma+T_s}\right)z^{-1}}E(z). \end{aligned}\] Transforming to the time domain, we have \[\tag{10.4} u_D[n] = \left(\frac{2\sigma-T_s}{2\sigma+T_s}\right) u_D[n-1] + \left(\frac{2}{2\sigma+T_s}\right)\left(e[n]-e[n-1]\right).\]

Interactive Figure 10.I1

Dirty derivative noise filtering

A pure finite-difference derivative reacts strongly to measurement noise. The dirty derivative keeps the derivative causal and band-limited; increasing sigma lowers the differentiator bandwidth and smooths the derivative estimate.

Interactive Figure 10.I1. The upper plot shows the noisy input signal v(t) and the true signal before measurement noise is added. The lower plot compares the true derivative with the raw finite-difference derivative and the dirty derivative. Use sigma to see the tradeoff between noise rejection and lag.

Interpretation

Bandwidth proxy: 1/sigma = rad/s; filter coefficient beta =

10.1.1 Integrator Anti-Windup

A potential problem with a straightforward implementation of PID controllers is integrator windup. When the error \(r-y\) is large and persists for an extended period, the value of the integrator can become large, or “wind up.” A large integrator will cause \(u\) to saturate, which will cause the system to push with maximum effort in the direction needed to correct the error. Since the value of the integrator will continue to wind up until the error signal changes sign, the control signal may not come out of saturation until well after the error has changed sign, which can cause a large overshoot and may destabilize the system.

Since integrator windup can destabilize the system, it is important to add an anti-windup scheme. A number of different anti-windup schemes are possible. In this section we will discuss two schemes that are commonly used in practice. The first scheme is based on the fact that integrators are typically used to correct for steady-state error and the fact that overshoot is caused by integrating error during the transients of the step response. Therefore, the integrator can be turned off when the derivative of the error is large. This anti-windup scheme is implemented by an if-statement conditioned on the size of \(\dot{e}\).

The second anti-windup scheme is to subtract from the integrator exactly the amount needed to keep \(u\) at the saturation bound. In particular, let \[u_{\text{unsat}}=k_P e + k_D u_D + k_I u_I\] denote the unsaturated control value before applying the anti-windup scheme. After the saturation block we get \[u = \text{sat}(u_{\text{unsat}}) = \text{sat}(k_P e + k_D u_D + k_I u_I).\] The idea of anti-windup is to modify the output of the integrator from \(u_I\) to \(u_I^{+}\) so that \[k_P e + k_D u_D + k_I u_I^{+} = \text{sat}(k_P e + k_D u_D + k_I u_I) = u.\] Subtracting \(u_{\text{unsat}}\) from \(u\) gives \[\begin{aligned} u-u_{\text{unsat}} &= (k_P e + k_D u_D + k_I u_I^{+})-(k_P e + k_D u_D + k_I u_I) \\ &= k_I(u_I^{+}-u_I). \end{aligned}\] Solving for \(u_I^{+}\) gives \[u_I^{+} = u_I + \frac{1}{k_I}(u-u_{\text{unsat}}),\] which is the updated value of the integrator that ensures that the control signal remains just out of saturation. Note that if the control value is not in saturation then \(u=u_{\text{unsat}}\) and the integrator value remains unchanged.

Interactive Figure 10.I2

Anti-windup response under actuator saturation

Compare a saturated PI controller with and without anti-windup on an intentionally underdamped second-order plant. The dashed traces show the no-anti-windup baseline; the colored traces show the selected controller. Use the actuator limit and integral gain to make windup more or less severe.

Interactive Figure 10.I2. The top plot shows the step response, the middle plot shows uunsat and usat, and the bottom plot shows the integrator state. Without anti-windup, the controller keeps integrating error while the actuator is saturated, so uunsat stays far beyond the actuator limit and the stored integrator drives a large overshoot. The axes rescale so this growth remains visible.

Overshoot
Time in saturation
Final error
Peak integrator state

Interpretation: windup is visible when uunsat remains far outside the actuator limit and the integrator state keeps growing. Anti-windup changes the stored integrator state, so the controller leaves saturation sooner and overshoots less.

10.1.2 Implementation

Python code that implements a general class for a PID loop is shown below.

import numpy as np

class PIDControl:
    def __init__(self, kp, ki, kd, limit, sigma, Ts, flag=True):
        self.kp = kp  # Proportional control gain
        self.ki = ki  # Integral control gain
        self.kd = kd  # Derivative control gain
        self.limit = limit  # The output saturates at this limit
        self.sigma = sigma  # dirty derivative bandwidth is 1/sigma
        self.beta = (2.0*sigma-Ts)/(2.0*sigma+Ts)
        self.Ts = Ts          # sample rate
        self.flag = flag
        # if flag == True, then returns
        #    u = kp * error + ki * integral(error) + kd * error_dot.
        # else returns
        # u = kp * error + ki * integral(error) - kd * y_dot.
        self.y_dot = 0.0  # estimated derivative of y
        self.y_d1 = 0.0  # Signal y delayed by one sample
        self.error_dot = 0.0  # estimated derivative of error
        self.error_d1 = 0.0  # Error delayed by one sample
        self.integrator = 0.0  # integrator

    def PID(self, r, y):
        # Compute the current error
        error = r - y
        # integrate error using trapazoidal rule
        self.integrator = self.integrator 
            + (self.Ts/2) * (error + self.error_d1)
        # PID Control
        if flag is True:
            # differentiate error
            self.error_dot = self.beta * self.error_dot 
                + (1-self.beta)/self.Ts * (error - self.error_d1)
            # PID control
            u_unsat = self.kp*error 
                      + self.ki*self.integrator 
                      + self.kd*self.error_dot
        else:
            # differentiate y
            self.y_dot = self.beta * self.y_dot 
                + (1-self.beta)/self.Ts * (y - self.y_d1)
            # PID control
            u_unsat = self.kp*error 
                      + self.ki*self.integrator 
                      - self.kd*self.y_dot
        # return saturated control signal
        u_sat = self.saturate(u_unsat)
        # integrator anti - windup
        if self.ki != 0.0:
            self.integrator = self.integrator 
                + self.Ts / self.ki * (u_sat - u_unsat)
        # update delayed variables
        self.error_d1 = error
        self.y_d1 = y
        return u_sat

    def PD(self, r, y):
        # Compute the current error
        error = r - y
        # PD Control
        if flag is True:
            # differentiate error
            self.error_dot = self.beta * self.error_dot 
                + (1-self.beta)/self.Ts * (error - self.error_d1)
            # PD control
            u_unsat = self.kp*error 
                      + self.kd*self.error_dot
        else:
            # differentiate y
            self.y_dot = self.beta * self.y_dot 
                + (1-self.beta)/self.Ts * (y - self.y_d1)
            # PD control
            u_unsat = self.kp*error 
                      - self.kd*self.y_dot
        # return saturated control signal
        u_sat = self.saturate(u_unsat)
        # update delayed variables
        self.error_d1 = error
        self.y_d1 = y
        return u_sat

    def saturate(self,u):
        if abs(u) > self.limit:
            u = self.limit*np.sign(u)
        return u



The PID controller class is initialized on lines 4–21, where kp, ki, and kd are the control gains, limit is the saturation limit for the control signal, sigma is the dirty derivative gain, Ts is the sample rate, and flag is a flag that indicates whether the controller differentiates the error or the output. The internal memory used to implement the differentiators and integrators is initialized to zero in lines 17–21, where y_d1 is the signal \(y\) delayed by one sample and error_d1 is the error delayed by one sample. PID control is implemented in lines 23–55 and PD control is implemented in lines 57–80. The integrator update is shown in lines 50–51.

10.1.3 Gain Selection for PID control

Gain selection for PID control usually proceeds in the following manner. The proportional and derivative gains \(k_P\) and \(k_D\) are first selected according to the methods discussed in Chapter 11. The integral gain \(k_I\) is then tuned by starting with zero and then slowly increasing the gain until the steady-state error is removed. The parameters associated with the anti-windup scheme, especially \(\bar{v}\), are also adjusted during this phase. The proportional and derivative gains can then be adjusted if necessary by retuning \(\omega_n\) and \(\zeta\). In the case of successive loop closure, integrators are only added on the outer loop.

The addition of an integrator has a destabilizing effect on the feedback system. This effect is most easily understood by using the root locus method described in Appendix 30, where it can be seen that for second-order systems, a large \(k_I\) will always result in closed-loop poles in the right half-plane. The root locus can also be used to aid in the selection of the integral gain \(k_I\), where the value of \(k_I\) is selected so that integrator has minimal impact on the closed-loop poles designed using PD control. A more effective method for selecting integral gains will be discussed in Chapter 15.

10.2.1 image Example Problem 3.1.13

The objective of this problem is to implement the PID controller using only measured outputs of the system.

(a) Modify the system dynamics file so that the parameters vary by up to 20% each time they are run (uncertainty parameter = 0.2).

(b) Change the simulation files so that the input to the controller is the output and not the state. The controller should only assume knowledge of the angle \(\theta\) and the reference angle \(r_\theta\).

(c) Implement the PID controller designed in Problems 3.1.11. Use the dirty derivative gain of \(\sigma=0.05\). Tune the integrator to remove the steady-state error caused by the uncertain parameters.

Design Study A guided exercise

Assemble the digital PID controller

Identify the implementation pieces that belong in the sampled controller class.

Step 1. Available feedback signal

Step 2. Discrete implementation choices

Step 3. Why simulate with uncertainty?

Pseudocode

The complete solution includes PID implementation code. Before opening it, outline how you would update the integrator, compute the dirty derivative, apply anti-windup, and return the control torque.

This prompt is ungraded. It is intended to connect the digital PID concepts to the implementation code in the complete solution.

10.3 Design Study B. Inverted Pendulum

10.3.1 image Example Problem 3.2.13

The objective of this problem is to implement the PID controller using only measured outputs of the system.

(a) Modify the system dynamics file so that the parameters \(m_1\), \(m_2\), \(\ell\) and \(b\) vary by up to 20% of their nominal value each time they are run (uncertainty parameter = 0.2).

(b) Change the simulation files so that the input to the controller is the output and not the state. The controller should only assume knowledge of the position \(z\) and the angle \(\theta\), as well as the reference position \(r_z\). Track a square wave with amplitude of 0.5 meters and a frequency of 0.04 Hz.

(c) Implement the nested PID loops designed in Problems 3.2.11. Use the dirty derivative gain of \(\sigma=0.05\). Tune the integrator to remove the steady-state error caused by the uncertain parameters.

Design Study B guided exercise

Prepare the nested digital PID implementation

Identify measured signals, dirty derivatives, uncertainty, and integral tuning.

Step 1. Available controller inputs

Step 2. Derivative implementation

Step 3. Robustness check

Pseudocode

The complete solution includes a nested PID controller class and a zero-canceling filter class. Before opening it, outline each component separately.

These prompts are ungraded. They are intended to connect the derivation to the implementation code in the complete solution.

10.4 Design Study C. Satellite Attitude Control

10.4.1 image Example Problem 3.3.13

The objective of this problem is to implement the PID controller using only measured outputs of the system.

(a) Modify the system dynamics file so that the parameters \(J_s\), \(J_p\), \(k\) and \(b\) vary by up to 20% of their nominal value each time they are run (uncertainty parameter = 0.2).

(b) Change the simulation files so that the input to the controller is the output and not the state. Assume that the controller only has knowledge of the angles \(\phi\) and \(\theta\) as well as the reference angle \(r_\phi\).

(c) Implement the nested PID loops designed in Problems 3.3.11. Use the dirty derivative gain of \(\sigma=0.05\). Tune the integrator to remove the steady-state error caused by the uncertain parameters.

Design Study C guided exercise

Plan the measured-output satellite PID implementation

This implementation uses uncertain plant parameters and measured angles rather than full state feedback.

Step 1. Plant uncertainty

Step 2. Measured signals

Step 3. Integrator purpose

Pseudocode

10.5 Interactive Implementation Check

Chapter 10 activity

Sample-time and discrete PID terms

Vary the sample time and consecutive error samples. The readouts show the trapezoidal integrator increment, a finite-difference derivative, and the dirty-derivative coefficient.

Integrator increment Finite difference Dirty derivative beta Sample-time effect

Coding-lab preparation: a discrete PID controller must store the previous error, previous measurement, differentiator state, and integrator state. Without that memory, the trapezoidal integral, derivative estimate, and anti-windup correction cannot be implemented correctly.

10.6 Coding Lab: Discrete PID Implementation

Objective: implement a sampled-data PID controller using the Chapter 10 update equations.

Evaluation criteria: the lab checks proportional action, trapezoidal integration, derivative-on-output, saturation, anti-windup behavior, and step-response tracking.

Use the code editor to complete the controller class, then use the automatic checks and plots to debug the implementation.

Figure 10.1 (Interactive). Discrete PID coding lab with automatic implementation checks.

10.7 Knowledge Check

Q1. Controller update timing

A digital PID controller updates at:

Q2. Saturation effect

Actuator saturation can cause:

Q3. Trapezoidal integral increment

Compute the trapezoidal integrator increment for these samples.

  • Ts = 0.1
  • ek = 1.0
  • ek-1 = 0.6

Show solution

Answer: 0.08 because 0.1(1.0 + 0.6)/2 = 0.08.

Q4. Finite-difference derivative

Compute the finite-difference derivative estimate for these samples.

  • Ts = 0.1
  • ek = 1.0
  • ek-1 = 0.6

Show solution

Answer: 4 because (1.0 - 0.6)/0.1 = 4.

Q5. Implementation memory

What must a digital PID controller keep between sample updates to compute integrals and derivatives?

Show solution

Answer: Stored state, memory, or previous samples. The controller needs delayed error/measurement values plus integrator and differentiator state.

Q6. Dirty derivative purpose

Why is a dirty derivative used instead of an ideal derivative in a digital PID implementation?

Q7. Integral action role

What is the main purpose of the integral term in a PID controller?

Q8. Saturation and stored integral state

If an actuator saturates while the integral state continues to grow, what problem is the controller experiencing?

10.8 Notes and References

A standard reference for digital implementation of PID controllers is [18]. Simple anti-wind-up schemes are discussed in [4, 18].

10.9 Notes and References

A standard reference for digital implementation of PID controllers is [18]. Simple anti-wind-up schemes are discussed in [4, 18].

Part IV

Observer Based Control Design

In Part III we focused on designing feedback control systems for second-order systems. Since second-order systems have two poles, we saw that it is possible to use feedback control with two gains to place the closed-loop poles at any desired location. In Chapter 14 of this book we will see that for an \(n^{th}\) order system it is possible to arbitrarily place the closed-loop poles, but that this will require \(n\) feedback gains. In that sense, the full state feedback controllers that we will derive in Chapter 14 are a generalization of PD control to higher-order systems. This generalization is most easily accomplished using the state-space model of the system derived in Chapter 9. In fact, the state-space model leads to efficient numerical routines for designing and implementing the feedback controller.

In Chapter 15 we show how integral control can be added to the state feedback controllers designed in Chapter 14. The method introduced in Chapter 15 has a significant advantage over the integrator tuning method discussed in Chapter 13 in the sense that tuning the integral gain will not impact the other closed-loop poles and therefore allows for greater design flexibility.

We saw in Chapter 13 that in order to implement PD/PID control, the derivative of the output needs to be reconstructed using a digital differentiator. The generalization of this idea to state feedback control is that the full state of the system must be reconstructed. The tool that we will use to reconstruct the system state is called an observer. The observer design problem will be discussed in Chapter 16.

It turns out that observers can be used in a variety of different contexts outside of feedback control. In particular, observers can be used to solve target tracking problems and to estimate the system parameters of complex dynamic systems. In the setting of feedback control where unknown input and output disturbances act on the system, observers can be used to estimate the unknown disturbances. In Chapter 17 we will show how to design the observer to estimate both the system state and the unknown constant input disturbance. We will also show that estimating the input disturbance is mathematically and functionally similar to adding an integrator.

The design tools developed in Part IV of this book use state-space models and require the use of linear algebra and matrix analysis. A brief review of linear algebra concepts that will be used in Part IV are given in Appendix 31.

11 Full State Feedback

11.1 Theory

In this chapter we will show how to use full state feedback to stabilize a linear time-invariant system represented in state-space form. Recall from Section 9.1.2, that for state-space equations given by \begin{align} \dot{x} &= Ax + Bu \tag{11.1}\\ y &= Cx + Du, \tag{11.2} \end{align} the poles of the system are the eigenvalues of \(A\), or in other words, the roots of the open-loop characteristic equation \[\Delta_{ol}(s) = \det(sI-A) = 0.\] The matrix \(A\) is called the state-interaction matrix because it specifies how the states interact with each other. The basic idea behind full state feedback is to use the feedback signal to change the interaction matrix so that the poles are in specified locations. A full state feedback controller is given by \[\tag{11.3} u = -Kx + \nu,\] where \(K\in\mathbb{R}^{m\times n}\) are the feedback gains, and \(\nu\) will be a signal that is specified later. Using 11.3 in Equation 11.1 results in the closed-loop state-space equations \begin{align} \dot{x} &= Ax + B(-Kx+\nu) = (A-BK)x + B\nu \tag{11.4}\\ y &= Cx, \tag{11.5} \end{align} where the interaction matrix is now \(A-BK\), and so the closed-loop poles will be given by the eigenvalues of \(A-BK\), or in other words, the roots of the closed-loop characteristic equation \[\Delta_{cl}(s) = \det(sI-(A-BK))=0.\] A natural question that will be addressed in the remainder of this section is how to select \(K\) so that the closed-loop characteristic equation is equal to a desired closed-loop characteristic polynomial \(\Delta_{cl}^d(s)\), where the designer selects the roots of \(\Delta_{cl}^d(s)=0\) to achieve the desired closed-loop performance.

Section 9.1.2 showed that the state-space model given by Equations 11.1–11.2 is equivalent to the transfer function model given by \[\tag{11.6} Y(s) = C(sI-A)^{-1}B U(s).\] While the mapping from state-space model to transfer function model is unique, the reverse is not true. In fact, there are an infinite number of state-space models that correspond to a particular transfer function model. Accordingly, we say that a state-space model is a realization of the transfer function model, if it produces the same input-output behavior when the initial conditions are zero.

In particular, define the change of variables \[\tag{11.7} z = P^{-1}x,\] where \(P\) is an invertible matrix. Then \begin{align} \dot{z} &= P^{-1}\dot{x} = P^{-1}(Ax+Bu) = P^{-1}APz + P^{-1}B u \tag{11.8}\\ y&= Cx = CPz \tag{11.9} \end{align} is an alternative state-space representation of system 11.1-11.2. To show that these two representations have the same input-output behavior, or in other words, the same transfer function, note from Equation 11.6 that the transfer function of system 11.8-11.9 is \[\begin{aligned} Y(s) &= \left( CP(sI-P^{-1}AP)^{-1}P^{-1}B \right) U(s) \\ &= \left( CP(sP^{-1}P-P^{-1}AP)^{-1}P^{-1}B\right) U(s) \\ &= \left( CP(P^{-1}(sI-A)P)^{-1}P^{-1}B \right) U(s) \\ &= \left( CPP^{-1}(sI-A)^{-1}PP^{-1}B \right) U(s) \\ &= \left( C(sI-A)^{-1}B \right) U(s), \end{aligned}\] which is identical to Equation 11.6. Therefore, Equations 11.1-11.2 and Equations 11.8-11.9 are realizations of the same system.

11.1.1 State-Space Realization in Control Canonic Form

In this section, we will derive one specific state-space realization for single-input single-output transfer functions, where the state feedback problem is particularly simple. The realization that we derive below is called the control canonic form of the system.

Consider the general SISO monic transfer function model given by \[\tag{11.10} Y(s) = \frac{b_ms^m + b_{m-1}s^{m-1} + \dots + b_1 s + b_0}{s^n + a_{n-1}s^{n-1} + \dots + a_1 s + a_0} U(s),\] where \(m<n\). The block diagram of the system is shown in Fig. 11.1.

General transfer function for a SISO system.

The first step in deriving the control canonic state-space equations is to artificially decompose the transfer function as shown in Fig. 11.2, where the numerator polynomial and the denominator polynomial appear in separate cascaded blocks, and where \(Z(s)\) is an artificial intermediate variable.

General transfer function for a SISO system decomposed into state dynamics and output dynamics.

In the \(s\)-domain, the equations corresponding to Fig. 11.2 can be written as \[\begin{aligned} Z(s) &= \frac{1}{s^n + a_{n-1}s^{n-1} + \dots + a_1 s + a_0} U(s) \\ Y(s) &= (b_ms^m + b_{m-1}s^{m-1} + \dots + b_1 s + b_0) Z(s). \end{aligned}\] Taking the inverse Laplace transform of these equations gives \begin{align} \frac{d^nz}{dt^n} &= u(t) - a_{n-1}\frac{d^{n-1}z}{dt^{n-1}} - \dots - a_1 \dot{z} - a_0 z(t) \tag{11.11}\\ y(t) &= b_m\frac{d^mz}{dt^m} + b_{m-1}\frac{d^{m-1}z}{dt^{m-1}} + \dots + b_1 \dot{z} + b_0 z(t). \tag{11.12} \end{align}

The next step in the derivation of the state-space equations is to draw the analog computer implementation of Equations 11.11 and 11.12, which is shown in Fig. 11.3.

Block diagram showing the analog computer implementation of Equations 11.11 and 11.12.

Labeling the output of the integrators as the state variables \(x_1, \dots, x_n\), as shown in Fig. 11.3, we can write the state-space equations as \begin{align} \begin{pmatrix} \dot{x}_1 \\ \dot{x}_2 \\ \vdots \\ \dot{x}_n \end{pmatrix} &= \begin{pmatrix} -a_{n-1} & -a_{n-2} & \dots & -a_1 & -a_0 \\ 1 & 0 & \dots & 0 & 0 \\ 0 & 1 & \dots & 0 & 0 \\ \vdots & & \ddots & & \vdots \\ 0 & 0 & \dots & 1 & 0 \end{pmatrix} \begin{pmatrix} x_1 \\ x_2 \\ \vdots \\ x_n \end{pmatrix} + \begin{pmatrix} 1 \\ 0 \\ \vdots \\ 0 \end{pmatrix} u \tag{11.13} \\ y &= \begin{pmatrix} 0 & \dots & 0 & b_m & \dots & b_1 & b_0 \end{pmatrix} \begin{pmatrix} x_1 \\ x_2 \\ \vdots \\ x_n \end{pmatrix} + 0\cdot u. \notag \end{align} In the case when \(m=n\) it is straightforward to show that the output equation becomes \[y = \begin{pmatrix} b_{n-1} - b_n a_{n-1}, & \dots & b_1 - b_n a_1, & b_0 - b_n a_0 \end{pmatrix} \begin{pmatrix} x_1 \\ x_2 \\ \vdots \\ x_n \end{pmatrix} + b_n\cdot u.\] We will define the control canonic realization as \[\begin{aligned} \dot{x}_c &= A_c x_c + B_c u \\ y &= C_c x_c + Du, \end{aligned}\] where \begin{align} A_c &\stackrel{\triangle}{=}\begin{pmatrix} -a_{n-1} & -a_{n-2} & \dots & -a_1 & -a_0 \\ 1 & 0 & \dots & 0 & 0 \\ 0 & 1 & \dots & 0 & 0 \\ \vdots & & \ddots & & \vdots \\ 0 & 0 & \dots & 1 & 0 \end{pmatrix} \tag{11.14}\\ B_c &\stackrel{\triangle}{=}\begin{pmatrix} 1 \\ 0 \\ \vdots \\ 0 \end{pmatrix} \tag{11.15} \\ C_c &\stackrel{\triangle}{=}\begin{cases} \begin{pmatrix} 0 & \dots & 0 & b_m & \dots & b_1 & b_0 \end{pmatrix} &\quad m<n \\ \begin{pmatrix} b_{n-1} - b_n a_{n-1}, & \dots & b_1 - b_n a_1, & b_0 - b_n a_0 \end{pmatrix} &\quad m=n \end{cases} \tag{11.16} \\ D &\stackrel{\triangle}{=}\begin{cases} 0 &\quad m<n \\ b_n &\quad m=n \end{cases}. \tag{11.17} \end{align} Note that the negative of the coefficients of the denominator of 11.10 constitute the first row of \(A_c\), and that the remainder of \(A_c\) has ones on the lower off diagonal and zeros in all other elements. Matrices with this structure are said to be in companion form. The \(B_c\) vector has a single one as its first element, with the remaining elements equal to zero. The coefficients of the numerator of Equation 11.10 are the last \(p\)-elements of \(C_c\).

As an example, suppose that the transfer function model of the system is given by \[Y(s) = \frac{9s + 20}{s^3 + 6s^2 - 11s + 8}U(s),\] then the control canonic realization of the system is given by \begin{align} \begin{pmatrix} \dot{x}_1 \\ \dot{x}_2 \\ \dot{x}_3 \end{pmatrix} &= \begin{pmatrix} -6 & 11 & -8 \\ 1 & 0 & 0 \\ 0 & 1 & 0 \end{pmatrix}\begin{pmatrix} x_1 \\ x_2 \\ x_3 \end{pmatrix} + \begin{pmatrix} 1 \\ 0 \\ 0\end{pmatrix} u \tag{11.18} \\ y &= \begin{pmatrix} 0 & 9 & 20 \end{pmatrix} \begin{pmatrix} x_1 \\ x_2 \\ x_3 \end{pmatrix}. \notag \end{align}

11.1.2 Full State Feedback using Control Canonic Form

The design of a state feedback controller is particularly easy when the state-space equations are in control canonic form. The key insight is that there is a direct relationship between matrices in companion form, as shown in Equation 11.14 and their characteristic polynomial \[\Delta_{ol}(s) = s^n + a_{n-1}s^{n-1} + \dots + a_1 s + a_0.\] Suppose that we let \[\tag{11.19} u = -K_cx_c + \nu = -\begin{pmatrix} k_1 & k_2 & \dots & k_{n-1} & k_n\end{pmatrix} \begin{pmatrix} x_1 \\ x_2 \\ \vdots \\ x_{n-1} \\ x_n \end{pmatrix} + \nu.\] Substituting into Equation 11.13 and rearranging gives \[\begin{gathered} \begin{pmatrix} \dot{x}_1 \\ \dot{x}_2 \\ \vdots \\ \dot{x}_n \end{pmatrix} = \begin{pmatrix} -(a_{n-1}+k_1) & -(a_{n-2}+k_2) & \dots & -(a_1+k_{n-1}) & -(a_0+k_n) \\ 1 & 0 & \dots & 0 & 0 \\ 0 & 1 & \dots & 0 & 0 \\ \vdots & & \ddots & & \vdots \\ 0 & 0 & \vdots & 1 & 0 \end{pmatrix} \begin{pmatrix} x_1 \\ x_2 \\ \vdots \\ x_n \end{pmatrix} % + \begin{pmatrix} 1 \\ 0 \\ \vdots \\ 0 \end{pmatrix} \nu. \end{gathered}\] Since the state interaction matrix is still in companion form, the characteristic polynomial of the closed-loop system is given by \[\Delta_{cl}(s) = s^n + (a_{n-1}+k_1)s^{n-1} + \dots + (a_1+k_{n-1}) s + (a_0+k_n).\] If the desired characteristic polynomial is given by \[\tag{11.20} \Delta_{cl}^d(s) = s^n + \alpha_{n-1}s^{n-1} + \dots + \alpha_1 s + \alpha_0,\] then we have that \[\begin{aligned} a_{n-1} + k_1 &= \alpha_{n-1} \\ a_{n-2} + k_2 &= \alpha_{n-2} \\ \vdots & \\ a_{1} + k_{n-1} &= \alpha_{1} \\ a_0 + k_n &= \alpha_0. \end{aligned}\] Defining the row vectors \[\begin{aligned} \mathbf{a}_A &= (a_{n-1}, a_{n-2}, \dots, a_1, a_0) \\ \boldsymbol{\alpha} &= (\alpha_{n-1}, \alpha_{n-2}, \dots, \alpha_1, \alpha_0) \\ K_c &= (k_1, k_2, \dots, k_{n-1}, k_n), \end{aligned}\] we have that the feedback gains satisfy \[\tag{11.21} K_c = \boldsymbol{\alpha}-\mathbf{a}_A,\] where the subscript “c” is used to emphasize that the gains are in control canonic form.

As an example, consider the state equations given in Equation 11.18. The open-loop characteristic polynomial is given by \[\Delta_{ol}(s) = s^3 + 6s^2 - 11 s + 8,\] with roots at \(-7.5885\), and \(0.7942\pm j0.6507\). Suppose that the desired closed-loop characteristic polynomial is \[\Delta_{cl}^d(s) = s^3 + 5s^2 + 12 s + 8,\] with roots at \(-1\) and \(-2\pm j2\), then \(\mathbf{a}_A = (6, -11, 8)\), and \(\boldsymbol{\alpha} = (5, 12, 8)\). The feedback gains that place the poles at the desired locations are therefore given by \[K_c = \boldsymbol{\alpha}-\mathbf{a}_A = (5, 12, 8)-(6, -11, 8) = (-1, 23, 0).\]

11.1.3 Full State Feedback: General Case

The formula given in Equation 11.21 assumes that the state-space equations are in control canonic form. It turns out that the closed-loop eigenvalues cannot always be arbitrarily assigned to desired locations. When they can, the system \(\dot{x}=Ax+Bu\) is said to be controllable. In this section we will derive an expression for the state feedback gains, and we will simultaneously derive a simple test for determining when the system is controllable.

Recall from Equations 11.7–11.9 that state-space equations can be transformed using the change of variables in Equation 11.7 without modifying the input-output properties of the system. This implies that the change of variables does not change the characteristic polynomial. We can verify this fact explicitly as follows: \[\begin{aligned} \det(sI-P^{-1}AP) &= \det(sP^{-1}P-P^{-1}AP) \\ &= \det\left(P^{-1}(sI-A)P\right) \\ &= \det(P^{-1})\det(sI-A)\det(P) \\ &= \det(sI-A). \end{aligned}\]

Therefore, to derive full state feedback gains for the general state-space equations \[\tag{11.22} \dot{x}=Ax+Bu,\] the idea is to find a state transformation matrix \(P\) so that the transformed system is in control canonic form, i.e., find \(P\) so that \[\tag{11.23} x_c=P^{-1}x,\] and \[\tag{11.24} \dot{x}_c = P^{-1}APx_c + P^{-1}B u = A_c x_c + B_c u,\] where \(A_c\) and \(B_c\) have the form given by Equations 11.14 and 11.15, respectively. Therefore, we need to find \(P\) so that \(P^{-1}B = B_c\), and \(P^{-1}AP=A_c\), which are satisfied if and only if \(B=PB_c\) and \(AP=PA_c\). Let \(P=(\mathbf{p}_1, \mathbf{p}_2, \dots, \mathbf{p}_n)\), where \(\mathbf{p}_i\in\mathbf{R}^n\) is the \(i^{th}\) column of \(P\). The requirement that \(B=PB_c\) implies that \[B = \begin{pmatrix} \mathbf{p}_1 & \mathbf{p}_2 & \dots & \mathbf{p}_n \end{pmatrix} \begin{pmatrix} 1 \\ 0 \\ \vdots \\ 0 \end{pmatrix} = \mathbf{p}_1.\] Therefore, \(\mathbf{p}_1=B\). The requirement that \(PA_c=AP\) implies that \[\begin{gathered} \begin{pmatrix} \mathbf{p}_1 & \mathbf{p}_2 & \dots & \mathbf{p}_n \end{pmatrix}\begin{pmatrix} -a_{n-1} & -a_{n-2} & \dots & -a_1 & -a_0 \\ 1 & 0 & \dots & 0 & 0 \\ 0 & 1 & \dots & 0 & 0 \\ \vdots & & \ddots & & \vdots \\ 0 & 0 & \dots & 0 & 0 \\ 0 & 0 & \vdots & 1 & 0 \end{pmatrix} \\ = A \begin{pmatrix} \mathbf{p}_1 & \mathbf{p}_2 & \dots & \mathbf{p}_n \end{pmatrix}. \end{gathered}\] After multiplication, the first \(n-1\) columns can be equated to get \begin{align} -a_{n-1}\mathbf{p}_1 + \mathbf{p}_2 &= A\mathbf{p}_1 \tag{11.25}\\ -a_{n-2}\mathbf{p}_1 + \mathbf{p}_3 &= A\mathbf{p}_2 \tag{11.26}\\ \vdots \\ -a_1\mathbf{p}_1 + \mathbf{p}_{n} &= A\mathbf{p}_{n-1}. \tag{11.28} \end{align} Equation 11.25, and the previous conclusion that \(\mathbf{p}_1=B\), implies that \[\mathbf{p}_2 = a_{n-1}B + AB.\] Using this result in Equation 11.26 gives \[\mathbf{p}_3 = a_{n-2}B + a_{n-1} AB + A^2B.\] We can continue to iteratively solve for each column of \(P\) until the \((n-1)^{th}\) column, which from Equation 11.28 is \[\mathbf{p}_n = a_1B + a_2AB + \dots + a_{n-1}A^{n-2}B + A^{n-1}B.\] Notice that each column in \(P\) is a linear combination of the elements \(B\), \(AB\), \(A^2B\), \(\dots\), \(A^{n-1}B\). Accordingly, defining \[\tag{11.29} \mathcal{C}_{A,B} = \begin{pmatrix} B & AB & A^2B & \dots & A^{n-1}B\end{pmatrix},\] gives \[\begin{aligned} \mathbf{p}_1 &= \mathcal{C}_{A,B}\begin{pmatrix} 1, & 0, & \dots & 0, & 0 \end{pmatrix}^\top, \\ \mathbf{p}_2 &= \mathcal{C}_{A,B}\begin{pmatrix} a_{n-1}, & 1, & \vdots & 0, & 0 \end{pmatrix}^\top, \\ \vdots &\qquad \vdots \\ \mathbf{p}_n &= \mathcal{C}_{A,B} \begin{pmatrix} a_1, & a_2, & \vdots & a_{n-1}, & 1 \end{pmatrix}^\top. \end{aligned}\] Defining the matrix \[\tag{11.30} \mathcal{A}_A = \begin{pmatrix} 1 & a_{n-1} & a_{n-2} & \dots & a_2 & a_1 \\ 0 & 1 & a_{n-1} & \vdots & a_3 & a_2 \\ 0 & 0 & 1 & \vdots & a_4 & a_3 \\ \vdots & & & \ddots & \vdots \\ 0 & 0 & 0 & \dots & 1 & a_{n-1} \\ 0 & 0 & 0 & \dots & 0 & 1 \end{pmatrix},\] gives that the transformation matrix that converts the system into control canonic form is \[P = \mathcal{C}_{A,B}\mathcal{A}_A.\] Notice that since \(\mathcal{A}_A\) is an upper triangular matrix with ones on the diagonal, \(\det(\mathcal{A}_A)=1\), implying that \(\mathcal{A}_A^{-1}\) always exists. It is clear that the matrix \(P\) is invertible with \[P^{-1}=\mathcal{A}_A^{-1}\mathcal{C}_{A,B}^{-1}\] if and only if \(\mathcal{C}_{A,B}^{-1}\) exists. The matrix \(\mathcal{C}_{A,B}\) in Equation 11.29 is called the controllability matrix, and a single input system is said to be controllable if \(\mathcal{C}\) is invertible. Therefore, when the original system 11.22 is controllable, there exists an invertible state transformation matrix \(P\) so that the change of variables in Equation 11.23 is well defined and that results in the transformed equations being in control canonic form via Equations 11.24.

In control canonic form, the state feedback equation is \[u = -K_cx_c + \nu = -(\boldsymbol{\alpha}-\mathbf{a}_A)x_c + \nu.\] Using Equation 11.23 the state feedback control can be expressed in the original states \(x\) as \begin{align} u &= -(\boldsymbol{\alpha}-\mathbf{a}_A)P^{-1}x + \nu \notag \\ &= -(\boldsymbol{\alpha}-\mathbf{a}_A)\mathcal{A}_A^{-1}\mathcal{C}_{A,B}^{-1}x + \nu \notag \\ &= - Kx + \nu, \tag{11.31} \end{align} where \[\tag{11.32} K \stackrel{\triangle}{=}(\boldsymbol{\alpha}-\mathbf{a}_A)\mathcal{A}_A^{-1}\mathcal{C}_{A,B}^{-1}.\] Equation 11.32 is called Ackermann’s formula for the feedback gains. Since \(\mathcal{C}_{A,B}\) is only square in the single-input case, Ackermann’s formula only holds for single input systems.

Using the full state feedback control in Equation 11.31 in the state equations 11.1-11.2 results in the closed-loop system \[\begin{aligned} \dot{x} &= (A-BK)x + B\nu \\ y&= Cx. \end{aligned}\] The resulting transfer function from \(\nu\) to \(y\) is given by \[\tag{11.33} Y(s) = \left(C(sI-(A-BK))^{-1}B\right)\nu(s).\]

A block diagram of the resulting closed-loop system is shown in Fig. 11.4 where the double line associated with \(x\) is meant to imply that the state \(x\) is not really available. The block diagram also shows the new input \(\nu\). Since the objective is for the output \(y\) to track the reference input \(r\), we let \(\nu(t)=k_r r(t)\), as shown in Fig. 11.4. The feedforward gain \(k_r\) is selected so that the DC gain from \(r\) to \(y\) is equal to one.

Full state feedback with reference input r.

From Equation 11.33, the transfer function from \(R\) to \(Y\) is given by \[\tag{11.34} Y(s) = \left(C(sI-(A-BK))^{-1}Bk_r\right) R(s),\] and the DC gain is \[\tag{11.35} k_{DC} = \lim_{s\to 0} \left[C(sI-(A-BK))^{-1}Bk_r\right] = -C(A-BK)^{-1}Bk_r.\] Therefore, the DC gain is equal to one if \[k_r = -\frac{1}{C(A-BK)^{-1}B}.\] The matrix \(A-BK\) will be invertible when there are no eigenvalues at zero. Since \(K\) is selected to place the eigenvalues in the open left half-plane, the matrix will always be invertible, and \(k_r\) exists. Note that in many applications, the output measured by the sensors is not the same as the desired reference output. In other words, the state-space equations may be given by \[\begin{aligned} \dot{x} &= Ax + Bu \\ y_r &= C_r x \\ y_m &= C_m x, \end{aligned}\] where \(y_r\) is the reference output and \(y_m\) is the measured output. In this case, the reference gain \(k_r\) is selected to make the DC gain from \(r\) to \(y_r\) equal to one, or in other words \[\tag{11.36} k_r = -\frac{1}{C_r(A-BK)^{-1}B}.\] Chapter 16 will describe observers that use the measured output \(y_m\) to reconstruct the state \(x\).

The feedforward gain computed in Equation 11.36 is for single input systems. More generally, if the size of the reference output \(y_r\) is equal to the size of the input vector \(u\in\mathbb{R}^m\), then \(C_r\in\mathbb{R}^{m\times n}\) and \(B\in\mathbb{R}^{n\times m}\), which implies that the transfer matrix in Equation 11.34 is square and has dimension \(m\times m\). Similarly, the resulting matrix gain \(K_r\in\mathbb{R}^{m\times m}\) will also be square and from Equation 11.35 will be equal to \[K_r = -\left[C_r(A-BK)^{-1}B\right]^{-1}.\]

11.1.4 State Feedback for Linearized Systems

Suppose that the state-space model is from a linearized system, i.e., suppose that \(x\in\mathbb{R}^n\) is the state and that \(x_e\in\mathbb{R}^n\) is the equilibrium state, and that \(\tilde{x}=x-x_e\) is the state linearized around the equilibrium. Similarly, suppose that \(u\in\mathbb{R}^m\) is the input, that \(u_e\in\mathbb{R}^m\) is the input at equilibrium, and that \(\tilde{u}=u-u_e\) is the input linearized around equilibrium, and that \(y_r\in\mathbf{R}^p\) is the reference output, \(y_{re}=C_rx_e\in\mathbf{R}^p\) is the reference output at equilibrium, and \(\tilde{y}_r=y_r-y_{re}\) is the reference output linearized about equilibrium, then the linearized state-space model is given by \[\begin{aligned} \dot{\tilde{x}} &= A\tilde{x} + B\tilde{u} \\ \tilde{y}_r &= C_r\tilde{x}. \end{aligned}\] Now suppose that the state feedback design process is used to find the state feedback controller \[\tag{11.37} \tilde{u} = -K\tilde{x} + k_r \tilde{r}\] where \(\tilde{r}=r-y_{re}\) is the reference input around the equilibrium output, and where the eigenvalues of \((A-BK)\) are in the open left half-plane, and the DC gain from \(\tilde{r}\) to \(\tilde{y}_r\) is one. The controller input to the plant is therefore \[\tag{11.38} u = u_e - K(x-x_e) + k_r(r-y_{re}).\]

11.2 Summary of Design Process - State Feedback

The state feedback design process can be summarized as follows.

Given the plant \[\begin{aligned} \dot{x} &= Ax + Bu \\ y_r &= C_rx \end{aligned}\] and the desired pole locations \(p_1, p_2, \dots, p_n\), find the gains \(K\) and \(k_r\) so that the feedback controller \[u = -Kx + k_r r\] places the poles at the desired location and results in a DC gain equal to one.

Step 1.
Check to see if the system is controllable by computing the controllability matrix \[\mathcal{C}_{A,B} = [B, AB, \dots, A^{n-1}B]\] and checking to see if \(\text{rank}(\mathcal{C})=n\).

Step 2.
Find the open-loop characteristic polynomial \[\Delta_{ol}(s)=\text{det}(sI-A) = s^n + a_{n-1}s^{n-1} + \cdots + a_1 s + a_0,\] and construct the row vector \[\mathbf{a}_A = (a_{n-1}, a_{n-2}, \dots, a_1, a_0)\] and the matrix \[\mathcal{A}_A = \begin{pmatrix} 1 & a_{n-1} & a_{n-2} & \cdots & a_2 & a_1 \\ 0 & 1 & a_{n-1} & \cdots & a_3 & a_2 \\ \cdots & & \ddots & & & \vdots \\ 0 & 0 & \cdots & 0 & 1 & a_{n-1} \\ 0 & 0 & \cdots & 0 & 0 & 1 \end{pmatrix}\]

Step 3.
Select the desired closed-loop polynomial \[\begin{aligned} \Delta_{cl}^d(s) &= (s-p_1)(s-p_2)\cdots(s-p_n) \\ &= s^n + \alpha_{n-1}s^{n-1} + \cdots + \alpha_1 s + \alpha_0, \end{aligned}\] and construct the row vector \[\boldsymbol{\alpha} = (\alpha_{n-1}, \alpha_{n-2}, \dots, \alpha_1, \alpha_0).\]

Step 4.
Compute the desired gains as \[\begin{aligned} K &= (\boldsymbol{\alpha}-\mathbf{a}_A)\mathcal{A}_A^{-1}\mathcal{C}_{A,B}^{-1} \\ k_r &= \frac{-1}{C_r(A-BK)^{-1}B}. \end{aligned}\]

Using Python, these steps can be implemented as follows:

import control as cnt
import numpy as np

CC = cnt.ctrb(A,B)

# check for controllability
if np.linalg.matrix_rank(CC) == np.size(A,1):
    print('the system is controllable')
else:
    print('the system is not controllable')

# place the poles at p1, p2, ..., pn
K = cnt.place(A, B, [p1, p2, p3])

# compute reference gain
kr = -1/(C @ np.linalg.inv(A - B @ K) @ B)

11.2.1 Simple example

Given the system \[\begin{aligned} \dot{x} &= \begin{pmatrix} 0 & 1 \\ 2 & 3 \end{pmatrix} x + \begin{pmatrix} 0 \\ 4 \end{pmatrix} u \\ y_r &= \begin{pmatrix} 5 & 0 \end{pmatrix} x \end{aligned}\] find the feedback gain \(K\) to place the closed-loop poles at \(-1\pm j\), and the reference gain \(k_r\) so that the DC gain is one.

Step 1.
The controllability matrix is given by \[\mathcal{C}_{A,B} = [B, AB] = \begin{pmatrix} 0 & 4 \\ 4 & 12 \end{pmatrix}.\] The determinant is \(\det(\mathcal{C})=-16\neq 0\), therefore the system is controllable.

Step 2.
The open-loop characteristic polynomial is \[\Delta_{ol}(s)=\det(sI-A) = \det\begin{pmatrix} s & -1 \\ -2 & s-3 \end{pmatrix} = s^2 - 3s -2,\] which implies that \[\begin{aligned} \mathbf{a}_A &= (-3, -2) \\ \mathcal{A}_A &= \begin{pmatrix} 1 & -3 \\ 0 & 1 \end{pmatrix} \end{aligned}\]

Step 3.
The desired closed-loop polynomial is \[\Delta_{cl}^d(s) = (s+1-j)(s+1+j)=s^2+2s+2,\] which implies that \[\boldsymbol{\alpha} = \begin{pmatrix}2, & 2\end{pmatrix}.\]

Step 4.
The gains are therefore given as \[\begin{aligned} K &= (\boldsymbol{\alpha}-\mathbf{a}_A)\mathcal{A}_A^{-1}\mathcal{C}_{A,B}^{-1} \\ &= \left( (2, 2) - (-3, -2) \right)\begin{pmatrix}1 & 3 \\ 0 & 1\end{pmatrix}\begin{pmatrix}-\frac{3}{4} & \frac{1}{4} \\ \frac{1}{4} & 0 \end{pmatrix} \\ &= \begin{pmatrix} 5 & 4 \end{pmatrix} \begin{pmatrix} 0 & \frac{1}{4} \\ \frac{1}{4} & 0 \end{pmatrix} \\ &= \begin{pmatrix} 1 & \frac{5}{4} \end{pmatrix} \end{aligned}\] \[\begin{aligned} k_r &= \frac{-1}{C_r(A-BK)^{-1}B} \\ &= \frac{-1}{\begin{pmatrix} 5 & 0 \end{pmatrix}\left(\begin{pmatrix}0 & 1 \\ 2 & 3\end{pmatrix}-\begin{pmatrix} 0 \\ 4 \end{pmatrix}\begin{pmatrix} 1 & \frac{5}{4}\end{pmatrix}\right)^{-1}\begin{pmatrix} 0 \\ 4 \end{pmatrix}} \\ &= \frac{-1}{\begin{pmatrix} 5 & 0 \end{pmatrix}\left(\begin{pmatrix}0 & 1 \\ 2 & 3\end{pmatrix}-\begin{pmatrix} 0 & 0 \\ 4 & 5 \end{pmatrix}\right)^{-1}\begin{pmatrix} 0 \\ 4 \end{pmatrix}} \\ &= \frac{-1}{\begin{pmatrix} 5 & 0 \end{pmatrix}\begin{pmatrix}0 & 1 \\ -2 & -2\end{pmatrix}^{-1}\begin{pmatrix} 0 \\ 4 \end{pmatrix}} \\ &= \frac{-1}{-10} = \frac{1}{10}. \end{aligned}\]

Chapter 11 guided activity

Work through a second state-feedback design

Use the same procedure as the simple example above. For the system below, compute each quantity in order and click Check before moving on. The solution for each step is revealed only after that step is checked.

x = 0 1 1 2 x + 0 2 u yr = 3 0 x

Desired closed-loop poles: -2 ± j.

Step 1. Controllability matrix

Compute the controllability matrix. Enter the four entries row by row and the determinant.

CA,B =

Step 2. Open-loop characteristic polynomial

Find the open-loop characteristic polynomial coefficients.

a =

Step 3. Desired closed-loop polynomial

Find the desired closed-loop characteristic polynomial from the specified poles.

α =

Step 4. State-feedback gain

Compute the state-feedback gain using the pole-placement method from this section. Enter the two entries of K.

K =

Step 5. Check A - BK

Use your K to form A - BK. Enter the four entries row by row.

A - BK =

Step 6. Reference gain

Compute the reference gain for unit steady-state tracking.

11.3.1 image Example Problem 3.1.14

The objective of this problem is to implement a state feedback controller using the full state. Start with the simulation files developed in Homework 3.1.13.

(a) Select the closed-loop poles as the roots of the equation \(s^2 + 2\zeta\omega_n + \omega_n^2 = 0\), where \(t_r = 0.4890\) and \(\zeta = 0.707\). These values may be different from the parameters found in Homework 3.1.11.

(b) Add the state-space matrices \(A\), \(B\), \(C\), \(D\) derived in Homework 3.1.9 to your param file.

(c) Verify that the state-space system is controllable by checking that \(\text{rank}(\mathcal{C}_{A,B})=n\).

(d) Find the feedback gain \(K\) so that the eigenvalues of \((A-BK)\) are equal to the desired closed-loop poles. Find the reference gain \(k_r\) so that the DC gain from \(\theta_r\) to \(\theta\) is equal to one. Note that if you used the exact same pole values from Homework 3.1.11, \(K=(k_p, k_d)\) where \(k_p\) and \(k_d\) are the proportional and derivative gains found in that problem. Why?

(e) Modify the control code to implement the state feedback controller. Assume that you have access to the entire state.

Design Study A guided exercise

Design full-state feedback

Start from the Chapter 6 state-space model and check controllability before computing gains.

Step 1. Controllability matrix

Step 2. Desired polynomial

Step 3. Reference gain purpose

Pseudocode

The complete solution includes state-feedback controller code. Before opening it, outline how you would compute the state-feedback input from \(x\), \(K\), and \(k_r\).

This prompt is ungraded. It is intended to connect the gain calculation to the implementation code in the complete solution.

11.4 Design Study B. Inverted Pendulum

11.4.1 image Example Problem 3.2.14

The objective of this problem is to implement a state feedback controller using the full state. Start with the simulation files developed in Homework 3.2.13.

(a) Find the desired closed-loop poles using the values for \(\zeta_z=\zeta_\theta=0.9\), and tune rise times based on the following \(t_z=5 t_{\theta}\).

(b) Add the state-space matrices \(A\), \(B\), \(C\), \(D\) derived in Homework 3.2.9 to your param file.

(c) Verify that the state-space system is controllable by checking that: \(\text{rank}(\mathcal{C})=n\).

(d) Find the feedback gain \(K\) so that the eigenvalues of \((A-BK)\) are equal to the desired closed-loop poles. Find the reference gain \(k_r\) so that the DC gain from \(z_r\) to \(z\) is equal to one.

(e) Implement the state feedback scheme and tune the closed-loop poles to get a good response. You should be able to get a much faster response using state-space methods.

Design Study B guided exercise

Design pendulum full-state feedback

Check controllability, desired pole structure, and reference gain purpose.

Step 1. Controllability

Step 2. Desired pole timing

Step 3. Reference gain

Pseudocode

The complete solution includes implementation code. Before opening it, outline the algorithm in your own words.

This prompt is ungraded. It is intended to connect the derivation to the implementation code in the complete solution.

11.5 Design Study C. Satellite Attitude Control

11.5.1 image Example Problem 3.3.14

The objective of this problem is to implement a state feedback controller using the full state. Start with the simulation files developed in Homework 3.3.13.

(a) Using the values for \(\omega_{n_\phi}\), \(\zeta_\phi\), \(\omega_{n_{\theta}}\), and \(\zeta_{\theta}\) selected in Homework 3.3.11, find the desired closed-loop poles.

(b) Add the state-space matrices \(A\), \(B\), \(C\), \(D\) derived in Homework 3.3.9 to your param file.

(c) Verify that the state-space system is controllable by checking that \(\text{rank}(\mathcal{C}_{A,B})=n\).

(d) Find the feedback gain \(K\) so that the eigenvalues of \((A-BK)\) are equal to the desired closed-loop poles. Find the reference gain \(k_r\) so that the DC gain from \(\phi_r\) to \(\phi\) is equal to one.

(e) Implement the state feedback scheme and tune the closed-loop poles to get a good response. You should be able to get a much faster response using state-space methods.

Design Study C guided exercise

Plan satellite state feedback

Use the four-state satellite model, verify controllability, place closed-loop poles, and compute reference gain for \(\phi\) tracking.

Step 1. Model used for control

Step 2. Required algebra checks

Step 3. Compare with nested PID

11.6 Interactive State-Feedback Check

Chapter 11 activity

Pole placement and reference gain

For the companion-form example with open-loop characteristic polynomial s2 + 3s + 2, choose two desired real poles. The readout shows the desired polynomial, the state-feedback gain K, and the feedforward gain kr needed for unit DC tracking.

Desired poles Desired polynomial Feedback gain K Reference gain kr

Pole placement sets the closed-loop dynamics through A - BK. The reference gain sets the steady-state scale from command to output.

11.7 Coding Lab: Full-State Feedback

Objective: compute the controllability matrix, synthesize full-state feedback gains, compute the reference gain, and verify unit-step tracking.

Plant for the lab: use the second-order state-space system x = Ax + Bu, y = Cx, with A = (0, 1; -2, -3), B = (0; 1), and C = (1, 0). Equivalently, y″ + 3y′ + 2y = u with states x1 = y and x2 = y′.

Design target: place the closed-loop poles at -2 and -5 using u = -Kx + krr.

Evaluation criteria: the lab checks controllability rank, feedback gain dimensions and values, closed-loop pole locations, reference gain, and simulated tracking.

Figure 11.1 (Interactive). Full-state feedback coding lab with closed-loop pole and tracking checks.

11.8 Knowledge Check

Q1. State information

Full-state feedback assumes the controller has access to:

Q2. Closed-loop matrix

With u = -Kx + krr, the closed-loop state matrix is:

Q3. Controllability rank

For A with rows (0, 1) and (-2, -3), and B with entries (0, 1), the controllability matrix has full rank. Enter its rank.

Show solution

Answer: 2. The two-state system is controllable when the controllability matrix has rank 2.

Q4. Reference gain from desired poles

For desired poles at -2 and -5 in the companion-form example, enter kr for unit DC tracking.

Show solution

Answer: 10. The desired polynomial constant term is 2 × 5 = 10.

Q5. Pole placement versus tracking

In one phrase, distinguish what pole placement does from what kr does.

Show solution

Answer: Pole placement sets the closed-loop dynamics; kr sets the reference-to-output steady-state gain.

Q6. Controllability matrix

For A with rows (0, 1) and (-2, -3), and B with entries (0, 1), which matrix is \[B AB\]?

Q7. Meaning of full controllability

If a SISO system is controllable, what does that imply for state-feedback pole placement?

Q8. Closed-loop state matrix

For xdot = Ax + Bu and u = -Kx + krr, what is the closed-loop state matrix?

Q9. Reference gain role

What is the main role of kr in the state-feedback law?

11.9 Notes and References

Controllability is typically defined as follows. The state-space system \[\dot{x}=Ax+Bu\] is said to be controllable from initial state \(x_0\), if there exists a control function \(u(t)\) defined on some interval \(t\in[0,T]\) that transitions the state to the origin. It can be shown that for linear time-invariant systems, the system is controllable if and only if the rank of the controllability matrix \(\mathcal{C}_{A,B}\) is equal to the size of the state \(n\). For single input systems, this is equivalent to \(\mathcal{C}_{A,B}\) being invertible. Controllability is an interesting and deep topic that extends nicely to nonlinear and multi-input systems. For further information see [5, 6, 12].

Ackermann’s formula given in Equation 11.32 is only valid for single input systems. In the multi-input case, the controllability matrix \(\mathcal{C}_{A,B}\) is not square and therefore cannot be inverted. However, a more general formula can be derived if \(\mathcal{C}_{A,B}\) has rank \(n\). The more general formula is implemented by the place command in both MATLAB and Python. For additional information on the derivation of the feedback gain in the MIMO case see [6].

12 Integrator with Full State Feedback

12.1 Theory

In the previous chapter we derived a full state feedback controller that stabilized the system and ensured that the DC gain from the reference \(r(t)\) to the reference output \(y_r(t)\) is equal to one. If the model is precise, meaning that we know all of the parameters exactly and we have not neglected any dynamics, or if there are no disturbances on the system, then the output will track the reference as time goes to infinity. However, models are never precise, and there are almost always disturbances on the system, which implies that there will be steady-state error in the response. In Chapter 12 we showed that adding an integrator to the controller is an effective way of eliminating steady-state error caused by model mismatch and input/output disturbances. In this section we will show how to add an integrator to the full state feedback controller derived in Chapter 14.

A block diagram of the system with full state feedback and an integrator is shown in Fig. 12.1.

Full state feedback with integrator.

Let the state of the integrator be defined as \(x_I\), as shown in Fig. 12.1. Then \[\dot{x}_I = r-y_r = r-C_rx.\] In Appendix 30 we argue, using the root locus, that adding an integrator after the other gains are selected will change all of the pole locations. Since the pole placement design methods described in Part III were limited to second-order systems, we did not have an effective method for placing the system poles and the integrator pole simultaneously. On the other hand, the pole placement technique described in Chapter 14 was not limited to second-order systems. As such, there should be a way to use the methods of Chapter 14 to simultaneously place both the system poles and the integrator pole. To do so, we augment the states of the original system with the integrator state \(x_I\). Since the dynamics of the original system are given by \(\dot{x}=Ax+Bu\), the dynamics of the augmented system are given by \[\tag{12.1} \begin{pmatrix} \dot{x} \\ \dot{x}_I \end{pmatrix} = \begin{pmatrix} A & \mathbf{0} \\ -C_r & \mathbf{0}\end{pmatrix} \begin{pmatrix} x \\ x_I \end{pmatrix} + \begin{pmatrix} B \\ \mathbf{0} \end{pmatrix} u + \begin{pmatrix} 0 \\ 1 \end{pmatrix} r,\] where the state of the augmented system is \((x^\top, x_I)^\top\), the interaction matrix, or the “\(A\)-matrix,” of the augmented system is \[A_1 = \begin{pmatrix} A & \mathbf{0} \\ -C_r & \mathbf{0}\end{pmatrix},\] and the “\(B\)-matrix” of the augmented system is \[B_1=\begin{pmatrix} B \\ \mathbf{0}\end{pmatrix}.\] The first question that might be asked is whether the augmented system \((A_1,B_1)\) is controllable when the original system \((A,B)\) is controllable. Since the original system is controllable, we know that the controllability matrix \[\mathcal{C}_{A,B} = \begin{pmatrix} B & AB & \dots & A^{n-1}B \end{pmatrix}\] has rank \(n\). For the augmented system, the controllability matrix is \[\mathcal{C}_{A_1,B_1} = \begin{pmatrix} B & AB & A^2B & \dots & A^{n-1}B & A^nB \\ 0 & -C_rB & -C_rAB & \dots & -C_rA^{n-2}B & -C_rA^{n-1}B \end{pmatrix},\] which is guaranteed to have rank \(n+1\) if \(C_rA^{n-1}B \neq 0\). When the augmented system is controllable, we can use the pole placement technique described in Chapter 14 to place the system poles and the pole of the integrator simultaneously using the augmented system. For example, letting \(A_1\) and \(B_1\) represent the augmented system, and using the Python place command

import control as cnt
K1 = cnt.place(A1,B1, [p1,...,pn,pI])

where \(p_I\) is the integrator pole. The resulting controller is \[\begin{aligned} u(t) &= -K_1\begin{pmatrix}x \\ x_I \end{pmatrix} = -\begin{pmatrix} K & k_I \end{pmatrix}\begin{pmatrix}x \\ x_I \end{pmatrix} =-Kx-k_Ix_I\\ &= \underbrace{-Kx(t)}_{\text{state feedback}} - \underbrace{k_I \int_0^t(r(\tau)-y_r(\tau))d\tau}_{\text{integral feedback}} \quad. \end{aligned}\]

We can show that adding the integrator ensures that the DC gain of the closed-loop system is equal to one. Indeed, from Equation 12.1 the augmented closed-loop system is \[\begin{aligned} \begin{pmatrix} \dot{x} \\ \dot{x}_I \end{pmatrix} &= \begin{pmatrix} A & \mathbf{0} \\ -C_r & \mathbf{0}\end{pmatrix} \begin{pmatrix} x \\ x_I \end{pmatrix} - \begin{pmatrix} B \\ \mathbf{0} \end{pmatrix} \begin{pmatrix} K & k_I \end{pmatrix}\begin{pmatrix} x \\ x_I \end{pmatrix} + \begin{pmatrix} 0 \\ 1 \end{pmatrix} r \\ &= \begin{pmatrix} A-BK & -Bk_I \\ -C_r & 0\end{pmatrix}\begin{pmatrix} x \\ x_I \end{pmatrix} + \begin{pmatrix} 0 \\ 1 \end{pmatrix} r, \end{aligned}\] where the reference output equation is \[y_r = \begin{pmatrix} C_r & 0 \end{pmatrix} \begin{pmatrix} x \\ x_I \end{pmatrix}.\] Therefore, the transfer function from \(R(s)\) to \(Y_r(s)\) is \[Y_r(s) = \begin{pmatrix} C_r & 0 \end{pmatrix} \left(sI - \begin{pmatrix} A-BK & -Bk_I \\ -C_r & 0\end{pmatrix}\right)^{-1} \begin{pmatrix} 0 \\ 1 \end{pmatrix} R(s),\] which implies that the DC gain is \[\begin{aligned} k_{DC} &= -\begin{pmatrix} C_r & 0 \end{pmatrix} \begin{pmatrix} A-BK & -Bk_I \\ -C_r & 0\end{pmatrix}^{-1} \begin{pmatrix} 0 \\ 1 \end{pmatrix}. \end{aligned}\] Defining \(M\stackrel{\triangle}{=}(A-BK)^{-1}\), and using the Matrix inversion formula for block matrices given in Appendix 31 Equation P.7.2 we get \[\begin{aligned} k_{DC} &= -\begin{pmatrix} C_r & 0 \end{pmatrix} \begin{pmatrix} M-MBk_I(C_rMBk_I)^{-1}C_rM & -MBk_I(C_rMBk_I)^{-1} \\ -(C_rMBk_I)^{-1}C_rM & (C_rMBk_I)^{-1}\end{pmatrix} \begin{pmatrix} 0 \\ 1 \end{pmatrix} \\ &= C_rMBk_I(C_rMBk_I)^{-1} \\ &= 1. \end{aligned}\]

12.1.1 Integral Feedback for Linearized Systems

Suppose that the state-space model is from a linearized system, i.e., suppose that \(x\in\mathbb{R}^n\) is the state, \(x_e\in\mathbb{R}^n\) is the equilibrium state, and that \(\tilde{x}=x-x_e\) is the state linearized around the equilibrium. Similarly, suppose that \(u\in\mathbb{R}^m\) is the input, that \(u_e\in\mathbb{R}^m\) is the input at equilibrium, and that \(\tilde{u}=u-u_e\) is the input linearized around equilibrium, and that \(y_r\in\mathbf{R}^p\) is the reference output, \(y_{re}=C_rx_e\in\mathbf{R}^p\) is the reference output at equilibrium, \(\tilde{y}_r=y_r-y_{re}\) is the reference output linearized about equilibrium, and the reference input is given by \(\tilde{r}=r-y_{re}\). In this case the integral state is selected as \(\tilde{x}_I=\int(\tilde{r}-\tilde{y}_r)d\tau\), and the augmented system is given by \[\begin{pmatrix} \dot{\tilde{x}} \\ \dot{\tilde{x}}_I \end{pmatrix} = \begin{pmatrix} A & \mathbf{0} \\ -C_r & \mathbf{0}\end{pmatrix} \begin{pmatrix} \tilde{x} \\ \tilde{x}_I \end{pmatrix} + \begin{pmatrix} B \\ \mathbf{0} \end{pmatrix} \tilde{u} + \begin{pmatrix} 0 \\ 1 \end{pmatrix} \tilde{r}.\] The pole placement design proceeds as in the previous section with the resulting controller being \[\tilde{u} = -K\tilde{x} - k_I \int_{-\infty}^t \tilde{e}(\tau)d\tau.\] Noting that \[\tilde{e} = \tilde{r}-\tilde{y} = (r-y_{re})-(y_r-y_{re}) = r-y_r\] we get that the controller for the linearized system is given by \[u = u_e - K(x-x_e) - k_I \int_{-\infty}^t (r(\tau)-y_r(\tau))d\tau.\]

12.2 Summary of Design Process - State Feedback with Integrator

The design process for adding an integrator to state feedback can be summarized as follows. Given the plant \[\begin{aligned} \dot{x} &= Ax + Bu \\ y_r &= C_rx, \end{aligned}\] where we desire that \(y_r\) tracks the reference \(r\) using integral action using the controller \[u(t) = -Kx(t) - k_I\int_{-\infty}^t (r(\tau)-y_r(\tau))d\tau,\] with desired closed-loop gains at \(p_1, p_2, \dots, p_n\), \(p_I\).

Step 1.
Augment the state evolution equation as \[\begin{pmatrix}\dot{x} \\ \dot{x}_I \end{pmatrix} = \begin{pmatrix} A & \mathbf{0} \\ -C_r & \mathbf{0} \end{pmatrix} \begin{pmatrix}x \\ x_I\end{pmatrix} + \begin{pmatrix}B \\ \mathbf{0}\end{pmatrix}u + \begin{pmatrix}\mathbf{0} \\ I\end{pmatrix}r,\] and let \[\begin{aligned} A_1 &= \begin{pmatrix} A & \mathbf{0} \\ -C_r & \mathbf{0} \end{pmatrix} \\ B_1 &= \begin{pmatrix}B \\ \mathbf{0}\end{pmatrix} \end{aligned}\]

Step 2.
Follow the pole placement procedure outlined in Chapter 14 to find \(K_1\) that places the poles of the augmented system at \(p_1, p_2, \dots, p_n\), and \(p_I\).

Step 3.
Find the gains \(K\) and \(k_I\) as \[\begin{aligned} K &= K_1(1:n) \\ k_I &= K_1(n+1). \end{aligned}\]

Using Python, these steps can be implemented using the following script.

import numpy as np
import control as cnt

# augment the system matrices
A1 = np.vstack((
    np.hstack((A, np.zeros((np.size(A,1),1)))),
    np.hstack((-Cr, 0)) ))
    
B1 = np.vstack((
    B, 0))

# Compute the gains if the system is controllable
if np.linalg.matrix_rank(cnt.ctrb(A1, B1)) != np.size(A1,1):
    print("The system is not controllable")
else:
    K1 = cnt.acker(A1, B1, [p1, p2, ..., pn, pI])

    #extract the state feedback gains and the integral gain
    K = K1[0,0:-1]
    ki = K1[0,-1]

print('K: ', K)
print('ki: ', ki)

12.2.1 Simple example

Given the system \[\begin{aligned} \dot{x} &= \begin{pmatrix} 0 & 1 \\ 2 & 3 \end{pmatrix} x + \begin{pmatrix} 0 \\ 4 \end{pmatrix} u \\ y_r &= \begin{pmatrix} 5 & 0 \end{pmatrix} x \end{aligned}\] find the feedback gain \(K\) to place the closed-loop poles at \(-1\pm j\), and the reference gain \(k_r\) so that the DC gain is one, and add an integrator with gain at \(p_I=-0.1\).

Step 1.
Form the augmented system \[\begin{aligned} A_1 &= \begin{pmatrix} A & \mathbf{0} \\ -C_r & \mathbf{0} \end{pmatrix} = \begin{pmatrix} 0 & 1 & 0 \\ 2 & 3 & 0 \\ -5 & 0 & 0 \end{pmatrix} \\ B_1 &= \begin{pmatrix} B \\ \mathbf{0} \end{pmatrix} = \begin{pmatrix} 0 \\ 4 \\ 0 \end{pmatrix} \end{aligned}\]

Step 2.
To place the poles at \(p_1=-1+j\), \(p_2=-1-j\), \(p_I=-0.1\), we first form the controllability matrix \[\mathcal{C}_{A_1,B_1} = [B_1, A_1B_1, A_1^2B_1] = \begin{pmatrix} 0 & 4 & 12 \\ 4 & 12 & 44 \\ 0 & 0 & -20 \end{pmatrix}.\] The determinant is \(det(\mathcal{C}_{A_1,B_1})=320\neq 0\), therefore the system is controllable.

The open-loop characteristic polynomial \[\begin{aligned} \Delta_{ol}(s)&=\text{det}(sI-A_1) = \text{det}\begin{pmatrix} s & -1 & 0 \\ -2 & s-3 & 0 \\ 5 & 0 & s\end{pmatrix} \\ &= s^3 - 3s^2 -2s, \end{aligned}\] which implies that \[\begin{aligned} \mathbf{a}_{A_1} &= \begin{pmatrix}-3, & -2, & 0\end{pmatrix} \\ \mathcal{A}_{A_1} &= \begin{pmatrix} 1 & -3 & -2 \\ 0 & 1 & -3 \\ 0 & 0 & 1 \end{pmatrix}. \end{aligned}\]

The desired closed-loop polynomial \[\begin{aligned} \Delta_{cl}^d(s) &= (s+1-j)(s+1+j)(s+0.1) \\ &=s^3+2.1s^2+2.2s+0.2, \end{aligned}\] which implies that \[\boldsymbol{\alpha} = \begin{pmatrix}2.1, & 2.2, & 0.2\end{pmatrix}.\]

The augmented gains are therefore given as \[\begin{aligned} K_1 &= (\boldsymbol{\alpha}-\mathbf{a}_{A_1})\mathcal{A}_{A_1}^{-1}\mathcal{C}_{A_1,B_1}^{-1} \\ &= \left( (2.1, 2.2, 0.2) - (-3, -2, 0) \right) \cdot \\ &\qquad \begin{pmatrix}1 & -3 & -2 \\ 0 & 1 & -3 \\ 0 & 0 & 1\end{pmatrix}^{-1}\begin{pmatrix}0 & 4 & 12 \\ 4 & 12 & 44 \\ 0 & 0 & -20 \end{pmatrix}^{-1} \\ &= \begin{pmatrix} 1.05, & 1.275, & -0.01 \end{pmatrix} \end{aligned}\]

Step 3.
The feedback gains are therefore given by \[\begin{aligned} K &= K_1(1:2) = \begin{pmatrix} 1.05, & 1.275 \end{pmatrix} \\ k_I &= K_1(3) = -0.01 \end{aligned}\]

Alternatively, we could have used the following Python script

import numpy as np
import control as cnt

# define original state-space system and desired poles
A = np.array([[0.0, 1.0], [2.0, 3.0]])
B = np.array([[0.0], [4.0]])
Cr = np.array([5.0, 0])

p1 = -1.0 - 1.j
p2 = -1.0 + 1.j
pI = -0.1

# augment the system matrices
A1 = np.vstack((
    np.hstack((A, np.zeros((np.size(A,1),1)))),
    np.hstack((-Cr, 0)) ))
B1 = np.vstack((
    B, 0))

# Compute the gains if the system is controllable
if np.linalg.matrix_rank(cnt.ctrb(A1, B1)) != np.size(A1,1):
    print("The system is not controllable")
else:
    K1 = cnt.acker(A1, B1, [p1, p2, pI])

    #extract the state feedback gains and the integral gain
    K = K1[0,0:-1]
    ki = K1[0,-1]

Chapter 12 guided activity

Work through a second integrator-augmented design

Use the same procedure as the simple example above. For the system below, compute each quantity in order and click Check before moving on. The solution for each step is revealed only after that step is checked.

x = 0 1 -2 -3 x + 0 1 u Cr = 1 0

Desired augmented closed-loop poles: -1 and -2 ± j.

Step 1. Augmented system

Form A1 = (A, 0; -Cr, 0) and B1 = (B; 0). Enter A1 row by row and B1 from top to bottom.

A1 =
B1 =

Step 2. Augmented controllability matrix

Compute CA1,B1 = \[B1, A1B1, A12B1\]. Enter the matrix row by row and the determinant.

CA1,B1 =

Step 3. Open-loop augmented polynomial

Compute det(sI - A1) = s3 + a2s2 + a1s + a0.

a =

Step 4. Desired augmented polynomial

Compute (s + 1)((s + 2)2 + 1) = s3 + alpha2s2 + alpha1s + alpha0.

α =

Step 5. Augmented feedback gain

Use K1 = (alpha - a) AcalA1-1CA1,B1-1. Enter the three entries of K1.

K1 =

Step 6. Extract the gains

Separate K1 into the state-feedback gain K and the integrator gain kI.

K =
kI =

12.3.1 image Example Problem 3.1.15

Modify the state feedback solution developed in Homework 3.1.14 to add an integrator with anti-windup.

Add a 0.25 Newton disturbance to the system and allow the system parameters to change up to 20%.

Tune the integrator pole (and other gains if necessary) to get good tracking performance.

Design Study A guided exercise

Add integral action

Augment the state with the integral of tracking error and place the added pole deliberately.

Step 1. Augmented system size

Step 2. Integrator pole placement

Step 3. Gain partition

Pseudocode

The complete solution includes state-feedback-with-integrator code. Before opening it, outline how you would update the integrator state, compute the augmented feedback input, and apply anti-windup if needed.

This prompt is ungraded. It is intended to connect the augmented-state design to the implementation code in the complete solution.

12.4 Design Study B. Inverted Pendulum

12.4.1 image Example Problem 3.2.15

(a) Modify the state feedback solution developed in Homework 3.2.14 to add an integrator with anti-windup to the position feedback.

(b) Add a constant input disturbance of 0.5 Newtons to the input of the plant and allow the system parameters to change up to 20%.

(c) Tune the integrator pole (and other gains if necessary) to get good tracking performance. You may need to make the gains less aggressive (slower rise time) to get stable performance.

Design Study B guided exercise

Add cart-position integral action

Augment the system with an integrator on z tracking error.

Step 1. Integrated output

Step 2. Augmented size

Step 3. Gain partition

Pseudocode

The complete solution includes implementation code. Before opening it, outline the algorithm in your own words.

This prompt is ungraded. It is intended to connect the derivation to the implementation code in the complete solution.

12.5 Design Study C. Satellite Attitude Control

12.5.1 image Example Problem 3.3.15

Modify the state feedback solution developed in Homework 3.3.14 to add an integrator with anti-windup to the feedback loop for \(\phi\).

Add a constant input disturbance of 1 Newton-meter to the input of the plant and allow the plant parameters to vary up to 20%.

Tune the integrator pole (and other gains if necessary) to get good tracking performance.

Design Study C guided exercise

Add satellite integrator feedback

The augmented controller integrates panel-angle tracking error while handling disturbance, uncertainty, and actuator limits.

Step 1. Choose the integrator error

Step 2. Robustness challenge

Step 3. Anti-windup purpose

12.6 Interactive Augmented-State Check

Chapter 12 activity

Integrator pole tradeoff

Adding integral action creates one extra state and one extra pole to place. Move the integrator pole and disturbance level to see the qualitative speed/effort tradeoff. The readouts use the book’s pole-placement idea: a farther-left integrator pole increases the response rate associated with the added integrator state, but it also tends to require larger control action and can make the transient more aggressive.

Estimated settling effect Relative control effort Overshoot tendency Tuning note

The augmented matrices add one integrator state with xI dot = r - yr. That is why the bottom row contains -Cr in A1 and why controllability must be checked again. In this activity, |pI| is the selected integrator-pole magnitude and d is the constant disturbance size.

12.7 Knowledge Check

Q1. Augmented state

Adding an integrator to state feedback introduces:

Q2. Integrator row

The integrator row in the augmented A1 matrix contains:

Q3. Augmented dimension

If the original plant has two states and one tracking integrator is added, enter the augmented system order.

Show solution

Answer: 3. The augmented system contains the two physical states plus one integrator state.

Q4. Augmented matrix sign

For Cr = (1, 0) and xI′ = r - Crx, enter the first entry of the integrator row in A1.

Show solution

Answer: -1. The row is -Cr, so (1, 0) becomes (-1, 0).

Q5. Purpose of integral action

Integral action is primarily added to remove what kind of error or bias?

Show solution

Answer: Steady-state tracking error or constant bias. The integrator keeps acting until the accumulated error is driven down.

Q6. Purpose of the augmented integrator

In state feedback with integral action, what does the added integrator state represent?

Q7. Augmented A row

If xI = r - y = r - Cx, which row appears in the augmented A matrix for the integrator equation?

Q8. Slow integrator pole

What is a likely consequence of choosing the integrator pole much slower than the rest of the closed-loop poles?

12.8 Notes and References

Integral control for linear state-space systems is a well-established technique. Additional examples can be found in [4, 5, 19]. A nice introduction to integral control for nonlinear systems is given in [20].

13 Observers

13.1 Theory

In the previous two chapters we assumed that the full state \(x\) was available to the controller for full state feedback. In this chapter we remove that assumption and show how the state can be reconstructed given the measurements. We will assume that the state-space model is given by \begin{align} \dot{x} &= Ax + Bu \tag{13.1}\\ y &= C x \tag{13.2} \\ y_r &= C_r x, \notag \end{align} where \(y_r\in\mathbb{R}^r\) is the reference output as discussed in the previous two chapters, and \(y\in\mathbb{R}^p\) is the measured output, or the signals measured by the sensors. While the objective of the controller is to force \(y_r(t)\) to converge to the reference \(r(t)\), the objective of the observer is to estimate the state \(x(t)\) given a history of the input \(u(t)\) and the measured output \(y(t)\). In this book, the estimate of the state will be denoted as \(\hat{x}(t)\).

A block diagram of the closed-loop system with observer-based control is shown in Fig. 13.1. Comparing Fig. 13.1 to the case of full state feedback in Fig. 11.4, note that the controller uses the estimated state \(\hat{x}\) instead of the full state \(x\). In other words, the controller in Equation 11.37 becomes \[u=-K\hat{x} + k_r r.\]

Closed-loop system with observer-based feedback.

In this chapter we will design a so-called Luenberger observer that has the structure given by \[\tag{13.3} \dot{\hat{x}} = \underbrace{A\hat{x} + Bu}_{\text{predictor}} + \underbrace{L \left(y - C \hat{x} \right)}_{\text{corrector}}.\] The first term in Equation 13.3, i.e., \(\dot{\hat{x}}=A\hat{x}+Bu\) is a copy of the equations of motion for the plant given in Equation 13.1. The second term given by \(L(y-C\hat{x})\) is a correction term, where \(L\) is the observer gain, and \((y-C\hat{x})\) is the difference between the measured output \(y=C x\) and the predicted value of the measured output \(C\hat{x}\). The term \(y-C\hat{x}\) is called the innovation signal.

Defining the observer error as \(e=x-\hat{x}\) and differentiating with respect to time gives \[\begin{aligned} \dot{e} &= \dot{x} - \dot{\hat{x}} \\ &= Ax + Bu - \left(A\hat{x} + Bu + Ly - LC\hat{x}\right) \\ &= A(x-\hat{x}) - LC x + LC\hat{x} \\ &= (A-LC)(x-\hat{x}) \\ &= (A-LC)e. \end{aligned}\] Therefore, the poles that govern the time-evolution of the observation error are given by the eigenvalues of \(A-LC\). The observer design problem is therefore to select \(L\) to place the eigenvalues of \(A-LC\) at locations specified by the control engineer. The derivation of a formula for the observer gain \(L\) proceeds in a manner similar to the derivation of the feedback gain \(K\) in Chapter 14.

13.1.1 Observer Design using Observer Canonic Form

Given the general SISO monic transfer function \[\tag{13.4} Y(s) = \frac{b_ms^m + b_{m-1}s^{m-1} + \dots + b_1 s + b_0}{s^n + a_{n-1}s^{n-1} + \dots + a_1 s + a_0} U(s),\] where \(n>m\), and taking the inverse Laplace transform gives \[\begin{gathered} \frac{d^ny}{dt^n} + a_{n-1}\frac{d^{n-1}y}{dt^{n-1}} + \dots + a_1 \dot{y} + a_0 y(t) \\ = b_m\frac{d^m u}{dt^m} + b_{m-1}\frac{d^{m-1}u}{dt^{m-1}} + \dots + b_1 \dot{u} + b_0 u(t). \end{gathered}\] Solving for the \(n^{th}\) derivative of \(y\) and collecting terms with similar order derivatives gives \[\begin{gathered} \frac{d^ny}{dt^n} = - a_{n-1}\frac{d^{n-1}y}{dt^{n-1}} - a_{m+1}\frac{d^{m+1}y}{dt^{m+1}} \\ + \left(b_m\frac{d^m u}{dt^m} - a_m\frac{d^m y}{dt^m}\right) + \dots + \left(b_1 \dot{u} - a_1 \dot{y}\right) + \left(b_0 u - a_0 y\right). \end{gathered}\] Integrating \(n\) times gives \begin{gather} \tag{13.5} y(t) = \int\Big[ - a_{n-1} y \int\Big[ - \dots - \int\Big[ - a_{m+1} y \\ + \int\Big[\left(b_m u - a_m y\right) + \dots \\ + \int\Big[\left(b_1 u - a_1 y\right) + \int \left(b_0 u - a_0 y\right) \Big]\dots\Big]\dots\Big]. \end{gather}

The analog computer implementation of Equation 13.5 is shown in Fig. 13.2.

Block diagram showing the analog computer implementation of Equation 13.5.

Labeling the states as the output of the integrators, as shown in Fig. 13.2 and writing the equations in linear state-space form gives \begin{align} \begin{pmatrix}\dot{x}_1 \\ \dot{x}_2 \\ \vdots \\ \dot{x}_{n-1} \\ \dot{x}_n \end{pmatrix} &= \begin{pmatrix} -a_{n-1} & 1 & \dots & 0 & 0 \\ -a_{n-2} & 0 & \dots & 0 & 0 \\ \vdots & & \ddots & & \vdots \\ -a_1 & 0 & \dots & 0 & 1 \\ -a_0 & 0 & \dots & 0 & 0 \end{pmatrix} \begin{pmatrix} x_1 \\ x_2 \\ \vdots \\ x_{n-1} \\ x_n \end{pmatrix} + \begin{pmatrix} 0 \\ \vdots \\ 0 \\ b_m \\ \vdots \\ b_1 \\ b_0 \end{pmatrix} u \tag{13.6}\\ &y= \begin{pmatrix} 1 & 0 & \dots & 0 & 0\end{pmatrix}\begin{pmatrix} x_1 \\ x_2 \\ \vdots \\ x_{n-1} \\ x_n \end{pmatrix}. \tag{13.7} \end{align} We define the observer canonic realization as \[\begin{aligned} \dot{x}_o &= A_o x_o + B_o u \\ y &= C_{o} x_o, \end{aligned}\] where \begin{align} A_o &\stackrel{\triangle}{=}\begin{pmatrix} -a_{n-1} & 1 & \dots & 0 & 0 \\ -a_{n-2} & 0 & \dots & 0 & 0 \\ \vdots & & \ddots & & \vdots \\ -a_1 & 0 & \dots & 0 & 1 \\ -a_0 & 0 & \dots & 0 & 0 \end{pmatrix} \tag{13.8} \\ B_o &\stackrel{\triangle}{=}\begin{pmatrix} 0 \\ \vdots \\ 0 \\ b_m \\ \vdots \\ b_1 \\ b_0 \end{pmatrix} \tag{13.9} \\ C_o &\stackrel{\triangle}{=}\begin{pmatrix} 1 & 0 & \dots & 0 & 0\end{pmatrix}. \tag{13.10} \end{align} Comparing the state-space equations in observer canonic form in Equations 13.8–13.10 with the state-space equations for control canonic form in Equations 11.14-11.16, we see that \[\begin{aligned} A_o &= A_c^\top \\ B_o &= C_c^\top \\ C_o &= B_c^\top. \end{aligned}\]

Comparing the state equation in Equation 13.6 with the transfer function in Equation 13.4 we see that the eigenvalues of \(A_o\) are the roots of the open-loop characteristic polynomial \[\Delta_{ol}(s) = \det(sI-A_o) = s^n + a_{n-1}s^{n-1} + \dots + a_1 s + a_0.\] Since \(C_o\) in Equation 13.7 has the structure of one in the first element followed by zeros, we see that the structure of \(A_o-L_oC_o\) is given by \[A_o-L_oC_o = \begin{pmatrix} -(a_{n-1}+\ell_1) & 1 & \dots & 0 & 0 \\ -(a_{n-2}+\ell_2) & 0 & \dots & 0 & 0 \\ \vdots & & \ddots & & \vdots \\ -(a_1+\ell_{n-1}) & 0 & \dots & 0 & 1 \\ -(a_0+\ell_n) & 0 & \dots & 0 & 0 \end{pmatrix}.\] The characteristic polynomial for the closed-loop observation error is therefore given by \[\begin{aligned} \Delta_{cl,obs}(s) &= \det(sI-(A_o-L_oC_o)) \\ & = s^n + (a_{n-1}+\ell_1)s^{n-1} + \dots + (a_1+\ell_{n-1}) s + (a_0+\ell_n). \end{aligned}\] If the desired characteristic polynomial for the closed-loop observation error is \[\tag{13.11} \Delta_{cl,obs}^d(s) = s^n + \beta_{n-1} s^{n-1} + \dots + \beta_1 s + \beta_0,\] then we have that \[\begin{aligned} a_{n-1}+\ell_1 &= \beta_{n-1} \\ a_{n-2}+\ell_2 &= \beta_{n-2} \\ \vdots \\ a_1+\ell_{n-1} &= \beta_1 \\ a_0+\ell_{n} &= \beta_0. \end{aligned}\] Defining the vectors \[\begin{aligned} \mathbf{a}_A &\stackrel{\triangle}{=}(a_{n-1}, a_{n-2}, \dots, a_1, a_0) \\ \boldsymbol{\beta} &\stackrel{\triangle}{=}(\beta_{n-1}, \beta_{n-2}, \dots, \beta_1, \beta_0) \\ L_o &\stackrel{\triangle}{=}(\ell_1, \ell_2, \dots, \ell_{n-1}, \ell_{n})^\top, \end{aligned}\] we have that the observer gain satisfies \[\tag{13.12} L_o = (\boldsymbol{\beta}-\mathbf{a}_A)^\top,\] where the subscript “o” is used to emphasize what the gains are when the state equations are in observer canonic form. As an example, suppose that the transfer function model of the system is given by \[Y(s) = \frac{9s+20}{s^3+6s^2-11s+8}U(s),\] then the state-space equations in observer canonic form are given by \[\begin{aligned} \dot{x}_o &= \begin{pmatrix} -6 & 1 & 0 \\ 11 & 0 & 1 \\ -8 & 0 & 0 \end{pmatrix} x_o + \begin{pmatrix} 0 \\ 9 \\ 20 \end{pmatrix} u \\ y &= \begin{pmatrix} 1 & 0 & 0 \end{pmatrix} x_o. \end{aligned}\] The open-loop characteristic polynomial is \[\Delta_{ol}(s) = s^3+6s^2-11s+8,\] with roots at \(-7.5885\), and \(0.7942\pm j0.6507\). Suppose that the desired poles for the observation error are at \(-10\) and \(-20\pm j20\), then the desired closed-loop polynomial for the observation error is \[\begin{aligned} \Delta_{cl,obs}^d(s) &= (s+10)(s+20-j20)(s+20+j20) \\ &= s^3 + 50s^2 + 1200s + 8000, \end{aligned}\] then \(\mathbf{a}_{A_o}=(6,-11,8)\), \(\boldsymbol{\beta}=(50,1200,8000)\), and the observer gain that places the eigenvalues of \(A_o-L_oC_o\) at the desired locations is given by \[L_o = (\boldsymbol{\beta}-\mathbf{a}_{A_o})^\top = \begin{pmatrix} 50 \\ 1200 \\ 8000 \end{pmatrix} - \begin{pmatrix} 6 \\ -11 \\ 8 \end{pmatrix} = \begin{pmatrix} 44 \\ 1211 \\ 7992 \end{pmatrix}.\]

13.1.2 Observer Design: General State-Space Equations

The formula given in Equation 13.12 assumes that the state-space equations are in observer canonic form. Similar to the general full state feedback case discussed in Section 14.1.3, a formula for the observer gains can be derived for general state-space equations. Following the method used in Section 14.1.3, the strategy is to find a state transformation matrix that converts the general state-space equations into observer canonic form. Rather than repeating the steps in Section 14.1.3 we will derive the formula for the observer gain by noting the similarities between the design problem for full state feedback and the design problem for the observer gain.

For full state feedback, the feedback gains \(K\) that place the eigenvalues of \(A-BK\) at the roots of the desired characteristic equation given in Equation 11.20 are given by Equation 11.32 or \[\tag{13.13} K = (\boldsymbol{\alpha}-\mathbf{a}_A)\mathcal{A}_A^{-1}\mathcal{C}_{A,B}^{-1},\] where \[\begin{aligned} \mathcal{A}_A &= \begin{pmatrix} 1 & a_{n-1} & a_{n-2} & \dots & a_2 & a_1 \\ 0 & 1 & a_{n-1} & \vdots & a_3 & a_2 \\ 0 & 0 & 1 & \vdots & a_4 & a_3 \\ \vdots & & & \ddots & \vdots \\ 0 & 0 & 0 & \dots & 1 & a_{n-1} \\ 0 & 0 & 0 & \dots & 0 & 1 \end{pmatrix}, \\ \mathcal{C}_{A,B} &= \begin{pmatrix}B & AB & A^2B & \cdots & A^{n-1}B\end{pmatrix}, \end{aligned}\] and where the subscripts are used to indicate that \(\mathcal{A}_A\) is a function of the matrix \(A\), and \(\mathcal{C}_{A,B}\) is a function of the matrices \(A\) and \(B\).

The observer design problem is to find the observer gain \(L\) that places the eigenvalues of \(A-LC\) at the roots of Equation 13.11. Recalling from Appendix 31 that for a general square matrix \(M\), the eigenvalues of \(M\) equal the eigenvalues of \(M^\top\), the observer problem can be posed as finding \(L\) that places the eigenvalues of \(A^\top - C^\top L^\top\) at the roots of Equation 13.11. This problem is identical to the full state feedback gain problem with \(A\) replaced by \(A^\top\), \(B\) replaced by \(C^\top\), and \(K\) replaced by \(L^\top\). Making the appropriate substitutions in Ackermann’s formula 13.13 gives \[\tag{13.14} L^\top = (\boldsymbol{\beta}-\mathbf{a}_{A})\mathcal{A}_{A^\top}^{-1}\mathcal{C}_{A^\top,C^\top}^{-1}\] Since \(\det(sI-A)=\det(sI-A^\top)\), the characteristic equations for \(A\) and \(A^\top\) are identical, which implies that \(\mathbf{a}_A=\mathbf{a}_{A^\top}\) and \(\mathcal{A}_A=\mathcal{A}_{A^\top}\). Taking the transpose of Equation 13.14 gives \[\tag{13.15} L = \mathcal{C}_{A^\top,C^\top}^{-\top}\mathcal{A}_{A}^{-\top}(\boldsymbol{\beta}-\mathbf{a}_{A})^\top,\] where we have used the notation \[M^{-\top}\stackrel{\triangle}{=}\left(M^{-1}\right)^\top = \left(M^\top\right)^{-1}.\] Defining the observability matrix \[\begin{aligned} \mathcal{O}_{A,C} &\stackrel{\triangle}{=}\mathcal{C}_{A^\top,C^\top}^\top \\ &= \begin{pmatrix} C^\top & A^\top C^\top & (A^\top)^2C^\top & \cdots & (A^\top)^{n-1}C^\top\end{pmatrix}^\top \\ &= \begin{pmatrix} C \\ CA \\ CA^2 \\ \vdots \\ CA^{n-1}\end{pmatrix}, \end{aligned}\] the observer gain 13.15 can be written as \[\tag{13.16} L = \mathcal{O}_{A,C}^{-1}\mathcal{A}_{A}^{-\top}(\boldsymbol{\beta}-\mathbf{a}_{A})^\top,\] where \(L\) is well defined if the observability matrix \(\mathcal{O}_{A,C}\) is invertible. Accordingly, the system \((A,C)\) is said to be observable if \(\text{rank}(\mathcal{O}_{A,C})=n\). Equation 13.16 is Ackermann’s formula for the observer gain \(L\). Ackermann’s formula is only valid for single output systems. For multi-output systems there are more advanced methods that are implemented in the MATLAB and Python place commands. The observer gain \(L\) that places the eigenvalues of \(A-LC\) at locations \(q_1, q_2, \dots, q_n\) can be found using the following Python commands

import numpy as np
import control as cnt

if np.linalg.matrix_rank(cnt.obsv(A,C)) != n:
    print('System Not Observable') 
else:      # if so, compute observer gains
    L = cnt.place(A.T,C.T,[q1,q2,...,qn]).T

where the first operation checks to see if the system is observable by checking whether \(\text{rank}(\mathcal{O}_{A,C})=n\). When finding the gain \(L\) it is important to note the three transposes which correspond to the transposes in Equation 13.14.

If an integrator is used in the control law, as discussed in Chapter 15, then the complete observer-based controller is shown in Fig. 13.3. Note that integral feedback uses the reference output \(y_r\), whereas the observer uses the measured output \(y\). There are many systems for which the measured output is identical to the reference output.

Closed-loop system with observer-based feedback, including integral feedback.

13.1.3 Separation Principle

The observer-based feedback design consists of two steps:

  • Find the state feedback gains \(K\) to place the eigenvalues of \(A-BK\) at specified locations \(p_1,\dots,p_n\),

  • Find the observer gains \(L\) to place the eigenvalues of \(A-LC\) at specified locations \(q_1,\dots,q_n\).

Since the closed-loop system includes both the observer and the state feedback, it is important to analyze whether the closed-loop system is stable and to determine the closed-loop poles. If the integrator is excluded in Fig. 13.3 then the closed-loop system has \(2n\) states: \(n\) states associated with the open-loop plant \(x\) and \(n\) states associated with the observer \(\hat{x}\). Since the reference input does not affect the internal stability of the systems, we can set \(r=0\) and the equations of motion for the closed-loop system can be written as \[\begin{aligned} \dot{x} &= Ax + Bu \\ \dot{\hat{x}} &= A\hat{x} + Bu + L(y - C \hat{x}) \\ u &= -K\hat{x} \\ y &= C x, \end{aligned}\] which implies that \[\begin{pmatrix} \dot{x} \\ \dot{\hat{x}} \end{pmatrix} = \begin{pmatrix} A & -BK \\ LC & A-BK-LC \end{pmatrix} \begin{pmatrix} x \\ \hat{x} \end{pmatrix}.\] Recalling that a change of variables does not change the eigenvalues of the system, and defining the observation error as \(e=x-\hat{x}\), and noting that \[\begin{pmatrix} x \\ e \end{pmatrix} = \begin{pmatrix} I & \mathbf{0} \\ I & -I \end{pmatrix}\begin{pmatrix} x \\ \hat{x} \end{pmatrix},\] we have that \[\begin{aligned} \begin{pmatrix} \dot{x} \\ \dot{e} \end{pmatrix} &= \begin{pmatrix} I & \mathbf{0} \\ I & -I \end{pmatrix}\begin{pmatrix} \dot{x} \\ \dot{\hat{x}} \end{pmatrix} \\ &= \begin{pmatrix} I & \mathbf{0} \\ I & -I \end{pmatrix}\begin{pmatrix} A & -BK \\ LC & A-BK-LC \end{pmatrix} \begin{pmatrix} x \\ \hat{x} \end{pmatrix} \\ &= \begin{pmatrix} I & \mathbf{0} \\ I & -I \end{pmatrix}\begin{pmatrix} A & -BK \\ LC & A-BK-LC \end{pmatrix} \begin{pmatrix} I & \mathbf{0} \\ I & -I \end{pmatrix}^{-1} \begin{pmatrix} x \\ e \end{pmatrix}, \end{aligned}\] and noting that \[\begin{pmatrix} I & \mathbf{0} \\ I & -I \end{pmatrix}^{-1} = \begin{pmatrix} I & \mathbf{0} \\ I & -I \end{pmatrix}\] gives \[\begin{pmatrix} \dot{x} \\ \dot{e} \end{pmatrix} = \begin{pmatrix} A-BK & BK \\ \mathbf{0} & A-LC \end{pmatrix} \begin{pmatrix} x \\ e \end{pmatrix}.\] Using the determinant properties for block diagonal matrices discussed in Appendix 31, it is straightforward to show that \[\text{eig}\begin{pmatrix} A-BK & BK \\ \mathbf{0} & A-LC \end{pmatrix} = \text{eig}(A-BK)\cup \text{eig}(A-LC).\]

Therefore, the poles of the closed-loop system are precisely the poles selected during the design of the feedback gains \(K\) in addition to the poles selected during the design of the observer gains \(L\). This happy circumstance is called the separation principle, which in essence implies that the controller and the observer can be designed separately and then combined without affecting the stability of the system. Unfortunately, the separation principle does not hold in general for nonlinear systems, and even more unfortunately, while the separation principle guarantees stability, it turns out that the addition of an observer can negatively impact the robustness of a state feedback design.

13.1.4 Observer Design for Linearized Systems

Suppose that the state-space model is from a linearized system, i.e., suppose that \(x\in\mathbb{R}^n\) is the state, \(x_e\in\mathbb{R}^n\) is the equilibrium state, and that \(\tilde{x}=x-x_e\) is the state linearized around the equilibrium. Similarly, suppose that \(u\in\mathbb{R}^m\) is the input, that \(u_e\in\mathbb{R}^m\) is the input at equilibrium, and that \(\tilde{u}=u-u_e\) is the input linearized around equilibrium, and that \(y\in\mathbf{R}^p\) is the measured output, \(y_{me}=C x_e\in\mathbf{R}^p\) is the measured output at equilibrium, and \(\tilde{y}=y-y_{e}\) is the measured output linearized about equilibrium, then the linearized state-space model is given by \[\begin{aligned} \dot{\tilde{x}} &= A\tilde{x} + B\tilde{u} \\ \tilde{y} &= C\tilde{x}. \end{aligned}\] The observer design problem then finds an observer gain so that the eigenvalues of \(A-LC\) are at specified locations, and the resulting observer is \[\dot{\hat{\tilde{x}}} = A\hat{\tilde{x}} + B\tilde{u} + L(\tilde{y}-C\hat{\tilde{x}}),\] where \(\hat{\tilde{x}}=\hat{x}-x_e\). Writing the observer in terms of \(\hat{x}\) gives \[\dot{\hat{x}}-\dot{x}_e = A(\hat{x}-x_e) + B(u-u_e) + L\left((y-y_{e})-C(\hat{x}-x_e)\right).\] Noting that \(\dot{x}_e=0\) and that \(y_{e}=C x_e\) gives \[\dot{\hat{x}} = A(\hat{x}-x_e) + B(u-u_e) + L\left(y-C\hat{x}\right).\]

13.2 Summary of Design Process - Observer Design

The procedure for designing an observer is summarized as follows.

Given the plant \[\begin{aligned} \dot{x} &= Ax + Bu \\ y &= C x \end{aligned}\] find the observer gain \(L\) so that the state observer \[\dot{\hat{x}}=A\hat{x} + Bu + L(y-C\hat{x})\] has stable estimation error dynamics with poles located at \(q_1, q_2, \dots, q_n\).

Step 1.
Check to see if the system is observable by computing the observability matrix \[\mathcal{O}_{A,C} = \begin{pmatrix} C \\ C A \\ C A^2 \\ \vdots \\ C A^{n-1}\end{pmatrix}\] and checking to see if \(\text{rank}(\mathcal{O}_{A,C})=n\).

Step 2.
Find the open-loop characteristic polynomial \[\Delta_{ol}(s)=\text{det}(sI-A) = s^n + a_{n-1}s^{n-1} + \cdots + a_1 s + a_0,\] and construct the row vector \[\mathbf{a}_A = \begin{pmatrix} a_{n-1}, & a_{n-2}, & \dots, & a_1, & a_0\end{pmatrix}\] and the matrix \[\mathcal{A}_A = \begin{pmatrix} 1 & a_{n-1} & a_{n-2} & \cdots & a_2 & a_1 \\ 0 & 1 & a_{n-1} & \cdots & a_3 & a_2 \\ \cdots & & \ddots & & & \vdots \\ 0 & 0 & \cdots & 0 & 1 & a_{n-1} \\ 0 & 0 & \cdots & 0 & 0 & 1 \end{pmatrix}\]

Step 3.
Find the desired characteristic polynomial for the observation error \[\begin{aligned} \Delta_{obs}^d(s) &= (s-q_1)(s-q_2)\cdots(s-q_n) = s^n + \beta_{n-1}s^{n-1} + \cdots + \beta_1 s + \beta_0, \end{aligned}\] and construct the row vector \[\boldsymbol{\beta} = \begin{pmatrix}\beta_{n-1}, & \beta_{n-2}, & \dots, & \beta_1, & \beta_0 \end{pmatrix}.\]

Step 4.
Compute the desired observer gains as \[L = \mathcal{O}_{A,C}^{-1}(\mathcal{A}_A^\top)^{-1}(\boldsymbol{\beta}-\mathbf{a}_A)^\top\]

Using Python, these steps can be implemented using the following script.

import numpy as np
import control as cnt

if np.linalg.matrix_rank(cnt.obsv(A,C)) != n:
    print('System Not Observable') 
else:   # if so, compute observer gains
    L = cnt.place(A.T,C.T,[q1,q2,...,qn]).T

13.2.1 Simple example

Given the system \[\begin{aligned} \dot{x} &= \begin{pmatrix} 0 & 1 \\ 2 & 3 \end{pmatrix} x + \begin{pmatrix} 0 \\ 4 \end{pmatrix} u \\ y &= \begin{pmatrix} 5 & 0 \end{pmatrix} x \end{aligned}\] find the observer gain \(L\) so that the state observer \[\dot{\hat{x}} = A\hat{x} + Bu + L(y-C\hat{x})\] has stable estimation error dynamics with poles located at \(-10\pm j10\).

Step 1.
The observability matrix is given by \[\mathcal{O} = \begin{pmatrix} C \\ CA \end{pmatrix} = \begin{pmatrix} 5 & 0 \\ 0 & 5 \end{pmatrix}.\] The determinant is \(det(\mathcal{O})=25\neq 0\), therefore the system is observable.

Step 2.
The open-loop characteristic polynomial \[\Delta_{ol}(s)=\text{det}(sI-A) = \text{det}\begin{pmatrix} s & -1 \\ -2 & s-3 \end{pmatrix} = s^2 - 3s -2,\] implies that \[\begin{aligned} \mathbf{a} &= \begin{pmatrix} -3, & -2 \end{pmatrix} \\ \mathcal{A} &= \begin{pmatrix} 1 & -3 \\ 0 & 1 \end{pmatrix} \end{aligned}\]

Step 3.
The desired characteristic polynomial for the observation error is \[\Delta_{obs}^d(s) = (s+10-j10)(s+10+j10)=s^2+20s+200,\] which implies that \[\boldsymbol{\beta} = \begin{pmatrix} 20, & 200 \end{pmatrix}.\]

Step 4.
The observation gains are therefore given as \[\begin{aligned} L &= \mathcal{O}^{-1}(\mathcal{A}^\top)^{-1}(\boldsymbol{\beta}-\mathbf{a})^\top \\ &= \begin{pmatrix}\frac{1}{5} & 0 \\ 0 & \frac{1}{5} \end{pmatrix}\begin{pmatrix}1 & 0 \\ 3 & 1\end{pmatrix}\left( (20, 200) - (-3, -2) \right)^\top \\ &= \begin{pmatrix}1/5 & 0 \\ 3/5 & 1/5 \end{pmatrix}\begin{pmatrix}23 \\ 202\end{pmatrix} = \begin{pmatrix} 23/5 \\ 271/5 \end{pmatrix} \end{aligned}\]

Alternatively, we could have used the following Python script

import numpy as np
import control as cnt

# original state-space system
A = np.array([[0.0, 1.0], [2.0, 3.0]])
B = np.array([[0.0], [4.0]])
C = np.array([[5.0, 0.0]])

# desired poles for observer
q1 = -10 + 10.j
q2 = -10 - 10.j

# is the system observable?
if np.linalg.matrix_rank(cnt.obsv(A,C)) != np.size(A,1):
    print('System Not Observable')
else:  # if so, compute observer gains
    L = cnt.place(A.T,C.T,[q1,q2]).T

The corresponding observer is given by \[\tag{13.17} \dot{\hat{x}} = \begin{pmatrix} 0 & 1 \\ 2 & 3 \end{pmatrix}\hat{x} + \begin{pmatrix} 0 \\ 4 \end{pmatrix} u + \begin{pmatrix} 23/5 \\ 271/5 \end{pmatrix} \left( y - \begin{pmatrix} 5 & 0 \end{pmatrix}\hat{x} \right),\] and can be implemented as member functions within a Python class as follows (see the solutions for case studies A-C for class-specific implementation examples):

def update_observer(self, y_m):
    # update the observer using RK4 integration
    F1 = self.observer_f(self.x_hat, y_m)
    F2 = self.observer_f(self.x_hat + self.Ts / 2 * F1, y_m)
    F3 = self.observer_f(self.x_hat + self.Ts / 2 * F2, y_m)
    F4 = self.observer_f(self.x_hat + self.Ts * F3, y_m)

    self.x_hat += self.Ts / 6 * (F1 + 2 * F2 + 2 * F3 + F4)

    return self.x_hat

def observer_f(self, x_hat, y_m):
    # xhatdot = A*xhat + B*u + L(y-C*xhat)
    # assumes that all matrices below are np.arrays
    xhat_dot = self.A @ x_hat \
               + self.B @ self.u \
               + self.L @ (y_m-self.C @ x_hat)

    return xhat_dot

Digital implementation of the observer in Equation 13.17 requires two persistent (or member) variables, one for \(\hat{x}\) and one for \(u\). The observer is updated using the RK4 algorithm in lines 3–8. The differential equation that describes the observer is given on lines 15–17.

Chapter 13 guided activity

Work through a second observer design

Use the same procedure as the simple example above. For the system below, compute each quantity in order and click Check before moving on. The solution for each step is revealed only after that step is checked.

x = 0 1 -6 -5 x + 0 1 u y = 2 0 x

Desired observer poles: -4 ± j3.

Step 1. Observability matrix

Compute O = (C; CA). Enter the four entries row by row and the rank.

O =

Step 2. Open-loop characteristic polynomial

Compute det(sI - A) = s2 + a1s + a0.

a =

Step 3. Desired observer polynomial

Compute (s + 4 - j3)(s + 4 + j3) = s2 + beta1s + beta0.

β =

Step 4. Observer gain

Use L = O-1(AcalT)-1(beta - a)T. Enter the two entries of L.

L =

Step 5. Check A - LC

Use your L to form A - LC. Enter the trace and determinant of A - LC.

13.3.1 image Example Problem 3.1.16

The objective of this problem is to design an observer that estimates the state of the system and uses the estimated state in the controller designed in Homework 3.1.15.

For the sake of understanding the function of the observer, for this problem we will use exact parameters, without an input disturbance. Modify the arm dynamics so that the parameters known to the controller are the actual plant parameters (uncertainty parameter \(\alpha=0\)).

Verify that the state-space system is observable by checking that \(\text{rank}(\mathcal{O}_{A,C})=n\).

Modify the controller to add an observer to estimate the state \(\hat{x}\), and then use the estimate of the state \(\hat{x}\) in your feedback controller. Tune the poles of the controller and observer to obtain good performance.

Modify the simulation files so that the controller outputs both \(u\) and \(\hat{x}\). Add a plotting routine to plot both the state and the estimated state of the system on the same graph.

As motivation for the next chapter, add an input disturbance to the system of \(0.05\) and observe that there is steady-state error in the response. This is caused by a steady-state error in the observation error. In the next chapter we will show how to remove the steady-state error in the observation error.

Design Study A guided exercise

Design the observer

Check observability, choose faster observer poles, and interpret estimated states.

Step 1. Observability rank

Step 2. Observer pole speed

Step 3. Estimated state notation

Pseudocode

The complete solution includes separate observer-update and control-update functions. Before opening it, outline each component separately.

These prompts are ungraded. They are intended to connect the observer equations to the implementation code in the complete solution.

13.4 Design Study B. Inverted Pendulum

13.4.1 image Example Problem 3.2.16

The objective of this problem is to design an observer that estimates the state of the system and to use the estimated state in the controller designed in Homework 3.2.15.

For the sake of understanding the function of the observer, for this problem we will use exact parameters, without an input disturbance. Modify the pendulum dynamics so that the parameters known to the controller are the actual plant parameters (uncertainty parameter \(\alpha=0\)).

Verify that the state-space system is observable by checking that \(\text{rank}(\mathcal{O}_{A,C})=n\).

In the control block, add an observer to estimate the state \(\hat{x}\), and use the estimate of the state in your feedback controller. Tune the poles of the controller and observer to obtain good performance.

Modify the simulation files so that the controller outputs both \(u\) and \(\hat{x}\). Add a plotting routine to plot both the state and the estimated state of the system on the same graph.

As motivation for the next chapter, add an input disturbance to the system of \(0.05\) and observe that there is steady-state error in the response even though there is an integrator. This is caused by a steady-state error in the observation error. In the next chapter we will show how to remove the steady-state error in the observation error.

Design Study B guided exercise

Design the pendulum observer

Use measured z and theta to estimate the full state for feedback.

Step 1. Observability

Step 2. Observer pole choice

Step 3. Estimated state use

Pseudocode

The complete solution includes separate observer-update and control-update functions. Before opening it, outline each component separately.

These prompts are ungraded. They are intended to connect the derivation to the implementation code in the complete solution.

13.5 Design Study C. Satellite Attitude Control

13.5.1 image Example Problem 3.3.16

The objective of this problem is to design an observer that estimates the state of the system and to use the estimated state in the controller designed in Homework 3.3.15.

For the sake of understanding the function of the observer, for this problem we will use exact parameters, without an input disturbance. Modify the satellite dynamics so that the parameters known to the controller are the actual plant parameters (uncertainty parameter \(\alpha=0\)).

Verify that the state-space system is observable by checking that \(\text{rank}(\mathcal{O}_{A,C})=n\).

In the control block, add an observer to estimate the state \(\hat{x}\), and use the estimate of the state in your feedback controller. Tune the poles of the controller and observer to obtain good performance.

Modify the simulation files so that the controller outputs both \(u\) and \(\hat{x}\). Add a plotting routine to plot both the state and the estimated state of the system on the same graph.

As motivation for the next chapter, add an input disturbance to the system of \(1.0\) Newton-meter and observe that there is steady-state error in the response even though there is an integrator. This is caused by a steady-state error in the observation error. In the next chapter we will show how to remove the steady-state error in the observation error.

Design Study C guided exercise

Plan the satellite observer

The observer estimates the full four-state satellite state from measured outputs.

Step 1. Observer setup

Step 2. Observability check

Step 3. Motivation for disturbance observers

13.6 Interactive Observer Check

Chapter 13 activity

Innovation term explorer

The observer is a model copy plus a correction term. For the simple constant-velocity system x = Ax with A = (0, 1; 0, 0) and y = (1, 0)x, change L = (l1, l2)T and watch how the innovation y - Cx changes the long-time estimate.

Observer gain L Error dynamics Estimated poles Final error norm

Interactive Figure 13.I1. The solid traces show true position and velocity; dashed traces show the observer estimates. The innovation y - Cx drives the correction L(y - Cx).

Check your understanding

In this activity, what does the innovation y - Cx measure?

Chapter 13 activity

Observability matrix rank: 1D car

For a car moving in one dimension, let x1 be position and x2 be velocity. The model is xdot = Ax with A = (0, 1; 0, 0). Change C = (c1, c2) and watch how the observability matrix O = (C; CA) changes.

Output matrix C Observability matrix O det(O) Rank conclusion

Interactive Figure 13.I2. Position sensing can reveal velocity through how position changes over time. Velocity-only sensing cannot reveal the absolute initial position.

Check your understanding

Which measurement makes the 1D car observable?

Why is velocity-only sensing not observable for this model?

13.7 Coding Lab: Observer Design

Objective: synthesize a Luenberger observer gain and implement the observer update equation.

Evaluation criteria: the lab checks observability rank, observer-gain dimensions and values, observer pole locations, and convergence of the estimation error.

Figure 13.1 (Interactive). Observer-design coding lab with automatic convergence checks.

13.8 Knowledge Check

Q1. Observer purpose

An observer is used primarily to estimate:

Q2. Error dynamics

The observer error dynamics are governed by:

Q3. Observability rank

A two-state SISO system is observable when its observability matrix has what rank?

Show solution

Answer: 2. Full rank means the initial state can be reconstructed from the output history.

Q4. One-step residual correction

If y = 0.8 and Cx = 1.2, enter the measurement residual y - Cx.

Show solution

Answer: -0.4 because y - Cx = 0.8 - 1.2 = -0.4.

Q5. Separation principle

What principle says controller poles and observer poles can be chosen separately?

Show solution

Answer: The separation principle.

Q6. Observability matrix

For A = 01-2-3 and C = 10 , which matrix is the observability matrix O = (C; CA)?

Q7. Meaning of observability

What does full-rank observability mean for a linear model?

Q8. Observer error matrix

Which matrix determines the observer estimation-error dynamics?

Q9. Fast observer pole tradeoff

What is a practical downside of placing observer poles extremely far left?

13.9 Notes and References

The original source for Luenberger observers is in [21]. Observer design using pole placement is covered in most introductory textbooks on control, see for example [4, 22, 23], as well as introductions to state-space design [5, 6]. The most common definition of observability is that a dynamic system is said to be observable if the initial state \(x_0\) can be reconstructed by observing the output over any finite interval. Linear time-invariant systems are observable if and only if the observability matrix is full rank [5]. Observer theory and design is an interesting topic in its own right. The design of nonlinear observers is currently an active area of research. The most commonly used observer for nonlinear systems is the extended Kalman filter [24, 25].

14 Disturbance Observers

14.1 Theory

In previous sections we have discussed that modeling errors and other real-world effects result in an input disturbance to the system as shown in Fig. 14.1.

Input disturbance to plant modeled by state-space equations.

The objective of this section is to explain the effect of the disturbance on an observer. It turns out that the disturbance creates a steady-state bias in the observer states. We will also describe how the observer can be augmented to estimate the disturbance and to remove the steady-state observation error. This is the dual of adding an integrator to a state-space system.

To understand the effect of the disturbance on the observer, note that when the disturbance is present, the state-space equations for the system are \[\begin{aligned} \dot{x} &= Ax + B(u+d) \\ y &= C x. \end{aligned}\] The standard equation for the observer is \[\tag{14.1} \dot{\hat{x}} = A\hat{x} + Bu + L(y-C\hat{x}).\] Defining the observation error as \(e=x-\hat{x}\) and taking the derivative with respect to time gives \begin{align} \dot{e} &= \dot{x}-\dot{\hat{x}} \\ &= Ax + Bu + Bd - A\hat{x} - Bu - LCx + LC\hat{x} \notag\\ &= (A-LC)e + Bd. \tag{14.3} \end{align} Taking the Laplace transform of both sides while accounting for the initial condition, and solving for \(E(s)\) gives \[E(s) = (sI-(A-LC))^{-1}e(0) + (sI-(A-LC))^{-1}B\mathcal{L}\{d(t)\}.\] Therefore, the error is due to two terms. The first term involves the initial conditions \(e(0)\) and decays to zero if the eigenvalues of \(A-LC\) are in the open left half of the complex plane. The second term is driven by the disturbance and for a constant bounded disturbance, it will result in a constant bounded observation error.

If the disturbance \(d(t)\) were perfectly known, then we could modify the observer in Equation 14.1 as \[\tag{14.4} \dot{\hat{x}} = A\hat{x} + B(u+d) + L(y-C\hat{x}),\] so that the evolution of the observation error becomes \[\begin{aligned} \dot{e} &= \dot{x}-\dot{\hat{x}} \\ &= Ax + B(u+d) - A\hat{x} - B(u+d) - LCx + LC\hat{x} \\ &= (A-LC)e, \end{aligned}\] which, in contrast to Equation 14.3 is not driven by the disturbance \(d\). However, since \(d\) is not known it needs to be estimated. The basic idea in this chapter is to estimate \(d\) using an augmented observer.

If we assume that \(d\) is constant, then the differential equation that governs the evolution of \(d\) is given by \(\dot{d}=0\). Therefore, if we augment the state \(x\) of the system with the disturbance, then the equations of motion can be written as \[\begin{aligned} \begin{pmatrix} \dot{x} \\ \dot{d} \end{pmatrix} &= \begin{pmatrix} A & B \\ \mathbf{0} & 0 \end{pmatrix} \begin{pmatrix} x \\ d\end{pmatrix} + \begin{pmatrix} B \\ 0 \end{pmatrix} u \\ y &= \begin{pmatrix} C & 0 \end{pmatrix} \begin{pmatrix} x \\ d \end{pmatrix}. \end{aligned}\] Define the augmented state-space matrices as \[\begin{aligned} A_2 &= \begin{pmatrix} A & B \\ \mathbf{0} & 0 \end{pmatrix} \\ C_2 &= \begin{pmatrix} C & 0 \end{pmatrix}. \end{aligned}\] If \((A_2,C_2)\) are observable, then using the techniques discussed in Chapter 16 we can design an observer for the augmented system, where the augmented observer equations are \[\begin{pmatrix}\dot{\hat{x}} \\ \dot{\hat{d}} \end{pmatrix} = \begin{pmatrix} A & B \\ \mathbf{0} & 0 \end{pmatrix}\begin{pmatrix} \hat{x} \\ \hat{d}\end{pmatrix} + \begin{pmatrix} L \\ L_d\end{pmatrix} \left( y - \begin{pmatrix} C & 0 \end{pmatrix} \begin{pmatrix} \hat{x} \\ \hat{d} \end{pmatrix} \right) + \begin{pmatrix} B \\ 0 \end{pmatrix} u\] or in component form \[\begin{aligned} \dot{\hat{x}} &= A\hat{x} + B\left(u+\hat{d}\right) + L (y-C\hat{x}) \\ \dot{\hat{d}} &= L_d (y-C\hat{x}), \end{aligned}\] where the gain \(L_2 = (L^\top, L_d)^\top\) is obtained using the Ackermann formula \[L_2 = \mathcal{O}_{A_2,C_2}^{-1}(\mathcal{A}_{A_2}^\top)^{-1}(\boldsymbol{\beta}_d-\mathbf{a}_{A_2})^\top,\] where \(\mathbf{a}_{A_2}\) is obtained from the characteristic polynomial of \(A_2\), and \(\boldsymbol{\beta}_d\) is obtained from the desired characteristic polynomial for \(A_2-L_2C_2\). Alternatively, \(L_2\) can be found using the Python place command:

import control as cnt 
L2 = cnt.place(A2.T,C2.T,desired_observer_poles).T

14.1.1 Simple Example

Consider the example in Sections 14.2.1, 15.2.1, and 16.2.1. A block diagram for the system is shown in Fig. 14.2, where a constant input disturbance has been added to the system.

Block diagram for a simple example, where a constant input disturbance has been added to the system.

Suppose that a standard feedback controller without an integrator and without a disturbance observer is designed for this system. An example of potential Python code is

import numpy as np
import control as cnt

P.A = np.array([[0., 1.0], [2.0, 3.0]])
P.B = np.array([[0.], [4.0]])
P.C = np.array([[5.0, 0]])
P.D = 0

P.Ts = 0.01 #sampling time

# pick poles for the controller
wn_ctrl = 1
zeta_ctrl = 0.707
charpoly = [1., 2.0*zeta_ctrl*wn_ctrl, wn_ctrl**2]
des_ctrl_poles = np.roots(charpoly)

# pick poles for the observer
wn_obsv = 10.0
zeta_obsv = 0.707
charpoly = [1., 2.0*zeta_obsv*wn_obsv, wn_obsv**2]
des_obsv_poles = np.roots(charpoly)

# is the system controllable?
    if np.linalg.matrix_rank(cnt.ctrb(P.A, P.B)) != np.size(P.A, 1):
print('System Not Controllable')
else:
    P.K = cnt.place(P.A, P.B, des_ctrl_poles)
    P.kr = -1.0/(P.C*np.linalg.inv(P.A-P.B*P.K)*P.B)

# is the system observable?
if np.linalg.matrix_rank(cnt.obsv(P.A, P.C)) != np.size(P.A, 1):
    print('System Not Observable')
else:
    P.L = cnt.place(P.A.T, P.C.T, des_obsv_poles).T

The associated control code is

# variables 'xhat' and 'u' must be declared as global, or
# class member variables for the sake of persistence, and the
# measurement 'y' and reference input 'r' must be passed in.
N = 10

# solve the observer differential equations using N steps of
# RK1 for i = 1 to N
for i in range(N):
    self.xhat = self.xhat + P.Ts/N*(P.A*self.xhat + \
                                    P.B*self.u + \
                                    P.L*(y-P.C*self.xhat))

# observer-based update with feedback controller
self.u = P.kr*r - P.K*self.xhat

The step response for this controller is shown in Fig. 14.3, where it is obvious that the input disturbance is causing a large steady-state error in the system response, as well as in the estimation error.

Step response for standard observer-based control without integrator and without disturbance observer.
Figure 14.3 (Interactive). Adjust disturbance and reference to see steady-state and estimation-error behavior.

If an integrator is added to the system using the following design file

# design file with integrator
integrator_pole = -1.0

# augment system to add integrator
P.A1 = np.block([[P.A, np.zeros((2,1))], [-P.C, 0]])
P.B1 = np.block([[P.B], [0]])

# is this system controllable?
if np.linalg.matrix_rank(cnt.ctrb(P.A1, P.B1)) != np.size(P.A1, 1):
    print('System Not Controllable')
else:
    K1 = cnt.place(P.A1, P.B1, np.concatenate((des_ctrl_poles,
                                               [integrator_pole])))
    P.K = K1[0,0:-1]
    P.ki = K1[0, -1]

and the control code listed below:

# variables 'xhat,' 'error_d1, 'integrator,' and 'u' must be
# declared as global, or class member variables for the sake
# of persistence, and the measurement 'y' and reference input
# 'r' must be passed in.
N = 10

# solve the observer differential equations using N steps of
# RK1 for i = 1 to N
for i in range(N):
    self.xhat = self.xhat + P.Ts/N*(P.A*self.xhat + \
                                    P.B*self.u + \
                                    P.L*(y-P.C*self.xhat))

# implement the integrator
error = r-y
self.integrator = self.integrator + \
                  (P.Ts/2.0)*(error+self.error_d1)
self.error_d1 = error

# observer-based feedback controller
self.u = -P.K*self.xhat - P.ki*self.integrator

The response of the system with the integrator is shown in Fig. 14.4, where it is clear that the steady-state error in the response has been removed, but where there is now a steady-state response in the estimation error.

Step response for observer-based control with integrator but without disturbance observer.
Figure 14.4 (Interactive). Adjust disturbance and integrator gain to see tracking and estimation-error tradeoffs.

Now consider the case where the integrator is not present, but we add a disturbance observer. The design code is listed below.

# is the system controllable?
if np.linalg.matrix_rank(cnt.ctrb(P.A, P.B)) != np.size(P.A, 1):
    print('System Not Controllable')
else:
    P.K = cnt.place(P.A, P.B, des_ctrl_poles)
    P.kr = -1.0/(P.C*np.linalg.inv(P.A-P.B*P.K)*P.B)

# augment system for disturbance observer
disturb_obsv_pole = -2.0
P.A2 = np.block([[P.A, P.B], [np.zeros((1,2)), 0]])
P.B2 = np.block([[P.B], [0]])
P.C2 = np.block([P.C, 0])

# is the system observable?
if np.linalg.matrix_rank(cnt.obsv(P.A2, P.C2)) != np.size(P.A2, 1):
    print('System Not Observable')
else:
    P.L2 = cnt.place(P.A2.T, P.C2.T,
                     np.concatenate((des_obsv_poles,
                                     [disturb_obsv_pole]))).T

The associated control code is listed below.

# variables 'x_obsv' and 'u' must be declared as global, or
# class member variables for the sake of persistence, and the
# measurement 'y' and reference input 'r' must be passed in.
N = 10

# solve the observer differential equations using N steps of
# RK1 for i = 1 to N
for i in range(N):
    self.x_obsv = self.x_obsv + P.Ts/N*(P.A2*self.x_obsv + \
                                        P.B2*self.u + \
                                        P.L2*(y-P.C2*self.x_obsv))
xhat = self.x_obsv[0, 0:-1]
dhat = self.x_obsv[0, -1]

# observer-based feedback controller with disturbance observer
self.u = P.kr*r - P.K*self.xhat - dhat

Note the presence of \(\hat{d}\) on Line 13. The disturbance estimate is subtracted from the control input on Line 16. The resulting system response is shown in Fig. 14.5.

Step response for observer-based control with a disturbance observer rather than an integrator.
Figure 14.5 (Interactive). Adjust disturbance and disturbance-observer gain to compare disturbance rejection.

Note that in this case, the steady-state error in both the system response and the estimation error has been removed. At this point, the integrator can be added back into the system to remove the effect of model mismatch and other disturbances on the system.

14.2.1 image Example Problem 3.1.17

(a) Modify the simulation from HW 3.1.16 so that the uncertainty parameter in arm_dynamics.m is \(\alpha=0.2\), representing 20% inaccuracy in the knowledge of the system parameters and so that the input disturbance is \(0.5\) Newton-meters. Also, add noise to the output channel \(\theta_m\) with a standard deviation of \(0.001\). Before adding the disturbance observer, run the simulation and note that the controller is not robust enough to handle the large input disturbance.

(b) Add a disturbance observer to the controller, and verify that the steady-state error in the estimator has been removed. Tune the system to get good response.

Design Study A guided exercise

Add a disturbance observer

Augment the observer so it estimates a constant input disturbance along with the plant state.

Step 1. Disturbance model

Step 2. Augmented observer order

Step 3. Purpose

Pseudocode

The complete solution includes a simulation script and a disturbance-observer controller class. Before opening it, outline each component separately.

These prompts are ungraded. They are intended to connect the disturbance-observer design to the implementation code in the complete solution.

14.3 Design Study B. Inverted Pendulum

14.3.1 image Example Problem 3.2.17

(a) Modify the simulation from HW 3.2.16 so that the uncertainty parameter in pendulum_dynamics.m is \(\alpha=0.2\), representing 20% inaccuracy in the knowledge of the system parameters, and so that the input disturbance is \(0.5\). Also, add noise to the output channels \(z_m\) and \(\theta_m\) with a standard deviation of \(0.001\). Before adding the disturbance observer, run the simulation and note that the controller is not robust to the large input disturbance.

(b) Add a disturbance observer to the controller, and verify that the steady-state error in the estimator has been removed. Tune the system to get good response.

Design Study B guided exercise

Add a disturbance observer

Augment the observer so it can estimate a constant input disturbance.

Step 1. Baseline failure mode

Step 2. Disturbance model

Step 3. Noise level

Pseudocode

The complete solution includes a simulation script and a disturbance-observer controller class. Before opening it, outline each component separately.

These prompts are ungraded. They are intended to connect the derivation to the implementation code in the complete solution.

14.4 Design Study C. Satellite Attitude Control

14.4.1 image Example Problem 3.3.17

(a) Modify the simulation from HW 3.3.16 so that the uncertainty parameter in satellite_dynamics.m is \(\alpha=0.2\), representing 20% inaccuracy in the knowledge of the system parameters and so that the input disturbance is \(1.0\) Newton-meters. Also, add noise to the output channels \(\phi_m\) and \(\theta_m\) with a standard deviation of \(0.001\). Before adding the disturbance observer, run the simulation and note that the controller is not robust to the large input disturbance.

(b) Add a disturbance observer to the controller, and verify that the steady-state error in the estimator has been removed. Tune the system to get good response.

Design Study C guided exercise

Plan the satellite disturbance observer

The disturbance observer estimates the input disturbance that the ordinary observer-based controller cannot reject robustly.

Step 1. Stress-test conditions

Step 2. What gets estimated?

Pseudocode

14.5 Interactive Disturbance-Observer Check

Chapter 14 activity

Augmented disturbance-observer explorer

The plant receives a step to a constant input disturbance at t = 1 s. Change the disturbance size and the disturbance-observer pole to see how the augmented observer drives d toward the true disturbance through the innovation term y - Cx.

Final disturbance estimate Final tracking error Estimate settling time Interpretation

The same plant, controller, and augmented observer structure used in the chapter example are simulated. The pole slider moves the added disturbance-estimator pole.

For the matched constant-disturbance model, changing the pole should mainly change how quickly d converges. It should not be interpreted as changing the ideal final disturbance value.

Chapter 14 comparison

Standard observer vs. disturbance observer

Compare the standard observer-based controller with the augmented disturbance observer. Both see the same constant input disturbance, but only the augmented observer estimates d and subtracts it from the control input.

Standard final error Augmented final error Final d Main lesson

Dashed gray traces use the standard observer. Teal traces use the augmented disturbance observer. Dashed blue marks the reference command; dashed brown marks the true disturbance.

Chapter 14 code map

Connect the code to the observer equations

Select the mathematical role played by each line from the disturbance-observer implementation. The goal is to see how the code implements the augmented equations and the control input \(u = k_r r - K\hat{x} - \hat{d}\).

Correct matches Feedback

Chapter 14 observability

Can the augmented disturbance state be observed?

A disturbance observer augments the plant state with a constant-disturbance state, \(x_2 = [x_1,\;x_2,\;d]^T\). The observer can estimate \(d\) only when the augmented pair \((A_2, C_2)\) is observable.

  1. Choose what the sensor measures through \(C\).
  2. Choose where the disturbance enters through \(B_d\).
  3. Check whether the resulting observability matrix has rank 3, which means both plant states and the added disturbance state can be inferred from output history.
Observability matrix
Rank
Interpretation

14.6 Knowledge Check

Q1. Disturbance observer purpose

A disturbance observer is intended to estimate:

Q2. Model fit

A constant-disturbance observer is most useful when the disturbance is:

Q3. Augmented observer dimension

If a two-state plant is augmented with one constant-disturbance state, enter the observer model order.

Show solution

Answer: 3. The augmented observer estimates two plant states plus one disturbance state.

Q4. Bias reduction

If an output bias is 0.5 without disturbance estimation and 0.1 after estimation, enter the remaining bias.

Show solution

Answer: 0.1. The disturbance observer reduces the bias when the disturbance model matches the real disturbance.

Q5. Disturbance classification

Name one disturbance category discussed in the observer/disturbance chapters.

Show solution

Answer: Examples include input disturbance, output disturbance, and model uncertainty.

Q6. Constant-disturbance augmentation

How is an unknown constant disturbance commonly represented in the augmented observer model?

Q7. Using the disturbance estimate

How should a disturbance estimate be used in the control law?

Q8. Poor model fit

Which disturbance is least well represented by a constant-disturbance observer?

14.7 Notes and References

Disturbance observers are one example of how observers can be used to estimate a variety of different parameters in the system. In general, observers can be used to estimate model parameters like mass and inertia, but in this case, nonlinear observers are required. The most commonly used nonlinear observer is the extended Kalman filter. Derivations of the extended Kalman filter can be found in [24–26]. In robotics, observers are used to estimate the system state, but also the biases in gyroscopes and accelerometers [27], which are a form of input disturbances.

Part V

Loop-shaping Control Design

This part of the book introduces the loop-shaping design method based on the frequency response characteristics of the system. In Part II we derived transfer function and state-space models based on the linearized system. In Part III we showed that PID controllers can be used to regulate the output of second-order systems. For higher-order systems, PID can be used if the original system can be written as a cascade, or series, of second-order systems. In Part IV we showed that controllers can be derived for higher-order systems using state-space models. The state-space design method is a time-domain method that focuses on shaping the time-response of the system. In this part of the book we extend PID control using frequency domain ideas where we shape the frequency response of the system. When the transfer function is available, it provides a compact representation of the frequency response of the open-loop system. Therefore, in this part we will focus on transfer function models of the system. The methods in this part are not constrained to second-order systems and do not depend on a cascade structure. In fact, they do not even require a transfer function of the system, as long as the frequency response, or Bode plot, is known.

Chapter 18 is a review of frequency response models of linear time-invariant systems and develops intuition concerning the Bode plot of the input-output response. In Chapter 19 we show how performance specifications for reference tracking, disturbance rejection, and noise attenuation can be related to the frequency response of the open loop control-plant pair. Chapter 20 addresses stability of the closed-loop system from a frequency response point of view. Chapter 21 represents the culminating chapter in this part of the book and describes how to design the controller to achieve closed-loop stability and to satisfy design specifications on reference tracking, disturbance rejection, and noise attenuation.

15 Frequency Response of LTI Systems

15.1 Theory

15.1.1 Manipulating Complex Numbers

Any complex number \(z\) can be represented in rectangular coordinates as \[z = \Re\{z\} + j \Im\{z\},\] where \(\Re\{z\}\) is the real part of \(z\), and \(\Im\{z\}\) is the imaginary part of \(z\). Similarly, \(z\) can be represented in polar form as \[\tag{15.1} z = \left|z\right|e^{j\angle z},\] where \(\left|z\right|\) denotes the magnitude of \(z\) and \(\angle z\) denotes the angle or phase of \(z\). The relationship between the real and imaginary parts, and the magnitude and phase of \(z\), are depicted in Fig. 15.1.

Relationship between the real and imaginary parts of z, and the magnitude and phase of z.

From the geometry shown in Fig. 15.1 we can see that \[\begin{aligned} \left|z\right| &= \sqrt{\Re\{z\}^2 + \Im\{z\}^2} \\ \angle z &= \tan^{-1}\frac{\Im\{z\}}{\Re\{z\}}. \end{aligned}\] Similarly, from Euler’s relationship \[e^{j\theta} = \cos\theta + j\sin\theta,\] we have from Equation 15.1 that \[z = \left|z\right|e^{j\angle z} = \left|z\right|\cos\angle z + j \left|z\right|\sin\angle z\] which implies that \[\begin{aligned} \Re\{z\} &= \left|z\right|\cos\angle z \\ \Im\{z\} &= \left|z\right|\sin\angle z. \end{aligned}\]

The conjugate of \(z\), denoted \(\bar{z}\), is given by \[\bar{z} = \Re\{z\}-j\Im\{z\} = \left|z\right|e^{-j\angle z}.\] Note that \(z\bar{z} = \left|z\right|^2\).

Suppose that \(z_1 = \left|z_1\right|e^{j\angle z_1}\) and \(z_2=\left|z_2\right|e^{j\angle z_2}\) are two complex numbers, then \[\begin{aligned} z_1z_2 &= \left|z_1\right|e^{j\angle z_1}\left|z_2\right|e^{j\angle z_2} \\ &= \left|z_1\right|\left|z_2\right|e^{j\angle z_1}e^{j\angle z_2} \\ &= \left|z_1\right|\left|z_2\right|e^{j(\angle z_1 + \angle z_2)}, \end{aligned}\] therefore when multiplying complex numbers, their magnitudes multiply, but their phases add. Similarly, we have \[\frac{z_1}{z_2} = \frac{\left|z_1\right|e^{j\angle z_1}}{\left|z_2\right|e^{j\angle z_2}} = \frac{\left|z_1\right|}{\left|z_2\right|}\frac{e^{j\angle z_1}}{e^{j\angle z_2}} = \frac{\left|z_1\right|}{\left|z_2\right|}e^{j(\angle z_1 - \angle z_2)},\] therefore when dividing complex numbers, their magnitudes divide, but their phases subtract.

A transfer function \(H(s)\) is a complex number for any specific value of \(s\). Therefore, \(H(s)\) can be expressed in both rectangular and polar forms as \[H(s) = \Re\{H(s)\} + j\Im\{H(s)\} = \left|H(s)\right|e^{j\angle H(s)}.\] For example, if \(H(s) = \frac{1}{s+1}\), then when \(s=2+j3\) \[\begin{aligned} H(2+j3) &= \frac{1}{2+j3+1}= \frac{1}{3+j3} = \frac{1}{3+j3}\frac{3-j3}{3-j3} \\&= \frac{1}{6} - j\frac{1}{6} = \sqrt{\frac{1}{18}}e^{-j\frac{\pi}{4}}. \end{aligned}\] If \(H(s)\) has multiple poles and zeros, then the magnitude and phase of \(H(s)\) can be represented in terms of the magnitude and phase of the poles and zeros. For example, suppose that \[H(s) = \frac{K(s+z_1)(s+z_2)\dots(s+z_m)}{(s+p_1)(s+p_2)\dots(s+p_n)}.\] Since \((s+a)\) is a complex number for any \(s\), it can be written in polar form as \(s+a=\left|s+a\right|e^{j\angle(s+a)}\), therefore \[\begin{aligned} H(s) &= \frac{K(s+z_1)(s+z_2)\dots(s+z_m)}{(s+p_1)(s+p_2)\dots(s+p_n)} \\ &= \frac{\left|K\right|e^{j\angle K} \left|s+z_1\right|e^{j\angle(s+z_1)}\left|s+z_2\right|e^{j\angle(s+z_2)}\dots\left|s+z_m\right|e^{j\angle(s+z_m)}} {\left|s+p_1\right|e^{j\angle(s+p_1)}\left|s+p_2\right|e^{j\angle(s+p_2)}\dots\left|s+p_n\right|e^{j\angle(s+p_n)}} \\ &= \frac{\left|K\right|\left|s+z_1\right|\left|s+z_2\right|\dots\left|s+z_m\right|}{\left|s+p_1\right|\left|s+p_2\right|\dots\left|s+p_n\right|} \frac{e^{j\angle K} e^{j\angle(s+z_1)}e^{j\angle(s+z_2)}\dots e^{j\angle(s+z_m)}}{e^{j\angle(s+p_1)}e^{j\angle(s+p_2)}\dots e^{j\angle(s+p_n)}} \\ &= \frac{\left|K\right|\left|s+z_1\right|\left|s+z_2\right|\dots\left|s+z_m\right|}{\left|s+p_1\right|\left|s+p_2\right|\dots\left|s+p_n\right|} e^{j\left(\angle K + \sum_{i=1}^m \angle (s+z_i) - \sum_{i=1}^n \angle (s+p_i)\right)}. \end{aligned}\] Therefore \begin{align} \left|H(s)\right| &= \frac{\left|K\right|\left|s+z_1\right|\left|s+z_2\right|\dots\left|s+z_m\right|}{\left|s+p_1\right|\left|s+p_2\right|\dots\left|s+p_n\right|} \tag{15.2}\\ \angle H(s) &= \angle K + \sum_{i=1}^m \angle (s+z_i) - \sum_{i=1}^n \angle (s+p_i). \tag{15.3} \end{align}

15.1.2 Frequency Response of LTI Systems

In systems theory, the magnitude and phase representations of the transfer function \(H(s)\) are used because they have important physical meaning. In particular, suppose that \(H(s)\) represents a physical system with input \(u(t)\) and output \(y(t)\) as shown in Fig. 15.2.

LTI system represented by the transfer function H(s) with input u(t) and output y(t).

If the input to the system is given by a sinusoid of magnitude \(A\) and frequency \(\omega_0\), i.e., \[u(t) = A\sin(\omega_0t),\] then the output is given by \[\tag{15.4} y(t) = A\left|H(j\omega_0)\right|\sin(\omega_0 t + \angle H(j\omega_0)).\] Therefore, the transfer function \(H(s)\) is an elegant and compact representation of the frequency response of the system, in that the magnitude of \(H(j\omega_0)\) describes the gain of the system for input signals with frequency \(\omega_0\), and the phase of \(H(j\omega_0)\) describes the phase shift imposed by the system on input signals with frequency \(\omega_0\). For example, Fig. 15.3 shows the input-output response of an LTI system with transfer function \(H(s)=\frac{1}{s+1}\). The input signal, which is shown in grey, is \(u(t)=\sin(\omega_0 t)\) where \(\omega_0\) changes in each subplot. The output signal is shown in blue and is given by Equation 15.4. Note that in subplot (a) the time scale is different from that of the other subplots. When \(\omega_0=0.1\), \(H(j\omega_0)\approx 0.995e^{j5^\circ}\). Accordingly, in subplot (a), the output is only slightly attenuated, with very little phase shift. In contrast, when \(\omega_0=5\), \(H(j\omega_0)\approx 0.2 e^{j80^\circ}\), and in subplot (f) we see that the output is approximately 20% of the input with a phase shift approaching \(90\) degrees.

Frequency response to LTI system with transfer function H(s)=1/(s+1).

Chapter 15 interactive figure

Sinusoidal input and steady-state output

For H(s)=1/(s+1), move the input frequency. The output amplitude and phase shift are computed from H(jω), then plotted against the input signal.

Interactive Figure 15.I1. Move the input frequency to see how H(jw) changes the output amplitude and phase.

|H(jω)|
Phase shift
Interpretation

Therefore, the response of an LTI system to inputs at different frequencies can be visualized by plotting the magnitude and phase of \(H(j\omega)\) as a function of \(\omega\). The frequency response of \(H(s)=1/(s+1)\) is plotted in two different ways in Fig. 15.4. In subfigure (a) a linear scale is used for both \(\left|H(j\omega)\right|\) and \(\angle H(j\omega)\), as well as the frequency scale \(\omega\). In subfigure (b), the scale for magnitude is in dB: \(20\log\left|H(j\omega)\right|\) whereas the scale for \(\angle H(j\omega)\) is linear, however, in both cases a log scale for \(\omega\) is used on the \(x\)-axis. The plot in subfigure (b) is called a Bode plot. It should be clear from Fig. 15.4 that the Bode plot provides much more useful information than a linear plot since it more effectively reveals the behavior of the system at lower frequencies. For this reason, Bode plots are the most common method to display the frequency response of the system.

Frequency response of H(s)=1/(s+1) on a linear scale (a), and a logarithmic scale (b).

Chapter 15 interactive figure

Linear scale versus Bode scale

For H(s)=1/(s+1), move the frequency marker. The left plot uses linear magnitude and linear frequency; the right plot shows the same response as a Bode plot with dB magnitude and log frequency.

Interactive Figure 15.I2. Compare the same frequency response on a linear plot and on a Bode plot. The shaded area on the linear plot shows how low-frequency behavior is compressed when many decades are shown on a linear axis.

Selected frequency
|H(jω)|
20log10|H(jω)|
∠H(jω)
Interpretation
dB conversion reference: 0 dB → |H| = 1 -3 dB → |H| ≈ 0.707 -20 dB → |H| = 0.1 -40 dB → |H| = 0.01

Check your interpretation

Why is the Bode plot more useful here?

As a note, since the magnitude of \(H(j\omega)\) is displayed on the Bode plot as \(20\log\left|H(j\omega)\right|\) in units of dB, note that \(20\log\left|H(j\omega)\right|=0\) dB implies that \(\left|H(j\omega)\right|=1\). Similarly, \(20\log\left|H(j\omega)\right|=20\) dB implies that \(\left|H(j\omega)\right|=10\) and \(20\log\left|H(j\omega)\right|=40\) dB implies that \(\left|H(j\omega)\right|=100\). Going in the other direction, \(20\log\left|H(j\omega)\right|=-20\) dB implies that \(\left|H(j\omega)\right|=0.1\), and \(20\log\left|H(j\omega)\right|=-40\) dB implies that \(\left|H(j\omega)\right|=0.01\). In general, \[20\log\left|H(j\omega)\right|=20n\text{~dB~} \implies \left|H(j\omega)\right|=10^n.\]

15.1.3 Straight-line Approximations for Bode Plots

While the Bode plot for a system can be easily generated using the MATLAB or Python bode command, it is still useful to understand how to approximately draw a Bode plot by hand. The reason for this is that in the loop-shaping design methodology, we add elements to the control transfer function \(C(s)\) to "shape" the Bode plot of the loop gain \(P(s)C(s)\) where \(P(s)\) is the transfer function of the plant. Learning to approximately draw the Bode plot by hand will provide helpful insights into this process. Therefore, in this section we provide a brief tutorial on how to approximate the Bode plot for a transfer function \(H(s)\).

We start by putting the transfer function into Bode canonical form by factoring out the poles and zeros as follows: \[\begin{aligned} H(s) &= \frac{K(s+z_1)(s+z_2)\dots(s+z_m)}{(s+p_1)(s+p_2)\dots(s+p_n)} \\ &= \frac{Kz_1z_2\dots z_m}{p_1p_2\dots p_n}\frac{(1+s/z_1)(1+s/z_2)\dots(1+s/z_m)}{(1+s/p_1)(1+s/p_2)\dots(1+s/p_n)}. \end{aligned}\] Therefore, following Equations 15.2 and 15.3 we have \begin{align} \left|H(j\omega)\right| &= \left|\frac{Kz_1z_2\dots z_m}{p_1p_2\dots p_m}\right| \frac{\left|1+j\omega/z_1\right|\left|1+j\omega/z_2\right|\dots\left|1+j\omega/z_m\right|}{\left|1+j\omega/p_1\right|\left|1+j\omega/p_2\right|\dots\left|1+j\omega/p_n)\right|} \tag{15.5}\\ \angle H(j\omega) &= \angle \left(\frac{Kz_1z_2\dots z_m}{p_1p_2\dots p_m}\right) + \sum_{i=1}^m \angle (1+j\omega/z_i) - \sum_{i=1}^n \angle (1+j\omega/p_i). \tag{15.6} \end{align} Since \(20\log\left|AB\right|=20\log\left|A\right|+20\log\left|B\right|\), Equation 15.5 gives \begin{gather} \tag{15.7} 20\log\left|H(j\omega)\right| = 20\log \left|\frac{Kz_1z_2\dots z_m}{p_1p_2\dots p_m}\right| \\ + \sum_{i=1}^m 20\log\left|1+j\omega/z_i\right| - \sum_{i=1}^n 20\log\left|1+j\omega/p_i\right|. \end{gather}

Drawing the Bode plot for a general transfer function with real poles and zeros, can be decomposed into drawing the Bode plot for each pole and zero, and then graphically adding them to get the general Bode plot. Note first that \[20\log \left|\frac{Kz_1z_2\dots z_m}{p_1p_2\dots p_m}\right|\] is not a function of \(\omega\) and is therefore a constant line on the Bode plot. Also note that \[\angle \left(\frac{Kz_1z_2\dots z_m}{p_1p_2\dots p_m}\right)\] is also a constant and is either \(0\) degrees if \(\left(\frac{Kz_1z_2\dots z_m}{p_1p_2\dots p_m}\right)>0\), or \(180\) degrees if \(\left(\frac{Kz_1z_2\dots z_m}{p_1p_2\dots p_m}\right)<0\).

We start by drawing the Bode plot when \(H(s) = s+z\) has a single zero at \(s=-z\) and \(z>0\). The first step is to put the transfer function in Bode canonical form as \[H(j\omega) = z(1+j\frac{\omega}{z}).\] Therefore, from Equation 15.7 we have \[\begin{aligned} 20\log\left|H(j\omega)\right| &= 20\log\left|z\right| + 20\log\left|1+j\frac{\omega}{z}\right| \\&= 20\log\left|z\right| + 20\log\sqrt{1+(\omega/z)^2}. \end{aligned}\] When \(\omega/z\ll 1\) we have that \(\sqrt{1+(\omega/z)^2}\approx 1\), implying that \[20\log\left|H(j\omega)\right| \approx 20\log\left|z\right|.\] Note that since this term is not a function of \(\omega\), it is a constant value on the Bode plot. On the other hand, when \(\omega/z \gg 1\) we have that \(\sqrt{1+(\omega/z)^2}\approx \left|\omega/z\right|\), giving \[20\log\left|H(j\omega)\right| \approx 20\log\left|z\right| + 20\log\left|\omega/z\right|.\] Note that the second term is a straight line on a Bode plot that intersects the \(0\) dB axis at \(\omega=z\) and increases \(20\) dB for every factor of 10 increase in \(\omega\). Therefore, on the Bode plot, the slope of the second term is \(+20\) dB/decade. A straight-line approximation is shown in Fig. 15.5, along with the Bode plot produced by MATLAB.

Straight-line approximation for a single zero.

Note that the largest mismatch between the straight-line approximation and the actual Bode plot is at \(\omega=z\). In that case we have \[20\log\left|H(jz)\right| \approx 20\log\left|z\right| + 20\log\sqrt{2}=20\log\left|z\right| + 3~dB.\] Therefore, at the corner frequency \(z\) the Bode plot is \(3\) dB above the low frequency response.

To approximate the phase plot, note that \[\tag{15.8} \angle H(j\omega) = \angle z(1+j\omega/z) =\tan^{-1}\frac{\omega}{z}.\] When \(\omega=z\) we have that \(\tan^{-1} 1 = 45\) degrees. When \(\omega\ll z\), we have that \(\tan^{-1}(\omega/z)\approx 0\) degrees, and when \(\omega\gg z\), we have that \(\tan^{-1}(\omega/z)\approx 90\) degrees. The phase plot as calculated by MATLAB is shown in Fig. 15.5. An adequate straight-line approximation is obtained by setting the phase to zero when \(\omega<z/10\), i.e., one decade less than \(z\), and setting the phase to \(90\) degrees when \(\omega>10z\), i.e., one decade greater than \(z\), and drawing a straight line between those points so that the phase at \(z\) is \(45\) degrees. The straight-line approximation for the phase is also shown in black in Fig. 15.5.

The straight-line approximation for phase as described above assumes that \(z>0\), i.e., that the zero is in the left half of the complex plane. For right-half-plane zeros when \(z<0\), the phase as calculated in Equation 15.6 is \[\angle H(j\omega) = \angle z + \angle (1+j\omega/z) = 180^\circ - \tan^{-1}\frac{\omega}{\left|z\right|}.\] Therefore, the phase starts at \(180\) degrees and decreases by \(90\) degrees as \(\omega\) gets large rather than increases. Fig. 15.6 shows the Bode plot and its straight-line approximation when the zero is in the right half-plane. When a system has a zero in the right half-plane, it is called non-minimum phase because of the \(180\) degree phase increase at low frequencies.

Straight-line approximation for a zero in the right half of the complex plane.

Now consider drawing the Bode plot for a single pole, i.e., \(H(s) = \frac{p}{s+p}\), which has a single pole at \(s=-p\) which is in the right half-plane when \(p>0\). In Bode canonical form \(H(s)\) becomes \[H(j\omega) = \frac{1}{1+j\frac{\omega}{p}}.\] Therefore, from Equation 15.7 we have \[\begin{aligned} 20\log\left|H(j\omega)\right| &= 20\log\left|1\right| - 20\log\left|1+j\frac{\omega}{p}\right| \\&= - 20\log\sqrt{1+(\omega/p)^2}. \end{aligned}\] When \(\omega/p\ll 1\), we have that \(\sqrt{1+(\omega/p)^2}\approx 1\), implying that \[20\log\left|H(j\omega)\right| \approx 0.\] Note that since this term is not a function of \(\omega\), it is a constant value at \(0\) dB on the Bode plot. On the other hand, when \(\omega/p \gg 1\), we have that \(\sqrt{1+(\omega/p)^2}\approx \left|\omega/p\right|\), giving \[20\log\left|H(j\omega)\right| \approx -20\log\left|\omega/p\right|.\] Note that the second term is a straight line on a Bode plot that intersects the \(0\) dB axis when \(\omega=p\) and decreases at \(-20\) dB for every factor of 10 increase in \(\omega\). Therefore, on the Bode plot, the slope of the second term is \(-20\) dB/decade. A straight-line approximation is shown in Fig. 15.7, along with the Bode plot produced by MATLAB.

Straight-line approximation for a single pole.

Note that the largest mismatch between the straight-line approximation and the actual Bode is at \(\omega=p\). In that case, we have \[20\log\left|H(jp)\right| \approx -20\log\sqrt{2}=-3~dB.\] Therefore, at the corner frequency \(p\) the Bode plot is \(3\) dB below the low frequency response.

To approximate the phase plot, note that \[\tag{15.9} \angle H(j\omega) = -\angle (1+j\frac{\omega}{p}) = -\tan^{-1}\frac{\omega}{p}.\] When \(\omega=p\) we have that \(-\tan^{-1} 1 = -45\) degrees. When \(\omega\ll p\), we have that \(-\tan^{-1}(\omega/p)\approx 0\) degrees, and when \(\omega\gg p\), \(-\tan^{-1}(\omega/p)\approx -90\) degrees. The phase plot as calculated by MATLAB is shown in Fig. 15.7. An adequate straight-line approximation is obtained by setting the phase to zero when \(\omega<p/10\), i.e., one decade less than \(p\), and setting the phase to \(-90\) degrees when \(\omega>10p\), i.e., one decade greater than \(p\), and drawing a straight line between those points so that the phase at \(p\) is \(-45\) degrees. The straight-line approximation for the phase is also shown in Fig. 15.7.

The straight-line approximation for phase as described above assumes that \(p>0\), i.e., that the pole is in the left half of the complex plane. For right-half-plane poles when \(p<0\), the phase as calculated in Equation 15.6 is \[\angle H(j\omega) = -\angle (1+j\omega/p) = \tan^{-1}\frac{\omega}{\left|p\right|}.\] Therefore, the phase starts at \(0\) degrees and increases by \(90\) degrees as \(\omega\) gets large. Fig. 15.8 shows the Bode plot and its straight-line approximation when the pole is in the right half-plane. Note that stability and instability are not directly evident from the shapes of the magnitude and phase plots.

Straight-line approximation for a pole in the right half of the complex plane.

Chapter 15 interactive figure

Single pole/zero Bode builder

Choose one first-order factor and move the corner frequency. The plot compares the exact Bode response with the straight-line approximation used for hand sketches.

Interactive Figure 15.I3. Compare exact first-order magnitude and phase with their straight-line approximations.

Magnitude slope
Phase change
Corner value
Guide frequencies

Suppose now that the poles are complex. Let \[H(s)=\frac{\omega_n^2}{s^2+2\zeta\omega_ns+\omega_n^2}.\] In Bode canonical form we have \[\begin{aligned} H(j\omega) &= \frac{1}{\omega_n^2}\frac{\omega_n^2}{\frac{(j\omega)^2}{\omega_n^2} + 2\zeta\omega_n\left(\frac{j\omega}{\omega_n^2}\right) + 1}\\ &= \frac{1}{\left(1-\left(\frac{\omega}{\omega_n}\right)^2\right) + j 2\zeta\left(\frac{\omega}{\omega_n}\right)} \\ &= \frac{1}{\sqrt{\left(1-\frac{\omega^2}{\omega_n^2}\right)^2 + 4\zeta^2\frac{\omega^2}{\omega_n^2}}} e^{-j\tan^{-1}\left(\frac{2\zeta\frac{\omega}{\omega_n}}{1-\frac{\omega^2}{\omega_n^2}}\right)}. \end{aligned}\] Therefore \[\begin{aligned} \left|H(j\omega)\right| &= \frac{1}{\sqrt{\left(1-\frac{\omega^2}{\omega_n^2}\right)^2 + 4\zeta^2\frac{\omega^2}{\omega_n^2}}} \\ \angle H(j\omega) &= -\tan^{-1}\left(\frac{2\zeta\frac{\omega}{\omega_n}}{1-\frac{\omega^2}{\omega_n^2}}\right). \end{aligned}\] When \(\omega \ll \omega_n\) we have that \(20\log_{10}\left|H(j\omega)\right|\approx 20\log_{10}\left|1\right| = 0\) dB. Also, \(\angle H(j\omega)\approx -\tan^{-1}\frac{0}{1}=0\) degrees. Alternatively, when \(\omega \gg \omega_n\) we have \[\begin{aligned} 20\log_{10}\left|H(j\omega)\right| &\approx -20\log \sqrt{\left(\frac{\omega^2}{\omega_n^2}\right)^2 + 4\zeta^2\frac{\omega^2}{\omega_n^2}} \\ &\approx -20\log \sqrt{\left(\frac{\omega^2}{\omega_n^2}\right)^2} \\ &\approx -20\log \left|\frac{\omega}{\omega_n}\right|^2 \\ &= -40\log \left|\frac{\omega}{\omega_n}\right|, \end{aligned}\] which is a straight line that crosses the \(0\) dB axis at \(\omega_n\) with a slope of \(-40\) dB/decade. When \(\omega=\omega_n\) we have \(20\log_{10}\left|H(j\omega)\right| = -20\log_{10}\sqrt{4\zeta^2} = -20\log_{10}\left|2\zeta\right|\). When \(\zeta=0.707=\frac{\sqrt{2}}{2}\), then \(20\log_{10}\left|H(j\omega)\right|=-20\log_{10}1/\sqrt{2} =-3\) dB. For the angle plot, when \(\omega \ll \omega_n\) we have \(\angle H(j\omega)\approx \tan^{-1}\frac{0}{1} = 0\) degrees. When \(\omega \gg \omega_n\) we have \(\angle H(j\omega) \approx \tan^{-1}\left(2\zeta \frac{\omega_n}{\omega}\right)\approx -180\) degrees, and when \(\omega=\omega_n\) we have \(\angle H(j\omega)\approx - \tan^{-1}\frac{2\zeta}{0}=-90\) degrees.

The Bode plots for different values of \(\zeta\) are shown in Fig. 15.9.

The Bode plot for a second-order system for various values of \zeta.

Chapter 15 interactive figure

Second-Order System Bode response

Move the damping ratio and natural frequency for H(s) = ωn2 / (s2 + 2ζωns + ωn2). Low damping creates resonant peaking near ωn.

Interactive Figure 15.I4. Move ζ and ωn to see resonant peaking, phase transition, and -40 dB/dec high-frequency rolloff.

Peak magnitude
Phase at ωn
High-frequency slope

15.1.4 Example

Find the straight-line approximation for the Bode plot of the transfer function \[\tag{15.10} H(s) = \frac{20}{s(s+10)}.\] In Bode canonical form we have \[H(j\omega) = \frac{20}{10}\frac{1}{j\omega(1+j\frac{\omega}{10})}.\] Therefore \begin{gather} \tag{15.11} 20\log_{10}\left|H(j\omega)\right|= \\ 20\log_{10} 2 - 20\log_{10}\left|\omega\right| - 20\log_{10}\sqrt{1+\left(\frac{\omega}{10}\right)^2}. \end{gather} Note that the term due to the pole at zero, namely \(-20\log_{10}\left|\omega\right|\) is a straight line that intercepts the \(0\) dB line at \(\omega=1\), and has a slope of \(-20\) dB per decade. Therefore, the Bode plot for magnitude will be the graphical addition of three terms:

  1. A constant term at \(20\log_{10} 2 = 2\) dB,

  2. A straight line with slope of \(-20\) dB/decade, passing through the \(0\) dB line at \(\omega=1\), and

  3. A first order low-pass filter with a cut-off frequency at \(\omega=10\).

Similarly, the phase is given by \[\begin{aligned} \angle H(j\omega) &= \angle 2 - \angle j\omega - \angle (1+j\frac{\omega}{10}) \\ &= 0 - \tan^{-1}\frac{\omega}{0} - \tan^{-1}\frac{\omega}{10} \\ &= - 90^\circ - \tan^{-1}\frac{\omega}{10}. \end{aligned}\] The straight-line approximation and the Bode plot generated by MATLAB are shown in Fig. 15.10.

Bode plot for the transfer function given in Equation 15.10.

Chapter 15 interactive figure

Build Example 15.1.4 term by term

Turn on each factor in H(s) = 20/(s(s+10)) to see how the straight-line magnitude and phase approximations are built by graphical addition. The exact full response stays visible as a reference.

15.1.5 Example

Find the straight-line approximation for the Bode plot of the transfer function \[\tag{15.12} H(s) = \frac{8000(s+1)(s+10)}{(s+2)(s+20)(s+200)}.\] In Bode canonical form we have \[\begin{aligned} H(j\omega) &= \frac{8000\cdot 10}{2\cdot 20\cdot 200}\frac{(1+j\omega)(1+j\frac{\omega}{10})} {(1+j\frac{\omega}{2})(1+j\frac{\omega}{20})(1+j\frac{\omega}{200})} \\ &= 10\frac{(1+j\omega)(1+j\frac{\omega}{10})} {(1+j\frac{\omega}{2})(1+j\frac{\omega}{20})(1+j\frac{\omega}{200})}. \end{aligned}\] Therefore \[\begin{gathered} 20\log_{10}\left|H(j\omega)\right|= 20\log_{10} 10 + 20\log_{10}\left|1+j\omega\right| + \\ 20\log_{10}\left|1+j\frac{\omega}{10}\right| -20\log_{10}\left|1+j\frac{\omega}{2}\right| \\ -20\log_{10}\left|1+j\frac{\omega}{20}\right| -20\log_{10}\left|1+j\frac{\omega}{200}\right|. \end{gathered}\] Therefore, the Bode plot for magnitude will be the graphical addition of a constant gain, two zeros, and three poles. Similarly, the phase is given by \[\begin{gathered} \angle H(j\omega) = \angle 10 + \angle (1+j\omega) + \angle (1+j\frac{\omega}{10}) \\ - \angle (1+j\frac{\omega}{2}) - \angle (1+j\frac{\omega}{20}) - \angle (1+j\frac{\omega}{200}). \end{gathered}\] The straight-line approximation and the Bode plot generated by MATLAB are shown in Fig. 15.11.

Bode plot for the transfer function given in Equation 15.12.

Chapter 15 interactive figure

Build worked examples term by term

Use this review figure to build each worked example the same way as Example 15.1.4: choose the factors, predict the final high-frequency behavior, then compare the individual straight-line terms, their cumulative approximation, and the exact full response.

15.2.1 image Example Problem 3.1.18

Draw by hand the Bode plot of the single-link robot arm from torque \(\tilde{\tau}\) to angle \(\tilde{\theta}\) given that the equilibrium angle is \(\theta_e=0\). Use the bode command (from MATLAB or Python) and compare your results.

Design Study A guided exercise

Build the arm Bode plot

Decompose the arm transfer function into gain, integrator, and first-order pole terms.

Bode plot for the single-link robot arm transfer function.

Use the plotted response to connect the gain, integrator, and pole terms to the magnitude slope and phase trend.

Step 1. Bode building blocks

Step 2. Asymptotic slopes

Step 3. Phase trend

Pseudocode

The complete solution includes Bode-plot generation code. Before opening it, outline how you would define the transfer function, compute the frequency response, and plot magnitude and phase.

This prompt is ungraded. It is intended to connect the Bode construction to the implementation code in the complete solution.

15.3 Design Study B. Inverted Pendulum

15.3.1 image Example Problem 3.2.18

(a) Draw by hand the Bode plot of the inner loop transfer function from force \(F\) to angle \(\theta\) for the inverted pendulum. Use the bode command (from MATLAB or Python) and compare your results.

(b) Draw by hand the Bode plot of the outer loop transfer function from angle \(\theta\) to position \(z\) for the inverted pendulum. Use the bode (from MATLAB or Python) command and compare your results.

Design Study B guided exercise

Decompose the pendulum Bode plots

Classify the inner and outer loop transfer-function factors.

Inner-loop pendulum Bode plot.

The inner loop includes both a left-half-plane pole and a right-half-plane pole.

Step 1. Inner-loop factors

Step 2. Outer-loop factors

Step 3. Comparison method

Pseudocode

The complete solution computes separate inner-loop and outer-loop Bode plots. Before opening it, outline each component separately.

These prompts are ungraded. They are intended to connect the derivation to the implementation code in the complete solution.

15.4 Design Study C. Satellite Attitude Control

15.4.1 image Example Problem 3.3.18

(a) Draw by hand the Bode plot of the inner loop transfer function from torque \(\tau\) to angle \(\theta\) for the satellite attitude problem. Use the bode command (from MATLAB or Python) and compare your results.

(b) Draw by hand the Bode plot of the outer loop transfer function from body angle \(\theta\) to panel angle \(\phi\) for the satellite attitude problem. Use the bode command (from Python or MATLAB) and compare your results.

Design Study C guided exercise

Build satellite Bode plots

The inner loop behaves like two integrators; the outer loop contains a lightly damped flexible mode.

Step 1. Inner plant structure

Step 2. Outer plant structure

Step 3. Physical interpretation

15.5 Interactive Frequency-Response Check

Chapter 15 activity

Complex response readout

Move the real and imaginary parts of H(jω). The readout connects rectangular form, magnitude, phase, and dB magnitude, which are the same quantities used to build Bode plots.

Figure 1.5. The sliders move the complex frequency-response vector and change its magnitude and phase.
Rectangular form
Magnitude
Phase
Magnitude in dB

Coding-lab preparation: evaluating a frequency response means substituting s = jw, then computing magnitude, phase, and dB values over a frequency grid.

15.6 Coding Lab: Frequency Response Evaluation

Objective: evaluate a transfer function on the imaginary axis and compute Bode magnitude and phase.

Evaluation criteria: the lab checks complex substitution at s = jw, vectorized array output, magnitude in dB, and phase in degrees.

Figure 15.1 (Interactive). Frequency-response coding lab comparing student and reference Bode calculations.

15.7 Knowledge Check

Q1. Frequency-response substitution

Frequency response is found by evaluating a transfer function at:

Q2. Pole slope

A pole typically changes the high-frequency magnitude slope by:

Q3. Complex magnitude

Enter the magnitude of the complex number 3 + j4.

Show solution

Answer: 5 because sqrt(3^2 + 4^2) = 5.

Q4. dB conversion

Enter 20 log10(0.1) in dB.

Show solution

Answer: -20 dB because log10(0.1) = -1.

Q5. Sinusoidal steady-state output

For stable G(s) = 3/(s + 4) and input u(t) = 2 sin(t), which steady-state output is closest?

Q6. Complex substitution

What substitution converts a transfer function G(s) into its frequency response?

Q7. Net Bode slope

At frequencies well above both break frequencies, what net magnitude-slope change comes from one pole and one zero?

Q8. dB conversion

Which dB value is closest to a magnitude ratio of 0.5?

Q9. Phase-lead interpretation

Which statement best describes the effect of increasing the lead parameter M in a phase-lead block?

15.8 Notes and References

A good introduction to frequency response for linear time-invariant system is [16]. A good overview of the Bode plot and straight-line approximations to the Bode plot is contained in [4] and many other introductory textbooks on feedback control.

16 Frequency Domain Specifications

16.1 Theory

In this chapter we show how the magnitude of the frequency response of the open-loop system can be used to determine the performance of the closed-loop feedback system. A general feedback loop is shown in Fig. 16.1. In this feedback system, \(r(t)\) is the reference input to be tracked by \(y(t)\), \(d_{in}(t)\) is an unknown input disturbance, \(d_{out}\) is an unknown output disturbance, and \(n(t)\) is an unknown noise signal. Note that because of the presence of \(n\), the error signal \(e=r-y\) is no longer the input to \(C(s)\). The input to \(C(s)\) is now \(r-y-n\). Note that this definition differs from the one used in Chapter 12 and will result in a different transfer function between the error and the noise. To find the transfer function from the inputs \(r\), \(d_{in}\), \(d_{out}\), and \(n\) to the error \(e(t)\) we start by finding the transfer functions to \(y\). Starting at \(Y(s)\) and following the loop backward until returning to \(Y\) we get \begin{align} & Y(s) = -D_{out}(s) + P \left( - D_{in}(s) + C\left(R(s) - N(s) - Y(s)\right) \right) \notag \\ \implies & (1+PC) Y(s) = PC R(s) - PC N(s) - D_{out}(s) - P D_{in}(s) \notag \\ & Y(s) = \frac{PC}{1+PC}R(s) - \frac{PC}{1+PC} N(s) % - \frac{1}{1+PC} D_{out}(s) - \frac{P}{1+PC} D_{in}(s). \tag{16.1} \end{align} Defining the error to be \(E(s) \stackrel{\triangle}{=}R(s)-Y(s)\) we get \begin{align} E(s) &= R(s) - Y(s) \\ % &= \frac{1}{1+PC}R(s) + \frac{PC}{1+PC} N(s) % + \frac{1}{1+PC} D_{out}(s) + \frac{P}{1+PC} D_{in}(s), \tag{16.3} \end{align} Therefore,

  1. The transfer function from the reference \(r\) to the error \(e\) is \(\frac{1}{1+P(s)C(s)}\),

  2. The transfer function from the noise \(n\) to the error \(e\) is \(\frac{P(s)C(s)}{1+P(s)C(s)}\),

  3. The transfer function from the output disturbance \(d_{out}\) to the error \(e\) is \(\frac{1}{1+P(s)C(s)}\), and

  4. The transfer function from the input disturbance \(d_{in}\) to the error \(e\) is \(\frac{P(s)}{1+P(s)C(s)}\).

General feedback loop.

Chapter 16 activity

Trace the error transfer path

Select one input signal and follow how it appears in the error equation. The highlighted path reinforces why different specifications use different closed-loop transfer functions.

Figure 1.6. The selected path shows which blocks determine the transfer function from the chosen input to the error signal.

Selected path

Transfer to error:

Specification connection:

For typical applications, we have that

  1. The reference signal \(r(t)\) is a low frequency signal with frequency content below \(\omega_r\),

  2. The noise signal \(n(t)\) is a high frequency signal with frequency content above \(\omega_{\mathit{no}}\),

  3. The output disturbance signal \(d_{out}(t)\) is a low frequency signal with frequency content below \(\omega_{d_{out}}\),

  4. The input disturbance signal \(d_{in}(t)\) is a low frequency signal with frequency content below \(\omega_{d_{in}}\).

The objective for the control design is to find \(C(s)\) so that the following specifications are satisfied:

  1. Tracking: Track reference signals \(r(t)\) with frequency content below \(\omega_r\) so that the error due to the reference signal satisfies \[\left|e(t)\right|\leq \gamma_r\left|r(t)\right|,\]

  2. Noise Attenuation: Attenuate noise signals \(n(t)\) with frequency content above \(\omega_{no}\) so that the error due to the noise signal satisfies \[\left|e(t)\right|\leq \gamma_n\left|n(t)\right|,\]

  3. Reject Output Disturbances: Reject output disturbance signals \(d_{out}(t)\) with frequency content below \(\omega_{d_{out}}\) so that the error due to the output disturbance signal satisfies \[\left|e(t)\right|\leq \gamma_{d_{out}}\left|d_{out}(t)\right|,\]

  4. Reject Input Disturbances: Reject input disturbance signals \(d_{in}(t)\) with frequency content below \(\omega_{d_{in}}\) so that the error due to the input disturbance signal satisfies \[\left|e(t)\right|\leq \gamma_{d_{in}}\left|d_{in}(t)\right|.\]

The objective in the remainder of this chapter is to show how each of these specifications can be translated into a requirement on the magnitude of the (open) loop gain \(20\log_{10}\left|P(j\omega)C(j\omega)\right|\).

16.1.1 Tracking

The transfer function from the reference signal \(r(t)\) to the error \(e(t)\) is \[E(s) = \frac{1}{1+P(s)C(s)}R(s).\] Therefore, \[\left|E(j\omega)\right| \leq \left|\frac{1}{1+P(j\omega)C(j\omega)}\right|\left|R(j\omega)\right|.\] The objective is to track reference signals \(r(t)\) with frequency content below \(\omega_r\) so that the error due to the reference signal satisfies \[\left|e(t)\right|\leq \gamma_r \left|r(t)\right|.\] Therefore, the controller \(C(s)\) needs to be designed so that \[\left|\frac{1}{1+P(j\omega)C(j\omega)}\right| \leq \gamma_r,\] or equivalently so that \[\left|1+P(j\omega)C(j\omega)\right| \geq \frac{1}{\gamma_r}.\] If \(\left|P(j\omega)C(j\omega)\right|\gg 1\), then a sufficient condition is that \[\left|P(j\omega)C(j\omega)\right| \geq \frac{1}{\gamma_r},\] or equivalently \[\tag{16.4} 20\log_{10}\left|P(j\omega)C(j\omega)\right| \geq 20\log_{10}1/\gamma_r,\] which needs to be satisfied for all \(\omega\leq\omega_r\). On a Bode plot, the constraint represented by Equation 16.4 is shown graphically in Fig. 16.2.

Bode plot representation of the loop-shaping constraint corresponding to tracking r(t) so that the corresponding error satisfies \left|e(t)\right|\leq\gamma_r\left|r(t)\right|.

Alternatively, from the Bode plot of \(PC\) we can compute the tracking characteristics of the closed-loop system. For example, suppose that on the Bode plot \[20\log_{10}\left|P(j\omega)C(j\omega)\right|> B_r\text{~dB}\] for all \(\omega<\omega_r\), then \[\left|P(j\omega)C(j\omega)\right|> 10^{B_r/20},\] for all \(\omega<\omega_r\). If \(\left|P(j\omega)C(j\omega)\right|\gg 1\) for all \(\omega<\omega_r\), then \[\left|\frac{1}{1+P(j\omega)C(j\omega)}\right|\lessapprox 10^{-B_r/20},\] which implies that \[\left|E(j\omega)\right| \leq 10^{-B_r/20} \left|R(j\omega)\right|\] for all \(\omega<\omega_r\), or in other words that \[\tag{16.5} \left|e(t)\right| \leq 10^{-B_r/20} \left|r(t)\right|,\] for all \(r(t)\) with frequency content below \(\omega_r\), which implies that \[\gamma_r = 10^{-B_r/20}.\]

16.1.2 Noise Attenuation

The transfer function from the noise signal \(n(t)\) to the error \(e(t)\) is \[E(s) = \frac{P(s)C(s)}{1+P(s)C(s)}N(s).\] Therefore, \[\left|E(j\omega)\right| \leq \left|\frac{P(j\omega)C(j\omega)}{1+P(j\omega)C(j\omega)}\right|\left|N(j\omega)\right|.\] The objective is to attenuate noise signals \(n(t)\) with frequency content above \(\omega_{no}\) so that the error due to the noise signal satisfies \[\left|e(t)\right|\leq \gamma_n \left|n(t)\right|.\] Therefore, the controller \(C(s)\) needs to be designed so that \[\left|\frac{P(j\omega)C(j\omega)}{1+P(j\omega)C(j\omega)}\right| \leq \gamma_n.\] If \(\left|P(j\omega)C(j\omega)\right|\ll 1\), then a sufficient condition is that \[\left|P(j\omega)C(j\omega)\right| \leq \gamma_n,\] or equivalently \[\tag{16.6} 20\log_{10}\left|P(j\omega)C(j\omega)\right| \leq 20\log_{10}\gamma_n,\] which needs to be satisfied for all \(\omega\geq\omega_{no}\). On a Bode plot, the constraint represented by Equation 16.6 is shown graphically in Fig. 16.3.

Bode plot representation of the loop-shaping constraint corresponding to attenuating the noise n(t) so that the corresponding error satisfies \left|e(t)\right|\leq\gamma_n\left|n(t)\right|.

Alternatively, from the Bode plot of \(PC\) we can compute the noise attenuation characteristics of the closed-loop system. For example, suppose that on the Bode plot \[20\log_{10}\left|P(j\omega)C(j\omega)\right|< -B_n\text{~dB}\] for all \(\omega>\omega_{no}\), then \[\left|P(j\omega)C(j\omega)\right|< 10^{-B_n/20},\] for all \(\omega>\omega_{no}\). If \(P(j\omega)C(j\omega)\ll 1\) for all \(\omega>\omega_{no}\), then \[\left|\frac{P(j\omega)C(j\omega)}{1+P(j\omega)C(j\omega)}\right|\lessapprox 10^{-B_n/20},\] which implies that \[\left|E(j\omega)\right| \leq 10^{-B_n/20} \left|N(j\omega)\right|\] for all \(\omega>\omega_{no}\), or in other words that \[\left|e(t)\right| \leq 10^{-B_n/20} \left|n(t)\right|,\] for all \(n(t)\) with frequency content above \(\omega_{no}\), which implies that \[\gamma_n = 10^{-B_n/20}.\]

16.1.3 Reject Output Disturbances

The transfer function from the output disturbance signals \(d_{out}(t)\) to the error \(e(t)\) is \[E(s) = \frac{1}{1+P(s)C(s)}D_{out}(s).\] Therefore, \[\left|E(j\omega)\right| \leq \left|\frac{1}{1+P(j\omega)C(j\omega)}\right|\left|D_{out}(j\omega)\right|.\] The objective is to attenuate output disturbance signals \(d_{out}(t)\) with frequency content below \(\omega_{d_{out}}\) so that the error due to the output disturbance signal satisfies \[\left|e(t)\right|\leq \gamma_{d_{out}} \left|d_{out}(t)\right|.\] Therefore, the controller \(C(s)\) needs to be designed so that \[\left|\frac{1}{1+P(j\omega)C(j\omega)}\right| \leq \gamma_{d_{out}},\] or equivalently so that \[\left|1+P(j\omega)C(j\omega)\right| \geq \frac{1}{\gamma_{d_{out}}}.\] If \(\left|P(j\omega)C(j\omega)\right|\gg 1\), then a sufficient condition is that \[\left|P(j\omega)C(j\omega)\right| \geq \frac{1}{\gamma_{d_{out}}},\] or equivalently \[\tag{16.7} 20\log_{10}\left|P(j\omega)C(j\omega)\right| \geq 20\log_{10}1/\gamma_{d_{out}},\] which needs to be satisfied for all \(\omega\leq\omega_{d_{out}}\). On a Bode plot, the constraint represented by Equation 16.7 is shown graphically in Fig. 16.4.

Bode plot representation of the loop-shaping constraint corresponding to rejecting the output disturbance d_{out}(t) so that the corresponding error satisfies \left|e(t)\right|\leq\gamma_{d_{out}}\left|d_{out}(t)\right|.

Alternatively, from the Bode plot of \(PC\) we can compute the output disturbance rejection characteristics of the closed-loop system. For example, suppose that on the Bode plot \[20\log_{10}\left|P(j\omega)C(j\omega)\right|> B_{d_{out}}\text{~dB}\] for all \(\omega<\omega_{d_{out}}\), then \[\left|P(j\omega)C(j\omega)\right|> 10^{B_{d_{out}}/20},\] for all \(\omega<\omega_{d_{out}}\). If \(\left|P(j\omega)C(j\omega)\right|\gg 1\) for all \(\omega<\omega_{d_{out}}\), then \[\left|\frac{1}{1+P(j\omega)C(j\omega)}\right|\lessapprox 10^{-B_{d_{out}}/20},\] which implies that \[\left|E(j\omega)\right| \leq 10^{-B_{d_{out}}/20} \left|D_{out}(j\omega)\right|\] for all \(\omega<\omega_{d_{out}}\), or in other words that \[\left|e(t)\right| \leq 10^{-B_{d_{out}}/20} \left|d_{out}(t)\right|,\] for all \(d_{out}(t)\) with frequency content below \(\omega_{d_{out}}\), which implies that \[\gamma_{d_{out}} = 10^{-B_{d_{out}}/20}.\]

16.1.4 Reject Input Disturbances

The transfer function from the input disturbance signals \(d_{in}(t)\) to the error \(e(t)\) is \[E(s) = \frac{P(s)}{1+P(s)C(s)}D_{in}(s).\] Therefore, \[\left|E(j\omega)\right| \leq \left|\frac{P(j\omega)}{1+P(j\omega)C(j\omega)}\right|\left|D_{in}(j\omega)\right|.\] The objective is to attenuate input disturbance signals \(d_{in}(t)\) with frequency content below \(\omega_{d_{in}}\) so that the error due to the input disturbance signal satisfies \[\left|e(t)\right|\leq \gamma_{d_{in}} \left|d_{in}(t)\right|.\] Therefore, the controller \(C(s)\) needs to be designed so that \[\left|\frac{P(j\omega)}{1+P(j\omega)C(j\omega)}\right| \leq \gamma_{d_{in}},\] or equivalently so that \[\frac{\left|1+P(j\omega)C(j\omega)\right|}{\left|P(j\omega)\right|} \geq \frac{1}{\gamma_{d_{in}}}.\] If \(\left|P(j\omega)C(j\omega)\right|\gg 1\), then a sufficient condition is that \[\frac{\left|P(j\omega)C(j\omega)\right|}{\left|P(j\omega)\right|} \geq \frac{1}{\gamma_{d_{in}}},\] or equivalently \[\tag{16.8} 20\log_{10}\left|P(j\omega)C(j\omega)\right| - 20\log_{10}\left|P(j\omega)\right| \geq 20\log_{10}1/\gamma_{d_{in}},\] which needs to be satisfied for all \(\omega\leq\omega_{d_{in}}\). On a Bode plot, the constraint represented by Equation 16.8 is shown graphically in Fig. 16.5, where it can be seen that the loop gain \(\left|PC\right|\) must be above the magnitude of the plant \(\left|P\right|\) by the specified amount.

Bode plot representation of the loop-shaping constraint corresponding to rejecting the input disturbance d_{in}(t) so that the corresponding error satisfies \left|e(t)\right|\leq\gamma_{d_{in}}\left|d_{in}(t)\right|.

Alternatively, from the Bode plot of \(PC\) we can compute the input disturbance rejection characteristics of the closed-loop system. For example, suppose that on the Bode plot \[20\log_{10}\left|P(j\omega)C(j\omega)\right|-20\log_{10}\left|P(j\omega)\right|> B_{d_{in}}\text{~dB}\] for all \(\omega<\omega_{d_{in}}\), then \[\frac{\left|P(j\omega)C(j\omega)\right|}{\left|P(j\omega)\right|}> 10^{B_{d_{in}}/20},\] for all \(\omega<\omega_{d_{in}}\). If \(\left|P(j\omega)C(j\omega)\right|\gg 1\) for all \(\omega<\omega_{d_{in}}\), then \[\left|\frac{P(j\omega)}{1+P(j\omega)C(j\omega)}\right|\lessapprox 10^{-B_{d_{in}}/20},\] which implies that \[\left|E(j\omega)\right| \leq 10^{-B_{d_{in}}/20} \left|D_{in}(j\omega)\right|\] for all \(\omega<\omega_{d_{in}}\), or in other words that \[\tag{16.9} \left|e(t)\right| \leq 10^{-B_{d_{in}}/20} \left|d_{in}(t)\right|,\] for all \(d_{in}(t)\) with frequency content below \(\omega_{d_{in}}\), which implies that \[\gamma_{d_{in}} = 10^{-B_{d_{in}}/20}.\]

16.1.5 Frequency Response Characterization of System Type

Recall that the loop gain \(P(s)C(s)\) is said to be

  • Type 0 if there are no free integrators,

  • Type 1 if there is one free integrator,

  • Type 2 if there are two free integrators, etc.

15.1.5.1 Type 0 System

Note that for a type 0 system \[\begin{aligned} & \lim_{s\to 0} P(s)C(s) = \text{~constant} \\ \implies & \lim_{\omega\to 0}\left|P(j\omega)C(j\omega)\right| = \text{~constant} \\ \implies & \lim_{\omega\to 0} 20\log_{10}\left|P(j\omega)C(j\omega)\right| = \text{~constant}. \end{aligned}\] In other words, at low frequency, the Bode magnitude plot is as shown in Fig. 16.6.

Bode plot of a type 0 system.

Recall that for a step input to a type 0 system where \(R(s) = A/s\), the steady-state error is \[e_{ss} = \lim_{t\to \infty} e(t) = \lim_{s\to 0} sE(s) = \lim_{s\to 0} \frac{A}{1+P(s)C(s)} = \frac{A}{1+M_p},\] where \[M_p = \lim_{s\to 0}P(s)C(s) = \lim_{\omega\to 0} \left|P(j\omega)C(j\omega)\right|.\] As shown in Fig. 16.6, \(20\log_{10}M_p\) is the constant limit of the loop gain as \(\omega\to 0\).

Therefore, from the Bode plot of \(PC\) for a type 0 system, we can compute the tracking error for a step input of size \(A\). Suppose that on the Bode plot \[\lim_{\omega\to 0} 20\log_{10}\left|P(j\omega)C(j\omega)\right| = B_0\text{~dB}.\] Then \[M_p = 10^{B_0/20},\] and \[\tag{16.10} \lim_{t\to\infty}\left|e(t)\right| \leq \frac{1}{1+M_p} A.\]

15.1.5.2 Type 1 System

For a type 1 system since \(P(s)C(s)\) has one free integrator \[\begin{aligned} & \lim_{s\to 0} sP(s)C(s) = \text{~constant} \\ \implies & \lim_{\omega\to 0}\left|(j\omega)P(j\omega)C(j\omega)\right| = \text{~constant} \\ \implies & \lim_{\omega\to 0}\frac{\left|P(j\omega)C(j\omega)\right|}{\left|\frac{1}{j\omega}\right|} = \text{~constant} \\ \implies & \lim_{\omega\to 0} \left[ 20\log_{10}\left|P(j\omega)C(j\omega)\right| - 20\log_{10}\left|\frac{1}{j\omega}\right|\right] = \text{~constant}. \end{aligned}\] In other words, at low frequency, the Bode magnitude plot of \(20\log_{10}\left|P(j\omega)C(j\omega)\right|\) has a slope of \(-20\) dB/decade as \(\omega\to 0\), as shown in Fig. 16.7.

Bode plot of a type 1 system.

Recall that for a ramp input to a type 1 system where \(R(s) = A/s^2\), the steady-state error is \[e_{ss} = \lim_{t\to \infty} e(t) = \lim_{s\to 0} sE(s) = \lim_{s\to 0} \frac{A}{s+sP(s)C(s)} = \frac{A}{M_v},\] where \[M_v = \lim_{s\to 0}sP(s)C(s) = \lim_{\omega\to 0} \left|(j\omega)P(j\omega)C(j\omega)\right|.\] As shown in Fig. 16.7, \(20\log_{10}M_v\) is the amount that the loop gain exceeds the Bode plot of \(20\log_{10}\left|1/j\omega\right|\) as \(\omega\to 0\).

Therefore, from the Bode plot of \(PC\) for a type 1 system, we can compute the tracking error for a ramp input with slope \(A\). Suppose that on the Bode plot \[\lim_{\omega\to 0} \left[ 20\log_{10}\left|P(j\omega)C(j\omega)\right| - 20\log_{10}\left|\frac{1}{j\omega}\right| \right] = B_1\text{~dB},\] then \[M_v = 10^{B_1/20},\] and \[\tag{16.11} \lim_{t\to\infty}\left|e(t)\right| \leq \frac{1}{M_v} A.\]

15.1.5.3 Type 2 System

For a type 2 system where \(P(s)C(s)\) has two free integrators we have \[\begin{aligned} & \lim_{s\to 0} s^2P(s)C(s) = \text{~constant} \\ \implies & \lim_{\omega\to 0}\left|(j\omega)^2P(j\omega)C(j\omega)\right| = \text{~constant} \\ \implies & \lim_{\omega\to 0}\frac{\left|P(j\omega)C(j\omega)\right|}{\left|\frac{1}{j\omega}\right|^2} = \text{~constant} \\ \implies & \lim_{\omega\to 0} \left[ 20\log_{10}\left|P(j\omega)C(j\omega)\right| - 20\log_{10}\left|\frac{1}{j\omega}\right|^2\right] = \text{~constant}. \end{aligned}\] In other words, at low frequency, the Bode magnitude plot of \(20\log_{10}\left|P(j\omega)C(j\omega)\right|\) has a slope of \(-40\) dB/decade as \(\omega\to 0\), as shown in Fig. 16.8.

Bode plot of a type 2 system.

Recall that for a parabolic input to a type 2 system where \(R(s) = A/s^3\), the steady-state error is \[e_{ss} = \lim_{t\to \infty} e(t) = \lim_{s\to 0} sE(s) = \lim_{s\to 0} \frac{A}{s^2+s^2P(s)C(s)} = \frac{A}{M_a},\] where \[M_a = \lim_{s\to 0}s^2P(s)C(s) = \lim_{\omega\to 0} \left|(j\omega)^2P(j\omega)C(j\omega)\right|.\] As shown in Fig. 16.8, \(20\log_{10}M_a\) is the amount that the loop gain exceeds the Bode plot of \(20\log_{10}\left|1/j\omega\right|^2\) as \(\omega\to 0\).

Therefore, from the Bode plot of \(PC\) for a type 2 system, we can compute the tracking error for a parabola input with curvature \(A\). Suppose that on the Bode plot \[\lim_{\omega\to 0} \left[ 20\log_{10}\left|P(j\omega)C(j\omega)\right| - 20\log_{10}\left|\frac{1}{j\omega}\right|^2 \right] = B_2\text{~dB}.\] Then \[M_a = 10^{B_2/20},\] and \[\tag{16.12} \lim_{t\to\infty}\left|e(t)\right| \leq \frac{1}{M_a} A.\]

Chapter 16 activity

Measure system type from the low-frequency slope

Use two markers to measure the low-frequency slope of |L(jω)|. The slope tells you how many free integrators are in the loop: 0, 1, or 2. After classifying the type, choose an input class to estimate the corresponding steady-state error constant.

Step 1: measure the low-frequency slope

Place both markers on the low-frequency straight-line part of the Bode magnitude curve.

Marker 1 gain|L(jω1)| = dB
Marker 2 gain|L(jω2)| = dB

slope = (gain2 - gain1) / (log10ω2 - log10ω1) dB/decade

Slope-to-type reference: 0 dB/decade → Type 0 -20 dB/decade → Type 1 -40 dB/decade → Type 2

Figure 1.7. Use the two markers to estimate the low-frequency slope. After the type is classified correctly, the orange guide shows the input class used to measure the relevant error constant.

Step 2: estimate the steady-state error

The input size A scales the final error. It does not move the Bode curve. After the type is classified, compare |L(jω)| with the selected input-class guide to estimate Mp, Mv, or Ma.

System type measurement

Measured slope

Type classification

Measured constant

Steady-state result

Interpretation

16.2.1 image Example Problem 3.1.19

For the single-link robot arm, use the bode command (from MATLAB or Python) to create a graph that simultaneously displays the Bode plots for (1) the plant, (2) the plant under PID control, using the control gains calculated in HW 3.1.13.

(a) To what percent error can the closed-loop system under PID control track the desired input if all of the frequency content of \(\theta_r(t)\) is below \(\omega_r = 0.4\) radians per second?

(b) If the reference input is \(\theta_r(t) = 5t^2\) for \(t\geq 0\), what will the steady-state tracking error to this input be when using PID control?

(c) If all of the frequency content of the input disturbance \(d_{in}(t)\) is below \(\omega_{d_{in}} = 0.01\) radians per second, what percentage of the input disturbance shows up in the output \(\theta\) under PID control?

(d) If all of the frequency content of the noise \(n(t)\) is greater than \(\omega_{no} = 100\) radians per second, what percentage of the noise shows up in the output signal \(\theta\)?

Design Study A guided exercise

Measure frequency-domain specifications

Read tracking, disturbance, and noise bounds as frequency-specific magnitude requirements.

Bode plot for the single-link robot arm with PID control and
specification markers.

Use the marked Bode plot to read the frequency and magnitude values used in the specification checks.

Step 1. Tracking specification variables

Step 2. Convert magnitude bound to percent

Step 3. Identify high and low-frequency specs

16.3 Design Study B. Inverted Pendulum

16.3.1 image Example Problem 3.2.19

For the inner loop of the inverted pendulum, use the bode command (in Python or MATLAB) to create a graph that simultaneously displays the Bode plots for (1) the plant, and (2) the plant under PD control, using the control gains calculated in Homework 3.2.13.

(a) To what percent error can the closed-loop system track the desired input if all of the frequency content of \(\theta_r(t)\) is below \(\omega_r = 1.0\) radians per second?

(b) If all of the frequency content of the sensor noise on the inner \(n(t)\) is greater than \(\omega_{no} = 200\) radians per second, what percentage of the noise shows up in the output signal \(\theta\)?

For the outer loop of the inverted pendulum, use the MATLAB bode command to create a graph that simultaneously displays the Bode plots for the plant, and the plant under PID control, using the control gains calculated in Homework 3.2.13.

(c) If the reference signal \(y_r(t)\) has frequency content below \(\omega_r=0.001\) radians/second, what is the tracking error under PID control if \(\left|r(t)\right|\leq 50\)?

Design Study B guided exercise

Read pendulum frequency-domain specs

Use Bode-plot bounds to estimate tracking and noise attenuation.

Inner-loop pendulum Bode plot with specifications.

Use the markers to connect dB bounds to tracking and noise percentages.

Step 1. Inner-loop tracking frequency

Step 2. Inner-loop noise frequency

Step 3. Outer-loop reference frequency

16.4 Design Study C. Satellite Attitude Control

16.4.1 image Example Problem 3.3.19

For the inner loop of the satellite attitude control, use the bode command to create a graph that simultaneously displays the Bode plots for (1) the plant, and (2) the plant under PD control, using the control gains calculated in Homework 3.3.13.

(a) To what percent error can the closed-loop system under PD control track a step in \(\theta_r(t)=20 t^2\) for \(t\geq0\)?

(b) If the input disturbance has frequency content below \(\omega_{d_{in}}=0.1\) radians per second, what percentage of the input disturbance appears in the output?

For the outer loop of the satellite attitude control, use the bode command to create a graph that simultaneously displays the Bode plots for (1) the plant, (2) the plant under PID control using the control gains calculated in Homework 3.3.13.

(c) If all of the frequency content of the noise \(n(t)\) is greater than \(\omega_{no} = 10\) radians per second, what percentage of the noise shows up in the output signal \(\phi\), using PI control?

Design Study C guided exercise

Read satellite frequency-domain specs

Use Bode-plot offsets to estimate tracking error, disturbance rejection, and noise transmission.

Step 1. Inner-loop tracking type

Step 2. Disturbance frequency

Step 3. Outer-loop noise

16.5 Interactive Specification Check

Chapter 16 activity

Measure frequency-domain specifications

Select a specification, choose a base plant, then set the specification frequency and dB level. The shaded region marks the acceptable part of the loop-gain plot for that frequency-domain requirement.

The amplitude A scales the steady-state error calculation for the system-type cases. It does not move the Bode curves; it changes the computed error for step, ramp, and parabolic reference inputs.

Figure 1.8. The gray curve is the base plant magnitude |P(jω)|. The blue curve is the loop gain |P(jω)C(jω)| after the loop-height offset is applied.

Measured specification

At the selected frequency:

Computed bound:

Interpretation:

16.6 Knowledge Check

Q1. Low-frequency gain

Tracking error is small when low-frequency loop gain is:

Q2. Noise attenuation

Noise attenuation generally requires loop gain to be:

Q3. Sensitivity bound

If a specification requires |S| <= 0.1, enter that bound in dB.

Show solution

Answer: -20 dB because 20 log10(0.1) = -20.

Q4. Loop-gain requirement

Approximately how many dB of loop gain are needed for |S| near 0.1 when L is large?

Show solution

Answer: About 20 dB. When L is large, S is approximately 1/L.

Q5. Output disturbance function

Which closed-loop function is most directly associated with output disturbance rejection?

Show solution

Answer: Sensitivity, S = 1/(1+PC), is the key function for output disturbance and tracking error.

Q6. Noise attenuation bound

If high-frequency sensor noise should contribute less than 1 percent to the output, what magnitude bound should the relevant noise transfer path satisfy?

Q7. Tracking-error function

Which closed-loop function is most directly used to bound low-frequency reference tracking error in unity feedback?

Q8. Disturbance location

Why do input-disturbance and output-disturbance specifications use different transfer paths?

Q9. System type from slope

What low-frequency loop-gain slope indicates one free integrator?

Q10. Why not high gain everywhere?

Why not simply make the loop gain very large at every frequency?

16.7 Notes and References

17 Stability and Robustness Margins

17.1 Theory

17.1.1 Phase and Gain Margins

To achieve the objectives discussed in Chapter 19, the closed-loop system must be stable. Recall that tracking performance and disturbance rejection characteristics are determined by the loop shape at low frequencies when \(\left|P(j\omega)C(j\omega)\right|\gg 1\). Similarly, noise attenuation properties are determined by the loop shape at high frequencies when \(\left|P(j\omega)C(j\omega)\right|\ll 1\). In both cases we ignored the phase of \(P(j\omega)C(j\omega)\). It turns out that stability of the closed-loop system is determined by the phase of \(P(j\omega)C(j\omega)\) when \(P(j\omega)C(j\omega)=1\), as depicted in Fig. 17.1.

The shape of the magnitude plot primarily determines the tracking and disturbance rejection characteristics at low frequencies and the noise attenuation at high frequencies. Stability is primarily determined by the phase at the crossover frequency.

Define the crossover frequency \(\omega_{co}\) to be the frequency where \[\left|P(j\omega_{co})C(j\omega_{co})\right|=1,\] or equivalently where \[20\log_{10}\left|P(j\omega_{co})C(j\omega_{co})\right| = 0\text{~dB}.\] The phase \(\angle P(j\omega_{co})C(j\omega_{co})\) at the crossover frequency plays a critical role in determining the stability of the system. To better understand why this is the case, consider the transfer functions from \(R\), \(D_{in}\), \(D_{out}\), and \(N\), to \(E\) in Equation 16.3. The denominator in each transfer function is \(1+P(s)C(s)\). Therefore, the closed-loop poles are given by the closed-loop characteristic equation \[1+P(s)C(s) = 0,\] or equivalently where \[P(s)C(s) = -1.\]

Recall that for any \(s\), \(P(s)C(s)\) is a complex number with magnitude and phase. Therefore, given any \(s_0\) we can draw \(1+P(s_0)C(s_0)\) in the complex plane as shown in Fig. 17.2.

The plot of 1+P(s_0)C(s_0) in the complex plane, is the sum of the complex number 1+j0 and P(s_0)C(s_0).

Since the physical response of the system is determined by \(P(s)C(s)\) evaluated on the \(j\omega\)-axis, there are stability problems if there exists an \(\omega_0\) such that \(P(j\omega_0)C(j\omega_0)=-1\), or in other words when \[\left|P(j\omega_0)C(j\omega_0)\right|=1 \qquad\text{and}\qquad \angle P(j\omega_0)C(j\omega_0) = -180^\circ,\] as shown in Fig. 17.3.

The plot of 1+P(j\omega_0)C(j\omega_0) in the complex plane when P(j\omega_0)C(j\omega_0)=-1.

Since the magnitude of the loop gain is equal to one at the crossover frequency \(\omega_{co}\), it turns out that the quality of stability is determined by the phase of the loop gain at the crossover frequency. Define the phase margin \(PM\) as \[PM = \angle P(j\omega_{co})C(j\omega_{co}) - (-180)^\circ.\] Fig. 17.4 depicts the phase margin on the Bode plot.

The phase margin PM is the difference between the phase of P(j\omega)C(j\omega) and -180 degrees at the crossover frequency \omega_{co}. The gain margin GM is the magnitude of P(j\omega)C(j\omega) when the phase crosses -180 degrees.

Chapter 17 interactive figure

Measure gain and phase margins on a Bode plot

Move the loop gain and added phase lag. The same loop shape is used in the gain and phase plots, so the crossover markers and margin measurements update together.

Increasing gain usually moves the gain crossover. Adding phase lag directly reduces the phase margin and can reduce the gain margin.

Figure 1.9. Interactive Figure 17.I1. Phase margin is read at gain crossover; gain margin is read at phase crossover.

Gain crossover

Phase crossover

Phase margin

Gain margin

Robustness note

Another way to understand the phase margin is shown in Fig. 17.5. The phase margin indicates the angular distance that \(P(j\omega_{co})C(j\omega_{co})\) is from \(-1\).

Alternative graphical view of the phase margin PM.

A related quantity is the Gain Margin \(GM\), which measures how far the magnitude \(\left|P(j\omega)C(j\omega)\right|\) is from unity when the phase \(\angle P(j\omega)C(j\omega) = -180\) degrees. The gain margin is depicted on the Bode plot in Fig. 17.4. An alternative view is shown in Fig. 17.6.

Alternative graphical view of the gain margin GM.

A good control design will have large phase and gain margins. A phase margin of \(PM=60\) degrees is considered to be very good and is optimal for many applications. A gain margin of \(GM=10\) dB would be considered very good for most applications.

17.1.2 Open and Closed Loop Frequency Response

From Equation 16.1, the transfer function from the reference \(R(s)\) to the output \(Y(s)\) is \[Y(s) = \frac{P(s)C(s)}{1+P(s)C(s)}R(s)\] Note that

  • when \(\left|P(j\omega)C(j\omega)\right|\gg 1\), then \(\left|\frac{P(j\omega)C(j\omega)}{1+P(j\omega)C(j\omega)}\right|\approx 1\),

  • when \(\left|P(j\omega)C(j\omega)\right|\ll 1\), then \(\left|\frac{P(j\omega)C(j\omega)}{1+P(j\omega)C(j\omega)}\right|\approx \left|P(j\omega)C(j\omega)\right|\).

When \(\left|P(j\omega)C(j\omega)\right|=1\), i.e., when \(\omega=\omega_{co}\), then \(\left|\frac{P(j\omega_{co})C(j\omega_{co})}{1+P(j\omega_{co})C(j\omega_{co})}\right|\) is a complex number divided by a complex number, and the magnitude will depend on the phase of the \(P(j\omega_{co})C(j\omega_{co})\), or in other words the phase margin \(PM\). As shown in Figure 17.5, \(PM\) will determine the magnitude of \(1+P(j\omega_{co})C(j\omega_{co})\). When \(PM\) is small, \(\left|1+P(j\omega_{co})C(j\omega_{co})\right|\) will be small and \(\left|\frac{P(j\omega_{co})C(j\omega_{co})}{1+P(j\omega_{co})C(j\omega_{co})}\right|\) will be larger than one. When \(PM\) is larger than \(90\) degrees, \(\left|1+P(j\omega_{co})C(j\omega_{co})\right|\) will be larger than \(\left|P(j\omega_{co})C(j\omega_{co})\right|\) and \(\left|\frac{P(j\omega_{co})C(j\omega_{co})}{1+P(j\omega_{co})C(j\omega_{co})}\right|\) will be less than one.

Fig. 17.7 shows the closed-loop Bode plot superimposed on the open-loop Bode plot for different values of the phase margin. Note that when the phase margin is \(PM=60\) degrees, the closed-loop frequency response looks very similar to the closed-loop frequency response for a second-order system when \(\zeta=0.707\), as shown in Fig. 15.9. Phase margins smaller than \(60\) degrees have a peaking response similar to a second-order system with \(\zeta<0.707\). Note also that the bandwidth of the closed-loop system is approximately the crossover frequency of the open-loop system. In general, the crossover frequency \(\omega_{co}\) plays a similar role for general systems that the natural frequency \(\omega_n\) plays for second-order systems.

Closed-loop Bode plot superimposed on the open-loop Bode plot, together with the closed-loop step response, for different phase margins.

Chapter 17 interactive figure

Phase margin, closed-loop peaking, and ringing

Predict what will happen before moving the slider: if the phase margin decreases, should the closed-loop frequency-response peak and the step-response overshoot increase or decrease? The plots use a second-order approximation to show the trend described in the text.

Figure 1.10. Interactive Figure 17.I3. Smaller phase margin increases the closed-loop resonant peak and step-response overshoot. Faint curves show reference cases at 45, 60, and 80 degrees.

Damping proxy

Closed-loop peak

Step overshoot

Design interpretation

Approximation used

Fig. 17.7 also shows the corresponding step response for the closed-loop system. The step response looks similar to the step response for second-order systems shown in Fig. 8.3, where again, the step response for \(PM=60\) degrees in Fig. 17.7 is roughly equivalent to the step response for \(\zeta=0.707\) in Fig. 8.4.

For a given reference signal, the size of the control signal \(u(t)\) is determined by the crossover frequency. A large crossover frequency will result in a larger control signal \(u(t)\). Fig. 17.8 shows the open and closed-loop transfer functions for a plant equal to \(P(s) = \frac{1}{s(s+1)}\) and for three different controllers that are tuned for equivalent phase margins but with crossover frequency at \(2\), \(20\), and \(200\) respectively. The corresponding control signal when the reference is a unit step is also shown in Fig. 17.8. Note that as \(\omega_{co}\) increases, the magnitude of the control signal increases and the speed of the response also increases. In fact, the integral of the control signals will be the same for each \(\omega_{co}\). Therefore, saturation constraints on \(u(t)\) will necessarily limit the size of the crossover frequency \(\omega_{co}\).

Closed-loop Bode plot superimposed on the open-loop Bode plot, together with the corresponding control signal, for different crossover frequencies.

Chapter 17 interactive figure

Crossover frequency and control effort

Move the crossover frequency while holding a similar phase-margin trend. The response gets faster as ωco increases, but the required control signal grows.

Figure 1.11. Interactive Figure 17.I4. Larger crossover frequency makes the response faster, but actuator effort increases.

Settling-time proxy

Peak control effort

Design warning

17.1.3 Bode Phase Gain Relationship

In Bode’s original work, he proved the following theorem that relates the slope of the magnitude plot to the phase.

. For any stable, minimum phase (i.e., zeros in the LHP), linear time-invariant system \(G(s)\), the phase of \(G(j\omega)\) is uniquely related to \(20\log_{10}\left|G(j\omega)\right|\) by \[\tag{17.1} \angle G(j\omega_0) = \frac{1}{\pi}\int_{-\infty}^{\infty} \left(\frac{dM}{du}\right)W(u)\,du,\] where \[\begin{aligned} M &= 20\log_{10}\left|G(j\omega)\right|, \\ u &= \log_{10}\left|\frac{\omega}{\omega_0}\right|, \\ W(u) &= \log_{10}\left(\coth \frac{\left|u\right|}{2}\right). \end{aligned}\]

The term \(\frac{dM}{du}\) in Equation 17.1 is the slope of the magnitude of \(G(j\omega)\) on the Bode plot. A plot of \(W(u)\) is shown in Fig. 17.9, where it can be seen that \(W(u)\) heavily weights the slope of the Bode magnitude around \(\omega_0\), but also includes bleed-over from the slope for roughly a decade before and after \(\omega_0\). This implies that the phase of \(P(j\omega)C(j\omega)\) at \(\omega=\omega_0\) is determined by the slope of the Bode magnitude plot in a region about \(\omega_0\).

The weighting function W(u) in the Bode gain-phase relationship heavily weights the slope around \omega_0.

Recall that the phase for an integrator \(1/s\) is \(-90\) degrees and that the phase for a differentiator is \(90\) degrees. Also, recall that the phase for a constant is \(0\) degrees. Therefore, we can approximate Equation 17.1 as follows:

  • \(\text{Slope of~} 20\log_{10}\left|G(j\omega_0)\right| \approx +20 \text{~dB/dec~} \\ \implies \angle G(j\omega_0) \approx +90 \text{~deg}\),

  • \(\text{Slope of~} 20\log_{10}\left|G(j\omega_0)\right| \approx 0 \text{~dB/dec~} \\ \implies \angle G(j\omega_0) \approx 0 \text{~deg}\),

  • \(\text{Slope of~} 20\log_{10}\left|G(j\omega_0)\right| \approx -20 \text{~dB/dec~} \\ \implies \angle G(j\omega_0) \approx -90 \text{~deg}\),

  • \(\text{Slope of~} 20\log_{10}\left|G(j\omega_0)\right| \approx -40 \text{~dB/dec~} \\ \implies \angle G(j\omega_0) \approx -180 \text{~deg}\),

  • \(\text{Slope of~} 20\log_{10}\left|G(j\omega_0)\right| \approx -60 \text{~dB/dec~} \\ \implies \angle G(j\omega_0) \approx -270 \text{~deg}\).

Of course, these values are approximate and require that the slope around \(\omega_0\) persist for approximately a decade before and after \(\omega_0\).

While we do not directly use Equation 17.1 in practice, it has clear implications for feedback design. In particular, the takeaway message is that to have a good phase margin, the slope of the Bode magnitude plot at the crossover frequency \(\omega_{co}\) cannot be too steep, and that it needs to be reasonably shallow for roughly a decade before and after crossover. As a rule of thumb, a phase margin of \(PM=60\) degrees requires that the slope at crossover is between \(-20\) dB/dec and \(-40\) dB/dec. In other words, the ideal loop shape will need to look something like Fig. 17.10. It is also important to understand that the Bode phase-gain theorem requires that there is adequate frequency separation between the frequency content of signals that we are tracking or rejecting and the frequency content of the sensor noise that is to be attenuated.

The ideal loop shape is large at low frequencies to achieve good tracking and disturbance rejection, is small at high frequencies to attenuate sensor noise, has a shallow slope at the crossover frequency to achieve a good phase margin, and has a small enough crossover frequency to satisfy the input saturation constraints.

Chapter 17 interactive figure

Ideal loop-shape checklist

Adjust the loop-shape parameters and use the checklist to connect the ideal Bode picture in Figure 17.10 to the design requirement it represents.

Figure 1.12. Interactive Figure 17.I5. Adjust the loop shape and select checklist items to explain the ideal requirements in Figure 17.10.

Low-frequency gainDesign goal: make the loop gain large at low frequency.

Why it mattersLarge low-frequency loop gain makes the sensitivity function small where commands and disturbances usually have most of their energy.

How to check or fix itCheck that |PC| is well above 0 dB at low frequency. Increase low-frequency gain with integral action or lag, but watch the crossover frequency.

Current checklist status

Self-check Which design action best supports this region?

17.2.1 image Example Problem 3.1.20

For the single-link robot arm, use the bode and margin commands (from Python or MATLAB) to find the phase and gain margin for the closed-loop system under PID control. On the same graph, plot the open-loop Bode plot and the closed-loop Bode plot. What is the bandwidth of the closed-loop system, and how does this relate to the crossover frequency? Use the gains found in HW 3.1.13.

Design Study A guided exercise

Measure stability margins

Use the open-loop Bode plot to identify crossover, gain margin, phase margin, and bandwidth.

Bode
plots of open-loop and closed-loop PID-controlled arm responses.

Use this plot to identify gain crossover, phase margin, gain margin, and closed-loop bandwidth.

Step 1. Gain crossover definition

Step 2. Phase margin reference

Step 3. Bandwidth relationship

Pseudocode

The complete solution includes margin-plot code. Before opening it, outline how you would compute the open-loop and closed-loop transfer functions, measure margins, and annotate the Bode plot.

This prompt is ungraded. It is intended to connect the margin measurements to the implementation code in the complete solution.

17.3 Design Study B. Inverted Pendulum

17.3.1 image Example Problem 3.2.20

For this problem, use the gains found in HW 3.2.13.

  • For the inner loop of the inverted pendulum, use the Python or MATLAB bode and margin commands to find the phase and gain margin for the inner loop system under PD control. On the same graph, plot the open-loop Bode plot and the closed-loop Bode plot. What is the bandwidth of the inner loop, and how does this relate to the crossover frequency?

  • For the outer loop of the inverted pendulum, use the bode and margin commands to find the phase and gain margin for the outer loop system under PID control. Plot the open and closed-loop Bode plots for the outer loop on the same plot as the open and closed-loop Bode plots for the inner loop. What is the bandwidth of the outer loop, and how does this relate to the crossover frequency?

  • What is the bandwidth separation between the inner (fast) loop, and the outer (slow) loop? For this design, is successive loop closure justified?

Design Study B guided exercise

Measure pendulum stability margins

Compare inner-loop and outer-loop margins and bandwidths.

Inner-loop pendulum margins plot.

Use margin plots to compare crossover, phase margin, gain margin, and bandwidth.

Step 1. Inner-loop bandwidth

Step 2. Outer-loop bandwidth

Step 3. Bandwidth separation

Pseudocode

The complete solution computes separate inner-loop and outer-loop margin plots. Before opening it, outline each component separately.

These prompts are ungraded. They are intended to connect the derivation to the implementation code in the complete solution.

17.4 Design Study C. Satellite Attitude Control

17.4.1 image Example Problem 3.3.20

For this problem, use the gains found in HW 3.3.13.

  • For the inner loop of the satellite attitude controller, use the bode and margin commands (from MATLAB or Python) to find the phase and gain margin for the inner loop system under PD control. On the same graph, plot the open-loop Bode plot and the closed-loop Bode plot. What is the bandwidth of the closed-loop system, and how does this relate to the crossover frequency?

  • For the outer loop of the satellite attitude controller, use the bode and margin commands to find the phase and gain margin for the outer loop system under PID control. Plot the open and closed-loop Bode plots for the outer loop on the same plot as the open and closed-loop Bode plots for the inner loop. What is the bandwidth of the closed-loop system, and how does this relate to the crossover frequency?

  • What is the bandwidth separation between the inner (fast) loop, and the outer (slow) loop? For this design, is successive loop closure justified?

Design Study C guided exercise

Measure satellite stability margins

Compare the inner and outer loop crossover frequencies, phase margins, bandwidths, and bandwidth separation.

Step 1. Inner-loop margin context

Step 2. Outer-loop margin context

Step 3. Successive-loop closure judgment

17.5 Coding Lab: Stability Margins

Objective: estimate gain crossover, phase margin, phase crossover, and gain margin from sampled Bode data.

Evaluation criteria: the lab checks interpolation at crossover points and compares the computed margins to a reference result.

Figure 17.1 (Interactive). Stability-margin coding lab with crossover annotations.

17.6 Knowledge Check

Q1. Phase margin location

Phase margin is measured at:

Q2. Gain margin location

Gain margin is measured relative to:

Q3. Phase margin calculation

If the phase at gain crossover is -135 degrees, enter the phase margin in degrees.

Show solution

Answer: 45 degrees because the phase is 45 degrees above -180 degrees.

Q4. Gain margin calculation

At phase crossover, the magnitude is -8 dB. Enter the gain margin in dB.

Show solution

Answer: 8 dB because the gain could increase by 8 dB before reaching 0 dB at phase crossover.

Q5. Missing crossover

If the Bode plot has no gain crossover, what should you say about phase margin?

Show solution

Answer: It is undefined or does not exist because there is no gain-crossover frequency where it can be measured.

Q6. Phase margin readout

At the gain-crossover frequency, the phase is -140 degrees. What is the phase margin?

Q7. Gain margin readout

At phase crossover, the magnitude is -12 dB. What is the gain margin?

Q8. Gain increase consequence

What commonly happens when loop gain is increased in a system whose phase becomes more negative at higher frequency?

Q9. Missing phase crossover

If the Bode plot does not show a phase crossover in the plotted frequency range, what should you conclude about gain margin from that plot alone?

17.7 Notes and References

18 Compensator Design

18.1 Theory

The loop-shaping design methodology is to add elements to the compensator \(C(s)\) to achieve a loop shape that satisfies the design specifications and that results in good stability margins, ideally \(PM\approx 60\) degrees, all while satisfying input saturation constraints. The idea is that the controller \(C(s)\) will be composed of several building blocks: \[C(s) = C_1(s)C_2(s)\cdots C_q(s).\] Since the loop gain is \(P(s)C(s)\), on the Bode plot we have \[\begin{aligned} 20\log_{10}\left|PC\right| &= 20\log_{10}\left|P\right| + \sum_{i=1}^q 20\log_{10}\left|C_i\right| \\ \angle PC &= \angle P + \sum_{i=1}^q \angle C_i. \end{aligned}\] Therefore, the total design can be realized by adding different elements to the Bode plot until the design specifications are satisfied. In this chapter we will discuss the following five basic building blocks for loop-shaping design:

  • Proportional Gain. A proportional gain introduces no phase shift (assuming \(k_P>0\)) and affects only the magnitude plot by moving it up or down. A proportional gain is used to change the location of the crossover frequency.

  • Integral (PI) Control. An integrator adds \(-20\) dB of slope and \(-90\) degrees of phase at all frequencies. The addition of an integrator changes the system type. A modified PI controller can be used to affect only the low frequency loop gain, thereby enhancing reference tracking and input/output disturbance rejection.

  • Low-pass Filter. Low-pass filters are used to decrease the loop gain at high frequencies to achieve noise attenuation.

  • phase-lag Filter. A phase-lag filter can be used to increase the loop gain at low frequencies thereby enhancing reference tracking and input/output disturbance rejection. A phase-lag filter differs from integral control in that it does not change the system type.

  • phase-lead Filter. A phase-lead filter can be used to add phase at the crossover frequency and can thereby stabilize the system and increase the phase margin.

Each of these basic building blocks will be described in more detail in the sections that follow.

18.1.1 Building Block #1: Proportional Gain

The first basic building block for loop-shaping design is proportional control where \[C_P(s) = k_P.\] Proportional control is used to change the loop gain at all frequencies, without affecting the phase. A Bode plot for proportional control is shown in Fig. 18.1 for different values of \(k_P\).

The Bode plot for proportional gain at different values of k_P. The proportional gain adds a constant to the loop shape at all frequencies and does not affect the phase at any frequency.

18.1.2 Building Block #2: Integral Control

The second basic building block for loop-shaping design is proportional-integral (PI) control where \(k_P=1\), i.e., \[C_{PI}(s) = 1+\frac{k_I}{s} = \frac{s+k_I}{s}.\] The Bode plot of \(C_{PI}\) for different values of \(k_I\) is shown in Fig. 18.2. Integral control is used to change the system type by changing the slope of the loop gain by \(-20\) dB/dec at low frequencies. The Bode plot for integral control is shown in Fig. 18.2 for different values of \(k_I\). It is clear that integral control changes the slope for frequencies \(\omega<k_I\) while not affecting the loop gain when \(\omega > k_I\). Note also that integral control decreases the phase at low frequencies, which negatively impacts stability. Therefore, integral control is usually applied at low frequencies, where \(k_I \ll \omega_{co}\).

The Bode plot for integral control at different values of k_I. Integral control changes the system type by decreasing the slope of the loop shape by -20 dB/dec for frequencies below k_I, while leaving high frequencies unaffected.

18.1.3 Building Block #3: Low-Pass Filter

The third basic building block for loop-shaping design is a low-pass filter where \[C_{LPF}(s) = \frac{p}{s+p}.\] Note that the low-pass filter is constructed so that the DC gain is one. The Bode plot for a low-pass filter is shown in Fig. 18.3 for different values of \(p\). It is evident from Fig. 18.3 that a low-pass filter decreases the loop gain when \(\omega>p\) while leaving the loop gain unaffected when \(\omega<p\). Low-pass filters are used at high frequencies to enhance noise attenuation.

The Bode plot for a low-pass filter at different values of the pole p. A low-pass filter decreases the slope of the loop shape by -20 dB/dec for frequencies above p, while leaving low frequencies unaffected.

18.1.4 Building Block #4: Phase-Lag Filter

The fourth basic building block for loop-shaping design is a phase-lag filter where \[\tag{18.1} C_{Lag}(s) = \frac{s+z}{s+p},\] where \(z>p>0\). Note that the phase-lag filter is constructed so that \[\lim_{s\to\infty}\frac{s+z}{s+p} = \lim_{s\to\infty}\frac{1+\frac{z}{s}}{1+\frac{p}{s}} = 1.\] Therefore, phase-lag filters change the loop gain at low frequencies while leaving high frequencies unaffected. The Bode plot for a phase-lag filter is shown in Fig. 18.4 when \(z=1\) and when \(p=z/M\) for different values of pole-zero separation \(M\). Note that phase-lag filters increase the gain at low frequencies and that the total amount of gain is equal to the separation between the zero and the pole. Specifically, the increased gain on the Bode plot is equal to \(20\log_{10}M\). Phase-lag filters are used to enhance tracking performance and input/output disturbance rejection. Unfortunately, phase-lag filters decrease the phase between the zero and the pole and will therefore negatively affect stability if the zero is too close to the crossover frequency. Therefore, phase-lag filters are typically added at low frequencies and are characterized by the zero \(z\) where the effect of the lag ends and the pole-zero separation \(M\) which indicates the maximum gain at low frequencies. Accordingly, the lag filter 18.1 can be written as \[C_{Lag}(s) = \frac{s+z}{s+z/M}.\]

The Bode plot for a phase-lag filter when the zero is at z=1 and the pole is at p=z/M, for different values of M. A phase-lag filter increases the loop gain at low frequencies while leaving high frequencies unaffected.

18.1.5 Building Block #5: phase-lead Filter

The final basic building block for loop-shaping design that we will discuss is a phase-lead filter where \[\tag{18.2} C_{Lead}(s) = \left(\frac{p}{z}\right)\left(\frac{s+z}{s+p}\right),\] where \(p>z>0\). Note that the phase-lead filter is constructed so that \[\lim_{s\to 0}\frac{p}{z}\frac{s+z}{s+p} = 1.\] Therefore, phase-lead filters change the loop gain at high frequencies while leaving low frequencies unaffected. The Bode plot for a phase-lead filter is shown in Fig. 18.5 when \(z=1\) and when \(p=Mz\) for different values of pole-zero separation \(M\). Note that phase-lead filters increase the phase for frequencies between the zero and the pole. It can be shown that the peak of the phase plot shown in Fig. 18.5 is at \[\omega_{Lead} = \sqrt{zp}\] which is the midpoint between \(z\) and \(p\) on the Bode plot. It can also be shown that the increase in phase at \(\omega_{Lead}\) is \[\phi_{Lead} = \tan^{-1}\sqrt{\frac{p}{z}}-\tan^{-1}\sqrt{\frac{z}{p}}.\] Phase-lead filters are used to increase the phase margin and thereby enhance the stability and robustness of the system. Typically, \(\omega_{Lead}\) is selected to be the crossover frequency \(\omega_{co}\) to obtain the maximum benefit to the phase margin. Unfortunately, phase-lead filters also increase the loop gain at high frequencies as shown in Fig. 18.5, which will make the closed-loop system more sensitive to noise. Therefore, phase-lead filters are typically accompanied by a low-pass filter at higher frequencies. Since phase-lead filters are typically added at the frequency giving the desired bump in phase, it is convenient to write the transfer function 18.2 in terms of the center frequency \(\omega_{Lead}\) and the lead ratio \(M\). Using the relationship \(p=Mz\) and \(\omega_{Lead}=\sqrt{pz}\) we can write Equation 18.2 as \[\begin{aligned} C_{Lead}(s) &= M \left(\frac{s+\frac{\omega_{Lead}}{\sqrt{M}}}{s+\omega_{Lead}\sqrt{M}}\right) \\ C_{Lead}(s) &= \frac{\frac{\sqrt{M}}{\omega_{Lead}}s+1}{\frac{1}{\omega_{Lead}\sqrt{M}}s+1}. \end{aligned}\]

The Bode plot for a phase-lead filter when \omega_{Lead}=1, for different values of M. A phase-lead filter increases the phase around \omega_{Lead}. It also increases the loop gain at high frequencies.

Chapter 18 interactive figure

Compensator building-block explorer

Choose one compensator building block. The first controls set that block’s design parameters. The frequency marker does not change the block; it only reads the magnitude and phase at one point on the plot.

Interactive Figure 18.I1. Move the block parameters to see which frequency region and phase range each controller element changes.

Transfer block
Derived pole/zero locations
Magnitude effect
Phase effect
Best used for
Design warning
Probe readout

Check 1. Choosing a block for phase margin

If the loop shape has roughly the right crossover frequency but the phase margin is too small, which building block is usually the most direct choice?

Check 2. Interpreting the lead-filter tradeoff

When you increase the phase-lead ratio M, what tradeoff should you watch for?

Check 3. Explain a design choice

Choose one block from the explorer. In one or two sentences, explain what frequency range it changes and what design tradeoff it introduces.

Show guidance

A strong response names the block, identifies the affected frequency range, and includes the tradeoff. For example, a low-pass filter reduces high-frequency gain for noise attenuation but adds phase lag near the pole.

18.1.6 Simple Example 1

Given the open-loop plant \[P(s) = \frac{1}{s+1},\] design a controller \(C(s)\) so that the closed-loop system satisfies the following constraints:

(1) Tracks a ramp within \(\gamma_1=0.03\).

(2) Attenuate noise with frequency content above \(\omega_n=10\) rad/sec by \(\gamma_n = 0.1\).

(3) Reject input disturbances with frequency content below \(\omega_{d_{in}}=0.1\) rad/sec by \(\gamma_{d_{in}}=0.1\).

(4) Phase margin that is approximately \(60\) degrees.

The first three design specifications can be displayed on the Bode magnitude plot as shown in Fig. 18.6. To track a ramp within \(\gamma_1=0.03\) requires that the loop gain be above \[B_1 = 20\log_{10}\left|\frac{1}{0.03}\right|-20\log_{10}\left|\omega\right|\] as \(\omega\to 0\). Therefore, to satisfy this specification, we need to find \(C\) so that the Bode plot for \(PC\) rises above the green line on the top left of Fig. 18.6.

To attenuate noise with frequency content above \(\omega_n=10\) rad/sec by \(\gamma_n = 0.1\), the loop gain should be below \[B_n = 20\log_{10}\left|0.1\right| = -20~\text{dB}\] for \(\omega>10\) rad/sec. Therefore, we need to design \(C\) so that the Bode plot for \(PC\) is below the green line in the bottom right of Fig. 18.6.

To reject input disturbances with frequency content below \(\omega_{d_{in}}=0.1\) rad/sec by \(\gamma_{d_{in}}=0.1\), requires that the loop gain is above \[20\log_{10}\left|\frac{1}{0.1}\right| + 20\log_{10}\left|P(j\omega_{d_{in}})\right| = 20-0=20\text{~dB}\] for \(\omega<0.1\) rad/sec. Therefore, we need to design \(C\) so that the Bode plot for \(PC\) is above the green line in the left-middle of Fig. 18.6.

The Bode plot for the open-loop plant in Example 1, together with the design specifications.

To increase the type of the system so that the slope of \(PC\) is \(-20\) dB/dec as \(\omega\to 0\), integral control can be added. Fig. 18.7 shows the loop gain of \(PC\) when \[C(s) = C_{P}(s)C_{PI}(s) = \left(2\right)\left(\frac{s+0.4}{s}\right).\]

The Bode gain plot of P and PC when C includes proportional and integral control.

To increase the loop gain at low frequencies to get above the \(1/s\) line as \(\omega\to 0\), a phase-lag filter can be added. Fig. 18.8 shows the loop gain of \(PC\) when \[C(s) = C_{P}(s)C_{PI}(s)C_{Lag}(s) = \left(2\right)\left(\frac{s+0.4}{s}\right)\left(\frac{s+0.8}{s+0.8/50}\right).\] From Fig. 18.8 we see that the closed-loop system will satisfy the tracking and input disturbance specifications.

The Bode gain plot of P and PC when C includes proportional, integral, and lag filters.

To decrease the loop gain at high frequencies to achieve the noise attenuation specification, a low-pass filter can be added at \(p=5\). Fig. 18.9 shows the loop gain of \(PC\) when \[\begin{aligned} C(s) &= C_{P}(s)C_{PI}(s)C_{Lag}(s)C_{LPF}(s) \\ &= \left(2\right)\left(\frac{s+0.4}{s}\right)\left(\frac{s+0.8}{s+0.8/50}\right)\left(\frac{5}{s+5}\right). \end{aligned}\] The phase margin for this design is \(PM=63\) degrees and so all of the design specifications are satisfied, as shown in Fig. 18.9.

The Bode gain plot of P and PC when C includes proportional, integral, lag, and low-pass filters.

Chapter 18 interactive figure

Build the loop shape one compensator at a time

Step through the same loop-shaping sequence used in the example. Each card adds one compensator block, compares the new loop shape against the previous step, and shows which design requirements are satisfied.

Interactive Figure 18.I2. The dashed blue curve is the previous step and the solid blue curve is the current loop shape. The bottom panel shows phase so the crossover/phase-margin tradeoff stays visible.

Added block
Cumulative controller
What changed?
Design prompt
Spec status
Stability context

Python code that implements this example is shown below.

from control import *
import matplotlib.pyplot as plt
import numpy as np

Plant = tf([1],[1,1]) #transfer function for plant

# initialize frequency response for plant only
plt.figure()
plt.grid(which='both')

###################################
# input disturbance specification #
###################################
# reject dist below this frequency
omega_din = 10**-1
omega = np.logspace(-4, np.log10(omega_din))
Pmag, phase, _ = bode(Plant, omega, Plot=False)

# amount of input disturbance in output
gamma_din = 0.1
mag_din = 20*np.log10(1/gamma_din)*np.ones(omega.size)+
          20*np.log10(Pmag)
plt.semilogx(omega, mag_din, color=[0, 1, 0], ls=':',
             label='$d_{in}$ constraint')

#######################
# noise specification #
#######################
# attenuate noise above this frequency
omega_n = 10^1

#attenuate noise by this amount
gamma_n = .1
omega = np.logspace(np.log10(omega_n),2+np.log10(omega_n))
plt.semilogx(omega, 20*np.log10(gamma_n)*np.ones(omega.size),
             color=[0, 1, 0], ls='--', label='noise constraint')

#######################
# steady state errror #
#######################
#steady state tracking of ramp
gamma_1 = .03
omega = np.logspace(-4, 0)
plt.semilogx(omega, 20*np.log10(1/gamma_1)-20*np.log10(omega),
             color=[0, 1, 0], ls='-.',
             label='tracking error constraint')

# open-loop freq response for plant only
omega = np.logspace(-4, 3)
Pmag, phase, omega = bode(Plant,omega, Plot=False)
Pmag_dB = 20*np.log10(Pmag)
plt.semilogx(omega, Pmag_dB, label='$P(s)$')

##################
# control design #
##################
C = 1.0

#proportional control
C_kp = 2.0

#integral control
k_I = 0.4
C_PI = tf([1, k_I], [1, 0])

#phase lag
z = 0.8
M = 50.0
C_lag = tf([1, z], [1, z/M])

#low-pass filter
p = 5
C_lpf = tf([p], [1, p])

#total filter:
# for figure 18-7
C1 = C*C_kp*C_PI

# for figure 18-8
C2 = C*C_kp*C_PI*C_lag

# for figure 18-9
C3 = C*C_kp*C_PI*C_lag*C_lpf

# open-loop freq response of the controller + plant
omega = np.logspace(-4, 3)
PC_mag, phase, _ = bode(Plant*C3, omega, Plot=False)
plt.semilogx(omega, 20*np.log10(PC_mag),
             label='$P(s)C_{k_p}C_{PI}C_{lag}C_{lpf}= P(s)C(s)$')

plt.title('Bode Diagram')
plt.xlabel('Frequency (rad/s)')
plt.ylabel('Magnitude (dB)')
plt.legend()

plt.show()

18.1.7 Controller Implementation

The loop-shaping design procedure produces a controller \(C(s)\) that will have multiple elements, including integrators, lead and lag filters, and low-pass filters. Each of these elements is straightforward to implement using analog circuits. However, if the controller is to be implemented on digital hardware using computer code, what is the best way to proceed? While there are many possibilities, one option that is straightforward to implement and fits well with the previous chapters is to implement the controller using state-space equations. The controller \[U(s) = C(s) E(s)\] is first converted to continuous time state-space equations using, for example, control canonical form, to produce the equations \begin{align} \dot{z}_C &= A_{C}z_C + B_{C}e \tag{18.3} \\ u &= C_{C}z_C + D_{C}e \tag{18.4} \end{align} where \(e(t)=r(t)-y(t)\) is the input to the state-space equations, and the control signal \(u(t)\) is the output. In the example of the previous section we get \[C(s) = \frac{10 s^2 + 12 s + 3.2}{s^3 + 5.016 s^2 + 0.08 s}.\] Therefore, using controller canonical form, the controller implementation is \[\begin{aligned} \dot{z}_C &= \begin{pmatrix} -5.016 & -0.08 & 0 \\ 1 & 0 & 0 \\ 0 & 1 & 0\end{pmatrix} z_C +\begin{pmatrix} 1 \\ 0 \\ 0 \end{pmatrix}e \\ u &= \begin{pmatrix} 10 & 12 & 3.2 \end{pmatrix}z_C. \end{aligned}\] In Python, the command to find the state-space equations from the controller transfer function ‘C’ is given below:

    C_ss = tf2ss(C)
    A_C = C_ss.A
    B_C = C_ss.B
    C_C = C_ss.C
    D_C = C_ss.D

The controller is then implemented by integrating the differential equations between sample times. If \(T_s\) is the sample time, and \(N=10\) Euler steps are used between each sample, then Python code that implements the controller is shown below:

# assuming that self.z_C (the controller state) has been
# initialized elsewhere and that the controller ss equations
# are available in the Python class
def u = updateController(self, r, y):
    # calc error signal
    error = r - y

    # Euler integration steps per control calculation
    N = 10

    # integrate differential equation for controller
    for i in range(N):
        self.z_C = self.z_C + Ts / N * (self.A_C * self.z_C 
                                        + self.B_C * error)
    u = self.C_C * self.z_C + self.D_C * error

    return u

The inputs to the controller are the reference signal \(r\), the output \(y\), and the current time \(t\). The error signal is computed on Line 5. The control dynamics 18.3 are integrated using \(N\) Euler steps in Lines 11–13, and the control output equation is computed in Line 14.

18.1.8 Prefilter Design

There are applications where it is very difficult to meet the design specifications at both low and high frequencies and still achieve a phase margin that is close to \(60\) degrees. If for example, the phase margin is close to \(45\) degrees, then there will be a peak in the closed-loop Bode plot. As shown in Fig. 17.7, the peak in the closed-loop Bode plot produces overshoot and ringing in the closed-loop step response. One method for reducing the overshoot in the closed-loop step response is to add a prefilter \(F(s)\) as shown in Fig. 18.10.

The closed-loop system with a prefilter F(s) on the reference command r.

The role of the prefilter \(F(s)\) is to attenuate frequencies in \(r(t)\) that resonate with the closed-loop system and produce the overshoot. From a Bode plot perspective, the goal of the prefilter is to flatten the closed-loop Bode plot so that the peak is removed. There are several standard forms used for the prefilter. These include a notch filter and a low-pass filter. For simplicity, we will discuss the use of a low-pass filter below. As explained previously, the transfer function for a low-pass filter is given by \[\tag{18.5} F(s) = \frac{p}{s+p},\] where the DC gain is equal to one.

Just as the controller \(C(s)\) was implemented using state-space equations, the prefilter can also be implemented using state-space equations. The prefilter \[R_f(s) = F(s) R(s)\] is converted to continuous time state-space equations using, for example, control canonical form, to produce the equations \begin{align} \dot{z}_F &= A_Fz_F + B_F r \tag{18.6} \\ r_f &= C_Fz_F + D_F r \tag{18.7} \end{align} where the reference \(r(t)\) is the input to the state-space equations, and the filtered reference signal \(r_f(t)\) is the output. For the transfer function given in Equation 18.5 we get \[\begin{aligned} \dot{z}_F &= -p z_F + r \\ r_f &= p z_F. \end{aligned}\]

In Python, the command to find the state-space equations is given below, where \(F\) is the transfer-function object representing the prefilter:

    F_ss = tf2ss(F)
    A_F = F_ss.A
    B_F = F_ss.B
    C_F = F_ss.C
    D_F = F_ss.D

The prefilter is then implemented by integrating the differential equations between sample times. If \(T_s\) is the sample time, and \(N=10\) Euler steps are used between each sample, then Python code that implements the controller plus prefilter is given below:

# assuming that self.z_C and self.z_F have been initialized
# elsewhere and that the controller AND prefilter ss equations
# (e.g. A_C, B_C, C_C, D_C, A_F, B_F, etc.) are available from
# the Python class

def u = updateController(self, r, y):

    # Euler integration steps per filter calculation
    N = 10

    # integrate differential equation for controller
    for i in range(N):
        # prefilter the reference command
        self.z_F = self.z_F + Ts / N * (self.A_F * self.z_F 
                                        + self.B_F * r)
        r_filtered = self.C_F * self.z_F + self.D_F * r

        # error signal uses filtered reference
        error = r_filtered - y
        self.z_C = self.z_C + Ts / N * (self.A_C * self.z_C 
                                        + self.B_C * error)

    u = self.C_C * self.z_C + self.D_C * error

    return u

17.1.8.1 Prefilter Example

As an example, consider the open-loop system \(PC\) shown in Fig. 18.11. The phase margin is \(PM=42.5\) degrees resulting in a peak in the closed-loop frequency response, as shown in Fig. 18.11. The corresponding step response is shown in Fig. 18.12, where it can be seen that there is significant ringing in the step response.

To remove the peak in the closed-loop frequency response, a prefilter is added to the system as shown in Fig. 18.10, where the low-pass filter pole is \(p=9\), resulting in \[F(s) = \frac{9}{s+9}.\] The Bode magnitude of the prefilter \(F\) is shown in Fig. 18.11, as well as the prefiltered closed-loop response \(FPC/(1+PC)\). As can be seen from Fig. 18.11, the prefilter removes the peak in the closed-loop frequency response. The corresponding step response is shown in Fig. 18.12, where it can be seen that the ringing has been significantly reduced.

The loop gain for the open-loop system PC, the closed-loop system PC/(1+PC), the prefilter F, and the closed-loop system with the prefilter FPC/(1+PC).
The step response of the closed-loop system PC/(1+PC) and the closed-loop system with the prefilter FPC/(1+PC).

Chapter 18 interactive figure

Prefilter pole and reference-response ringing

Move the prefilter pole. The frequency plot shows how the prefilter attenuates the resonant peak, and the time plot shows the corresponding reduction in ringing.

Interactive Figure 18.I3. A slower prefilter removes more high-frequency command content, reducing ringing at the cost of slower reference response.

Prefilter
Peak tendency
Step-response tradeoff

18.1.9 Successive Loop Closure Design

When loop shaping is used to design an inner and outer loop controller in a successive loop closure design, the design of the outer loop can take into account the complete dynamics of the inner loop. This is in contrast to the design of PID controllers in Chapter 11 where the inner loop was replaced with the DC gain. Fig. 18.13 shows the system architecture for loop-shaping design. The inner and outer loop controllers are accompanied by the prefilter \(F(s)\) which is only on the outer loop.

The control architecture for a successive loop closure design, with prefilter.

Chapter 18 interactive figure

Successive loop closure: design, close, collapse, design outer loop

Step through the architecture to trace signals, close the fast inner loop, and see how the outer-loop plant changes after the inner-loop dynamics are collapsed into an equivalent block.

Current task
Plant seen by designer
Key equation
Why this step matters
Self-check

Interactive Figure 18.I4. Trace the signals, close the inner loop, and use the closed inner-loop dynamics as part of the outer-loop plant.

The first step is to design the inner loop controller \(C_{in}(s)\) using the plant \(P_{in}(s)\). However, for the design of the outer loop controller \(C_{out}(s)\), we can use the outer loop plant in cascade with the inner closed-loop system. Therefore, the plant for the outer loop design is given by \[P = P_{out}\left(\frac{P_{in}C_{in}}{1+P_{in}C_{in}}\right).\] Examples will be given in the sections below.

18.2.1 image Example Problem 3.1.21

For this homework assignment we will use loopshaping to improve the PID controllers developed in HW 3.1.13. Let \(C_{pid}(s)\) be the PID controller designed in HW 3.1.13. The final control will be \(C(s) = C_{pid}(s)C_{l}(s)\) where \(C_l\) is designed using loopshaping techniques.

(a) Design \(C_l(s)\) to meet the following objectives:

(1) Improve tracking and disturbance rejection by a factor of 10 for reference signals and disturbances below \(0.07\) rad/sec,

(2) Improve noise attention by a factor of 10 for frequencies above \(1000\) radians/sec.

(3) Phase margin that is approximately \(PM=60\) degrees.

(b) Add zero mean Gaussian noise with standard deviation \(\sigma^2=0.01\) to the simulation developed in HW 3.1.13.

(c) Implement the controller \(C(s)\) in simulation using its state-space equivalent.

(d) Note that despite having a good phase margin, there is still significant overshoot, due in part to the windup effect in the phase-lag filter. This can be mitigated by adding a prefilter, that essentially modifies the hard step input into the system. Add a low-pass filter for \(F(s)\) as a prefilter to flatten out the closed-loop Bode response and implement in simulation using its discrete-time state-space equivalent.

Design Study A guided exercise

Choose compensator building blocks

Translate each performance shortfall into a loop-shaping compensator block.

Bode magnitude plot of the arm loop gain with design specification
regions.

Use the specification regions to decide which compensator block should improve low-frequency gain, phase margin, and high-frequency noise attenuation.

Step 1. Low-frequency tracking/disturbance improvement

Step 2. Phase margin improvement

Step 3. High-frequency noise attenuation

Step 4. Reference-shaping block

Pseudocode

The complete solution includes loop-shaping code. Before opening it, outline how you would build the compensator term by term, check the Bode specifications, and compare the final step response and control effort.

This prompt is ungraded. It is intended to connect the compensator choices to the implementation code in the complete solution.

18.3 Design Study B. Inverted Pendulum

18.3.1 image Example Problem 3.2.21

For this homework assignment we will use the loopshaping design technique to design a successive loop closure controller for the inverted pendulum.

  • First consider the inner loop, where \(P_{in}(s)\) is the transfer function of the inner loop derived in HW 3.2.8. Using a proportional and phase-lead controller, design \(C_{in}(s)\) to stabilize the system with a phase margin close to 60 deg, and to ensure that noise above \(\omega_{no}=200\) rad/s is rejected by \(\gamma_{no}=0.1\). We want the closed-loop bandwidth of the inner loop to be approximately 40 rad/s. Note that since the gain on \(P_{in}(s)\) is negative, the proportional gain will also need to be negative.

  • Now consider the design of the controller for the outer loop system. The ‘plant’ for the design of the outer loop controller is \[P = P_{out}\frac{P_{in}C_{in}}{1+P_{in}C_{in}}.\] Design the outer loop controller \(C_{out}\) so that the system is stable with phase margin close to \(PM=60\) degrees, and so that reference signals with frequency below \(\omega_r=0.0032\) radians/sec are tracked with error \(\gamma_r=0.00001\), and noise with frequency content above \(\omega_{no}=1000\) radians/sec are rejected with \(\gamma_{no}=0.0001\). Design the crossover frequency so that the rise time of the system is about 2 sec.

Design Study B guided exercise

Plan the pendulum loop-shaping design

Choose compensator building blocks for inner and outer loop requirements.

Inner-loop pendulum loop-shaping specification plot.

Start with the inner-loop plant and design blocks that stabilize the upright pendulum while satisfying noise and bandwidth requirements.

Step 1. Proportional gain sign

Step 2. Phase-margin block

Step 3. Noise requirement

Pseudocode

The complete solution includes separate loop-shaping scripts for the inner and outer loops. Before opening it, outline each component separately.

These prompts are ungraded. They are intended to connect the derivation to the implementation code in the complete solution.

18.4 Design Study C. Satellite Attitude Control

18.4.1 image Example Problem 3.3.21

For this homework assignment we will use the loopshaping design technique to design a successive loop closure controller for the satellite attitude problem.

  • First consider the inner loop, where \(P_{in}(s)\) is the transfer function of the inner loop derived in HW 3.3.8. The Bode plot for this system shows an underdamped resonant mode. We have seen in previous chapters that this resonant mode can be removed by introducing rate feedback of the form \[u = - k_D \dot{y} + u',\] where \(y\) is the output signal and \(u'\) is the additional control signal to be designed. Using the derivative gain \(k_{D_\theta}\) found in HW 3.3.13, find the revised transfer function from \(\tau'\) to \(\theta\), and use this transfer function for \(P_{in}(s)\). Letting \[\tau'(s) = C_{in}(s) E(s),\] where \(e(t) = \theta_r(t)-\theta(t)\), design \(C_{in}(s)\) to meet the following specifications:

    • The inner loop will track \(\theta_r\) with frequency content below \(\omega_r=0.01\) radians/sec to within \(\gamma_r=0.01\).

    • The inner loop will attenuate noise on the measurement of \(\theta\) for all frequencies above \(\omega_n=20\) rad/sec by \(\gamma_n=0.01\).

    • The phase margin of the inner loop should be around \(PM=60\) degrees.

  • Now consider the design of the controller for the outer-loop system. As shown in HW 3.3.8, the transfer function for the outer loop also has a strong resonant mode. As with the inner loop, use the derivative gain found in HW 3.3.13 to introduce rate damping and find the associated transfer function \(P_{out}(s)\). The “plant” for the design of the outer-loop controller is \[P = P_{out}\frac{P_{in}C_{in}}{1+P_{in}C_{in}}.\] Design the outer loop controller \(C_{out}\) to meet the following specs:

    • Track steps in \(\phi_r\) with zero steady-state error.

    • Reject input disturbances with frequency content below \(\omega_{d_{in}}=0.01\) by \(\gamma_{d_{in}}=0.1\).

    • Attenuate noise on the measurement of \(\phi\) with frequency content above \(\omega_n=10\) rad/sec by \(\gamma_n=10^{-4}\).

    • The phase margin of the outer loop should be around \(PM=60\) degrees.

    • Use a prefilter to reduce any peaking in the closed-loop response of the outer loop.

Design Study C guided exercise

Plan satellite loop shaping

The satellite loop-shaping design uses rate damping, inner-loop compensation, inner-loop collapse, outer-loop compensation, and a prefilter.

Step 1. Inner-loop plant preparation

Step 2. Outer-loop plant preparation

Step 3. Final design tradeoffs

Pseudocode

18.5 Interactive Compensator Design Check

Chapter 18 activity

Compensator design requirement dashboard

Tune real compensator blocks for P(s)=1/(s+1). The Bode plot shows how the controller changes the loop shape, and the checks below connect the design to tracking, stability margin, bandwidth, and noise attenuation requirements.

Interactive Figure 18.I5. The gray curve is the plant, the blue curve is the compensated loop, the orange curve is phase, and the green guides mark the design requirements.

Low-frequency tracking
Phase margin
Bandwidth
Noise attenuation
Controller
Suggested next move

18.6 Coding Lab: Compensator Design

Objective: compose compensator transfer-function blocks and score the resulting loop shape against design requirements.

Evaluation criteria: the lab checks low-frequency gain, high-frequency rolloff, phase margin, properness, and stable compensator poles.

Figure 18.1 (Interactive). Compensator-design coding lab with loop-shaping scorecard.

18.7 Knowledge Check

Q1. Proportional gain effect

A proportional gain primarily shifts the Bode magnitude:

Q2. Lead compensator purpose

A lead compensator is commonly used to add:

Q3. Gain combination

If two compensator blocks contribute +10 dB and -4 dB, enter the combined magnitude contribution in dB.

Show solution

Answer: 6 dB. Bode magnitudes in dB add when transfer-function blocks multiply.

Q4. Phase boost target

If the uncompensated phase margin is 30 degrees and the target is 60 degrees with a 20-degree safety allowance, enter the approximate phase boost to design for.

Show solution

Answer: 50 degrees: 60 - 30 + 20 = 50 degrees.

Q5. Reference-response shaping

Which block can reduce reference-command overshoot without directly changing loop stability margins?

Show solution

Answer: A prefilter shapes the reference path without directly changing the loop gain PC.

Q6. Lead block selection

Which compensator block is the most direct choice when the design needs more positive phase near crossover?

Q7. Lag block purpose

Why is a lag compensator commonly used in loop shaping?

Q8. Low-pass filter purpose

What is the main loop-shaping role of a low-pass filter?

Q9. Scorecard diagnosis

A design meets the low-frequency tracking requirement but fails because phase margin is too small. What is the most targeted next move?

Q10. Prefilter effect

What does a prefilter change most directly?

18.8 Notes and References

Part VI

Homework Problems

D Design Study: Mass Spring Damper

Figure 19.1 shows the mass-spring-damper system. The mass slides along a frictionless level surface and is connected to a wall by a spring with spring constant \(k\) and a damper with damping constant \(b\). The position of the mass is given by \(z\), where \(z=0\) is the position where the spring is not stretched. The speed of the mass is given by \(\dot{z}\). An external force \(F\) is applied to the mass as shown in Fig. 19.1.

Assume the following physical constants: \(m=5\) kg, \(k=3\) N/m, \(b=0.5\) N-sec/m.

image

Figure 19.1. Mass Spring Damper

D.2 Kinetic energy.

D.3 Equations of Motion.

D.4 Linearize equations of motion.

D.5 Transfer function model.

D.6 State-space model.

D.7 Pole placement using PD.

D.8 Second-order design.

D.9 Integrators and system type.

D.P.6 Root locus PID.

D.10 Digital PID.

D.11 Full state feedback.

D.12 Full state with integrator.

D.13 Observer based control.

D.14 Disturbance observer.

D.15 Frequency Response.

D.16 Loop gain.

D.17 Stability margins.

D.18 Loopshaping design.

image Homework D.2

(a) Using the configuration variable \(z\), write an expression for the kinetic energy of the system.

(b) Create an animation of the mass-spring-damper system. The input should be a variable \(z\). Turn in a screen capture of the animation.

image Homework D.3

(a) Find the potential energy for the system.

(b) Define the generalized coordinates.

(c) Find the generalized forces and damping forces.

(d) Derive the equations of motion using the Euler-Lagrange equations.

(e) Referring to Appendices P.1, P.2, and P.3, write a class or s-function that implements the equations of motion. Simulate the system using a variable force input. The output should connect to the animation function developed in homework D.2.

image Homework D.4

For the mass-spring-damper:

(a) Find the equilibria of the system.

(b) Linearize the system about the equilibria using Jacobian linearization.

(c) Linearize the system using feedback linearization.

image Homework D.5

For the equations of motion for the mass-spring-damper,

Using the Laplace transform, convert from time domain to the s-domain.

Find the transfer function from the input force \(F\) to the mass position \(z\).

Draw the associated block diagram.

image Homework D.6

For the equations of motion for the mass-spring-damper, define the states as \(x=(z,\dot{z})^{\top}\), and the input as \(u=F\), and the measured output as \(y=z\). Find the linear state-space equations in the form \[\begin{aligned} \dot{x} &= Ax + Bu \\ y &= Cx + Du. \end{aligned}\]

image Homework D.7

(a) Given the open-loop transfer function from force to position in Homework D.5, find the open-loop poles of the system, when the equilibrium position is \(z_e=0\).

(b) Using the PD control architecture shown in Figure 7.2, find the closed-loop transfer function from \(z_r\) to \(z\) and the closed-loop poles as functions of \(k_P\) and \(k_D\).

(c) Select \(k_P\) and \(k_D\) to place the closed-loop poles at \(p_1=-1\) and \(p_2=-1.5\).

(d) Using the gains from part (c), implement the PD control for the mass-spring-damper in simulation and plot the response of the system to a 1 m step input.

image Homework D.8

For the mass-spring-damper, do the following:

(a) Suppose that the design requirements are that the rise time is \(t_r \approx 2\) seconds, with a damping ratio of \(\zeta=0.707\). Find the desired closed-loop characteristic polynomial \(\Delta_{cl}^d(s)\), and the associated pole locations. Find the proportional and derivative gains \(k_P\) and \(k_D\) to achieve these specifications, and modify the simulation from HW D.7 to verify that the step response satisfies the requirements.

(b) Suppose that the size of the input force is limited to \(F_{\max}=6\) N. Modify the simulation to include a saturation block on the force \(F\). Using the rise time \(t_r\) as a tuning parameter, tune the PD control gains so that the input just saturates when a \(1\)-meter step is applied to \(z^r\). Plot the step response showing that saturation does not occur for a \(1\)-meter step input with the new control gains.

image Homework D.9

(a) When the controller for the mass-spring-damper is PD control, what is the system type? Characterize the steady-state error when the reference input is a step, a ramp, and a parabola. How does this change if you add an integrator?

(b) Consider the case where a constant disturbance acts at the input to the plant (for example an inaccurate knowledge of the spring constant in this case). What is the steady-state error to a constant input disturbance when the integrator is not present, and when it is present?

image Homework D.P.6

Add an integrator to obtain PID control for the mass-spring-damper. Put the characteristic equation in Evans’ form and use the MATLAB rlocus command to plot the root locus versus the integrator gain \(k_I\). Select a value for \(k_I\) that does not significantly change the other locations of the closed-loop poles.

image Homework D.10

The objective of this problem is to implement the PID controller using only measured outputs of the system.

(a) Modify the system dynamics file so that the parameters \(m\), \(k\), and \(b\) vary by up to 20% of their nominal value each time they are run (uncertainty parameter = 0.2). Additionally, add a step input for a disturbance with an amplitude of \(0.25\).

(b) Change the simulation files so that the input to the controller is the output and not the state. The controller should only assume knowledge of the position \(z\) and the reference position \(z_r\).

(c) Implement the PID controller designed in Problems D.11 in simulation. Use the dirty derivative gain of \(\sigma=0.05\). Tune the integrator to remove the steady-state error caused by the uncertain parameters.

image Homework D.11

The objective of this problem is to implement a state-feedback controller for the mass-spring-damper system using the full state. Start with the simulation files developed in Homework D.10.

(a) Select the closed-loop poles as the roots of the equation \(s^2 + 2\zeta\omega_n s + \omega_n^2 = 0\), where \(\omega_n\) and \(\zeta\) were found in Homework D.8.

(b) Add the state-space matrices \(A\), \(B\), \(C\), \(D\) derived in Homework D.6 to your param file.

(c) Verify that the state-space system is controllable by checking that \(\text{rank}(\mathcal{C}_{A,B})=n\).

(d) Find the feedback gain \(K\) so that the eigenvalues of \((A-BK)\) are equal to the desired closed-loop poles. Find the reference gain \(k_r\) so that the DC gain from \(z_r\) to \(z\) is equal to one. Note that \(K=(k_p, k_d)\) where \(k_p\) and \(k_d\) are the proportional and derivative gains found in Homework D.8. Why?

(e) Modify the control simulation code to implement the state feedback controller and then simulate. You do not need to include a disturbance input. To construct the state \(x=(z, \dot{z})^{\top}\) use a digital differentiator to estimate \(\dot{z}\).

image Homework D.12

(a) Modify the state feedback solution developed in Homework D.11 to add an integrator with anti-windup to the feedback loop for \(z\).

(b) Add a constant input disturbance of 0.25 Newtons to the input of the plant and allow the plant parameters to vary up to 20%.

(c) Tune the integrator pole (and other gains if necessary) to get good tracking performance.

image Homework D.13

The objective of this problem is to design an observer that estimates the state of the system and to use the estimated state in the controller designed in Homework D.12.

(a) For the sake of understanding the function of the observer, for this problem we will use exact parameters, without an input disturbance. Modify the mass dynamics so that the parameters known to the controller are the actual plant parameters (uncertainty parameter \(\alpha=0\)).

(b) Verify that the state-space system is observable by checking that \(\text{rank}(\mathcal{O}_{A,C})=n\).

(c) In the control block, add an observer to estimate the state \(\hat{x}\), and use the estimate of the state in your feedback controller. Tune the poles of the controller and observer to obtain good performance.

(d) Modify the simulation files so that the controller outputs both \(u\) and \(\hat{x}\). Add a plotting routine to plot both the state and the estimated state of the system on the same graph.

(e) As motivation for the next chapter, add an input disturbance to the system of \(0.25\) and observe that there is steady-state error in the response even though there is an integrator. This is caused by a steady-state error in the observation error. In the next chapter we will show how to remove the steady-state error in the observation error.

image Homework D.14

(a) Modify your solution from HW D.13 so that the uncertainty parameter is \(\alpha=0.2\), representing 20% inaccuracy in the knowledge of the system parameters, and so that the input disturbance is \(0.25\). Also, add noise to the output channel \(z_m\) with standard deviation of \(0.001\).

(b) Add a disturbance observer to the controller, and verify that the steady-state error in the estimator has been removed. Tune the system to get good response.

image Homework D.15

Draw by hand the Bode plot of the mass-spring-damper from force \(\tilde{F}\) to position \(\tilde{z}\). Use the bode command in MATLAB or Python and compare your results.

image Homework D.16

For the mass-spring-damper, use the bode command (from Python or MATLAB) to create a graph that simultaneously displays the Bode plots for (1) the plant, and (2) the plant under PID control, using the control gains calculated in Homework D.10. Use the dirty derivative when implementing the derivative portion of the PID control.

(a) What is the tracking error to a unit ramp under PID control?

(b) If the frequency content of the input disturbance \(d_{in}(t)\) is below \(\omega_{d_{in}} = 0.1\) radians per second, what percentage of the input disturbance shows up in the output \(z\) under PID control?

(c) If all of the frequency content of the noise \(n(t)\) is greater than \(\omega_{no} = 100\) radians per second, what percentage of the noise shows up in the output signal \(z\)?

image Homework D.17

For the mass-spring-damper, use the bode and margin commands (from MATLAB or Python) to find the phase and gain margin for the closed-loop system under PID control. On the same graph, plot the open-loop Bode plot and the closed-loop Bode plot. What is the bandwidth of the closed-loop system, and how does this relate to the crossover frequency? Use the gains found in HW D.10.

image Homework D.18

For this homework assignment we will use the loopshaping design technique to design a controller for the mass-spring-damper problem with dynamics given by \[Z(s) = \left(\frac{\frac{1}{m}}{s^2 + \frac{b}{m}s + \frac{k}{m}}\right) F(s).\] The controller designed in this problem will take the form \[F = C(s)E(s),\] where the error signal is \(e=z^r_f - z\), where \(z^r_f\) is the prefiltered reference command. Find the controller \(C(s)\) so that the closed-loop system meets the following specifications.

  • Reject constant input disturbances.

  • Track reference signals with frequency content below \(\omega_r=0.1\) rad/s to within \(\gamma_r=0.03\).

  • Attenuate noise on the measurement of \(z\) for all frequencies above \(\omega_n=500\) rad/s by \(\gamma_n=0.001\).

  • The phase margin is close to \(PM=60\) degrees.

  • Use a prefilter \(F(s)\) to reduce any peaking in the closed-loop response.

  • Implement a control strategy in simulation using the state-space or digital filter equivalents of \(C(s)\) and \(F(s)\).

E Design Study: Block on Beam

image

Figure 20.1 shows the system. The position of the block measured from the pivot point is \(z\) and the speed of the block along the direction of the beam is \(\dot{z}\). The angle of the beam from level is \(\theta\) and the angular speed of the beam is \(\dot{\theta}\). Gravity acts in the down direction. The mass of the block is \(m_1\) and the mass of the beam is \(m_2\). The length of the beam is \(\ell\). An external vertical force is applied at the end of the beam as shown in Fig. 20.1.

Use the following physical parameters: \(m_1=0.35\) kg, \(m_2=2\) kg, \(\ell=0.5\) m, \(g=9.8\) m/s\(^2\).

E.2 Kinetic energy.

E.3 Equations of Motion.

E.4 Linearize equations of motion.

E.5 Transfer function model.

E.6 State-space model.

E.8 Successive loop closure.

E.9 Integrators and system type.

E.P.6 Root locus PID.

E.10 Digital PID.

E.11 Full state feedback.

E.12 Full state with integrator.

E.13 Observer based control.

E.14 Disturbance observer.

E.15 Frequency Response.

E.16 Loop gain.

E.17 Stability margins.

E.18 Loopshaping design.

image Homework E.2

(a) Using the configuration variables \(z\) and \(\theta\), write an expression for the kinetic energy of the system. Assume that the block is a point mass with mass concentrated near the surface of the beam (i.e., it is not a tall block).

(b) Create an animation of the block on beam system. The inputs should be \(z\) and \(\theta\). Turn in a screen capture of the animation.

image Homework E.3

(a) Find the potential energy for the system.

(b) Define the generalized coordinates.

(c) Find the generalized forces and damping forces.

(d) Derive the equations of motion using the Euler-Lagrange equations.

(e) Referring to Appendices 25, 26, and 27, write a class or s-function that implements the equations of motion. Simulate the system using a variable force input. The output should connect to the animation function developed in homework E.2. Do not be surprised if the system does not behave well (i.e., the block seems to go off to infinity in one direction).

image Homework E.4

For the block-beam system:

(a) Find the equilibria of the system.

(b) Linearize the system about the equilibria using Jacobian linearization.

(c) If possible, linearize the system using feedback linearization.

image Homework E.5

For the block on beam system:

(a) Start with the linearized equations and use the Laplace transform to convert the equations of motion to the s-domain.

(b) Find the transfer functions from the input \(\tilde{F}(s)\) to the outputs \(\tilde{Z}(s)\) and \(\tilde{\Theta}(s)\). Find the transfer function from the input \(\tilde{\Theta}(s)\) to the output \(\tilde{Z}(s)\).

(c) Assume that deviations in the gravity torque away from the equilibrium torque due to motions of the block along the beam are small compared to the torque required to hold up the beam. This will allow you to ignore the \(m_1 g \tilde{z}\) term in the second equation of motion. How does this simplify your transfer functions?

(d) Draw a block diagram of your simplified system transfer functions in a cascade from the input \(\tilde{F}(s)\) to the intermediate state \(\tilde{\Theta}(s)\) and then to the output \(\tilde{Z}(s)\) .

image Homework E.6

Defining the states as \(\tilde{x}=(\tilde{z},\tilde{\theta},\dot{\tilde{z}},\dot{\tilde{\theta}})^{\top}\), the input as \(\tilde{u}=\tilde{F}\), and the measured output as \(\tilde{y}=(\tilde{z},\tilde{\theta})^{\top}\), find the linear state-space equations in the form \[\begin{aligned} \dot{\tilde{x}} &= A\tilde{x} + B\tilde{u} \\ \tilde{y} &= C\tilde{x} + D\tilde{u}. \end{aligned}\]

image Homework E.8

For the block and beam problem, do the following:

(a) Using the principle of successive loop closure, draw a block diagram that uses PD control for both inner loop control and outer loop control. For design purposes, let the equilibrium position for the block be \(z_e=\frac{\ell}{2}\). The input to the outer loop controller is the desired block position \(z_r\) and the output of the controller is the desired beam angle \(\tilde{\theta}_r\). The input to the inner loop controller is the desired beam angle \(\tilde{\theta}_r\) and the output is the force \(\tilde{F}\) on the end of the beam.

(b) Focusing on the inner loop, find the PD gains \(k_{P_\theta}\) and \(k_{D_\theta}\) so that the rise time of the inner loop is \(t_{r_\theta}=0.25\) second, and the damping ratio is \(\zeta_{\theta}=0.707\).

(c) Find the DC gain \(k_{DC_\theta}\) of the inner loop.

(d) Replacing the inner loop by its DC gain, find the PD gains \(k_{P_z}\) and \(k_{D_z}\) so that the rise time of the outer loop is \(t_{r_z}=10 t_{r_\theta}\) and the damping ratio is \(\zeta_z=0.707\).

(e) Implement the successive loop closure design for the block and beam in simulation where the commanded block position is given by a square wave with magnitude \(0.25\pm 0.15\) meters and frequency \(0.05\) Hz. Use the actual position in the block as a feedback linearizing term for the equilibrium force.

(f) Suppose that the size of the input force on the beam is limited to \(F_{\max}=15\) N. Modify the simulation to include a saturation block on the force \(F\). Using the rise time of the outer loop, tune the PD control law to get the fastest possible response without input saturation when a step of size \(0.25\) meter is placed on \(\tilde{z}^r\).

image Homework E.9

(a) When the inner loop controller for the block-beam system is PD control, what is the system type of the inner loop? Characterize the steady-state error when \(\tilde{\theta}^d\) is a step, a ramp, and a parabola. What is the system type with respect to an input disturbance?

(b) When the outer loop controller for the block-beam is PD control, what is the system type of the outer loop? Characterize the steady-state error when \(z^d\) is a step, a ramp, and a parabola. How does this change if you add an integrator? What is the system type with respect to an input disturbance for both PD and PID control?

image Homework E.P.6

Add an integrator to obtain PID control for the outer loop of the block-beam system. Put the characteristic equation in Evans’ form and use the MATLAB rlocus command to plot the root locus versus the integrator gain \(k_I\). Note that since the integrator gain will be negative, the transfer function in Evans’ form must be negated because the MATLAB rlocus command only plots the return for \(k_I>0\). Select a value for \(k_I\) that does not significantly change the other locations of the closed-loop poles.

image Homework E.10

The objective of this problem is to implement the PID controller using only measured outputs of the system.

(a) Modify the system dynamics file so that the parameters \(m_1\), \(m_2\), and \(\ell\) vary by up to 20% of their nominal value each time they are run (uncertainty parameter = 0.2). Also add a disturbance step input of magnitude \(0.5 N\).

(b) Change the simulation files so that the input to the controller is the output and not the state. Implement the nested PID loops in Problems E.11 in a separate class. Use the dirty derivative gain of \(\sigma=0.05\). Tune the integrators so that there is no steady-state error. The controller should only assume knowledge of the position \(z\), the angle \(\theta\), and the reference position \(z_r\).

(c) Note that the integrator gain will need to be negative which will cause problems for the anti-windup scheme that we have been implementing. Remove the old anti-windup scheme and implement a new scheme where the integrator only winds up when \(|\dot{z}|\) is small. You may also need to re-tune the rise time for the inner loop (due to the parameter uncertainty and disturbance input). Some combinations of uncertain parameters are very hard to recover from, so run your simulation multiple times before changing your gains significantly.

image Homework E.11

The objective of this problem is to implement a state feedback controller for the block and beam problem. Start with the simulation files developed in Homework E.10.

(a) Using the values for \(\omega_{n_z}\) and \(\zeta_z\) from Homework E.8, choose the desired locations of the four closed-loop poles so that their natural frequency is greater than \(\omega_{n_z}\) and damping ratio is greater than \(\zeta_z\).

(b) Add the state-space matrices \(A\), \(B\), \(C\), \(D\) derived in Homework E.6 to your param file.

(c) Verify that the state-space system is controllable by checking that \(\text{rank}(\mathcal{C}_{A,B})=n\).

(d) Find the feedback gain \(K\) such that the eigenvalues of \((A-BK)\) are equal to the desired closed-loop poles. Find the reference gain \(k_r\) so that the DC gain from \(z_r\) to \(z\) is equal to one.

(e) Implement the state feedback scheme in simulation and tune the closed-loop poles to vary the response of the system. Notice the effect of pole locations on the speed of response and the control effort required.

image Homework E.12

(a) Modify the state feedback solution developed in Homework E.11 to add an integrator with anti-windup to the feedback loop for \(z\).

(b) Add a constant input disturbance of 1 Newtons to the input of the plant and allow the plant parameters to vary up to 20%.

(c) Tune the integrator pole (and other gains if necessary) to get good tracking performance.

image Homework E.13

The objective of this problem is to design an observer that estimates the state of the system and to use the estimated state in the controller designed in Homework E.12.

(a) For the sake of understanding the function of the observer, for this problem we will use exact parameters, without an input disturbance. Modify the block beam dynamics so that the parameters known to the controller are the actual plant parameters (uncertainty parameter \(\alpha=0\)).

(b) Verify that the state-space system is observable by checking that \(\text{rank}(\mathcal{O}_{A,C})=n\).

(c) In the control block, add an observer to estimate the state \(\hat{x}\), and use the estimate of the state in your feedback controller. Tune the poles of the controller and observer to obtain good performance.

(d) Modify the simulation files so that the controller outputs both \(u\) and \(\hat{x}\). Add a plotting routine to plot both the state and the estimated state of the system on the same graph.

(e) As motivation for the next chapter, add an input disturbance to the system of \(0.5\) and observe that there is steady-state error in the response even though there is an integrator. This is caused by a steady-state error in the observation error. In the next chapter we will show how to remove the steady-state error in the observation error.

image Homework E.14

(a) Modify your solution from HW E.13 so that the uncertainty parameter is \(\alpha=0.2\), representing 20% inaccuracy in the knowledge of the system parameters, and so that the input disturbance is \(0.5\). Also, add noise to the output channels \(z_m\) and \(\theta_m\) with standard deviation of \(0.001\).

(b) Add a disturbance observer to the controller, and verify that the steady-state error in the estimator has been removed. Tune the system to get good response.

image Homework E.15

(a) Draw by hand the Bode plot of the inner loop transfer function from force \(\tilde{F}\) to angle \(\tilde{\theta}\) for the block-beam system. Use the bode command from MATLAB or Python and compare your results.

(b) Draw by hand the Bode plot of the outer loop transfer function from angle \(\tilde{\theta}\) to position \(\tilde{z}(t)\) for the block-beam system. Use the bode command and compare your results.

image Homework E.16

For the inner loop of the block-beam system, use the MATLAB or Python bode command to create a graph that simultaneously displays the Bode plots for (1) the plant, and (2) the plant under PD control, using the control gains calculated in Homework E.8. Use the dirty derivative when implementing the derivative portion of the PD control.

(a) To what percent error can the closed-loop system under PD control track the desired input if all of the frequency content of \(\theta_r(t)\) is below \(\omega_r = 1.0\) radians per second?

(b) If the frequency content of the input disturbance is all contained below \(\omega_{d_{in}}=0.8\) radians per second, what percentage of the input disturbance shows up in the output?

(c) If all of the frequency content of the noise \(n(t)\) is greater than \(\omega_{no} = 300\) radians per second, what percentage of the noise shows up in the output signal \(\theta\)?

For the outer loop of the block-beam, use the MATLAB or Python bode command to create a graph that simultaneously displays the Bode plots for (1) the plant, and (2) the plant under PID control using the control gains calculated in Homework E.10. Use the dirty derivative when implementing the derivative portion of the PID control.

(d) If the frequency content of an output disturbance is contained below \(\omega_{d_{out}}=0.1\) radian/sec, what percentage of the output disturbance will be contained in the output under PID control?

(e) If the reference signal is \(y_r(t) = 2\sin(0.6 t)\) what is the output error under PID control?

image Homework E.17

For this problem, use the gains found in HW E.10.

  • For the inner loop of the block-beam system, use the bode and margin commands (from MATLAB or Python) to find the phase and gain margin for the inner loop system under PD control. On the same graph, plot the open-loop Bode plot and the closed-loop Bode plot. What is the bandwidth of the closed-loop system, and how does this relate to the crossover frequency?

  • For the outer loop of the block-beam system, use the bode and margin commands to find the phase and gain margin for the outer loop system under PID control. Plot the open and closed-loop Bode plots for the outer loop on the same plot as the open and closed-loop Bode plots for the inner loop. What is the bandwidth of the closed-loop system, and how does this relate to the crossover frequency?

  • What is the bandwidth separation between the inner (fast) loop, and the outer (slow) loop? For this design, is successive loop closure justified?

image Homework E.18

For this homework assignment we will use the loopshaping design technique to design a successive loop closure controller for the block and beam problem.

  • First consider the inner loop, where \(P_{in}(s)\) is the transfer function of the inner loop derived in HW E.5. Design the inner control system \(C_{in}(s)\) to stabilize the system with a phase margin close to 60 degrees, and to ensure that reference inputs with frequency below \(\omega_r=1\) radians/sec have tracking error \(\gamma_r=0.0032\), and to ensure that noise above \(\omega_n=1000\) radians/second is rejected by \(\gamma_n=0.0032\).

  • Now consider the design of the controller for the outer loop system. The ‘plant’ for the design of the outer loop controller is \[P = P_{out}\frac{P_{in}C_{in}}{1+P_{in}C_{in}}.\] Design the outer loop controller \(C_{out}\) so that the system is stable with phase margin close to \(PM=60\) degrees, and so that constant input disturbances are rejected, reference signals with frequency below \(\omega_r=0.1\) radians/sec are tracked with error \(\gamma_r=0.01\), and noise with frequency content above \(\omega_n=100\) radians/sec are rejected with \(\gamma_n=0.001\). Add a prefilter \(F(s)\) to reduce peaking in the closed-loop transfer function.

  • Implement the developed control strategy in simulation using the state-space equivalents of \(C(s)\) and \(F(s)\).

F Design Study: Planar VTOL

image

In this design study we explore the control design for a simplified planar version of a quadrotor following a ground target. In particular, we constrain the dynamics to a two-dimensional plane. In Cartesian space, the position of the VTOL can be defined by a variable describing the vertical position, one describing the horizontal position, and one angular variable describing the orientation, as shown in Fig. 21.1. The planar vertical takeoff and landing (VTOL) system consists of a center pod of mass \(m_c\) and inertia \(J_c\), a right motor/rotor that is modeled as a point mass \(m_r\) that exerts a force \(f_r\) at a distance \(d\) from the center of mass, and a left motor/rotor that is modeled as a point mass \(m_\ell\) that exerts a force \(f_\ell\) at a distance \(-d\) from the center of mass. The position of the center of mass of the planar VTOL system is given by horizontal position \(z_v\) and altitude \(h\). The airflow through the rotor creates a change in the direction of flow of air and causes what is called “momentum drag.” Momentum drag can be modeled as a viscous drag force that is proportional to the horizontal velocity \(\dot{z}_v\). In other words, the drag force is \(F_{\text{drag}}=-\mu \dot{z}_v\). The target on the ground will be modeled as an object with position \(z_t\) and altitude \(h=0\). We will not explicitly model the dynamics of the target.

Use the following physical parameters: \(m_c=1\) kg, \(J_c=0.0042\) kg m\(^2\), \(m_r=0.25\) kg, \(m_\ell=0.25\) kg, \(d=0.3\) m, \(\mu = 0.1\) kg/s, \(g=9.81\) m/s\(^2\).

F.2 Kinetic energy.

F.3 Equations of Motion.

F.4 Linearize equations of motion.

F.5 Transfer function model.

F.6 State-space model.

F.7 Pole Placement using PD.

F.8 Successive loop closure.

F.9 Integrators and system type.

F.P.6 Root locus.

F.10 Digital PID.

F.11 Full state feedback.

F.12 Full state with integrator.

F.13 Observer based control.

F.14 Disturbance observer.

F.15 Frequency Response.

F.16 Loop gain.

F.17 Stability margins.

F.18 Loopshaping design.

image Homework F.2

(a) Using the configuration variables \(z_v\), \(h\), and \(\theta\), write an expression for the kinetic energy of the system.

(b) Create an animation of the planar VTOL system. The inputs to the animation should be \(z_v\), \(z_t\), \(h\), and \(\theta\). Turn in a screen capture of the animation.

image Homework F.3

(a) Find the potential energy for the system.

(b) Define the generalized coordinates and damping forces.

(c) Find the generalized forces. Note that the right and left forces are more easily modeled as a total force on the center of mass, and a torque about the center of mass.

(d) Derive the equations of motion for the planar VTOL system using the Euler-Lagrange equations.

(e) Referring to Appendices 25, 26, and 27, write a class or s-function that implements the equations of motion. Simulate the system using variable force inputs \(f_r\) and \(f_\ell\). The output should connect to the animation function developed in Homework F.2. Do not be surprised if the system does not behave well (i.e., if the VTOL system seems to crash or go off to infinity). We are simulating an open-loop system with no control to stabilize its behavior.

image Homework F.4

Since \(f_r\) and \(f_\ell\) appear in the equations as either \(f_r+f_\ell\) or \(d(f_r-f_\ell)\), it is easier to think of the inputs as the total force \(F\stackrel{\triangle}{=}f_r+f_\ell\), and the torque \(\tau=d(f_r-f_\ell)\). Note that since \[\begin{pmatrix} F \\ \tau \end{pmatrix} = \begin{pmatrix} 1 & 1 \\ d & -d \end{pmatrix}\begin{pmatrix} f_r \\ f_\ell \end{pmatrix},\] then \[\begin{pmatrix} f_r \\ f_\ell \end{pmatrix} = \begin{pmatrix} 1 & 1 \\ d & -d \end{pmatrix}^{-1}\begin{pmatrix} F \\ \tau \end{pmatrix} = \begin{pmatrix} \frac{1}{2} & \frac{1}{2d} \\ \frac{1}{2} & -\frac{1}{2d} \end{pmatrix} \begin{pmatrix} F \\ \tau \end{pmatrix}.\] Therefore, in subsequent exercises, if we determine \(F\) and \(\tau\), then the right and left forces are given by \[\begin{aligned} f_r &= \frac{1}{2} F + \frac{1}{2d}\tau \\ f_\ell &= \frac{1}{2}F - \frac{1}{2d}\tau. \end{aligned}\]

(a) Find the equilibria of the system.

(b) Linearize the equations about the equilibria using Jacobian linearization.

(c) If possible, linearize the system using feedback linearization.

image Homework F.5

For the planar VTOL system, note that the system naturally divides into so-called longitudinal dynamics (up-down motion) with total force \(\tilde{F}\) as the input and altitude \(\tilde{h}\) as the output, and lateral dynamics (side-to-side motion) with \(\tilde{\tau}\) as the input and \(\tilde{z}\) as the output, with \(\tilde{\theta}\) as an intermediate variable.

(a) Start with the linearized equations of motion and use the Laplace transform to convert the equations of motion to the s-domain.

(b) For the longitudinal dynamics, find the transfer function from the input \(\tilde{F}(s)\) to the output \(\tilde{H}(s)\).

(c) For the lateral dynamics, find the transfer function from the input \(\tilde{\tau}(s)\) to the intermediate state \(\tilde{\Theta}(s)\) and the output \(\tilde{Z}(s)\). Find the transfer function from \(\tilde{\Theta}(s)\) to \(\tilde{Z}(s)\).

(d) Draw a block diagram of the open loop longitudinal and lateral systems.

image Homework F.6

(a) Defining the longitudinal states as \(\tilde{x}_{lon}=(\tilde{h}, \dot{\tilde{h}})^\top\) and the longitudinal input as \(\tilde{u}_{lon}=\tilde{F}\) and the longitudinal output as \(\tilde{y}_{lon} = \tilde{h}\), find the linear state-space equations in the form \[\begin{aligned} \dot{\tilde{x}}_{lon} &= A\tilde{x}_{lon} + B\tilde{u}_{lon} \\ \tilde{y}_{lon} &= C\tilde{x}_{lon} + D\tilde{u}_{lon}. \end{aligned}\]

(b) Defining the lateral states as \(\tilde{x}_{lat}=(\tilde{z}, \tilde{\theta}, \dot{\tilde{z}}, \dot{\tilde{\theta}})^\top\) and the lateral input as \(\tilde{u}_{lat}=\tilde{\tau}\) and the lateral output as \(\tilde{y}_{lat} = (\tilde{z}, \tilde{\theta})^\top\), find the linear state-space equations in the form \[\begin{aligned} \dot{\tilde{x}}_{lat} &= A\tilde{x}_{lat} + B\tilde{u}_{lat} \\ \tilde{y}_{lat} &= C\tilde{x}_{lat} + D\tilde{u}_{lat}. \end{aligned}\]

image Homework F.7

For this problem we will only consider the longitudinal (up-down) dynamics of the VTOL system.

(a) Given the open-loop transfer function from total force \(\tilde{F}\) to altitude \(\tilde{h}\) found in homework  F.5, find the open-loop poles of the system.

(b) Using modified PD control architecture shown in the textbook, find the closed-loop transfer function from \(\tilde{h}_r\) to \(\tilde{h}\) and find the closed-loop poles as a function of \(k_P\) and \(k_D\).

(c) Select \(k_P\) and \(k_D\) to place the closed-loop poles at \(p_1=-0.2\) and \(p_2=-0.3\).

(d) Using the gains from part (c), implement the PD control for the altitude control in simulation and plot the response for a reference input of a square wave with magnitude \(5 \pm 3\) meters and frequency \(0.03\) Hz.

image Homework F.8

For the VTOL system, do the following:

(a) For the longitudinal (altitude) dynamics of the VTOL, suppose that the design requirements are that the rise time is \(t_r \approx 8\) seconds, with a damping ratio of \(\zeta=0.707\). Find the desired closed-loop characteristic polynomial \(\Delta_{cl}^d(s)\), and the associated pole locations. Find the proportional and derivative gains \(k_{P_h}\) and \(k_{D_h}\) to achieve these specifications, and modify the computer simulation from HW F.7 to verify that the response satisfies the requirements using the same reference input.

(b) The lateral dynamics (side-to-side) will be designed using successive loop closure with the inner-loop using torque to regulate the roll angle, and the outer-loop using roll angle to regulate the position \(z\). Focusing on the inner loop, find the PD gains \(k_{P_\theta}\) and \(k_{D_\theta}\) so that the rise time of the inner loop is \(t_{r_\theta}=0.8\) seconds, and the damping ratio is \(\zeta_{\theta}=0.707\).

(c) Find the DC gain \(k_{DC_\theta}\) of the inner loop.

(d) Replacing the inner loop by its DC gain, find the PD gains \(k_{P_z}\) and \(k_{D_z}\) so that the rise time of the outer loop is \(t_{r_z}=10 t_{r_\theta}\) and the damping ratio is \(\zeta_z=0.707\).

(e) Implement the successive loop closure design for the lateral control of the VTOL system where the commanded lateral position is given by a square wave with magnitude \(5 \pm 4\) meters and frequency \(0.05\) Hz. Tune the rise time for the inner lateral control loop to achieve good performance.

(f) Suppose that the size of the force on each rotor is constrained by \(0\leq f_\ell \leq f_{\max}=10\) N, and \(0\leq f_r \leq f_{\max}=10\) N. Modify the simulation to include saturations on the right and left forces \(f_\ell\) and \(f_r\). Using the rise time for the altitude controller, and the rise time for the lateral controller as tuning parameters, tune the controller to achieve the fastest possible response without input saturation.

image Homework F.9

(a) When the longitudinal controller for the VTOL system is PD control, what is the system type? Characterize the steady-state error when \(h^d\) is a step, a ramp, and a parabola. How does this change if you add an integrator? What is the system type with respect to an input disturbance for both PD and PID control?

(b) When the inner loop of the lateral controller for the VTOL system is PD control, what is the system type of the inner loop? Characterize the steady-state error when \(\tilde{\theta}^d\) is a step, a ramp, and a parabola. What is the system type with respect to an input disturbance?

(c) When the outer loop of the lateral controller for the VTOL system is PD control, what is the system type of the outer loop? Characterize the steady-state error when \(z^d\) is a step, a ramp, and a parabola. How does this change if you add an integrator? What is the system type with respect to an input disturbance for both PD and PID control?

image Homework F.P.6

(a) Add an integrator to obtain PID control for the longitudinal controller for the VTOL system. Put the characteristic equation in Evans’ form and use the MATLAB/Python rlocus command to plot the root locus versus the integrator gain \(k_{I_h}\). Select a value for \(k_{I_h}\) that does not significantly change the other locations of the closed-loop poles.

(b) Add an integrator to obtain PID control for the outer loop of the lateral controller for the VTOL system. Put the characteristic equation of the outer loop in Evans’ form and use the MATLAB/Python rlocus command to plot the root locus versus the integrator gain \(k_{I_z}\). Select a value for \(k_{I_z}\) that does not significantly change the other locations of the closed-loop poles.

image Homework F.10

The objective of this problem is to implement the PID controller using only measured outputs of the system.

(a) Modify the system dynamics file so that the parameters \(m_c\), \(J_c\), \(d\), and \(\mu\) vary by up to 20% of their nominal value each time they are run (uncertainty parameter = 0.2).

(b) Change the simulation files so that the input to the controller is the output and not the state. Implement the nested PID loops in Problem F.8. Use the dirty derivative gain of \(\sigma=0.05\). Tune the integrator so that there is no steady-state error. You may also adjust damping and rise time to improve performance. The controller should only assume knowledge of the position \(z\), the angle \(\theta\), the altitude \(h\), the reference position \(z_r\), and the reference altitude \(h_r\).

image Homework F.11

The objective of this problem is to implement a state feedback controller for the VTOL system. Start with the simulation files developed in Homework F.10.

(a) Using the values for \(\omega_{n_h}\), \(\zeta_h\), \(\omega_{n_z}\), and \(\zeta_z\) from Homework F.8, choose the closed-loop pole locations to ensure that the longitudinal poles have damping ratios greater than \(\zeta_h\) and natural frequencies greater than \(\omega_{n_h}\). Similarly, choose the closed-loop poles for the lateral dynamics to ensure that their damping ratios are greater than \(\zeta_z\) and natural frequencies greater than \(\omega_{n_z}\).

(b) Add the state-space matrices \(A\), \(B\), \(C\), \(D\) derived in Homework F.6 to your param file.

(c) Verify that the state-space system is controllable by checking that \(\text{rank}(\mathcal{C}_{A,B})=n\).

(d) Find the feedback gain \(K\) such that the eigenvalues of \((A-BK)\) are equal to the desired closed-loop poles. Find the reference gains \(k_{r_h}\) and \(k_{r_z}\) so that the DC gain from \(h_r\) to \(h\) is equal to one and the DC gain from \(z_r\) to \(z\) is equal to one.

(e) Implement the state feedback scheme and tune the closed-loop poles to get acceptable response. What changes would you make to your closed-loop pole locations to decrease the rise time of the system? How would you change them to lower the overshoot in response to a step command?

image Homework F.12

Modify the state feedback solution developed in Homework F.11 to add an integrator with anti-windup to the altitude feedback loop and to the position feedback loop.

Allow the plant parameters to vary up to 20% and add a constant input disturbance of \(0.1\) Newtons to the input of position dynamics simulating wind. Hint: The best place to add the wind force is in the class that implements the dynamics. For example, one possibility is to modify the \(z\) dynamics as: \(\ddot{z} = \left(-(f_r+f_l)sin(\theta)-\mu\dot{z}+F\_{wind}\right)/\left(m_c+2m_r\right)\)

Tune the integrator poles on both loops (and other gains if necessary) to get good tracking performance.

image Homework F.13

The objective of this problem is to design an observer that estimates the state of the system and to use the estimated state in the controller designed in Homework F.12.

(a) For the sake of understanding the function of the observer, for this problem we will use exact parameters, without an input disturbance. Modify the VTOL dynamics so that the parameters known to the controller are the actual plant parameters (uncertainty parameter \(\alpha=0\)).

(b) Verify that the state-space system is observable by checking that \(\text{rank}(\mathcal{O}_{A,C})=n\).

(c) In the control block, add an observer to estimate the state \(\hat{x}\), and use the estimate of the state in your feedback controller. Tune the poles of the controller and observer to obtain good performance.

(d) Modify the simulation files so that the controller outputs both \(u\) and \(\hat{x}\). Add a plotting routine to plot both the state and the estimated state of the system on the same graph.

(e) As motivation for the next chapter, add an input force disturbance to the system of \(1.0\) and an input torque disturbance of \(0.1\) and observe that there is steady-state error in the response even though there is an integrator. This is caused by a steady-state error in the observation error. In the next chapter we will show how to remove the steady-state error in the observation error.

image Homework F.14

(a) Modify your solution from HW F.13 so that the uncertainty parameter is \(\alpha=0.2\), representing 20% inaccuracy in the knowledge of the system parameters. Modify VTOL_dynamics to add an altitude disturbance of \(1.0\) and a wind disturbance of \(1.0\) m/s. A Python code snippet that implements these disturbances is given by

  from math import sin
  # disturbances
  wind = 1.0
  altitude_dist = 1.0

  # add wind disturbance
  zdot = zdot + wind

  zddot = -(fr+fl)*sin(theta)/(mc+2*mr)
  hddot = (-(mc+2*mr)*g  \ 
           + (fr+fl)*cos(theta))/(mc+2*mr)  \ 
           + altitude_dist
  thetaddot = d*(fr-fl)/(Jc+2*mr*d**2)

Before adding the disturbance observer, run the simulation and note that the controller is not robust to the input disturbance.

(b) Add a disturbance observer to both controllers, and add noise to each output with standard deviation of \(0.01\). Then verify that the steady-state error in the estimator has been removed and that the disturbances have been adequately compensated. Tune the system to get good response.

image Homework F.15

Draw by hand the Bode plot of the altitude transfer function from force \(\tilde{F}\) to altitude \(\tilde{h}\). Use the bode command (from MATLAB or Python) and compare your results.

Draw by hand the Bode plot of the inner loop transfer function for the lateral dynamics from torque \(\tau\) to angle \(\theta\). Use the bode command and compare your results.

Draw by hand the Bode plot of the outer loop transfer function for the lateral dynamics from angle \(\theta\) to position \(z(t)\). Use the bode command and compare your results.

image Homework F.16

For the altitude hold loop of the VTOL system, use the bode command (from MATLAB or Python) to create a graph that simultaneously displays the Bode plots for (1) the plant, and (2) the plant under PID control using the control gains calculated in Homework F.10. Use the dirty derivative when implementing the derivative portion of the PID control.

(a) What is the tracking error if the reference input is a parabola with curvature \(5\)?

(b) If all of the frequency content of the noise \(n(t)\) is greater than \(\omega_{no} = 30\) radians per second, what percentage of the noise shows up in the output signal \(h\)?

For the inner loop of the lateral controller for the VTOL system, use the bode command to create a graph that simultaneously displays the Bode plots for (1) the plant, and (2) the plant under PD control, using the control gains calculated in Homework F.8. Use the dirty derivative when implementing the derivative portion of the PD control.

(c) If the frequency content of the input disturbance is all contained below \(\omega_{d_{in}}=2\) radians per second, what percentage of the input disturbance shows up in the output?

(d) If a sensor for \(\theta\) is to be selected, what are the characteristics of the sensor (frequency band and size) that would result in measurement noise for \(\theta\) that is less than \(0.1\) degrees?

For the outer loop of the lateral controller for the VTOL system, use the bode command to create a graph that simultaneously displays the Bode plots for (1) the plant, and (2) the plant under PID control, using the control gains calculated in Homework F.10.

(e) To what percent error can the closed-loop system track the desired input if all of the frequency content of \(z_r(t)\) is below \(\omega_r = 0.1\) radians per second?

(f) If the frequency content of an output disturbance is contained below \(\omega_{d_{out}}=0.01\) radian/sec, what percentage of the output disturbance will be contained in the output?

image Homework F.17

For this problem, use the gains found in Homework F.10.

  • For the altitude hold loop of the VTOL system, use the bode and margin commands (from MATLAB or Python) to find the phase and gain margin for the closed-loop system under PID control. On the same graph, plot the open-loop Bode plot and the closed-loop Bode plot. What is the bandwidth of the closed-loop system, and how does this relate to the crossover frequency?

  • For the inner loop of the lateral control loop, use the bode and margin commands to find the phase and gain margin for the inner loop system under PD control. On the same graph, plot the open-loop Bode plot and the closed-loop Bode plot. What is the bandwidth of the closed-loop system, and how does this relate to the crossover frequency?

  • For the outer loop of the lateral control loop, use the bode and margin commands to find the phase and gain margin for the outer loop system under PD control. Plot the open and closed-loop Bode plots for the outer loop on the same plot as the open and closed-loop Bode plots for the inner loop. What is the bandwidth of the closed-loop system, and how does this relate to the crossover frequency?

  • What is the bandwidth separation between the inner (fast) loop, and the outer (slow) loop? For this design, is successive loop closure justified?

image Homework F.18

For this homework assignment we will use the loopshaping design technique to design a controller for the VTOL flight control problem.

(a) First consider the longitudinal or altitude control problem. For this part, the force command will be \[F = F_e + C_{lon}(s)E_h(s),\] where \(F_e\) is the equilibrium force as found in other homework problems, and the error signal is \(e_h=h^r_f - h_m\), where \(h^r_f\) is the prefiltered reference altitude command, and \(h_m\) is the measured altitude. Find the longitudinal controller \(C_{lon}(s)\) so that the closed-loop system meets the following specifications.

  • Reject constant input disturbances.

  • Track reference signals with frequency content below \(\omega_r=0.1\) rad/s to within \(\gamma_r=0.01\).

  • Attenuate noise on the measurement of \(h\) for all frequencies above \(\omega_n=200\) rad/s by \(\gamma_n=10^{-4}\).

  • The phase margin is close to \(PM=60\) deg.

  • Use a prefilter to improve the closed-loop response.

(b) Now consider the inner loop of the lateral, or position, dynamics. Find the inner loop controller \(C_{lat_{in}}(s)\) so that the inner loop is stable with phase margin approximately \(PM=60\) deg, and with closed-loop bandwidth approximately \(\omega_{co}=10\) rad/s. Add a low-pass filter to enhance noise rejection.

(c) For the outer loop of the lateral system, find the controller \(C_{lat_{out}}(s)\) to meet the following specifications:

  • Crossover frequency is around \(\omega_{co}=1\) rad/s.

  • Reject constant input disturbances.

  • Attenuate noise on the measurement of \(z\) for all frequencies above \(\omega_{no}=100\) rad/s by \(\gamma_{no}=10^{-5}\) .

  • The phase margin is close to \(PM=60\) deg.

  • Use a prefilter to reduce overshoot in the step response.

(d) Implement the developed control strategy in simulation using the state-space or digital filter equivalents of \(C(s)\) and \(F(s)\).

Appendices

Appendices

P.1 Simulating Control Systems Using Python

In this appendix we will show how to simulate the feedback control of a dynamic system using Python. Consider the general feedback control system shown in Figure 1.1. The output of the physical system is \(y(t)\), and the input to the physical system is \(u(t)\) plus an external disturbance signal \(d(t)\). The output of the system is corrupted by zero-mean noise \(n(t)\). The input to the controller is the reference signal \(r(t)\) as well as the output corrupted by noise. In Python, each block shown in Figure 1.1 is implemented using a Python class.

Block diagram of a general feedback system.

We will illustrate how to implement feedback control systems in Python by simulating the physical system described by the differential equation \[\tag{P.1.1} \ddot{y} + 2\dot{y} + 3 y = 4 u,\] and using the PID controller \[\tag{P.3.2} u(t) = k_p (r(t)-y(t)) + k_i \int_{-\infty}^t (r(\tau)-y(\tau))d\tau - k_d \dot{y}.\]

The feedback control system shown in Figure 1.1 is simulated in systemSim.py, which is listed below.

import matplotlib.pyplot as plt
from systemDynamics import systemDynamics
from systemController import systemController
from signalGenerator import signalGenerator
from systemAnimation import systemAnimation
from dataPlotter import dataPlotter

# simulation parameters
t_start = 0.0  # start time
t_end = 20.0  # end time
t_plot = 0.1  # sample rate for plotter and animation
Ts = 0.01  # sample rate for dynamics and controller

# instantiate system, controller, and reference classes
system = systemDynamics(sample_rate=Ts)
controller = pendulumController(sample_rate=Ts)
reference = signalGenerator(amplitude=0.5, frequency=0.05)
disturbance = signalGenerator(amplitude=1.0, frequency = 0.0)
noise = signalGenerator(amplitude=0.01)

# instantiate the simulation plots and animation
dataPlot = dataPlotter()
animation = systemAnimation()

t = t_start  # time starts at t_start
y = system.h()  # output of system at start of simulation
while t < t_end:  # main simulation loop
    # set time for next plot
    t_next_plot = t + t_plot
    # Propagate dynamics and controller at fast rate Ts
    while t < t_next_plot:
        r = reference.square(t)  # assign reference
        d = disturbance.step(t)  # simulate input disturbance
        n = noise.random(t)  # simulate sensor noise
        u = controller.update(r, y + n)  # update controller
        y = system.update(u + d)  # Propagate the dynamics
        t = t + Ts  # advance time by Ts
    # update animation and data plots
    animation.update(system.state)
    dataPlot.update(t, ref_input, pendulum.state, u)
    # pause causes the figure to be displayed during the simulation
    plt.pause(0.0001)

# Keeps the program from closing until the user presses a button.
print('Press key to close')
plt.waitforbuttonpress()
plt.close()

The physical system is implemented in a class contained in
systemDynamic.py, which will be discussed below, and which is imported on line 2, and instantiated on line 15. The system is updated at sample rate \(T_s\) given the control input \(u\) and the input disturbance \(d\) on line 36.

The controller is implemented in a class contained in
systemController.py, which will be discussed below, and which is imported on line 3, and instantiated on line 16. Given the reference input \(r\), and the system output \(y\), the controller is updated at the fast sample rate \(T_s\) on line 35. At the initial time, the controller needs the initial output at time \(t=0\), which is computed on line 26 before the main loop begins.

The reference input is implemented using the signalGenerator class that is contained in signalGenerator.py, which is described below and imported on line 4 and instantiated on line 17. The reference input at time \(t\), i.e., \(r(t)\), is assigned a value on line 32.

The external disturbance \(d(t)\) is also implemented using the
signalGenerator class and is instantiated on line 17, and assigned a value on line 33. For this example, the external disturbance will be a constant value of \(d(t)=1.0\). The disturbance is assigned on line 33, and is input to the system on line 36.

In addition to the feedback loop implemented above, the system will be visualized through an animation and by plotting important variables such as the reference input, the system states, and the control input. The animation and data plotting functions are implemented in systemAnimation.py and
dataPlotter.py, imported on lines 5 and 6, instantiated on lines 22 and 23, and updated on lines 39 and 40. The pause command on line 42 forces the animation and data plotting functions to update their displays each time through the loop.

P.1.1 System Dynamics

This section will describe how to implement the system dynamics given in Equation P.1.1. The first step is to convert the dynamics to the state-space form \[\begin{aligned} \dot{x} &= f(x, u) \\ y &= h(x,u). \end{aligned}\] For the differential equation in Equation P.1.1 let \(x = (y, \dot{y})^\top\), which gives \begin{align} \dot{x}& = \begin{pmatrix} \dot{x}_1 \\ \dot{x}_2 \end{pmatrix} = \begin{pmatrix} \dot{y} \\ \ddot{y} \end{pmatrix} = \begin{pmatrix} \dot{y} \\ -2\dot{y} - 3y + 4u \end{pmatrix} = \begin{pmatrix} x_2 \\ -2x_2 - 3 x_1 + 4 u \end{pmatrix} \stackrel{\triangle}{=}f(x,u) \tag{P.1.3} \\ y &= x_1 \stackrel{\triangle}{=}h(x). \tag{P.1.4} \end{align}

The dynamics of the system are implemented in systemDynamics.py, which is listed below.

import numpy as np 

class systemDynamics:
    def __init__(self, sample_rate):
        # Initial state conditions
        y0 = 0.0
        ydot0 = 0.0
        self.state = np.array([
            [y0],  # initial condition for y
            [ydot0],  # initial condition for ydot
        ])
        self.Ts = sample_rate  # sample rate of system
        self.limit = 1.0  # input saturation limit
        # system parameters
        self.a0 = 3.0
        self.a1 = 2.0
        self.b0 = 4.0
        # modify the system parameters by random value
        alpha = 0.2  # Uncertainty parameter
        self.a1 = self.a1 * (1.+alpha*(2.*np.random.rand()-1.))
        self.a0 = self.a0 * (1.+alpha*(2.*np.random.rand()-1.))
        self.b0 = self.b0 * (1.+alpha*(2.*np.random.rand()-1.))

    def f(self, state, u):
        # for system xdot = f(x,u), return f(x,u)
        y = state.item(0)
        ydot = state.item(1)
        # The equations of motion.
        yddot = -self.a1 * ydot - self.a0 * y + self.b0 * u
        # build xdot and return
        xdot = np.array([[ydot], [yddot]])
        return xdot

    def h(self):
        # Returns the measured output y = h(x)
        y = self.state.item(0)
        # return output
        return y

    def update(self, u):
        # This is the external method that takes the input u(t)
        # and returns the output y(t).
        u = self.saturate(u, self.limit)  # saturate the input
        self.rk4_step(u)  # propagate the state by one time step
        y = self.h()  # compute the output at the current state
        return y

    def rk4_step(self, u):
        # Integrate ODE using Runge-Kutta RK4 algorithm
        F1 = self.f(self.state, u)
        F2 = self.f(self.state + self.Ts / 2 * F1, u)
        F3 = self.f(self.state + self.Ts / 2 * F2, u)
        F4 = self.f(self.state + self.Ts * F3, u)
        self.state += self.Ts / 6 * (F1 + 2 * F2 + 2 * F3 + F4)

    def saturate(self, u, limit):
        if abs(u) > limit:
            u = limit*np.sign(u)
        return u

The system is initialized in lines 4–22. The state is initialized in lines 6–11 based on the initial conditions for \(y(0)\) and \(\dot{y}(0)\). The system parameters are initialized in lines 15–22. The parameters for any physical system are never known exactly. Therefore, feedback systems need to be designed to be robust to this uncertainty. In the simulation, we model uncertainty in our knowledge of the physical parameters by changing the nominal value by a uniform random variable. Let \(\alpha\) be the amount of change allowed for each parameter. For example, \(\alpha = 0.2\) means that the physical parameters may change by up to 20%. The function np.random.rand() returns a uniform random variable in the interval \([0, 1]\). Therefore, \((1 + \alpha (2*\texttt{np.random.rand()}-1))\) is a random variable in the interval \([-\alpha, \alpha]\). The nominal values for the physical parameters that are known to the designer are specified in lines 15–17. The actual values used by the simulation are randomly selected in lines 19–22.

The system dynamics \[\begin{aligned} \dot{x} &= f(x, u) \\ y &= h(x, u). \end{aligned}\] are specified in lines 24–38. Lines 24–32 define \(f(x,u)\), and lines 34–38 define \(h(x, u)\), as given by Equations P.1.3 and P.1.4 respectively.

The main feedback loop calls the update routine in lines 40–46. The update function first saturates the input in line 43, where the saturation function is defined in lines 56–59. The system dynamics are then propagated forward by one sample time \(T_s\) using the fourth-order Runge-Kutta algorithm in line 44, where the RK4 algorithm is specified in lines 48–54, as described in Appendix 28. The update function finally computes and returns the output \(y\) in lines 45–46.

P.1.2 Controller

This section will describe how to implement the PID controller given in Equation P.3.2. The controller is implemented in systemController.py, which is listed below.

import numpy as np

class systemController:
    def __init__(self, sample_rate):
        # specify gains
        self.kp = 1.0
        self.kd = 1.0
        self.ki = 1.0
        self.Ts = sample_rate
        self.sigma = 2.0 * self.Ts
        self.beta = (2.0*sigma-self.Ts)/(2.0*sigma+self.Ts)
        self.limit = 1.0
        # internal storage for differentiator
        self.y_dot = 0.0
        self.y_d1 = 0.0
        # internal storage for integrator
        self.integrator = 0
        self.error_d1 = 0

    def update(self, r, y):
        e = r - y  # define the error
        I = self.integrate_e(e)  # integrate error
        ydot = self.differentiate_y(y)  # differentiate y
        # form PID controller, saturate, and return
        u = self.kp * e + self.ki * I - self.kd * ydot
        u = self.saturate(u)
        return u

    def integrate_e(self, e):
        self.integrator = self.integrator 
            + (self.Ts / 2) * (error + self.error_d1)
        self.error_d1 = error
        return self.integrator

    def differentiate_y(self, y):
        self.y_dot = self.beta*self.y_dot 
            + (1-self.beta)/self.Ts * (y - self.y_d1)
        self.y_d1 = y
        return self.y_dot

    def saturate(self, u):
        if abs(u) > self.limit:
            u = self.limit*np.sign(u)
        return u

The controller is instantiated in lines 4–18. The PID gains are specified in lines 6–8. The sample rate of the controller is passed into the system at the time of instantiation and is assigned an internal variable \(T_s\) in line 9. The dirty derivative gain \(\sigma\), described in Chapter 13, is specified in line 10, and the intermediate gain \(\beta = \frac{2\sigma-T_s}{2\sigma+T_s}\) is specified on line 11. Internal storage variables for the differentiator and the integrator, as explained in Chapter 13, are given in lines 13–18. The PID control update routine is specified in lines 20–27. The error \(e=r-y\), as shown in Figure 1.1, is defined in line 21. The PID controller in Equation P.3.2 uses the integral of \(e\) and the derivative of \(y\). The integral of \(e\) is computed on line 22 using the routine specified in lines 29–33. A derivation of the integral equations is given in Chapter 13. The derivative of \(y\) is computed in line 23 using the routine specified in lines 35–39. A derivation of the dirty derivative equations is given in Chapter 13. Finally, the PID controller is computed, the value is saturated, and the result is returned in lines 25, 26, and 27, respectively.

P.1.3 Signal Generator

Python code for the signal generator class is listed below.

import numpy as np

class signalGenerator:
    def __init__(self, amplitude=1.0, frequency=0.001, y_offset=0):
        self.amplitude = amplitude  # signal amplitude
        self.frequency = frequency  # signal frequency
        self.y_offset = y_offset  # signal y-offset

    def square(self, t):
        if t % (1.0/self.frequency) <= 0.5/self.frequency:
            out = self.amplitude + self.y_offset
        else:
            out = - self.amplitude + self.y_offset
        return out

    def sawtooth(self, t):
        tmp = t % (0.5/self.frequency)
        out = 4 * self.amplitude * self.frequency*tmp 
              - self.amplitude + self.y_offset
        return out

    def step(self, t):
        if t >= 0.0:
            out = self.amplitude + self.y_offset
        else:
            out = self.y_offset
        return out

    def random(self, t):
        out = np.random.normal(self.y_offset, self.amplitude)
        return out

    def sin(self, t):
        out = self.amplitude * np.sin(2*np.pi*self.frequency*t) 
              + self.y_offset
        return out

The class is instantiated by passing in the desired amplitude of the signal, the frequency in Hertz, and a y-offset value. For random signals, the amplitude is interpreted to be the standard deviation of the signal. The signal generator can then be used to produce a square wave, a sawtooth signal, a step, a random signal, or a sinusoid, as specified in lines 9–36.

P.1.4 Data Plotter

The objective of the data plotter is to plot the relevant signals during the simulation. For this simple example, we will plot the output \(y\) and the reference \(r\) on one plot, the velocity \(\dot{y}\) on another plot, and the control signal \(u\) on a third plot. For plotting and animation, we will use the Python Matplotlib library. Python code for the data plotter class is listed below.

import matplotlib.pyplot as plt 
from matplotlib.lines import Line2D
import numpy as np

plt.ion()  # enable interactive drawing

class dataPlotter:
    def __init__(self):
        # Number of subplots = num_of_rows*num_of_cols
        self.num_rows = 3    # Number of subplot rows
        self.num_cols = 1    # Number of subplot columns
        # Crete figure and axes handles
        self.fig, self.ax = plt.subplots(self.num_rows,
                                         self.num_cols,
                                         sharex=True)
        # Instantiate lists to hold the time and data histories
        self.time_history = []  # time
        self.r_history = []  # reference r
        self.y_history = []  # output y
        self.ydot_history = []  # velocity ydot
        self.u_history = []  # input u
        # create a handle for every subplot.
        self.handle = []
        self.handle.append(subplotWindow(self.ax[0],
                                  ylabel='y',
                                  title='Simple System'))
        self.handle.append(subplotWindow(self.ax[1],
                                  ylabel='ydot'))
        self.handle.append(subplotWindow(self.ax[2],
                                  xlabel='t(s)',
                                  ylabel='u'))

    def update(self, time, reference, state, control):
        # update the time history of all plot variables
        self.time_history.append(time)
        self.r_history.append(reference)
        self.y_history.append(state.item(0))
        self.ydot_history.append(state.item(1))
        self.u_history.append(control)

        # update the plots with associated histories
        self.handle[0].update(self.time_history,
                              [self.r_history, self.y_history])
        self.handle[1].update(self.time_history,
                              [self.ydot_history])
        self.handle[2].update(self.time_history,
                              [self.u_history])

class subplotWindow:
    # Create each individual subplot.
    def __init__(self, ax, xlabel='', ylabel='', title='',
                 legend=None):
        ''' 
            ax - This is a handle to the  axes of the figure
            xlabel - Label of the x-axis
            ylabel - Label of the y-axis
            title - Plot title
            legend - A tuple of strings that identify the data. 
                     EX: ("data1","data2", ... , "dataN")
        '''
        self.legend = legend
        self.ax = ax                  # Axes handle
        self.colors = ['b', 'g', 'r', 'c', 'm', 'y', 'b']
        # A list of colors. The first color in the list corresponds
        # to the first line object, etc.
        # 'b' - blue, 'g' - green, 'r' - red, 'c' - cyan,
        # 'm' - magenta, 'y' - yellow, 'k' - black
        self.line_styles = ['-', '-', '--', '-.', ':']
        # A list of line styles.  The first line style in the list
        # corresponds to the first line object.
        # '-' solid, '--' dashed, '-.' dash_dot, ':' dotted
        self.line = []
        # Configure the axes
        self.ax.set_ylabel(ylabel)
        self.ax.set_xlabel(xlabel)
        self.ax.set_title(title)
        self.ax.grid(True)
        # Keeps track of initialization
        self.init = True   

    def update(self, time, data):
        # Adds data to the plot.
        # Initialize the plot the first time routine is called
        if self.init==True:
            for i in range(len(data)):
                # Instantiate line object and add it to the axes
                self.line.append(Line2D(time, data[i],
                    color=self.colors[np.mod(i,len(self.colors)-1)],
                    ls=self.line_styles
                            [np.mod(i, len(self.line_styles) - 1)],
                    label=self.legend
                        if self.legend!=None else None))
                self.ax.add_line(self.line[i])
            self.init = False
            # add legend if one is specified
            if self.legend!=None:
                plt.legend(handles=self.line)
        else: # Add new data to the plot
            # Updates the x and y data of each line.
            for i in range(len(self.line)):
                self.line[i].set_xdata(time)
                self.line[i].set_ydata(data[i])

        # Adjusts the axis to fit all of the data
        self.ax.relim()
        self.ax.autoscale()
           

The plotter is initialized in lines 9–31. Lines 10–11 specify that the plot window will contain three plots arranged as a \(3\times 1\) array. The routine keeps track of the time histories of all variables to be plotted. Lines 17–21 initialize time histories for the time \(t\), the reference signal \(r\), the output \(y\), the velocity \(\dot{y}\), and the input \(u\). Lines 23–31 set up the individual plots with labels by instantiating objects from the subplotWindow class, which will be described below.

The update method receives as input the current time,
reference, state, and control values. Lines 35–39 append the current values to the history lists maintained in memory for each of those values. The plots are then updated with the new histories in lines 42–47 by calling the subplotWindow.update method, which will be described below.

The subplotWindow class is instantiated in lines 50–79. If multiple data streams are on a single plot, the color of the line corresponds to the order specified on line 63, and the style of the lines will be in the order specified on line 68. The subplotWindow.update method is specified in lines 81–102. The first time the subplotWindow.update method is called, the line objects are initialized and plotted in lines 85–97. In subsequent calls to subplotWindow.update the data lines are modified in lines 100–102.

P.1.5 Animation

In this section we will show how to create an animation for the inverted pendulum case study. Consider the image of the inverted pendulum shown in Fig. 1.2, where the configuration is completely specified by the position of the cart \(z\) and the angle of the rod from vertical \(\theta\). The physical parameters of the system are the rod length \(\ell\), the base width \(w\), the base height \(h\), and the gap between the base and the track \(g\).

Drawing for inverted pendulum. The first step in developing an animation is to draw a figure of the object to be animated and identify all of the physical parameters.

The first step in developing the animation is to determine the position of points that define the animation. The pendulum will require that we draw three objects: the rectangular cart, the circular bob at the end of the rod, and the rod. We will draw the cart as a rectangle, the bob as a circle, and the rod as a line. In Python, rectangles are specified by their lower-left corner, their width, and their height. The lower left corner of the rectangle is \((z-w/2, g)\). In Python, circles are specified by their center and radius. The center of the bob is \((z+(\ell+R)\sin\theta, g+h+(\ell+R)\cos\theta)\). In Python, lines are specified by the \(x\) and \(y\) locations of their endpoints. The \(x\) locations of the endpoints of the rod are \(X=(z, z+\ell\sin\theta)\), and the \(y\) locations of the endpoints are \(Y=(g+h, g+h+\ell\cos\theta)\).

Python code for the animation class is listed below.

# 3rd-party
import numpy as np
import matplotlib.patches as mpatches

# local (controlbook)
from ..common.animator import MatplotlibAxisAnimator


class CartPendulumAnimator(MatplotlibAxisAnimator):
    def setup_background(self):
        self.color = "blue"

        self.length = 1.0
        self.cart_width = self.length / 2
        self.cart_height = self.length * 0.15
        self.gap = 0.01
        self.buffer = self.length * 3

        span = 10
        (groundline,) = self.ax.plot([-span, span], [0, 0], "k--")

        z0 = self.x_hist[0, 0]
        self.ax.grid(True)
        self.ax.set_aspect("equal", "box")
        self.ax.set_xlim(z0 - self.buffer, z0 + self.buffer)
        self.ax.set_ylim(-self.buffer / 2, self.buffer)

    def setup_changing_objects(self, x0, r0):
        z0, theta0 = x0[:2]
        bottom_left_corner = self.get_cart_corner(z0)
        self.cart = mpatches.Rectangle(
            xy=bottom_left_corner,
            width=self.cart_width,
            height=self.cart_height,
            rotation_point="xy",
            facecolor=self.color,
            edgecolor="black",
        )
        self.ax.add_patch(self.cart)

        x, y = self.get_pendulum_data(z0, theta0)
        (self.pendulum,) = self.ax.plot(x, y, lw=1, c=self.color)
        (self.bob,) = self.ax.plot(x[-1:], y[-1:], "o", c=self.color)

    def update_changing_objects(self, x, r):
        z, theta = x[:2]

        bottom_left_corner = self.get_cart_corner(z)
        self.cart.set_xy(bottom_left_corner)

        x, y = self.get_pendulum_data(z, theta)
        self.pendulum.set_data(x, y)
        self.bob.set_data(x[-1:], y[-1:])
        return (self.cart, self.pendulum, self.bob)

    def get_cart_corner(self, z):
        bottom_left = (z - self.cart_width / 2, self.gap)
        return bottom_left

    def get_pendulum_data(self, z, theta):
        bottom = self.gap + self.cart_height
        x = [z, z + self.length * np.sin(theta)]
        y = [bottom, bottom + self.length * np.cos(theta)]
        return x, y

The pendulumAnimation class is initialized in lines 7–18. The flag self.flag_init is used to indicate the first time the animation function is called. On the first call when self.flag_init==True, all of the plot elements are initialized and configured (see lines 38–45, lines 55–62, and lines 71–75). After the first call, when self.flag_init==False, each plot element is simply updated (see lines 47, lines 64, and lines 77–78). Line 10 initializes the plot window and axes, line 12 initializes an empty list of handles to plot objects, line 14 sets the size of the axes to be \(\pm 3\ell\) along the \(x\)-axis and \(-0.1\) to \(3\ell\) along the \(y\)-axis, line 16 draws the line representing the ground, and line 18 labels the \(x\)-axis as the configuration variable \(z\).

The animation function is updated each time step using the update method shown in lines 20–30. The input to the update method is the state of the pendulum, of which the first element is \(z\) and the second element is \(\theta\) (lines 21–22). Lines 24–26 then call methods that will be described below and that draw the cart, bob, and rod. Line 27 ensures that the axes are not distorted. Lines 29–30 set the initialization flag self.flat_init to False after the first call to update.

The draw_cart method is listed in lines 32–47. The cart is drawn as a rectangle patch, which is specified by its lower-left corner and the width and height of the rectangle. The lower-left corner of the rectangle is specified in lines 34–35, and the width and height are specified in line 42. The rectangle patch is created in lines 42–43 and appended to the list of handles in line 41. The patch is added to the graph in line 45. After initialization, the only element of the cart rectangle that changes with time is the lower-left corner, which is updated in line 47.

The draw_bob method is listed in lines 49–64. The bob is represented as a circle patch, which in Python is specified by the \(x-y\) coordinates of the center of the circle and by its radius. The \(x-y\) center coordinates are given in lines 51–53. The circle patch is initialized in lines 59–60, where resolution is the angular resolution of the circle patch, fc is the color of the bob, and ec is the color of the outline. The circle patch is added to the handle list in line 58, and the handle is added to the figure in line 62. After initialization, the only element of the bob that changes with time is its center, which is updated on line 64.

The draw_rod method is listed in lines 66–78. The rod is drawn as a line, which in Python is specified by the \(x\)- and \(y\)-coordinates of the start and end of the line; these coordinates are given in lines 68–69. The line object is created in line 74 and added to the handle list in line 75. After initialization, both ends of the line change with time and are updated on lines 77–78.

P.2 Simulating Control Systems Using MATLAB

In this appendix we will show how to simulate the feedback control of a dynamic system using MATLAB’s object-oriented class structure. Consider the general feedback control system shown in Figure 2.1. The output of the physical system is \(y(t)\), and the inputs to the physical system are \(u(t)\) and an external disturbance signal \(d(t)\). The output of the system \(y(t)\) is corrupted by zero-mean noise \(n(t)\). The input to the controller is the reference signal \(r(t)\) as well as the output corrupted by noise. In MATLAB, each block shown in Figure 2.1 can be implemented using a MATLAB class.

Block diagram of a general feedback system.

We will illustrate how to implement feedback control systems in MATLAB by simulating the physical system described by the differential equation \[\tag{P.2.1} \ddot{y} + 2\dot{y} + 3 y = 4 u,\] and using the PID controller \[\tag{P.2.2} u(t) = k_p (r(t)-y(t)) + k_i \int_{-\infty}^t (r(\tau)-y(\tau))d\tau - k_d \dot{y}.\]

The feedback control system shown in Figure 2.1 is simulated in systemSim.m, which is listed below.

t_start = 0;  % start time
t_end = 20;  % end time
t_plot = 0.1;  % sample rate for plotter and animation
Ts =0.01;  % sample rate for dynamics and controller

% instantiate system, controller, and reference classes
system = systemDynamics(Ts);
controller = systemController(Ts);
reference = signalGenerator(0.5, 0.05);
disturbance = signalGenerator(1.0, 0.0);
noise = signalGenerator(0.01);

% instantiate the data plots and animation
dataPlot = dataPlotter();
animation = systemAnimation();

% main simulation loop
t = t_start;  % time starts at t_start
y = system.h();  % system output at start of simulation
while t < t_end  
    % set time for next plot
    t_next_plot = t + P.t_plot;
    % updates control and dynamics at faster simulation rate
    while t < t_next_plot 
        r = reference.square(t);  % assign reference
        d = disturbance.step(t);  % simulate input disturbance
        n = noise.random(t);  % simulate noise
        u = controller.update(r, y + n);  % update controller
        y = system.update(u+d);  % Propagate the dynamics
        t = t + Ts; % advance time by Ts
    end
    % update animation and data plots
    animation.update(system.state);
    dataPlot.update(t, r, system.state, u);
end

The physical system is implemented in a class contained in systemDynamic.m, which will be discussed below, and which is instantiated on line 7. The system is updated at sample rate \(T_s\) given the control input \(u\) and the input disturbance \(d\) on line 29.

The controller is implemented in a class contained in
systemController.m, which will be discussed below, and which is instantiated on line 8. Given the reference input \(r\), and the system output \(y\), the controller is updated at the fast sample rate \(T_s\) on line 28. At the initial time, the controller needs the initial output at time \(t=0\), which is computed on line 19 before the main loop begins.

The reference input is implemented using the signalGenerator class that is contained in signalGenerator.m, which is described below, and which is instantiated on line 9. The reference input at time \(t\), i.e., \(r(t)\), is assigned a value on line 25.

The external disturbance \(d(t)\) is also implemented using the
signalGenerator class and is instantiated on line 10 and assigned a value on line 26. For this example, the external disturbance will be a constant value of \(d(t)=1.0\). The noise \(n(t)\) is also implemented using the signalGenerator class and is instantiated on line 11 and assigned a value on line 27.

In addition to the feedback loop as implemented above, the system will be visualized through an animation, and also by plotting important variables like the reference input, the system states, and the control input. The animation and data plotting functions are implemented in systemAnimation.m and
dataPlotter.m, which are instantiated on lines 14–15, and updated on lines 33–34.

P.2.1 System Dynamics

This section will describe how to implement the system dynamics given in Equation P.2.1. The first step is to convert the dynamics to the state-space form \[\begin{aligned} \dot{x} &= f(x, u) \\ y &= h(x,u). \end{aligned}\] For the differential equation in Equation P.2.1 let \(x = (y, \dot{y})^\top\), which gives \begin{align} \dot{x}& = \begin{pmatrix} \dot{x}_1 \\ \dot{x}_2 \end{pmatrix} = \begin{pmatrix} \dot{y} \\ \ddot{y} \end{pmatrix} = \begin{pmatrix} \dot{y} \\ -2\dot{y} - 3y + 4u \end{pmatrix} = \begin{pmatrix} x_2 \\ -2x_2 - 3 x_1 + 4 u \end{pmatrix} \stackrel{\triangle}{=}f(x,u) \tag{P.2.3} \\ y &= x_1 \stackrel{\triangle}{=}h(x). \tag{P.2.4} \end{align}

The dynamics of the system are implemented in systemDynamics.m, which is listed below.

classdef systemDynamics < handle
    properties
        state
        Ts
        limit
        a0
        a1
        b0
    end
    methods
        %---constructor-------------------------
        function self = systemDynamics(sample_rate)
            y0 = 0;  % initial condition for y
            ydot0 = 0;  % initial condition for ydot
            self.state = [...  % initial state
                        y0;...
                        ydot0;...  
                        ]; 
            self.Ts = sample_rate;
            self.limit = 1.0;  % saturation limit
            % system parameters
            self.a0 = 3.0;
            self.a1 = 2.0;
            self.b0 = 4.0;
            % modify the system parameters by random value
            alpha = 0.2;  % Uncertainty parameter
            self.a0 = self.a0 * (1+2*alpha*rand-alpha);  
            self.a1 = self.a1 * (1+2*alpha*rand-alpha);  
            self.b0 = self.b0 * (1+2*alpha*rand-alpha);  
        end
        
        function xdot = f(self, state, u)
            % Return xdot = f(x,u)
            y = state(1);
            ydot = state(2);
            % The equations of motion.
            yddot = -self.a1 * ydot - self.a0 * y + self.b0 * u;
            % build xdot and return
            xdot = [ydot; yddot];
        end
        
        function y = h(self)
            % y = h(x)
            y = self.state(1);
        end
        
        function y = update(self, u)
            % This is the external method that takes input u
            % and returns output y.
            u = self.saturate(u, self.limit);  % saturate input
            self.rk4_step(u);  % propagate state by one time step
            y = self.h();  % compute the output at current time
        end
        
        function self = rk4_step(self, u)
            % Integrate ODE using Runge-Kutta-4 algorithm
            F1 = self.f(self.state, u);
            F2 = self.f(self.state + self.Ts/2*F1, u);
            F3 = self.f(self.state + self.Ts/2*F2, u);
            F4 = self.f(self.state + self.Ts*F3, u);
            self.state = self.state...
                + self.Ts/6 * (F1 + 2*F2 + 2*F3 + F4);
        end
        
        function out = saturate(self, in, limit)
            if abs(in) > limit
                out = limit * sign(in);
            else 
                out = in;
            end
        end
        
    end
end

In MATLAB, the class definition classdef systemDynamics < handle must contain < handle to ensure that internal methods can modify the class properties. The internal properties are specified in lines 2–9. The class methods are specified in lines 10–66. The class constructor is given in lines 12–30 and is called when a class object is instantiated. The state is initialized on lines 13–18 based on the initial conditions for \(y(0)\) and \(\dot{y}(0)\). The system parameters are initialized in lines 21–29. The parameters for any physical system are never known exactly. Therefore, feedback systems need to be designed to be robust to this uncertainty. In the simulation, we model uncertainty in our knowledge of the physical parameters by changing the nominal value by a uniform random variable. Let \(\alpha\) be the amount of change allowed for each parameter. For example, \(\alpha = 0.2\) means that the physical parameters may change by up to 20%. The function rand() returns a uniform random variable in the interval \([0, 1]\). Therefore, \((1 + \alpha (2*\texttt{np.random.rand()}-1))\) is a random variable in the interval \([-\alpha, \alpha]\). The nominal values for the physical parameters that are known to the designer are specified in lines 22–24. The actual values used by the simulation are randomly selected in lines 27–29.

The system dynamics \[\begin{aligned} \dot{x} &= f(x, u) \\ y &= h(x, u). \end{aligned}\] are specified in lines 32–45. Lines 32–40 define \(f(x,u)\), and lines 42–45 define \(h(x, u)\), as given by Equations P.1.3 and P.1.4 respectively.

The main feedback loop calls the update method on lines 47–53. The update function first saturates the input on line 50, where the saturation function is defined in lines 64–70. The system dynamics are then propagated forward by one sample time \(T_s\) using the fourth-order Runge-Kutta algorithm on line 51, where the RK4 algorithm is specified on lines 55–62, as described in Appendix 28. The update function finally computes and returns the output \(y\) on line 52.

P.2.2 Controller

This section will describe how to implement the PID controller given in Equation P.2.2. The controller is implemented in systemController.m, which is listed below.

classdef systemController
    properties
        kp
        kd
        ki
        Ts
        sigma
        beta
        limit
        ydot
        y_d1
        integrator
        error_d1
    end
    methods
        %------constructor----------------------
        function self = systemController(sample_rate)
            % specify gains
            self.kp = 1.0;
            self.kd = 1.0;
            self.ki = 1.0;
            self.Ts = sample_rate;
            self.sigma = 2.0 * self.Ts;
            self.beta = (2.0*sigma-self.Ts)/(2.0*sigma+self.Ts);
            self.limit = 1.0;
            % internal storage for differentiator
            self.ydot = 0.0;
            self.y_d1 = 0.0;
            % internal storage for integrator
            self.integrator = 0;
            self.error_d1 = 0;
        end
        
        function u = update(self, r, y)
            e = r - y;  % define the error
            I = self.integrate_e(e);  % integrate error
            ydot = self.differentiate_y(y);  %differentiate y
            % form PID controller, saturate, and return
            u = self.kp * e + self.ki * I - self.kd * ydot;
            u = self.saturate(u);
        end
        
        function I = integrate_e(self, error)
            self.integrator = self.integrator...
                + (self.Ts / 2) * (error + self.error_d1);
            self.error_d1 = error;
            I = self.integrator;
        end

        function ydot = differentiate_y(self, y)
            self.ydot = self.beta*self.ydot...
                + (1-self.beta)/self.Ts * (y - self.y_d1);
            self.y_d1 = y;
            ydot = self.ydot;
        end
        
        function out = saturate(self, in):
            if abs(in) > self.limit
                out = self.limit * sign(u);
            else
                out = in;
            end
        end

    end
end

The controller properties are specified on lines 2–14 and instantiated in the constructor on lines 17–32. The PID gains are specified on lines 19–21. The sample rate of the controller is passed into the system at the time of instantiation and is assigned an internal variable \(T_s\) in line 9. The dirty derivative gain \(\sigma\), described in Chapter 13, is specified on line 22, and the intermediate gain \(\beta = \frac{2\sigma-T_s}{2\sigma+T_s}\) is specified on line 24. Internal storage variables for the differentiator and the integrator, as explained in Chapter 13, are given in lines 27–31. The PID control update routine is specified in lines 34–41. The error \(e=r-y\), as shown in Figure 2.1, is defined on line 35. The PID controller in Equation P.2.2 uses the integral of \(e\) and the derivative of \(y\). The integral of \(e\) is computed on line 36 using the routine specified on lines 43–48. A derivation of the integral equations is given in Chapter 13. The derivative of \(y\) is computed in line 37 using the routine specified in lines 50–53. A derivation of the dirty derivative equations is given in Chapter 13. Finally, the PID controller is computed, the value is saturated, and the result is returned on lines 39 and 40.

P.2.3 Signal Generator

MATLAB code for the signal generator class is listed below.

classdef signalGenerator
    %   produces: square_wave, step, sawtooth_wave, 
    %             random_wave, sin_wave.
    properties
        amplitude
        frequency
        y_offset
    end
    methods
        %---constructor--------------------------------
        function self = signalGenerator(...
                amplitude, frequency, y_offset)
            self.amplitude = amplitude;
            if nargin>1
                self.frequency = frequency;
            else
                self.frequency = 1;
            end
            if nargin>2
                self.y_offset = y_offset;
            else
                self.y_offset = 0;
            end
        end
        
        function out = square(self, t)
            if mod(t, 1/self.frequency)<=0.5/self.frequency
                out = self.amplitude + self.y_offset;
            else
                out = -self.amplitude + self.y_offset;
            end
        end
        
        function out = step(self, t)
            if t>=0
                out = self.amplitude + self.y_offset;
            else
                out = 0;
            end
        end
        
        function out = sawtooth(self, t)
            out = 4*self.amplitude*self.frequency...
                * mod(t, 0.5/self.frequency)...
                - self.amplitude + self.y_offset;
        end
        
        function out = random(self, t)
            out = sqrt(self.amplitude)*randn + self.y_offset;
        end
        
        function out = sin(self, t)
            out = self.amplitude*sin(2*pi*self.frequency*t)...
                + self.y_offset;
        end
    end
end

The class is instantiated by passing in the desired amplitude of the signal, the frequency in Hertz, and a y-offset value. For random signals, the amplitude is interpreted to be the standard deviation of the signal. The signal generator can then be used to produce a square wave, a sawtooth signal, a step, a random signal, or a sinusoid, as specified in lines 26–55.

P.2.4 Data Plotter

The objective of the data plotter is to plot the relevant signals during the simulation. For this simple example, we will plot the output \(y\) and the reference \(r\) on one plot, the velocity \(\dot{y}\) on another plot, and the control signal \(u\) on a third plot. MATLAB code for the data plotter class is listed below.

classdef dataPlotter < handle
    properties
        % data histories
        time_history
        r_history
        y_history
        ydot_history
        u_history
        index
        % figure handles
        r_handle
        y_handle
        ydot_handle
        u_handle
    end
    methods
        %--constructor--------------------------
        function self = dataPlotter(P)
            % Instantiate lists to hold the time and data histories
            self.time_history...
                = NaN*ones(1,(P.t_end-P.t_start)/P.t_plot);
            self.r_history...
                = NaN*ones(1,(P.t_end-P.t_start)/P.t_plot);
            self.y_history...
                = NaN*ones(1,(P.t_end-P.t_start)/P.t_plot);
            self.ydot_history...
                = NaN*ones(1,(P.t_end-P.t_start)/P.t_plot);
            self.u_history...
                = NaN*ones(1,(P.t_end-P.t_start)/P.t_plot);
            self.index = 1;
            % Create figure and axes handles
            figure(2), clf
            subplot(311)
                hold on
                self.r_handle...
                    = plot(self.time_history,...
                           self.r_history, 'g');
                self.y_handle...
                    = plot(self.time_history,...
                           self.y_history, 'b');
                ylabel('y')
                title('System Data')
            subplot(312)
                hold on
                self.ydot_handle...
                    = plot(self.time_history,...
                           self.ydot_history, 'b');
                ylabel('ydot')
            subplot(313)
                hold on
                self.u_handle...
                    = plot(self.time_history,...
                           self.u_history, 'b');
                ylabel('u')
        end
        
        function self=update(self, time, reference, states, control)
            % update the time history of all plot variables
            self.time_history(self.index) = time;
            self.r_history(self.index) = reference;
            self.y_history(self.index) = states(1);
            self.ydot_history(self.index) = states(2);
            self.u_history(self.index) = control;
            self.index = self.index + 1;
            % update the plots with associated histories
            set(self.r_handle,...
                'Xdata', self.time_history,...
                'Ydata', self.r_history)
            set(self.y_handle,...
                'Xdata', self.time_history,...
                'Ydata', self.y_history)
            set(self.ydot_handle,...
                'Xdata', self.time_history,...
                'Ydata', self.ydot_history)
            set(self.u_handle,...
                'Xdata', self.time_history,...
                'Ydata', self.u_history)
        end
    end
end

The plotter constructor is listed on lines 18–55. Lines 20–29 initialize arrays that will hold the data histories. Allocating memory for the arrays upon initialization speeds up the run-time execution of the data plotter. Lines 32–54 set up the plot window with three subplots and plot the initial data. The MATLAB plot routine returns a MATLAB handle to the line, which is a data structure that contains all data associated with each line. The first subplot (311) will plot \(r(t)\) in green (’g’), and \(y(t)\) in blue (’b’). The second subplot (312) will plot \(\dot{y}\) in blue, and the third subplot (313) will plot \(u(t)\) in blue.

The update method receives as input the current time,
reference, state, and control values. Lines 59–63 append the current values to their histories. The plots are then updated with the new histories in lines 66–77 by calling the set routine and passing in the associated handle.

P.2.5 Animation

In this section we will show how to create an animation for the inverted pendulum case study. Consider the image of the inverted pendulum shown in Fig. 2.2, where the configuration is completely specified by the position of the cart \(z\) and the angle of the rod from vertical \(\theta\). The physical parameters of the system are the rod length \(\ell\), the base width \(w\), the base height \(h\), and the gap between the base and the track \(g\).

Drawing for inverted pendulum. The first step in developing an animation is to draw a figure of the object to be animated and identify all of the physical parameters.

The first step in developing the animation is to determine the position of points that define the animation. The pendulum will require that we draw three objects: the rectangular cart, the circular bob at the end of the rod, and the rod. We will draw the cart as a rectangle, the bob as a circle, and the rod as a line. In MATLAB, rectangles are specified by their corners. The four corners of the rectangle are given by \[C = \begin{bmatrix} z-w/2, & g \\ z_w/2, & g \\ z+w/2, & g+h \\ z-w/2, & g+h \end{bmatrix}.\] In MATLAB, lines are specified by the \(x\) and \(y\) locations of their endpoints. The \(x\) locations of the endpoints of the rod are \(X=[z, z+\ell\sin\theta]\), and the \(y\) locations of the endpoints are \(Y=[g+h, g+h+\ell\cos\theta]\). In MATLAB, circles are drawn as a sequence of small line segments that must be specified by their \(x\) and \(y\) locations. The center of the bob is given by \(C = (z+(\ell+R)\sin\theta, g+h+(\ell+R)\cos\theta)\), and so points on the edge of the bob will be given by \(X = [C_x + R\cos\theta]\) and \(Y=[C_y + R\sin\theta]\). MATLAB code for the animation class is listed below.

The pendulumAnimation class is initialized on lines 14–32. Lines 15–19 set all of the plot parameters based on data passed through the structure P. Line 21 initializes the plot window and line 23 draws the ground track, which will not change during the animation. Lines 26–28 draw the base, bob, and line for the first time, and a MATLAB handle is returned for each object in the animation. Line 30 sets the plot axes, and line 31 labels the plot.

The animation function is updated each time step using the update method on lines 34–42. The input to the update method is the state of the pendulum, of which the first element is \(z\) and the second element is \(\theta\) (lines 36–37). Lines 38–40 then call methods that will be described below and that draw the cart, rod, and bob. Line 41 forces MATLAB to update the animation at each time step.

The draw_cart method is listed on lines 44–56. The cart is drawn using the fill routine, where the \(x\) and \(y\) locations of each corner must be specified, as shown on lines 46–49. The first time draw_cart is called, the cart_handle will not exist, and so it is created through a call to fill on line 52. Upon subsequent calls to draw_cart, the handle will exist and so the cart location is updated through the set command on line 54. Since the \(y\) data of the cart does not change with time, only the \(x\) data is updated.

The draw_rod method is listed on lines 58–71. The rod is drawn using the plot routine, where the \(x\) and \(y\) locations of the ends of the rod must be specified, as shown on lines 60–64. The first time draw_rod is called, the rod_handle will not exist, and so it is created through a call to plot on line 67. Upon subsequent calls to draw_rod, the handle will exist and so the rod points are updated through the set command on line 69. Note that both the \(x\) and the \(y\) data of the rod must be updated at each time step.

The draw_bob method is listed on lines 73–90. The bob is drawn using the fill routine, where the \(x\) and \(y\) locations of each point on the bob must be specified. The points are parameterized by \(\vartheta\), which ranges from zero to \(2\pi\). Line 74 establishes an array of \(N=10\) angle points. The center of the bob is specified on lines 76–79, and the \(x\) and \(y\) points along the outline of the bob are given on lines 81–82. The first time draw_bob is called, the bob_handle will not exist, so it is created through a call to fill on line 85. Upon subsequent calls to draw_bob, the handle will exist, so the bob location is updated through the set command on lines 87–88. Note that both the \(x\) and the \(y\) data of the bob must be updated at each time step.

P.3 Simulating Control Systems Using Simulink

In this appendix we will show how to simulate the feedback control of a dynamic system using Simulink. Consider the general feedback control system shown in Figure 3.1. The output of the physical system is \(y(t)\), and the inputs to the physical system are \(u(t)\) and an external disturbance signal \(d(t)\). The output of the system \(y(t)\) is corrupted by zero-mean noise \(n(t)\). The inputs to the controller are the reference signal \(r(t)\) and the output corrupted by noise.

We will illustrate how to implement feedback control systems in Simulink by simulating the physical system described by the differential equation \[\tag{P.3.1} \ddot{y} + 2\dot{y} + 3 y = 4 u,\] and using the PID controller \[\tag{P.3.2} u(t) = k_p (r(t)-y(t)) + k_i \int_{-\infty}^t (r(\tau)-y(\tau))d\tau - k_d \dot{y}.\]

The Simulink diagram that corresponds to Figure 3.1 is shown in Figure 3.2.

The system dynamics are implemented in the system block, the controller is implemented in the controller block, and the animation is implemented in the animation block. The reference \(r(t)\), the disturbance \(d(t)\), and the noise \(n(t)\) are all implemented using the built-in Simulink Signal Generator block. The built-in Simulink Scope blocks are used to display the output \(y\) and the reference \(r\), as well as the input \(u\).

System parameters can be loaded into Simulink at the beginning of a simulation by clicking on the Model Properties menu, as shown in Figure 3.3,

and then selecting Callbacks/InitFcn, as shown in Figure 3.4.

The commands listed under Model initialization function: are executed at the beginning of each Simulink simulation.

P.3.1 System Dynamics

In this section we will describe how to implement the system dynamics. Double-clicking the system block shown in Figure 3.2 results in the Simulink sub-diagram shown in Figure 3.5.

Double-clicking the System Dynamics block results in Figure 3.6, which shows an s-function dialog block.

In Simulink, system dynamics are implemented using s-functions. Simulink is essentially a sophisticated tool for solving interconnected hybrid ordinary differential and difference equations. Each block in Simulink is assumed to have the structure \begin{align} \dot{x}_c &= f(t, x_c, x_d, u); \qquad x_c(0) = x_{c0} \tag{P.3.3} \\ x_d[k+1] &= g(t, x_c, x_d, u); \qquad x_d[0] = x_{d0} \tag{P.3.4} \\ y &= h(t, x_c, x_d, u) \tag{P.3.5} , \end{align} where \(x_c\in{\mathbb{R}}^{n_c}\) is a continuous state with initial condition \(x_{c0}\), \(x_d\in{\mathbb{R}}^{n_d}\) is a discrete state with initial condition \(x_{d0}\), \(u\in{\mathbb{R}}^m\) is the input to the block, \(y\in{\mathbb{R}}^p\) is the output of the block, and \(t\) is the elapsed simulation time. An s-function is a Simulink tool for explicitly defining the functions \(f\), \(g\), and \(h\) and the initial conditions \(x_{c0}\) and \(x_{d0}\). As explained in the MATLAB/Simulink documentation, there are several methods for specifying an s-function. In this section, we provide an overview of the method that uses a Level-1 M-file s-function.

The system given in Equation P.3.1 is implemented using the s-function shown below.

function [sys,x0,str,ts,simStateCompliance]...
    =system_dynamics(t,x,u,flag)
switch flag
  case 0  % Initialize block
    [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes;
  case 1  % define xdot = f(t,x,u)
    sys=mdlDerivatives(t,x,u);
  case 3  % define y = h(t,x,u)
    sys=mdlOutputs(t,x,u);
  % GetTimeOfNextVarHit 
  otherwise
    DAStudio.error(...
        'Simulink:blocks:unhandledFlag',num2str(flag));
end
%==============================================
function [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes
sizes = simsizes;
sizes.NumContStates  = 2;
sizes.NumDiscStates  = 0;
sizes.NumOutputs     = 1+2;
sizes.NumInputs      = 1;
sizes.DirFeedthrough = 0;
sizes.NumSampleTimes = 1;   
sys = simsizes(sizes);

% define initial conditions
y0 = 0;  % initial condition for y
ydot0 = 0;  % initial condition for ydot
x0  = [y0; ydot0];
str = [];  % str is always an empty matrix
% initialize the array of sample times
ts  = [0 0];
simStateCompliance = 'UnknownSimState';

%==============================================
function sys=mdlDerivatives(t,x,u)
    % Return xdot = f(x,u)
    y = x(1);
    ydot = x(2);

    % system parameters
    persistent a0
    persistent a1
    persistent b0
    if t==0
        a0 = 3.0;
        a1 = 2.0;
        b0 = 4.0;
        % modify the system parameters by random value
        alpha = 0.2;  % Uncertainty parameter
        a0 = a0 * (1+2*alpha*rand-alpha);  
        a1 = a1 * (1+2*alpha*rand-alpha);  
        b0 = b0 * (1+2*alpha*rand-alpha); 
    end
    % The equations of motion.
    yddot = -a1 * ydot - a0 * y + b0 * u;
    % build xdot and return
    sys = [ydot; yddot];

%==============================================
function sys=mdlOutputs(t, x, u)
    y = x(1);
    sys = [y; x];  % return output and state

Lines 1–2 define the main s-function file. The inputs to this function are always the elapsed time \(t\); the state \(x\), which is a concatenation of the continuous state and discrete state; the input \(u\); and a flag, followed by user-defined input parameters, which are absent in this case. The Simulink engine calls the s-function and passes the parameters \(t\), \(x\), \(u\), and flag. When flag==0, the Simulink engine expects the s-function to return the structure sys, which defines the block; initial conditions x0; an empty string str; and an array ts that defines the sample times of the block. When flag==1, the Simulink engine expects the s-function to return the function \(f(t,x,u)\), and when flag==3, the Simulink engine expects the s-function to return \(h(t,x,u)\). The switch statement that calls the proper functions based on the value of flag is shown in Lines 3–13. The block setup and the definition of the initial conditions are shown in Lines 16–33. The numbers of continuous states, discrete states, outputs, and inputs are defined on Lines 18–21. The direct feedthrough term on Line 22 is set to one if the output depends explicitly on the input \(u\). For example, this occurs if \(D\neq 0\) in the linear state-space output equation \(y=Cx+Du\). The initial conditions are defined on Lines 26–29. The sample times are defined on Line 32. The format for this line is ts = [period offset], where period defines the sample period and is \(0\) for continuous time or \(-1\) for inherited, and where offset is the sample time offset, which is typically \(0\). The function \(f(t,x,u)\) is defined in Lines 36–58, and the output function \(h(t,x,u)\) is defined in Lines 61–63.

P.3.2 Controller

In this section we will describe how to implement the controller. Double-clicking the controller block shown in Figure 3.2 results in the Simulink sub-diagram shown in Figure 3.7, which also shows the pop-up window that results from clicking the Interpreted MATLAB Function block.

This block calls the MATLAB function system_controller.m with inputs u, coming into the Simulink block, and the parameter structure P, which must be defined in the MATLAB workspace. The m-file that defines the controller is listed below.

function u=system_controller(in, Ts)
    r   = in(1);
    y   = in(2);
    t   = in(3);
    % controller gains
    kp = 1;
    kd = 1;
    ki = 1;
    sigma = 2*Ts;
    beta = (2*sigma-Ts)/(2*sigma+Ts);
    limit = 1;
    
    % define the error
    error = r - y;  
    
    % set persistent variables at start of simulation
    persistent integrator
    persistent ydot
    persistent error_d1
    persistent y_d1
    if t<Ts
        integrator = 0;
        ydot = 0;
        error_d1 = error;
        y_d1 = y;
    end
    
    % update the integrator
    integrator = integrator + (Ts/2)*(error+error_d1);
    % update the derivative of y
    ydot = beta*ydot + (1-beta)*(y-y_d1)/Ts;
    % form PID controller, saturate, and return
    u_unsat = kp*error + ki*integrator - kd*ydot;
    u = saturate(u_unsat, limit);
    % update persistent delay variables
    error_d1 = error;
    y_d1 = y;
end
    
%-----------------------------------------------------------------
% saturation function
function out = sat(in,limit)
    if     in > limit,      out = limit;
    elseif in < -limit,     out = -limit;
    else                    out = in;
    end
end

The inputs to system_controller.m are in and the sample rate Ts. The input array is decomposed into the reference \(r\), the system output \(y\), and the time \(t\) on lines 2–4. The controller gains are set on lines 5–11, and the error is calculated on line 14. The persistent variables that must persist between function calls are defined and initialized on lines 16–26. The integrator is updated on line 29, the differentiator is updated on line 31, and the PID controller is specified on lines 33–34. The delay variables are updated on lines 36–37.

P.3.3 Animation

In this section we will show how to create an animation for the inverted pendulum case study in Simulink.

When a graphics function like plot is called in MATLAB, the function returns a handle to the plot. A graphics handle is similar to a pointer in C/C++ in the sense that all of the properties of the plot can be accessed through the handle. For example, the MATLAB command

    >> plot_handle=plot(t,sin(t))

returns a pointer, or handle, to the plot of sin(t). Properties of the plot can be changed by using the handle, rather than reissuing the plot command. For example, the MATLAB command

    >> set(plot_handle, 'YData', cos(t))

changes the plot to cos(t) without redrawing the axes, title, label, or other objects that may be associated with the plot. If the plot contains drawings of several objects, a handle can be associated with each object. For example,

    >> plot_handle1 = plot(t,sin(t))
    >> hold on
    >> plot_handle2 = plot(t,cos(t))

draws both sin(t) and cos(t) on the same plot, with a handle associated with each object. The objects can be manipulated separately without redrawing the other object. For example, to change cos(t) to cos(2t), issue the command

    >> set(plot_handle2, 'YData', cos(2*t))

We can exploit this property to animate simulations in Simulink by redrawing only the parts of the animation that change in time, and thereby significantly reducing the simulation time. To show how handle graphics can be used to produce animations in Simulink, we will show how to draw the inverted pendulum in a 2-D animation.

Consider the image of the inverted pendulum shown in Fig. 3.8, where the configuration is completely specified by the position of the cart \(z\), and the angle of the rod from vertical \(\theta\). The physical parameters of the system are the rod length \(\ell\), the base width \(w\), the base height \(h\), and the gap between the base and the track \(g\).

The first step in developing the animation is to determine the position of points that define the animation. For example, for the inverted pendulum in Fig. 3.8, the four corners of the base are \[(z+w/2, g), (z+w/2, g+h), (z-w/2, g+h), \text{ and } (z-w/2, g),\] and the two ends of the rod are given by \[(z, g+h) \text{ and } (z+L\sin\theta, g+h+L\cos\theta).\]

Since the base and the rod can move independently, each will need its own figure handle. The drawBase command can be implemented with the following MATLAB code:

function handle...
         = drawBase(z, width, height, gap, handle)
  X = [z-width/2,z+width/2,z+width/2,z-width/2];
  Y = [gap, gap, gap+height, gap+height];
  if isempty(handle),
    handle = fill(X,Y,'m');
  else
    set(handle,'XData',X,'YData',Y);
  end

Lines 2 and 3 define the X and Y locations of the corners of the base. Note that in Line 1, handle is both an input and an output. If an empty array is passed into the function, then the fill command is used to plot the base in Line 5. On the other hand, if a valid handle is passed into the function, then the base is redrawn using the set command in Line 7.

The MATLAB code for drawing the rod is similar and is listed below.

function handle...
         = drawRod(z,theta,L,gap,height,handle)
  X = [z, z+L*sin(theta)];
  Y = [gap+height, gap + height + L*cos(theta)];
  if isempty(handle),
    handle = plot(X, Y, 'g');
  else
    set(handle,'XData',X,'YData',Y);
  end

The main routine for the pendulum animation is listed below.

function drawPendulum(u)
  %
  z        = u(1);
  theta    = u(2);
  t        = u(3);

  %
  L = 1;
  gap = 0.01;
  width = 1.0;
  height = 0.1;

  %
  persistent base_handle
  persistent rod_handle

  %
  %
  if t==0,
    figure(1), clf
    track_width=3;
    %
    plot([-track_width,track_width],[0,0],'k'); 
    hold on
    base_handle...
       =drawBase(z, width, height, gap, []);
    rod_handle...
       =drawRod(z, theta, L, gap, height, []);
    axis([-track_width,track_width,...
          -L,2*track_width-L]);
  %
  else
    drawBase(z, width, height, gap, base_handle);
    drawRod(z, theta, L, gap, height, rod_handle);
  end

The routine drawPendulum is called from the Simulink file shown above, where there are three inputs: the position \(z\), the angle \(\theta\), and the time \(t\). Lines 3–5 rename the inputs to \(z\), \(\theta\), and \(t\). Lines 8–11 define the drawing parameters. We require that the handle graphics persist between function calls to drawPendulum. Since a handle is needed for both the base and the rod, we define two persistent variables in Lines 14 and 15. The if statement in Lines 19–32 is used to produce the animation. Lines 20–27 are called once at the beginning of the simulation, and draw the initial animation. Line 20 brings the figure 1 window to the front and clears it. Lines 21 and 23 draw the ground along which the pendulum will move. Line 25 calls the drawBase routine with an empty handle as input, and returns the handle base_handle to the base. Line 26 calls the drawRod routine, and Line 25 sets the axes of the figure. After the initial time step, all that needs to be changed are the locations of the base and rod. Therefore, in Lines 30 and 31, the drawBase and drawRod routines are called with the figure handles as inputs.

P.4 Numerical Solutions to Differential Equations

This appendix provides a brief overview of techniques for numerically solving ordinary differential equations, when the initial value is specified. In particular, we are interested in solving the differential equation \[\tag{P.4.1} \dot{x} = \frac{dx}{dt}(t) = f(x(t), u(t)), \qquad x(t_0),\] over the time interval \([t_0, t_f]\), where \(x(t)\in \mathbf{R}^n\), and \(u(t)\in\mathbf{R}^m\) is assumed to be known, and where we assume that \(f(\cdot,\cdot)\) is sufficiently smooth and that unique solutions to the differential equation exist for every \(x_0\).

Integrating both sides of Equation P.4.1 from \(t_0\) to \(t<t_f\) gives \[\tag{P.4.2} x(t) = x(t_0) + \int_{t_0}^t f(x(\tau), u(\tau))\,d\tau.\] The difficulty with solving Equation P.4.2 is that \(x(t)\) appears on both sides of the equation, and cannot therefore be solved explicitly for \(x(t)\). All numerical solution techniques attempt to approximate the solution to Equation P.4.2. Most techniques break the solution into small time increments, usually equal to the sample rate of the computer, which we denote by \(T_s\). Accordingly we write Equation P.4.2 as \begin{align} x(t) &= x(t_0) + \int_{t_0}^{t-T_s} f(x(\tau), u(\tau))\,d\tau + \int_{t-T_s}^t f(x(\tau), u(\tau))\,d\tau \notag \\ &= x(t-T_s) + \int_{t-T_s}^t f(x(\tau), x(\tau))\,d\tau. \tag{P.4.3} \end{align}

The simplest form of numerical approximation for the integral in Equation P.4.3 is to use the left endpoint method, where \[\int_{t-T_s}^t f(x(\tau), u(\tau))\,d\tau \approx T_s f(x(t-T_s), u(t-T_s)).\] Using the notation \(x_k \stackrel{\triangle}{=}x(t_0+k T_s)\) we get the numerical approximation to the differential equation in Equation P.4.1 as \[\tag{P.4.4} x_k = x_{k-1} + T_s f(x_k, u_k), \quad x_0 = x(t_0).\] Equation P.4.4 is called the Euler method, or a Runge-Kutta first order method (RK1).

While the RK1 method is often effective for numerically solving ODEs, it typically requires a small sample size \(T_s\). The advantage of the RK1 method is that it only requires one evaluation of \(f(\cdot, \cdot)\).

To improve the numerical accuracy of the solution, a second-order method can be derived by approximating the integral in Equation P.4.3 using the trapezoidal rule shown in Figure 10.1, where \[\int_a^b f(\xi)d\xi \approx (b-a)\left(\frac{f(a)+f(b)}{2}\right).\] Accordingly, \[\int_{t-T_s}^t f(x(\tau), u(\tau))d\tau \approx \frac{T_s}{2}\left(f(x(t-T_s),u(t-T_s)) + f(x(t), u(t))\right).\] Since \(x(t)\) is unknown, we use the RK1 method to approximate it as \[x(t) \approx x(t-T_s) + T_s f(x(t-T_s), u(t-T_s)).\] In addition, we typically assume that \(u(t)\) is constant over the interval \([t-T_s, T_s)\) to get \[\begin{gathered} \int_{t-T_s}^t f(x(\tau), u(\tau))d\tau \approx \frac{T_s}{2}\big(f(x(t-T_s),u(t-T_s)) \\ + f(x(t-T_s) + T_s f(x(t-T_s), u(t-T_s)), u(t-T_s))\big). \end{gathered}\] Accordingly, the numerical integration routine can be written as \begin{align} x_0 &= x(t_0) \notag \\ F_1 &= f(x_{k-1}, u_{k-1}) \tag{P.4.5}\\ F_2 & = f(x_{k-1} + T_sF_1, u_{k-1}) \notag \\ x_k &= x_{k-1} + \frac{T_s}{2} \left( F_1 + F_2 \right). \notag \end{align} Equation P.4.5 is the Runge-Kutta second-order method, or RK2. It requires two function calls to \(f(\cdot, \cdot)\) for every time sample.

The most common numerical method for solving ODEs is the Runge-Kutta fourth order method RK4. The RK4 method is derived using Simpson’s Rule \[\int_a^b f(\xi)d\xi \approx \left(\frac{b-a}{6}\right)\left(f(a) + 4f\left(\frac{a+b}{2}\right) + f(b)\right),\] which is found by approximating the area under the integral using a parabola. The standard strategy is to write the approximation as \[\int_a^b f(\xi)\xi \approx \left(\frac{b-a}{6}\right)\left(f(a) + 2f\left(\frac{a+b}{2}\right) + 2f\left(\frac{a+b}{2}\right) + f(b)\right),\] and then to use \[\begin{aligned} F_1 &= f(a) \\ F_2 &= f( a + \frac{T_s}{2}F_1) \approx f\left(\frac{a+b}{2}\right)\\ F_3 &= f( a + \frac{T_s}{2}F_2) \approx f\left(\frac{a+b}{2}\right) \\ F_4 &= f( a + T_s F_3) \approx f(b), \end{aligned}\] resulting in the RK4 numerical integration rule \begin{align} x_0 &= x(t_0) \notag \\ F_1 &= f(x_{k-1}, u_{k-1}) \notag \\ F_2 & = f(x_{k-1} + \frac{T_s}{2} F_1, u_{k-1}) \tag{P.4.10} \\ F_3 & = f(x_{k-1} + \frac{T_s}{2} F_2, u_{k-1}) \notag \\ F_4 & = f(x_{k-1} + T_s F_3, u_{k-1}) \notag \\ x_k &= x_{k-1} + \frac{T_s}{6} \left( F_1 + 2F_2 + 2F_3 + F_4 \right). \notag \end{align}

It can be shown that the RK4 method matches the Taylor series approximation of the integral in Equation P.4.3 up to the fourth order term. Higher order methods can be derived, but generally do not result in significantly better numerical approximations to the ODE. The step size \(T_s\) must still be chosen to be sufficiently small to result in good solutions. It is also possible to develop adaptive step size solvers. For example, the ODE45 algorithm in MATLAB solves the ODE using both an RK4 and an RK5 algorithm. The two solutions are then compared and if they are sufficiently different, then the step size is reduced. If the two solutions are close, then the step size can be increased.

P.4.1 Python Implementation of Numerical ODE Solvers

In the following code example, we show how to implement a system that is described by the second-order differential equation \[\ddot{y} + a_1 \dot{y} + a_2 \sin y = b u,\] where \(a_1\), \(a_2\) and \(b\) are constant coefficients and \(u\) is the system input. The first step is to put the system into state-space form. Selecting the states as \[x =\begin{pmatrix} x_1 \\ x_2 \end{pmatrix} \stackrel{\triangle}{=}\begin{pmatrix} y \\ \dot{y} \end{pmatrix}\] and differentiating gives the state-space equations \[\begin{aligned} \begin{pmatrix} \dot{x}_1 \\ \dot{x}_2 \end{pmatrix} &= \begin{pmatrix} x_2 \\ -a_1 x_2 - a_2 \sin x_1 + b u \end{pmatrix} \\ y &= x_1, \end{aligned}\] which is in the form \[\begin{aligned} \dot{x} &= f(x,u) \\ y &= h(x, u). \end{aligned}\]

Python code that implements a class for this system is given below. The class has two external properties: the sample rate self.Ts and the state self.state. The constant coefficients are treated as internal properties known only to the system and are therefore labeled as self.a1, self.a2, and self.b. When the class is instantiated, the __init__ function is called; this function initializes the states with their initial conditions and initializes the system coefficients \(a_1\), \(a_2\), and \(b\). The external method update takes the system input \(u\) and returns the system output \(y\). The update function first propagates the system dynamics \(\dot{x} = f(x,u)\) using one of the Runge-Kutta methods. In the code below, the RK4 algorithm is used, but internal methods that implement the RK1, RK2, and RK4 methods are all shown for educational purposes. The RK methods each use the internal function self.f, which specifies the system dynamics \(\dot{x}=f(x,u)\). This function is system-dependent. The update function then computes the output \(y=h(x)\) by calling the internal function self.h, which is also system-dependent.

import numpy as np

class systemDynamics:
    #  Model the system yddot + a1*ydot + a2*sin(y) = b*u
    def __init__(self, Ts=0.01):
        self.Ts = Ts  # sample rate
        # Specify the initial condition
        y0 = 0.0  # y at time zero
        ydot0 = 0.0  # ydot at time zero
        self.state = np.array([
            [y0],
            [ydot0],
        ])  # state at time zero
        self.a1 = 2.0
        self.a2 = 2.0
        self.b = 4.0

    def update(self, u):
        # This is the external method that takes the input u and
        # returns the output y.
        self.rk4_step(u)  # propagate the state by one time sample
        y = self.h()  # return the corresponding output
        return y

    def rk1_step(self, u):
        # Integrate ODE using Runge-Kutta RK1 algorithm
        F1 = self.f(self.state, u)
        self.state += self.Ts * F1

    def rk2_step(self, u):
        # Integrate ODE using Runge-Kutta RK2 algorithm
        F1 = self.f(self.state, u)
        F2 = self.f(self.state + self.Ts / 2 * F1, u)
        self.state += self.Ts / 2 * (F1 + F2)

    def _rk4_step(self, u):
        # Integrate ODE using Runge-Kutta RK4 algorithm
        F1 = self.f(self.state, u)
        F2 = self.f(self.state + self.Ts / 2 * F1, u)
        F3 = self.f(self.state + self.Ts / 2 * F2, u)
        F4 = self.f(self.state + self.Ts * F3, u)
        self.state += self.Ts / 6 * (F1 + 2 * F2 + 2 * F3 + F4)

    def f(self, state, u):
        # Return xdot = f(x,u)
        x1 = state.item(0)
        x2 = state.item(1)
        xdot = np.array([
            [x2],
            [-self._a1 * x2 - self._a2 * np.sin(x1) + self._b * u],
            ])
        return xdot

    def h(self):
        # return the output equations y=h(x)
        x1 = self.state.item(0)
        y = np.array([
            [x1],
            ])
        return y

The system is simulated using the following Python code. The system is instantiated on line 13. The while loop in lines 20–28 updates the internal system at the sample rate T_s rather than at the plot rate T_plot. The input is specified as a square wave on line 23. The system is propagated one step forward using the input u on line 24.

import matplotlib.pyplot as plt
from signalGenerator import signalGenerator
from plotData import plotData
from systemDynamics import systemDynamics

# simulation parameters
Ts = 0.01  # sample rate of simulation
T_plot = 0.1  # plot update rate
t_start = 0.0  # start time of simulation
t_end = 20.0  # end time of simulation

# instantiate system and input classes
system = systemDynamics(Ts)
input = signalGenerator(amplitude=0.5, frequency=0.1)

# instantiate the simulation plots and animation
dataPlot = plotData()

t = t_start  # time starts at t0=0
while t < t_end:  # main simulation loop
    t_next_plot = t + T_plot
    while t < t_next_plot:
        u = input.square(t)
        y = system.update(u)
        t = t + Ts  # advance time by Ts
    # update animation and data plots
    dataPlot.update(t, system.state, u)
    plt.pause(0.0001)
    
# Keeps the program from closing until the user presses a button.
print('Press key to close')
plt.waitforbuttonpress()
plt.close()

P.4.2 MATLAB Implementation of Numerical ODE Solvers

MATLAB code that implements a class for the system defined in the previous section is given below. The class has five properties: the sample rate self.Ts, the state self.state, and the constant coefficients self.a1, self.a2, and self.b. When the class is instantiated, the constructor systemDynamics(Ts) is called, which is where the states are initialized with their initial conditions, and the system coefficients \(a_1\), \(a_2\), and \(b\) are initialized. The class method update takes as its input the system input \(u\) and returns the system output \(y\). The update function first propagates the system dynamics \(\dot{x} = f(x,u)\) using one of the Runge-Kutta methods. In the code below, the RK4 algorithm is used, but internal methods that implement the RK1, RK2, and RK4 methods are all shown for educational purposes. The RK methods each use the internal function self.f, which is where the system dynamics \(\dot{x}=f(x,u)\) are specified. This function is system-dependent. The update function then computes the output \(y=h(x)\) by calling the internal function self.h, which is also system-dependent.

classdef systemDynamics < handle
    properties
        Ts
        state
        a1
        a2
        b
    end
    methods
        %---constructor-------------------------
        function self = systemDynamics(Ts)
            self.Ts = Ts;  % sample rate
            y0 = 0;  % initial y
            ydot0 = 0;  % initial y_dot
            self.state = [y0; ydot0];  % initial state
            self.a1 = 2; % system parameters
            self.a2 = 2;
            self.b = 4;
        end
        %----------------------------
        function y = update(self, u)
            % external method that takes u as input
            % and returns y
            self.rk4_step(u);
            y = self.h();
        end
        function self = rk1_step(self, u)
            % Integrate ODE using Runge-Kutta RK1 algorithm
            F1 = self.f(self.state, u);
            self.state = self.state + self.Ts * F1;
        end
        function self = rk2_step(self, u)
            % Integrate ODE using Runge-Kutta RK2 algorithm
            F1 = self.f(self.state, u);
            F2 = self.f(self.state + self.Ts/2*F1, u);
            self.state = self.state + self.Ts/2 * (F1 + F2);
        end
        function self = rk4_step(self, u)
            % Integrate ODE using Runge-Kutta RK4 algorithm
            F1 = self.f(self.state, u);
            F2 = self.f(self.state + self.Ts/2*F1, u);
            F3 = self.f(self.state + self.Ts/2*F2, u);
            F4 = self.f(self.state + self.Ts*F3, u);
            self.state = self.state...
                + self.Ts/6 * (F1 + 2*F2 + 2*F3 + F4);
        end
        function xdot = f(self, state, u)
            % Return xdot = f(x,u), 
            x1 = state(1);
            x2 = state(2);
            xdot = [x2;...
                -self.a1*x2 - self.a2*sin(x2) + self.b*u];
        end
        function y = h(self)
            % return y = h(x)
            x1 = self.state(1);
            y = x1;
        end
    end
end

The system is simulated using the following MATLAB code. The system is instantiated on line 7. The while loop in lines 13–23 updates the internal system at the sample rate T_s rather than at the plot rate T_plot. The input is specified as a square wave on line 17. The system is propagated one step forward using the input u on line 18.

% simulation parameters
Ts = 0.01;  % sample rate
T_plot = 0.1;  % plot update rate
t_start = 0.0; % simulation start time
t_end = 10.0; % simulation end timm
% instantiate dynamics and plotter
system = systemDynamics(Ts);  
input = signalGenerator(0.5, 0.2);
dataPlot = dataPlotter();

% main simulation loop
t = t_start;  
while t < t_end  
    % Propagate dynamics in between plot samples
    t_next_plot = t + P.t_plot;
    while t < t_next_plot 
        u = input.square(t);  % input is a square wave
        y = system.update(u);  % Propagate the dynamics
        t = t + P.Ts; % advance time by Ts
    end
    % update data plots
    dataPlot.update(t, system.state, u);
end

The Simulink engine implements a variety of different ODE solvers. The system dynamics are specified in an s-function. An s-function that implements the system described above is shown below.

function [sys,x0,str,ts,simStateCompliance]...
    = system_dynamics(t,x,u,flag)
switch flag
  % Initialization
  case 0
    [sys,x0,str,ts,simStateCompliance]...
        =mdlInitializeSizes();
  % Derivatives
  case 1
    sys=mdlDerivatives(t,x,u);
  % Update 
  case 2
    sys=mdlUpdate(t,x,u);
  % Outputs 
  case 3
    sys=mdlOutputs(t,x,u);
  % GetTimeOfNextVarHit 
  case 4
    sys=mdlGetTimeOfNextVarHit(t,x,u);
  % Terminate %
  case 9
    sys=mdlTerminate(t,x,u);
  % Unexpected flags %
  otherwise
    DAStudio.error(...
        'Simulink:blocks:unhandledFlag',...
        num2str(flag));

end

%
%==============================================
% mdlInitializeSizes
% Return the sizes, initial conditions, and 
%  sample times for the S-function.
%==============================================
%
function [sys,x0,str,ts,simStateCompliance]...
    =mdlInitializeSizes()

sizes = simsizes;

sizes.NumContStates  = 2;
sizes.NumDiscStates  = 0;
sizes.NumOutputs     = 1;
sizes.NumInputs      = 1;
sizes.DirFeedthrough = 0;
sizes.NumSampleTimes = 1;   

sys = simsizes(sizes);

% initialize the initial conditions%
y0 = 0;
ydot0 = 0;
x0  = [y0; ydot0];
% str is always an empty matrix
str = [];

% initialize the array of sample times
ts  = [0 0];
simStateCompliance = 'UnknownSimState';

%
%==============================================
% mdlDerivatives
% Return the derivatives for the continuous 
% states.
%==============================================
%
function sys=mdlDerivatives(t,x,u,P)
  x1 = x(1);
  x2 = x(2);
  xdot = [x2;...
          -self.a1*x2 - self.a2*sin(x2) + self.b*u];  
sys = xdot;
% end mdlDerivatives

%
%==============================================
% mdlUpdate
% Handle discrete state updates, sample time 
% hits, and major time step requirements.
%==============================================
%
function sys=mdlUpdate(t,x,u)

sys = [];

% end mdlUpdate

%
%==============================================
% mdlOutputs
% Return the block outputs.
%==============================================
%
function sys=mdlOutputs(t,x,u)
    x1 = x(1);
    y = x1;
sys = y;

% end mdlOutputs

%
%==============================================
% mdlGetTimeOfNextVarHit
%==============================================
%
function sys=mdlGetTimeOfNextVarHit(t,x,u)

sampleTime = 1;    
sys = t + sampleTime;

% end mdlGetTimeOfNextVarHit

%
%==============================================
% mdlTerminate
% Perform any end of simulation tasks.
%==============================================
%
function sys=mdlTerminate(t,x,u)

sys = [];

% end mdlTerminate

The state equations \(\dot{x}=f(x,u)\) are implemented in the function
mdlDerivatives on lines 70–75, and the output equation \(y=h(x)\) is implemented in the function mdlOutputs on lines 97–102. The system is initialized in mdlInitializeSizes on lines 38–61.

The numerical ODE solver can be specified by using the menu
Simulation > Model Configuration Parameters. Simulink has two types of solvers: fixed-step solvers and variable-step solvers. The dialog menu for fixed-step solvers is shown in Figure 4.1, where “ode4(Runge-Kutta)” corresponds to an RK4 method, “ode2(Heun)” corresponds to an RK2 method, and “ode1(Euler)” corresponds to an RK1 method. Simulink also has variable-step-size ODE solvers. The options for variable-step-size are shown in Figure 4.2. The “ode45 (Dormand-Prince)” solver works by solving the ODE over the next time step using both an ode4 and an ode5 method, comparing the two, and then reducing the step size if the difference is too large, and increasing the step size if the difference is within a tolerance.

Dialog window for Simulink fixed-step size solver.
Dialog window for Simulink variable-step size solver.

P.4.4 Notes and References

P.5 Review of Ordinary Differential Equations

This appendix provides a refresher on how to solve linear ordinary differential equations with constant coefficients. In particular, we focus on the step response of such systems.

P.5.1 First-Order ODEs

This section reviews how to use an integrating factor to find the solution to a scalar first-order differential equation.

Consider the first order linear constant coefficient ordinary differential equation \[\tag{P.5.1} \frac{dy}{dt}(t) = ay(t) + bu(t),\] with initial condition \(y(0)=y_0\), where \(a\) and \(b\) are constants. Equation P.5.1 can be rearranged as \[\tag{P.5.2} \frac{dy}{dt}(t) - ay(t) = bu(t).\] Multiplying both sides of Equation P.5.2 by the integrating factor \(e^{-at}\) gives \[\tag{P.5.3} e^{-at}\left(\frac{dy}{dt}(t) - ay(t)\right) = e^{-at}bu(t).\] Noting that the left-hand side of Equation P.5.3 is the derivative of \(e^{-at}y(t)\) gives \[\tag{P.5.4} \frac{d}{dt}\left(e^{-at}y(t)\right) = e^{-at}bu(t).\] Integrating both sides of Equation P.5.4 from \(0\) to \(t\) yields \[\int_0^t \frac{d}{d\tau}\left(e^{-a\tau}y(\tau)\right)d\tau = \int_0^te^{-a\tau}bu(\tau)d\tau,\] which implies that \[e^{-at}y(t) - e^{-a\cdot 0}y(0) = \int_0^te^{-a\tau}bu(\tau)d\tau.\] Solving for \(y(t)\) gives \[\tag{P.5.5} y(t) = \underbrace{e^{at}y_0}_{\text{homogeneous response}} + \underbrace{\int_0^t e^{a(t-\tau)}bu(\tau)d\tau}_{\text{forced response}},\] where the first term on the right is the homogeneous response, or the response to initial conditions, and the second term on the right is the forced response, or the response to the input \(u(t)\). Note that the forced response is the convolution of \(u(t)\) with the impulse response \(e^{at}\).

For the discussion to follow, it is important to note that if \(a\) is a complex number, then Equation P.5.5 still holds, but \(y(t)\) will be a complex function of time. To see this, assume that \(a=\sigma+j\omega\). Then \[\begin{aligned} e^{at} &= e^{(\sigma+j\omega)t} \\ &= e^{\sigma t} e^{j\omega t} \\ &= e^{\sigma t}(\cos(\omega t) + j\sin(\omega t)) \\ &= e^{\sigma t}\cos(\omega t) + je^{\sigma t}\sin(\omega t), \end{aligned}\] substituting into Equation P.5.5 yields the complex function \[\begin{gathered} y(t) = \left(e^{\sigma t}\cos(\omega t) y_0 + \int_0^t e^{\sigma (t-\tau)} \cos(\omega \tau) bu(\tau)d\tau\right) \\ + j\left( e^{\sigma t}\sin(\omega t) y_0 + \int_0^t e^{\sigma (t-\tau)} \sin(\omega (t-\tau)) bu(\tau)d\tau \right). \end{gathered}\] Note that if the real part of \(a\) is negative, or in other words if \(a\) is in the left half of the complex plane, then the homogeneous response decays to zero and the forced response is bounded if \(u(t)\) is bounded.

P.5.2 Inverse Laplace Transform

Taking the Laplace transform of Equation P.5.1 gives \[(sY(s) - y_0) = aY(s) + bU(s).\] Solving for \(Y(s)\) yields \[Y(s) = \left(\frac{1}{s-a}\right)y_0 + \left(\frac{b}{s-a}\right)U(s).\] Taking the inverse Laplace transform gives \[\tag{P.5.6} y(t) = \mathcal{L}^{-1}\left(\frac{1}{s-a}\right) y_0 + \mathcal{L}^{-1}\left(\frac{b}{s-a}\right)*\mathcal{L}^{-1}(U(s)),\] where \(*\) denotes the convolution operator. Comparing Equation P.5.5 with Equation P.5.6 implies that \[\tag{P.5.7} \mathcal{L}^{-1}\left(\frac{b}{s-a}\right) = be^{at}, \quad t\geq 0.\] In the limit, as \(a\to 0\) we get \[\tag{P.5.8} \mathcal{L}^{-1}\left(\frac{b}{s}\right) = b, \quad t\geq 0.\] Again we note that Equations P.5.7 and P.5.8 are true even when \(a\) and \(b\) are complex numbers.

P.5.3 Partial Fraction Expansion

The inverse Laplace transform, together with partial fraction expansion, can be used to find the response of first-order and higher-order systems to step inputs. For example, consider the task of finding the step response for the first-order system \[\tag{P.5.9} \dot{y} = -ay + bu,\] where \(a\) and \(b\) are real positive constants, where \(u\) is a step input of size \(A\), i.e., \[u(t) = \begin{cases} A & t\geq 0 \\ 0 & \text{~otherwise} \end{cases}.\] The Laplace transform of \(u(t)\) is \(U(s) = \frac{A}{s}\). Similarly, taking the Laplace transform of Equation P.5.9 and solving for \(Y(s)\) gives \[\tag{P.5.10} Y(s) = \left(\frac{b}{s+a}\right)U(s) = \frac{bA}{s(s+a)}.\] The partial fraction expansion of \(Y(s)\) expresses \(Y(s)\) as a linear combination of each factor in the denominator, i.e., \[\tag{P.5.11} Y(s) = \frac{c_1}{s} + \frac{c_2}{s+a}.\] To find the coefficients \(c_1\) and \(c_2\), set Equation P.5.11 equal to Equation P.5.10 to obtain \[\tag{P.5.12} \frac{c_1}{s} + \frac{c_2}{s+a} = \frac{bA}{s(s+a)}.\] To find \(c_1\), multiply both sides of Equation P.5.12 by \(s\) to obtain \[\tag{P.5.13} c_1 + \frac{s c_2}{s+a} = \frac{bA}{s+a}.\] To remove the term involving \(c_2\) in Equation P.5.13, set \(s=0\) to obtain \[c_1 = \frac{bA}{a}.\] To find \(c_2\), multiply both sides of Equation P.5.12 by \(s+a\) to obtain \[\tag{P.5.14} \frac{c_1(s+a)}{s} + c_2 = \frac{bA}{s}.\] To remove the term involving \(c_1\) in Equation P.5.14, set \(s=-a\) to obtain \[c_2 = -\frac{bA}{a}.\] Therefore, \[\tag{P.5.15} Y(s) = \frac{\frac{bA}{a}}{s} - \frac{\frac{bA}{a}}{s+a}.\] Since the inverse Laplace transform is a linear operator, we get \[\begin{aligned} y(t) &= \mathcal{L}^{-1}\left(\frac{\frac{bA}{a}}{s}\right) - \mathcal{L}^{-1}\left(\frac{\frac{bA}{a}}{s+a}\right) \\ &= \frac{bA}{a} - \frac{bA}{a}e^{-at}, \qquad t\geq 0 \\ &= \frac{bA}{a}(1-e^{-at}), \qquad t\geq 0. \end{aligned}\]

The same technique works for finding the step response for higher-order systems. As an example, find the unit step response of the system described by \[y^{(4)} + 10y^{(3)} + 35\ddot{y} + 50\dot{y} + 24 y = u.\] Taking the Laplace transform and solving for \(Y(s)\), and using the fact that \(U(s)=\frac{1}{s}\) gives \begin{align} Y(s) &= \left(\frac{1}{s^4+10s^3+35s^2+50s+24}\right)U(s) \notag \\ &= \left(\frac{1}{s^4+10s^3+35s^2+50s+24}\right)\frac{1}{s} \notag \\ & = \frac{1}{s}\left(\frac{1}{s+1}\right)\left(\frac{1}{s+2}\right)\left(\frac{1}{s+3}\right)\left(\frac{1}{s+4}\right). \tag{P.5.16} \end{align} Using partial fraction expansion we have that \[\tag{P.5.17} Y(s) = \frac{c_1}{s} + \frac{c_2}{s+1} + \frac{c_3}{s+2} + \frac{c_4}{s+3} + \frac{c_5}{s+4}.\] Setting Equation P.5.17 equal to Equation P.5.16 gives \begin{gather} \tag{P.5.18} \frac{c_1}{s} + \frac{c_2}{s+1} + \frac{c_3}{s+2} + \frac{c_4}{s+3} + \frac{c_5}{s+4} \\ = \frac{1}{s}\left(\frac{1}{s+1}\right)\left(\frac{1}{s+2}\right)\left(\frac{1}{s+3}\right)\left(\frac{1}{s+4}\right). \end{gather} The coefficient \(c_1\) is found by multiplying both sides of Equation P.5.18 by \(s\) and then setting \(s=0\) to remove the coefficients \(c_2\)–\(c_5\) to obtain \(c_1 = 1/24\). Following a similar procedure for each coefficient yields \(c_2=-1/6\), \(c_3=1/4\), \(c_4=-1/6\), and \(c_5=1/24\). The step response is therefore given by \[\begin{aligned} y(t) &= \mathcal{L}^{-1}\left(\frac{1/24}{s}\right) + \mathcal{L}^{-1}\left(\frac{-1/6}{s+1}\right) + \mathcal{L}^{-1}\left(\frac{1/4}{s+2}\right) \\ &\qquad + \mathcal{L}^{-1}\left(\frac{-1/6}{s+3}\right) + \mathcal{L}^{-1}\left(\frac{1/24}{s+4}\right) \\ &= \frac{1}{24} -\frac{1}{6}e^{-t} + \frac{1}{4}e^{-2t} - \frac{1}{6}e^{-3t} + \frac{1}{24}e^{-4t}, \qquad t\geq 0 \\ &= \frac{1}{24}\left(1 -4e^{-t} + 6e^{-2t} - 4e^{-3t} + e^{-4t}\right), \qquad t\geq 0. \end{aligned}\]

In MATLAB, the coefficients can be found by using the residue command. For the problem above we could use the matlab commands

num = 1;  %
%
den = poly([0,-1,-2,-3,-4]); 
%
[R,P,K] = residue(num,den);  

The vector R will contain the coefficients \(c_1\)–\(c_5\), the vector P contains the associated roots, and K will be the remainder polynomial if the numerator is a higher order polynomial than the denominator.

The method of partial fraction expansion is also valid if the poles of the system are complex. For example, consider finding the response of the second-order differential equation \[\ddot{y} + 2\zeta\omega_n\dot{y} + \omega_n^2y = \omega_n^2u,\] to a step of size \(A\). Taking the Laplace transform and letting \(U(s)=A/s\) gives \begin{align} Y(s) &= \left(\frac{\omega_n^2}{s^2+2\zeta\omega_ns+2\omega_n^2}\right)\frac{A}{s} \notag \\ & = \frac{A\omega_n^2}{s}\left(\frac{1}{s+\zeta\omega_n+j\omega_n\sqrt{1-\zeta^2}}\right) \\ &\qquad \cdot \left(\frac{1}{s+\zeta\omega_n-j\omega_n\sqrt{1-\zeta^2}}\right). \tag{P.5.20} \end{align} Expanding \(Y(s)\) as a sum of partial fractions yields \begin{gather} \tag{P.5.21} Y(s) = \frac{c_1}{s} + \left(\frac{c_2}{s+\zeta\omega_n+j\omega_n\sqrt{1-\zeta^2}}\right) \\ + \left(\frac{c_3}{s+\zeta\omega_n-j\omega_n\sqrt{1-\zeta^2}}\right). \end{gather} Setting Equation P.5.21 equal to Equation P.5.20 gives \[\begin{gathered} \frac{c_1}{s} + \left(\frac{c_2}{s+\zeta\omega_n+j\omega_n\sqrt{1-\zeta^2}}\right) + \left(\frac{c_3}{s+\zeta\omega_n-j\omega_n\sqrt{1-\zeta^2}}\right) \\ = \frac{A\omega_n^2}{s}\left(\frac{1}{s+\zeta\omega_n+j\omega_n\sqrt{1-\zeta^2}}\right)\left(\frac{1}{s+\zeta\omega_n-j\omega_n\sqrt{1-\zeta^2}}\right). \end{gathered}\] Solving for \(c_1\), \(c_2\), and \(c_3\) gives \[\begin{aligned} c_1 &= A \\ c_2 &= -\frac{A}{2}\left(1+j\frac{\zeta}{\sqrt{1+\zeta^2}}\right)\\ c_3 &= -\frac{A}{2}\left(1-j\frac{\zeta}{\sqrt{1-\zeta^2}}\right). \end{aligned}\] Therefore, \[Y(s) = \frac{A}{s} + \frac{-\frac{A}{2}\left(1+j\frac{\zeta}{\sqrt{1+\zeta^2}}\right)}{s+\zeta\omega_n+j\omega_n\sqrt{1-\zeta^2}} + \frac{-\frac{A}{2}\left(1-j\frac{\zeta}{\sqrt{1-\zeta^2}}\right)}{s+\zeta\omega_n-j\omega_n\sqrt{1-\zeta^2}}.\] Taking the inverse Laplace transform gives \[\begin{aligned} y(t) &= A - \frac{A}{2}\left(1+j\frac{\zeta}{\sqrt{1+\zeta^2}}\right)e^{-\zeta\omega_nt-j\omega_n\sqrt{1-\zeta^2}t} \\ &\qquad\qquad - \frac{A}{2}\left(1-j\frac{\zeta}{\sqrt{1-\zeta^2}}\right)e^{-\zeta\omega_nt+j\omega_n\sqrt{1-\zeta^2}t} \\ &= A\Bigg(1 - \frac{1}{2}\left|1+j\frac{\zeta}{\sqrt{1+\zeta^2}}\right|e^{-\zeta\omega_nt} \\ &\qquad\qquad \cdot \left(e^{-j\omega_n\sqrt{1-\zeta^2}t}e^{j\angle\left(1+j\frac{\zeta}{\sqrt{1+\zeta^2}}\right)} + e^{+j\omega_n\sqrt{1-\zeta^2}t}e^{j\angle\left(1-j\frac{\zeta}{\sqrt{1+\zeta^2}}\right)} \right)\Bigg) \\ &= A\Bigg(1 - \frac{1}{\sqrt{1-\zeta^2}}e^{-\zeta\omega_nt} \\ &\qquad\qquad \cdot \left(\frac{e^{-j\left(\omega_n\sqrt{1-\zeta^2}t-\tan^{-1}\left(\frac{\zeta}{\sqrt{1-\zeta^2}}\right)\right)} + e^{j\left(\omega_n\sqrt{1-\zeta^2}t-\tan^{-1}\left(\frac{\zeta}{\sqrt{1-\zeta^2}}\right)\right)}}{2} \right)\Bigg) \\ &= A\left(1 - \frac{1}{\sqrt{1-\zeta^2}}e^{-\zeta\omega_nt} \cos\left(\omega_n\sqrt{1-\zeta^2}t-\tan^{-1}\left(\frac{\zeta}{\sqrt{1-\zeta^2}}\right)\right)\right), \end{aligned}\] for \(t\geq 0\). In general, complex conjugate poles will always lead to complex conjugate coefficients that end up canceling to produce a decaying exponential multiplied by a cosine term with a phase shift. If the coefficients of the original ordinary differential equation are real, then the response will always be real.

second-order

P.6 Root Locus

The root locus has been an important pedagogical tool in control systems since the 1940s. It was important in the design of feedback amplifiers for communication circuits where the classic design involved the tuning of a small number of parameters. In this appendix we introduce the root locus and show how it can be used to understand the effect of adding an integrator to a second-order system with PD control. However, we should note that root locus can be used in many other settings. We are not including this appendix as a main chapter in the book because in our experience root locus is rarely used for actual design.

P.6.1 Theory

We begin by noting that for the closed-loop system shown in Figure 6.1, the transfer function from \(Y_r(s)\) to \(Y(s)\) can be computed as \[\begin{aligned} &Y(s) = P(s)C(s)(Y_r(s)-Y(s)) \\ \implies & Y(s) = \frac{P(s)C(s)}{1+P(s)C(s)}Y_r(s). \end{aligned}\] Therefore, the characteristic equation of the closed-loop system is given by \[\Delta_{cl} = 1+P(s)C(s)=0.\]

General feedback system with plant P(s) and controller C(s).

We have seen in Chapter 10 that by using PD control for a second-order system, it is possible to precisely select the locations of the closed-loop poles. When an integrator is added for PID control, it is also possible to precisely select the location of the three closed-loop poles. In this chapter we will introduce a simple and convenient tool for visualizing how the closed-loop poles change as a function of a single parameter. As motivation, consider a first-order plant under proportional control, as shown in Fig. 6.2.

A first-order plant under proportional control.

The closed-loop transfer function is given by \[Y(s) = \frac{k_P}{s+(2+k_P)} Y_r(s)\] and the closed-loop characteristic polynomial is given by \[\Delta_{cl}(s) = s + (2+k_P).\] Note that the location of the closed-loop pole is \[p_{cl} = -(2+k_P).\] We can create a plot of the location of the poles in the complex plane as shown in Fig. 6.3.

A plot of the closed-loop pole associated with Fig. 30.2 as a function of k_P>0.

When \(k_P=0\), the closed-loop pole is located at the open-loop pole \(-2\), but as \(k_P\) is increased from zero, the closed-loop pole moves from \(-2\) into the left half-plane in the direction of the arrow shown in Fig. 6.3. The plot of the closed-loop pole as a function of \(k_P\) is an example of a root locus.

As a second example, consider the second-order system under proportional control shown in Fig. 6.4.

A second-order plant under proportional control.

In this case the closed-loop transfer function is given by \[Y(s) = \frac{k_P}{s^2+2s+k_P} Y_r(s)\] Note that the open-loop poles are located at \(0\) and \(-2\). The closed-loop characteristic polynomial is given by \[\tag{P.6.1} \Delta_{cl}(s) = s^2 + 2s + k_P\] and the closed-loop poles are located at \[p_{cl} = -1 \pm \sqrt{1-k_P}.\] The positions of the closed-loop poles as a function of \(k_P>0\) are shown in Fig. 6.5.

A plot of the closed-loop poles associated with Fig. 30.4 as a function of k_P>0.

When \(k_P=0\), the closed-loop poles are equal to the open-loop poles at \(0\) and \(-2\). When \(0 < k_P \leq 1\), the closed-loop poles are both real and move toward \(-1\) with increasing \(k_P\). When \(k_P=1\) both poles are located at \(-1\). When \(k_P>1\) the two poles are complex with real part equal to \(-1\) and increasing complex part as \(k_P\) increases. The poles move in the direction of the arrows shown in Fig. 6.5.

The MATLAB command rlocus will plot the root locus and can be used interactively to find the gain associated with specific pole locations. To use the rlocus command in MATLAB, the characteristic equation must be put in Evans’ form, which is \[1 + kL(s) = 0,\] where \(k\) is the gain of interest. For example, the characteristic equation associated with the characteristic polynomial in Equation P.6.1 is \[\Delta_{cl}(s) = s^2 + 2s + k_P = 0.\] The characteristic equation can be put in Evans’ form by dividing both sides by \(s^2+2s\) and rearranging to obtain \[1 + k_P\left(\frac{1}{s^2+2s}\right) = 0,\] where \(L(s)=\frac{1}{s^2+2s}\). The MATLAB command that draws the root locus for this equation is

>> L = tf([1], [1, 2, 0]);
>> figure(1), clf, rlocus(L)

where the first line defines the transfer function \(L(s)=\frac{1}{s^2+2s}\) and the second line invokes the root locus command using \(L\).

The root locus tool is particularly useful for selecting the integrator gains after PD gains have been selected. For example, suppose that a PD controller has been designed for the second-order plant shown in Fig. 6.6 so that the closed-loop poles are located at \(-2\pm j2\), where \(k_P=8\) and \(k_D=2\).

Closed loop system where the proportional gains have been selected as k_P=8 and k_D=2.

Now suppose that an integrator is to be added to reject disturbances and eliminate steady-state error, but that the integrator gain \(k_I\) is to be selected so that the closed-loop poles deviate from \(-2\pm j2\) by less than 10%. The characteristic equation for the closed-loop system including the integrator is given by \[\begin{aligned} & 1+\left(\frac{1}{s^2+2s}\right)\left(\frac{k_Ds^2+k_Ps+k_I}{s}\right) = 0 \\ \implies & \frac{(s^3 + 2s^2) + (k_Ds^2+k_Ps+k_I)}{s^3 + 2s^2} = 0 \\ \implies & s^3 + (2+k_D)s^2 + k_P s + k_I = 0 \\ \implies & \frac{(s^3 + (2+k_D)s^2 + k_P s) + k_I}{s^3 + (2+k_D)s^2 + k_P s} = 0 \\ \implies & 1 + k_I\left(\frac{1}{s^3+(2+k_D)s^2+k_Ps}\right) = 0 \\ \implies & 1 + k_I\left(\frac{1}{s^3+4s^2+8s}\right)=0 \end{aligned}\] where the latter equation is in Evans’ form. Therefore, the MATLAB command for drawing the root locus is

>> L = tf([1], [1, 4, 8, 0]);
>> figure(1), clf, rlocus(L)

and the resulting plot is shown in Fig. 6.7.

The result of MATLAB’s rlocus command, with pole locations selected interactively near -2\pm j2.

Note from Fig. 6.7 that the poles when \(k_I=0\) are at \(0,-2\pm j2\) and are denoted by ‘x’. The root locus shows what happens to the closed-loop poles as \(k_I\) is increased from zero. Note from Fig. 6.7 that for large values of \(k_I\) the closed-loop poles are in the right half-plane and the system will be unstable. However, for a gain of \(k_I=3.81\) the closed-loop poles are located at \(-1.67\pm j1.74\). This technique can be used to select reasonable values for \(k_I\).

P.6.2.1 image Example Problem 3.1.30

For the single-link robot arm, use the PD gains derived in HW 3.1.11. Add an integrator to the controller to get PID control. Put the resulting closed-loop characteristic equation in Evans’ form and use the MATLAB rlocus command to plot the root locus versus the integrator gain \(k_I\). Select a value for \(k_I\) that does not significantly change the other locations of the closed-loop poles.

P.6.2.2 Solution

The closed-loop block diagram including an integrator is shown in Fig. 6.8.

PID control for the single-link robot arm.

The closed-loop transfer function is given by \[\tilde{\Theta}(s) = \frac{\frac{3k_P}{m\ell^2}s + \frac{3k_I}{m\ell^2}}{s^3 + \left(\frac{3b+3k_D}{m\ell^2}\right)s^2 + \frac{3k_P}{m\ell^2}s + \frac{3k_I}{m\ell^2}} \tilde{\Theta}^d(s).\] The characteristic equation is therefore \[s^3 + \left(\frac{3b+3k_D}{m\ell^2}\right)s^2 + \frac{3k_P}{m\ell^2}s + \frac{3k_I}{m\ell^2} = 0.\] In Evans’ form we have \[1 + k_I\left(\frac{\frac{3}{m\ell^2}}{s^3 + \left(\frac{3b+3k_D}{m\ell^2}\right)s^2 + \frac{3k_P}{m\ell^2}s}\right) = 0.\] The appropriate MATLAB command is therefore

>> L = tf([3/m/L^2],...
          [1,(3*b+3*kd)/m/L^2,3*kp/m/L^2,0]);
>> figure(1), clf, rlocus(L);

P.6.3 Design Study B. Inverted Pendulum

P.6.3.1 image Example Problem 3.2.30

Add an integrator to obtain PID control for the outer loop of the inverted pendulum system. Put the characteristic equation in Evans’ form and use the MATLAB rlocus command to plot the root locus versus the integrator gain \(k_I\). Select a value for \(k_I\) that does not significantly change the other locations of the closed-loop poles.

Design Study B guided exercise

Set up the pendulum root locus

Put the outer-loop PID characteristic equation in Evans form and vary the integral gain.

Outer-loop PID root-locus block diagram for pendulum.

Use the block diagram to identify the transfer function multiplied by k_I.

Step 1. Root-locus gain

Step 2. Evans form

Step 3. Gain selection goal

Pseudocode

The complete solution includes implementation code. Before opening it, outline the algorithm in your own words.

This prompt is ungraded. It is intended to connect the derivation to the implementation code in the complete solution.

P.6.4 Design Study C. Satellite Attitude Control

P.6.4.1 image Example Problem 3.3.30

Add an integrator to obtain PID control for the outer loop of the satellite system. Put the characteristic equation in Evans’ form and use the MATLAB rlocus command to plot the root locus versus the integrator gain \(k_I\). Select a value for \(k_I\) that does not significantly change the other locations of the closed-loop poles.

Design Study C guided appendix

Interpret the satellite PID root locus

The root-locus task adds an outer-loop integrator and varies \(k_I\). The goal is to remove steady-state error without moving the dominant poles too much.

Step 1. Root-locus gain

Step 2. Gain-selection criterion

P.6.5 Notes and References

P.7 Review of Linear Algebra

Let \(A\) be an \(m\times n\) matrix of real numbers, denoted as \(A\in\mathbb{R}^{m\times n}\). Then \[A = \begin{pmatrix} a_{11} & a_{12}& \dots & a_{1n} \\ a_{21} & a_{22} & \dots & a_{2n} \\ \vdots & & & \vdots \\ a_{m1} & a_{m2} & \dots & a_{mn} \end{pmatrix}.\] Matrix addition is defined element wise for matrices of compatible dimensions as \[\begin{gathered} \underbrace{\begin{pmatrix} a_{11} & a_{12}& \dots & a_{1n} \\ a_{21} & a_{22} & \dots & a_{2n} \\ \vdots & & & \vdots \\ a_{m1} & a_{m2} & \dots & a_{mn} \end{pmatrix}}_{A} + \underbrace{\begin{pmatrix} b_{11} & b_{12}& \dots & b_{1n} \\ b_{21} & b_{22} & \dots & b_{2n} \\ \vdots & & & \vdots \\ b_{m1} & b_{m2} & \dots & b_{mn} \end{pmatrix}}_{B} \\ = \underbrace{\begin{pmatrix} a_{11}+b_{11} & a_{12}+b_{12} & \dots & a_{1n}+a_{1n} \\ a_{21}+b_{21} & a_{22}+b_{22} & \dots & a_{2n}+b_{2n} \\ \vdots & & & \vdots \\ a_{m1}+b_{m1} & a_{m2}+b_{m2} & \dots & a_{mn}+b_{mn} \end{pmatrix}}_{C}. \end{gathered}\] To multiply a matrix times a vector, the inner dimensions must match: \[\underbrace{A}_{m\times n}\underbrace{x}_{n\times 1} = \begin{pmatrix} a_{11} & \dots & a_{1n} \\ \vdots && \vdots \\ a_{m1} & \dots & a_{mn} \end{pmatrix} \begin{pmatrix} x_1 \\ \vdots \\ x_n\end{pmatrix} = \begin{pmatrix} \sum_{i=1}^n a_{1i}x_i \\ \vdots \\ \sum_{i=1}^n a_{mi}x_i \end{pmatrix} = \underbrace{b}_{m\times 1}.\] For example, \[\begin{pmatrix} 1 & 2 \\ 3 & 4 \end{pmatrix} \begin{pmatrix} 5 \\ 6 \end{pmatrix} = \begin{pmatrix} 17 \\ 39 \end{pmatrix}.\] Multiplying two matrices also requires matching dimensions: \[\begin{aligned} \underbrace{A}_{m\times n} \underbrace{B}_{n\times p} &= \begin{pmatrix} a_{11} & \dots & a_{1n} \\ \vdots && \vdots \\ a_{m1} & \dots & a_{mn} \end{pmatrix} \begin{pmatrix} b_{11} & \dots & b_{1n} \\ \vdots && \vdots \\ b_{m1} & \dots & b_{mn} \end{pmatrix} \\ &= \begin{pmatrix} \sum_{i=1}^n a_{1i}b_{i1} & \dots & \sum_{i=1}^n a_{1i}b_{ip} \\ \vdots && \vdots \\ \sum_{i=1}^n a_{mi}b_{i1} & \dots & \sum_{i=1}^n a_{mi}b_{ip}\end{pmatrix} = \underbrace{C}_{m\times p}. \end{aligned}\] Note that if \(A\in\mathbb{R}^{m\times n}\) and \(B\in\mathbb{R}^{n\times p}\), then \(AB\) is a valid product, but \(BA\) is not a valid product. Even if the dimensions are compatible, i.e., if \(A\) and \(B\) are square, in general \[AB \neq BA.\]

P.7.1 Transpose

If \(A\in\mathbb{R}^{m\times n}\), then the transpose of \(A\), denoted as \(A^{\top}\in\mathbb{R}^{n\times m}\) is obtained by interchanging the rows and the columns. For example \[\begin{aligned} \begin{pmatrix} x_1 \\ x_2 \\ x_3 \end{pmatrix}^\top &= \begin{pmatrix} x_1 & x_2 & x_3 \end{pmatrix}, \\ \begin{pmatrix} 1 & 2 \\ 3 & 4 \end{pmatrix}^{\top} &= \begin{pmatrix} 1 & 3 \\ 2 & 4 \end{pmatrix}. \end{aligned}\] A square matrix \(A\) is said to be symmetric if \(A^\top=A\). Similarly, \(A\) is said to be skew-symmetric if \(A^\top=-A\). Every square matrix \(A\in\mathbb{R}^{n\times n}\) can be decomposed into the sum of a symmetric and a skew-symmetric matrix as \[\begin{aligned} A &= \frac{1}{2}A + \frac{1}{2}A + \frac{1}{2}A^\top - \frac{1}{2}A^\top \\ &= \left(\frac{1}{2}A + \frac{1}{2}A^\top\right) + \left(\frac{1}{2}A-\frac{1}{2}A^\top\right) \\ & = A_s + A_{ss}, \end{aligned}\] where \(A_s=\frac{1}{2}(A+A^\top)\) is symmetric, and \(A_{ss}=\frac{1}{2}(A-A^\top)\) is skew-symmetric.

The following properties are easily verified by direct manipulation: \[\begin{aligned} (AB)^\top &= B^\top A^\top \\ (A+B)^\top &= A^\top + B^\top. \end{aligned}\]

P.7.2 Trace

The trace operator is defined for square matrices. If \(A\in\mathbb{R}^{n\times n}\), then \[\text{tr}(A) = \sum_{i=1}^n a_{ii},\] or in other words, the sum of the diagonals of \(A\). For example \[\text{tr}\begin{pmatrix} 1 & 2 \\ 3 & 4 \end{pmatrix} = 1+4 = 5.\]

P.7.3 Determinant

The determinant operator is defined for square matrices \(A\in\mathbb{R}^{n\times n}\) as \[\det(A) = \sum_{j=1}^n a_{ij}\gamma_{ij},\] for any \(i=1,\dots,n\), where the co-factor \[\gamma_{ij} = (-1)^{(i+j)}\det(M_{ij})\] and where the minor \(M_{ij}\) is the \((n-1)\times(n-1)\) matrix obtained by removing the \(i^{th}\) row and the \(j^{th}\) column of \(A\). As an example, \[\begin{aligned} \det\begin{pmatrix} 1 & 2 & 3 \\ 4 & 5 & 0 \\ 6 & 7 & 8\end{pmatrix} &= 1\cdot\det\begin{pmatrix} 5 & 0 \\ 7 & 8\end{pmatrix} - 2\cdot\det\begin{pmatrix} 4 & 0 \\ 6 & 8 \end{pmatrix} \\ &\qquad + 3\cdot\det\begin{pmatrix} 4 & 5 \\ 6 & 7 \end{pmatrix} \\ &= 1\cdot(5\cdot 8 - 7\cdot 0) - 2\cdot(4\cdot 8 - 6\cdot 0) \\ &\qquad + 3\cdot(4\cdot 7 - 6\cdot 5) \\ &= -30. \end{aligned}\] The adjugate of \(A\) is defined as the transpose of the co-factors of \(A\): \[\text{adj}(A) = \begin{pmatrix} \gamma_{11} & \dots & \gamma_{n1} \\ \vdots & & \vdots \\ \gamma_{1n} & \dots & \gamma_{nn}\end{pmatrix}.\] We have the following properties for the determinant: \[\begin{aligned} \det(A) &= \det(A^\top) \\ \det(AB) &= \det(A)\det(B) \\ \det(A^{-1}) &= \frac{1}{\det(A)}. \end{aligned}\]

There are also well defined rules for finding the determinant of a block matrix. Let \[E = \begin{pmatrix} A & B \\ C & D \end{pmatrix}\] where \(A\in\mathbb{R}^{n\times n}\), \(B\in\mathbb{R}^{n\times p}\), \(C\in\mathbb{R}^{m\times n}\) and \(D\in\mathbb{R}^{m\times m}\), then it can be shown that if \(A\) is invertible, then \[\det(E) = \det(A) \det\left(D-CA^{-1}B\right).\] As a special case, if either \(B=0\) or \(C=0\), then \[\det(E) = \det(A)\det(D).\] For example, \[\det\begin{pmatrix} 1 & 2 & 3 & 4 & 5 \\ 2 & 3 & 4 & 5 & 6 \\ 3 & 4 & 5 & 6 & 7 \\ 0 & 0 & 0 & 8 & 9 \\ 0 & 0 & 0 & 9 & 10 \end{pmatrix} = \det\begin{pmatrix} 1 & 2 & 3 \\ 2 & 3 & 4 \\ 3 & 4 & 5 \end{pmatrix} \cdot\det\begin{pmatrix} 8 & 9 \\ 9 & 10 \end{pmatrix}.\]

P.7.4 Matrix Inverses

If \(A\in\mathbb{R}^{n\times n}\), and there exists a matrix \(B\in\mathbb{R}^{n\times n}\) such that \[AB = BA = I,\] then \(B\) is said to be the inverse of \(A\) and is denoted as \(B=A^{-1}\).

The inverse of any square matrix can be expressed in terms of its adjugate and its determinant as \[A^{-1} = \frac{\text{adj}(A)}{\text{det}(A)}.\] For a \(2\times 2\) matrix we have the simple formula \[\begin{pmatrix} a & b \\ c & d \end{pmatrix}^{-1} =\frac{\text{adj}\begin{pmatrix} a & b \\ c & d\end{pmatrix}}{\text{det}\begin{pmatrix} a & b \\ c & d \end{pmatrix}}= \frac{\begin{pmatrix} d & -b \\ -c & a\end{pmatrix}}{ad-bc}.\] If \(\det(A)\neq 0\), then \(A\) is called non-singular.

If \(A\) and \(B\) are nonsingular, then \[(AB)^{-1} = B^{-1}A^{-1}.\]

For block matrices it can be verified by direct substitution that \begin{align} \begin{pmatrix} A & B \\ C & D \end{pmatrix}^{-1} &= \begin{pmatrix} (A-BD^{-1}C)^{-1} & -(A-BD^{-1}C)^{-1}BD^{-1} \\ -D^{-1}C(A-BD^{-1}C)^{-1} & D^{-1}+D^{-1}C(A-BD^{-1}C)^{-1}BD^{-1} \end{pmatrix} \tag{P.7.1}\\ &= \begin{pmatrix} A^{-1}+A^{-1}B(D-CA^{-1}B)^{-1}CA^{-1} & -A^{-1}B(D-CA^{-1}B)^{-1} \\ -(D-CA^{-1}B)^{-1}CA^{-1} & (D-CA^{-1}B)^{-1} \end{pmatrix}, \tag{P.7.2} \end{align} from which we get the famous matrix inversion lemma \[\tag{P.7.3} (A-BD^{-1}C)^{-1} = A^{-1}+A^{-1}B(D-CA^{-1}B)^{-1}CA^{-1}.\] When \(C=0\) we get the simple formula \[\begin{pmatrix} A & B \\ 0 & D\end{pmatrix}^{-1} = \begin{pmatrix} A^{-1} & -A^{-1}BD^{-1} \\ 0 & D^{-1} \end{pmatrix}.\]

P.7.5 Eigenvalues and Eigenvectors

The pair \((\lambda, v)\) where \(\lambda \in \mathbb{C}\) and \(0\neq v\in\mathbb{C}^{n\times 1}\) is said to be an eigenvalue-eigenvector pair of the matrix \(A\in\mathbb{R}^{n\times n}\) if \[Av = \lambda v.\] The following statements are equivalent:

  1. \((\lambda, v)\) is an eigenvalue-eigenvector pair of \(A\),

  2. \(Av = \lambda v\),

  3. \((\lambda I - A)v = 0\), where \(I\) is the \(n\times n\) identity matrix,

  4. \(v\) is in the null space of \((\lambda I - A)\),

  5. \(\det(\lambda I-A)=0\).

For example, to find the eigenvalues and eigenvectors of \[A = \begin{pmatrix} 0 & 1 \\ -2 & -3 \end{pmatrix},\] first compute \[\begin{aligned} \det(\lambda I - A) &= \det\begin{pmatrix} \lambda & -1 \\ 2 & \lambda+3 \end{pmatrix} \\ &= \lambda^2 + 3\lambda + 2 = (\lambda+2)(\lambda+1). \end{aligned}\] Setting \(\det(\lambda I - A)=0\) implies that the eigenvalues are \[\lambda_1 = -2, \qquad \lambda_2 = -1.\] To find the eigenvector associated with \(\lambda_1\) we need to find a vector \(v_1\) that is in the null space of \((\lambda_1 I -A)\). Since \[(\lambda_1 I - A)v_1 = \begin{pmatrix} -2 & -1 \\ 2 & 1 \end{pmatrix}\begin{pmatrix} v_{11} \\ v_{12} \end{pmatrix} = \begin{pmatrix} 0 \\ 0 \end{pmatrix},\] we have that \(2v_{11}=-v_{12}\). Therefore, \(v_1 = (1, -2)^\top\) is in the null space of \((\lambda_1 I -A)\) and is an eigenvector of \(A\) associated with eigenvalue \(\lambda_1\).

To find the eigenvector associated with \(\lambda_2\) we need to find a vector \(v_2\) that is in the null space of \((\lambda_2 I -A)\). Since \[(\lambda_2 I - A)v_2 = \begin{pmatrix} -1 & -1 \\ 2 & 2 \end{pmatrix}\begin{pmatrix} v_{21} \\ v_{22} \end{pmatrix} = \begin{pmatrix} 0 \\ 0 \end{pmatrix},\] we have that \(v_{21}=-v_{22}\). Therefore, \(v_2 = (-1, 1)^\top\) is in the null space of \((\lambda_2 I -A)\) and is an eigenvector of \(A\) associated with eigenvalue \(\lambda_2\).

Since \(Av_1=\lambda_1 v_1\) and \(Av_2=\lambda_2 v_2\) we can write \[A\begin{pmatrix}v_1 & v_2\end{pmatrix} = \begin{pmatrix}v_1 & v_2\end{pmatrix} \begin{pmatrix} \lambda_1 & 0 \\ 0 & \lambda_2 \end{pmatrix}.\] Defining \(M = \begin{pmatrix} v_1 & v_2 \end{pmatrix}\) and \(\Lambda = \begin{pmatrix} \lambda_1 & 0 \\ 0 & \lambda_2 \end{pmatrix}\) we have \[AM = M\Lambda.\] When \(M\) is invertible, we have \[A = M\Lambda M^{-1}.\] \(M\) will always be invertible when the eigenvalues are distinct. For example, it can be verified that \[\begin{pmatrix} 0 & 1 \\ -2 & -3 \end{pmatrix} = \begin{pmatrix} 1 & -1 \\ -2 & 1 \end{pmatrix} \begin{pmatrix} -2 & 0 \\ 0 & 11 \end{pmatrix} \begin{pmatrix} 1 & -1 \\ -2 & 1 \end{pmatrix}^{-1}.\] The formula \(A=M\Lambda M^{-1}\) is called the eigen-decomposition of \(A\).

The trace and the determinant of \(A\) can be written in terms of the eigenvalues of \(A\) as \[\begin{aligned} \text{tr}(A) &= \sum_{i=1}^n \lambda_i(A), \\ \det(A) &= \Pi_{i=1}^n \lambda_i(A). \end{aligned}\] where \(\lambda_i(A)\) is the \(i^{th}\) eigenvalue of \(A\).

P.7.6 Linear Independence and Rank

The vectors \(x_1, x_2, \dots, x_p\in\mathbb{R}^{n\times 1}\) are said to be linearly independent if \[c_1 x_1 + c_2 x_2 + \dots + c_px_p=0,\] implies that \(c_1=c_2=\dots=c_p=0\). For example, the vectors \((1,0)^\top\) and \((0,1)^\top\) are linearly independent since \[c_1\begin{pmatrix} 1 \\ 0 \end{pmatrix} + c_2\begin{pmatrix} 0 \\ 1 \end{pmatrix} = \begin{pmatrix} c_1 \\ c_2 \end{pmatrix} = \begin{pmatrix} 0 \\ 0 \end{pmatrix}\] implies that \(c_1=c_2=0\). Alternatively, the vectors \((1,0)^\top\) and \((3, 0)^\top\) are not linearly independent since \[c_1\begin{pmatrix} 1 \\ 0 \end{pmatrix} + c_2\begin{pmatrix} 3 \\ 0 \end{pmatrix} = \begin{pmatrix} c_1+3c_0 \\ 0 \end{pmatrix} = \begin{pmatrix} 0 \\ 0 \end{pmatrix}\] is true if \(c_1=-3c_2\) for any \(c_2\).

The rank of a matrix is defined to be the number of linearly independent rows or columns. For example \[\begin{aligned} \text{rank}\begin{pmatrix} 1 & 0 \\ 0 & 1 \end{pmatrix} &= 2 \\ \text{rank}\begin{pmatrix} 1 & 3 \\ 0 & 0 \end{pmatrix} &= 1. \end{aligned}\]

P.7.7 Special Matrices

The matrix \(A\in\mathbb{R}^{n\times n}\) is said to be diagonal if \[A = \begin{pmatrix} a_{11} & 0 & \dots & 0 \\ 0 & a_{22} & \dots & 0 \\ \vdots & & \ddots & \vdots \\ 0 & 0 & \dots & a_{nn} \end{pmatrix}.\] For example, \[A = \begin{pmatrix} 2 & 0 & 0 & 0 \\ 0 & 3 & 0 & 0 \\ 0 & 0 & 4 & 0 \\ 0 & 0 & 0 & 5 \end{pmatrix}\] is a diagonal matrix.

The matrix \(A\in\mathbb{R}^{n\times n}\) is said to be upper triangular if \[A = \begin{pmatrix} a_{11} & a_{12} & \dots & a_{1n} \\ 0 & a_{22} & \dots & a_{2n} \\ \vdots & & \ddots & \vdots \\ 0 & 0 & \dots & a_{nn} \end{pmatrix}.\] For example, \[A = \begin{pmatrix} 2 & 3 & 4 & 5 \\ 0 & 6 & 7 & 8 \\ 0 & 0 & 9 & 10 \\ 0 & 0 & 0 & 11 \end{pmatrix}\] is an upper triangular matrix.

The matrix \(A\in\mathbb{R}^{n\times n}\) is said to be in upper companion form if \[A = \begin{pmatrix} -a_1 & -a_2 & \dots & -a_{n-1} & -a_n \\ 1 & 0 & \dots & 0 & 0 \\ \vdots & \ddots & & \vdots & 0 \\ 0 & 0 & \dots & 1 & 0 \end{pmatrix}.\] For example, \[A = \begin{pmatrix} -2 & -3 & -4 & -5 \\ 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \end{pmatrix}\] is in upper companion form.

The matrix \(A\in\mathbb{R}^{n\times n}\) is said to be a Vandermonde matrix if \[A = \begin{pmatrix} 1 & a_1 & a_1^2 & \dots & a_1^{n-1} \\ 1 & a_2 & a_2^2 & \dots & a_2^{n-1} \\ 1 & a_3 & a_3^2 & \dots & a_3^{n-1} \\ 1 & a_4 & a_4^2 & \dots & a_4^{n-1} \end{pmatrix}.\] For example, \[A = \begin{pmatrix} 1 & 2 & 4 & 9 \\ 1 & 3 & 9 & 27 \\ 1 & 4 & 16 & 64 \\ 1 & 5 & 25 & 125 \end{pmatrix}\] is a Vandermonde matrix.

Bibliography

[1] H. Goldstein, Classical Mechanics, Addison-Wesley, 1951

[2] V. I. Arnold, Mathematical Methods of Classical Mechanics, Springer Verlag, 1989

[3] J. Hanc, E. F. Taylor, and S. Tuleja, “Deriving Lagrange’s Equations using Elementary Calculus,” American Journal of Physics, vol. 72, no. 4, pp. 510–513, 2014

[4] G. F. Franklin, J. D. Powell, and A. Emami-Naeini, Feedback Control of Dynamic Systems, Addison Wesley, 2002

[5] J. P. Hespanha, Linear Systems Theory, Princeton University Press, 2009

[6] T. Kailath, Linear Systems, Prentice Hall, 1980

[7] C.-T. Chen, Linear System Theory and Design, Oxford University Press, 1999

[8] M. W. Spong, S. Hutchinson, and M. Vidyasagar, Robot Modeling and Control, Wiley, 2006

[9] K. S. Fu, R. C. Gonzalez, and C. S. G. Lee, Robotics: Control, Sensing, Vision, and Intelligence, McGraw Hill, 1987

[10] J. J. Craig, Introduction to Robotics: Mechanics and Control, Pearson Prentice Hall, 2005

[11] H. K. Khalil, Nonlinear Control, Pearson, 2015

[12] A. Isidori, Nonlinear Control Systems, Springer Verlag, 1989

[13] H. Nijmeijer and A. J. van der Schaft, Nonlinear Dynamical Control Systems, Springer Verlag, 1990

[14] S. Sastry, Nonlinear Systems: Analysis, Stability, and Control, Springer, 1999

[15] Krstić, Kanellakopaulis, and Kokotovic, Nonlinear and Adaptive Control Design, Wiley, 1995

[16] A. V. Oppenheim and A. S. Willsky, Signals & Systems, Prentice Hall, 1997

[17] P. M. DeRusso, R. J. Roy, C. M. Close, and A. A. Desrochers, State Variables for Engineers, Wiley, 1998

[18] G. F. Franklin, J. D. Powell, and M. Workman, Digital Control of Dynamic Systems, Addison Wesley, 1998

[19] Dorato, Abdallah, and Cerone, Linear-Quadratic Control: An Introduction, Prentice Hall, 1995

[20] H. K. Khalil, Nonlinear Systems, Prentice Hall, 2002

[21] D. G. Luenberger, “An Introduction to Observers,” IEEE Transactions on Automatic Control, vol. 16, no. 6, pp. 596–602, 1971

[22] K. J. Astrom and R. M. Murray, Feedback Systems: An Introduction for Scientists and Engineers, Princeton University Press, 2009

[23] R. C. Dorf and R. H. Bishop, Modern Control Systems, Pearson Education, 2016

[24] F. L. Lewis, Optimal Estimation: With an Introduction to Stochastic Control Theory, John Wiley & Sons, 1986

[25] S. Thrun, W. Burgard, and D. Fox, Probabilistic Robotics, MIT Press, 2006

[26] B. D. O. Anderson and J. B. Moore, Linear Optimal Control, Prentice Hall, 1971

[27] Aided Navigation: GPS with High Rate Sensors, McGraw-Hill, 2008

Index

A

Ackermann's formula 170, 212
adjugate of a matrix 74, 469
analog computer 207
analog computer implementation 163
augmented state-space equations 230
augmented system 186

B

block and beam 375
block matrix 470
Bode canonical form 256
Bode phase gain relationship 300
Bode plot 254, 256, 294

C

change of variables 162, 167
closed-loop Bode plot 297
closed-loop characteristic equation 162
closed-loop characteristic polynomial 88
closed-loop performance 273
closed-loop poles 88, 162
closed-loop transfer function 88
co-factor 469
companion form 165
complex conjugate poles 455
complex numbers 251
complex numbers - polar coordinates 251
complex numbers - rectangular coordinates 251
computed torque 56
conjugate of a complex number 252
control canonic form 163, 164, 474
control canonical form 324
control implementation 324
controllability matrix 169, 186
controllable 186
controllable system 169
critically damped 100
crossover frequency 293

D

damping forces 33
damping ratio 95, 98, 297
DC gain 96, 106, 170, 187
derivative control 82
derivative gain 83
design model 3
design models 46
design process 1
desired characteristic polynomial 88
determinant of a matrix 469
diagonal matrix 473
digital differentiator 158
digital implementation 217
dirty derivative 145
discrete differentiator 145
discrete integrator 145
distinct eigenvalues 472
disturbance observer 229
disturbance rejection 275, 278, 280, 293, 317

E

eigen-decomposition 472
eigenvalue of a matrix 471
eigenvalues 74, 161
eigenvector 471
equilibrium point 48
estimated state 205
Euler's relationship 252
Euler-Lagrange equation 10
Euler-Lagrange equations 31, 33

F

feedback linearization 47, 50, 56
final value theorem 125
first-order response 95
forced response 450
free integrator 130
frequency response 250, 254, 273, 297
full state feedback 161, 167
fundamental theorem of calculus 126

G

gain margin 296
generalized coordinates 10, 32
generalized forces 10, 32
generalized velocity 10

H

homogeneous response 450

I

innovation 206
input disturbance 131, 229, 273
input disturbance rejection 275, 280
input saturation 146, 298
integral control 82, 158, 159, 185, 314
integral feedback 212
integral gain 82
integrating factor 449
integrator 125, 144, 460
integrator anti-windup 145
interaction matrix 186
inverse Laplace transform 96, 97, 451
inverse of a matrix 470

J

Jacobian linearization 47, 49, 71

K

kinetic energy 8, 11

L

Lagrangian 33
Laplace transform 57, 73, 230, 450
linear independence 473
linearized system 171, 187
linearized systems 214
loop gain 294, 313
loop shaping control 3
loop-shaping 313
loopshape 293
loopshaping 250
low-pass filter 314, 315

M

magnitude of a complex number 251
magnitude of a transfer function 253
matrix 467
matrix addition 467
matrix adjugate 469
matrix determinant 469
matrix eigenvalue 471
matrix inverse 470
matrix minor 469
matrix multiplication 467
matrix rank 473
matrix trace 469
matrix transpose 468
measured output 171, 205
moments of inertia 16

N

natural frequency 95, 98, 297
noise 273
noise attenuation 275, 277, 293, 315
non-singular matrix 470
nonminimum phase zeros 104

O

observability matrix 211
observable 231
observable system 212
observation error 206
observer 205, 229
observer canonic form 208
observer error 206
observer gain 206, 209, 212
observer-based control 3
observers 158
open-loop characteristic polynomial 87
open-loop poles 87, 161
ordinary differential equations 449
output disturbance 131, 273
output disturbance rejection 275, 278
output equation 69
overdamped 100

P

parallel axis theorem 30
partial fraction expansion 102, 451
PD control 87
phase margin 294, 318
phase of a complex number 251
phase of a transfer function 253
phase-lag filter 314, 315
phase-lead filter 314, 317
PI control 82, 314
PID control 3, 82, 83, 143, 460
point mass 11, 31
pole locations 95
pole placement 185
poles 59, 74
potential energy 8, 31
potential energy of a spring 31
prefilter 325
proportional control 82
proportional gain 82, 314

R

rank of a matrix 473
rational transfer function 102
realization of a transfer function 162
reference command 82
reference input 131
reference output 171, 185, 205
residue 453
rise time 96, 99, 101
root locus 185, 457

S

s-function 427
sample period 145
sampled data system 143
second-order response 99
second-order systems 82
sensor noise 131
separation principle 212, 214
simulation Model 1
stability margins 313
state evolution equation 69
state feedback 158
state interaction matrix 161, 166
state-space equations 72, 161
state-space model 69, 205
state-space models 3, 158
steady-state error 83, 125
step response 95, 96, 101, 297, 449, 451
successive loop closure 105, 148, 327
system type 129, 132, 281, 315

T

Taylor series 47
trace of a matrix 469
tracking performance 275, 293, 317
transfer function 58, 60, 250, 253
transfer function model 162
transfer function models 3, 73
transpose of a matrix 468
Tustin approximation 145
type 0 system 282
type 1 system 283
type 2 system 284

U

underdamped 100
upper companion form 474
upper triangular matrix 474

V

Vandermonde matrix 474

Z

z-transform 144
zeros 59, 74, 101