Chapter 20: Capstone / Mini-Project

Lesson 5: Final Demo and Technical Presentation

In this lesson we formalize how to turn your capstone robot into a defensible experiment: we define quantitative performance metrics, connect them to linear control theory, design pass/fail criteria, and show how to process experimental data in code. Finally, we outline how to structure a rigorous technical presentation that communicates these results to an engineering audience.

1. Role of the Final Demo and Technical Presentation

By the end of the project, your robot is not just a prototype but an implemented control system with measurable performance. At a high level, we can view the robot as a dynamical system

\[ \dot{\mathbf{x}}(t) = f(\mathbf{x}(t), \mathbf{u}(t), \mathbf{d}(t)), \quad \mathbf{y}(t) = h(\mathbf{x}(t)), \]

where \( \mathbf{x}(t) \) is the state, \( \mathbf{u}(t) \) the control input, \( \mathbf{d}(t) \) disturbances, and \( \mathbf{y}(t) \) the measured output (e.g., end-effector position, mobile base pose, or joint angles).

For analysis around a nominal operating point, we typically use a linearized closed-loop model

\[ \dot{\tilde{\mathbf{x}}}(t) = A_{\mathrm{cl}} \tilde{\mathbf{x}}(t) + B_{\mathrm{cl}} \tilde{\mathbf{r}}(t), \quad \tilde{\mathbf{y}}(t) = C \tilde{\mathbf{x}}(t), \]

where \( \tilde{\mathbf{r}}(t) \) is the reference deviation. The final demo answers two key questions:

  1. Does the implemented system satisfy the project requirements?
  2. Can you convincingly explain why, using models, data, and control theory?

To formalize this, suppose you define a vector of performance metrics \( \mathbf{m} \in \mathbb{R}^q \), such as tracking error, settling time, and control effort. The requirement specification can then be written as a set of inequality constraints

\[ g_i(\mathbf{m}) \le 0, \quad i = 1,\dots,q, \]

where each \( g_i \) encodes a constraint like "overshoot at most 10%" or "RMS error below 2 cm". The final demo and technical presentation must show both the measured metrics \( \mathbf{m}_{\mathrm{exp}} \) and the predicted metrics \( \mathbf{m}_{\mathrm{model}} \) from your control design, and explain any discrepancy.

2. Tracking Error and Performance Metrics

Consider a single degree-of-freedom output (e.g., position of a joint) with reference \( r(t) \) and measured output \( y(t) \). The tracking error is

\[ e(t) = r(t) - y(t). \]

For a multi-output robot, we write \( \mathbf{e}(t) = \mathbf{r}(t) - \mathbf{y}(t) \), with \( \mathbf{r}(t), \mathbf{y}(t) \in \mathbb{R}^p \). Common continuous-time performance measures are:

  • Integral squared error (ISE):

    \[ J_{\mathrm{ISE}} = \int_0^T \| \mathbf{e}(t) \|_2^2 \,\mathrm{d}t. \]

  • Integral absolute error (IAE):

    \[ J_{\mathrm{IAE}} = \int_0^T \| \mathbf{e}(t) \|_1 \,\mathrm{d}t. \]

  • RMS error:

    \[ e_{\mathrm{RMS}} = \sqrt{\frac{1}{T}\int_0^T \| \mathbf{e}(t) \|_2^2 \,\mathrm{d}t }. \]

During a demo, you typically log discrete samples \( \mathbf{e}_k = \mathbf{e}(t_k) \) with sampling period \( \Delta t = t_{k+1} - t_k \). Discrete-time approximations are:

\[ \widehat{J}_{\mathrm{ISE}} = \sum_{k=0}^{N-1} \| \mathbf{e}_k \|_2^2 \,\Delta t, \quad \widehat{J}_{\mathrm{IAE}} = \sum_{k=0}^{N-1} \| \mathbf{e}_k \|_1 \,\Delta t, \]

\[ \widehat{e}_{\mathrm{RMS}} = \sqrt{\frac{1}{N}\sum_{k=0}^{N-1}\|\mathbf{e}_k\|_2^2 }. \]

For a step response with steady-state value \( y_{\mathrm{ss}} \), further time-domain metrics are:

  • Overshoot:

    \[ M_p = \frac{\max_{t \ge 0} y(t) - y_{\mathrm{ss}}}{y_{\mathrm{ss}}} \times 100\,\%. \]

  • Settling time (to tolerance \( \varepsilon \)):

    \[ t_s(\varepsilon) = \inf\left\{ t \ge 0 \;:\; |y(\tau) - y_{\mathrm{ss}}| \le \varepsilon |y_{\mathrm{ss}}| \ \forall \tau \ge t \right\}. \]

Your demo specification can thus be written as constraints such as \( M_p \le M_p^{\max} \), \( t_s(0.02) \le t_s^{\max} \), and \( e_{\mathrm{RMS}} \le e_{\mathrm{RMS}}^{\max} \).

3. Linking Linear Control Design to Measured Performance

In your control design phase (earlier in the project), you designed a controller (e.g., PID, state feedback) based on a linear model of the robot dynamics. For a SISO system with plant \( G(s) \) and controller \( C(s) \), the closed-loop transfer function from step reference to output is

\[ T(s) = \frac{C(s)G(s)}{1 + C(s)G(s)}. \]

A common design approximation is a dominant second-order closed-loop model

\[ T(s) \approx \frac{\omega_n^2}{s^2 + 2\zeta \omega_n s + \omega_n^2}, \]

with natural frequency \( \omega_n \) and damping ratio \( \zeta \). Under this approximation,

\[ M_p = \exp\!\left( -\frac{\pi \zeta}{\sqrt{1 - \zeta^2}} \right), \quad t_s(0.02) \approx \frac{4}{\zeta \omega_n}. \]

These formulas give you predicted values for overshoot and settling time. The final demo must compare them to the measured values from your logs.

For state-space designs, write the closed-loop linear system as

\[ \dot{\mathbf{x}}(t) = A_{\mathrm{cl}} \mathbf{x}(t) + B_{\mathrm{cl}} \mathbf{r}(t), \quad \mathbf{y}(t) = C \mathbf{x}(t). \]

Assume a constant reference \( \mathbf{r}(t) = \mathbf{r}_0 \) and that all eigenvalues of \( A_{\mathrm{cl}} \) satisfy

\[ \operatorname{Re}\big(\lambda_i(A_{\mathrm{cl}})\big) < 0 \quad \text{for all } i, \]

i.e. the closed-loop is asymptotically stable. Then the steady-state satisfies

\[ \mathbf{0} = A_{\mathrm{cl}}\mathbf{x}_{\mathrm{ss}} + B_{\mathrm{cl}}\mathbf{r}_0, \quad \Rightarrow \quad \mathbf{x}_{\mathrm{ss}} = -A_{\mathrm{cl}}^{-1} B_{\mathrm{cl}} \mathbf{r}_0, \]

\[ \mathbf{y}_{\mathrm{ss}} = C \mathbf{x}_{\mathrm{ss}}, \quad \mathbf{e}_{\mathrm{ss}} = \mathbf{r}_0 - \mathbf{y}_{\mathrm{ss}}. \]

In your presentation, you can explicitly show \( \mathbf{e}_{\mathrm{ss}} \) from the model and compare it to the measured steady-state error from experiments. This is a direct bridge between theory and demo.

4. Acceptance Criteria and Weighted Scores

Suppose you collect \( q \) scalar metrics \( m_1,\dots,m_q \) (e.g., overshoot, RMS error, maximum control input, battery consumption), and stack them in \( \mathbf{m} \in \mathbb{R}^q \):

\[ \mathbf{m} = (m_1,\dots,m_q)^{\top}. \]

A simple hard constraint acceptance region is

\[ \mathcal{A} = \left\{ \mathbf{m} \in \mathbb{R}^q \;:\; m_i \le m_i^{\max},\; i = 1,\dots,q \right\}. \]

The robot is accepted if \( \mathbf{m}_{\mathrm{exp}} \in \mathcal{A} \). In many projects, you also define a scalar score \( S(\mathbf{m}) \) to rank designs:

\[ S(\mathbf{m}) = \sum_{i=1}^q w_i \,\phi_i(m_i), \quad w_i \ge 0,\; \sum_{i=1}^q w_i = 1. \]

Here \( \phi_i \) are monotonically increasing penalty functions (e.g. \( \phi_i(m_i) = m_i \) or \( \phi_i(m_i) = m_i^2 \)). You may then define a passing threshold \( S_{\max} \) and say the system passes if \( S(\mathbf{m}_{\mathrm{exp}}) \le S_{\max} \).

In a technical presentation, clearly state:

  • Which metrics \( m_i \) you use and why.
  • Their bounds \( m_i^{\max} \) and score weights \( w_i \).
  • A concise table comparing model predictions and experimental values.

5. Experimental Protocol and Demo-Day Flow

A convincing demo is not a single lucky run; it is a protocol that can be repeated. A minimal protocol for a tracking task could be:

  1. Choose a reference trajectory \( r(t) \) representative of use.
  2. Decide on the metrics \( \mathbf{m} \) and thresholds.
  3. Fix a sampling period \( \Delta t \) and test duration \( T \).
  4. Run the test multiple times under similar conditions.
  5. Compute statistics (mean, variance) of each metric.

The conceptual flow on demo day can be illustrated as:

flowchart TD
  RQ["Review requirements and metrics"] --> EXPD["Design experiment (trajectory, horizon, sampling)"]
  EXPD --> SETUP["Set up robot, sensors, logging"]
  SETUP --> RUN["Execute N runs with same protocol"]
  RUN --> PROC["Post-process logs (compute ISE, RMS, etc.)"]
  PROC --> CHECK["Compare metrics to thresholds"]
  CHECK -->|pass| DEMO["Live demonstration and explanation"]
  CHECK -->|fail| DIAG["Diagnose cause, propose fixes"]
        

Your spoken narration during the live demo should follow this logic: first recall the requirement, then show the experimental protocol, then present the resulting metrics and interpretation.

6. Data Post-Processing in Python, C++, Java, and MATLAB/Simulink

Assume your logger produces a CSV file with columns t, r, y, u (time, reference, measured output, control input). Below are minimal examples to compute \( \widehat{J}_{\mathrm{ISE}} \) and \( \widehat{e}_{\mathrm{RMS}} \). These are generic numerical routines, but the same ideas appear in robotics libraries.

6.1 Python (NumPy / Matplotlib)


import numpy as np
import matplotlib.pyplot as plt

# Load log: columns t, r, y, u
data = np.loadtxt("log.csv", delimiter=",", skiprows=1)
t = data[:, 0]
r = data[:, 1]
y = data[:, 2]
u = data[:, 3]

dt = np.mean(np.diff(t))
e = r - y

J_ISE = np.sum(e**2) * dt
e_RMS = np.sqrt(np.mean(e**2))
e_inf = np.max(np.abs(e))

print(f"ISE = {J_ISE:.3f}")
print(f"RMS error = {e_RMS:.3f}")
print(f"Max error = {e_inf:.3f}")

# Example thresholds
RMS_max = 0.02
e_inf_max = 0.05

if e_RMS <= RMS_max and e_inf <= e_inf_max:
    print("Tracking requirements satisfied.")
else:
    print("Tracking requirements NOT satisfied.")

# Simple plot for presentation
plt.figure()
plt.plot(t, r, label="reference")
plt.plot(t, y, label="output")
plt.xlabel("time [s]")
plt.ylabel("position")
plt.legend()
plt.grid(True)
plt.show()
      

In more advanced robotics software stacks (e.g. ROS Python nodes), the same computations are often wrapped around incoming topic streams rather than log files.

6.2 C++ (using STL; Eigen in larger robotics projects)


#include <vector>
#include <cmath>
#include <iostream>

double compute_ISE(const std::vector<double>& t,
                   const std::vector<double>& r,
                   const std::vector<double>& y) {
    std::size_t N = t.size();
    if (N == 0) return 0.0;

    double J = 0.0;
    for (std::size_t k = 0; k + 1 < N; ++k) {
        double dt = t[k + 1] - t[k];
        double e = r[k] - y[k];
        J += e * e * dt;
    }
    return J;
}

double compute_RMS(const std::vector<double>& r,
                   const std::vector<double>& y) {
    std::size_t N = r.size();
    if (N == 0) return 0.0;

    double sum_sq = 0.0;
    for (std::size_t k = 0; k < N; ++k) {
        double e = r[k] - y[k];
        sum_sq += e * e;
    }
    return std::sqrt(sum_sq / static_cast<double>(N));
}

int main() {
    // In practice, load t, r, y from a CSV or from a ROS bag file.
    std::vector<double> t   = {0.0, 0.01, 0.02};
    std::vector<double> r   = {1.0, 1.0, 1.0};
    std::vector<double> y   = {0.8, 0.9, 0.95};

    double J_ISE = compute_ISE(t, r, y);
    double e_RMS = compute_RMS(r, y);

    std::cout << "ISE = " << J_ISE << "\n";
    std::cout << "RMS error = " << e_RMS << "\n";

    return 0;
}
      

In many robotics C++ projects, libraries like Eigen are used to handle vectors and matrices; the core metric formulas remain the same.

6.3 Java


public class Metrics {

    public static double computeISE(double[] t, double[] r, double[] y) {
        int N = t.length;
        if (N == 0) return 0.0;
        double J = 0.0;
        for (int k = 0; k + 1 < N; ++k) {
            double dt = t[k + 1] - t[k];
            double e = r[k] - y[k];
            J += e * e * dt;
        }
        return J;
    }

    public static double computeRMS(double[] r, double[] y) {
        int N = r.length;
        if (N == 0) return 0.0;
        double sumSq = 0.0;
        for (int k = 0; k < N; ++k) {
            double e = r[k] - y[k];
            sumSq += e * e;
        }
        return Math.sqrt(sumSq / (double) N);
    }

    public static void main(String[] args) {
        double[] t = {0.0, 0.01, 0.02};
        double[] r = {1.0, 1.0, 1.0};
        double[] y = {0.8, 0.9, 0.95};

        double J_ISE = computeISE(t, r, y);
        double e_RMS = computeRMS(r, y);

        System.out.println("ISE = " + J_ISE);
        System.out.println("RMS error = " + e_RMS);
    }
}
      

6.4 MATLAB / Simulink


% Load CSV: columns t, r, y, u
data = readmatrix("log.csv");
t = data(:, 1);
r = data(:, 2);
y = data(:, 3);
u = data(:, 4);

dt = mean(diff(t));
e = r - y;

J_ISE = sum(e.^2) * dt;
e_RMS = sqrt(mean(e.^2));

fprintf("ISE = %.3f\n", J_ISE);
fprintf("RMS error = %.3f\n", e_RMS);

% Plot for the report / slides
figure;
plot(t, r, "LineWidth", 1.2); hold on;
plot(t, y, "LineWidth", 1.2);
xlabel("time [s]");
ylabel("position");
legend("reference", "output");
grid on;

% Simulink integration:
%  - Place 'To Workspace' blocks on outputs r, y, u.
%  - Run: sim("capstone_model");
%  - Then use simout_y.time and simout_y.signals.values
      

These snippets are minimal but sufficient to compute and visualize control performance for your final demo and technical report.

7. Structuring the Technical Presentation

A good technical presentation follows a narrative that mirrors the engineering workflow. A typical structure:

  1. Motivation and task definition
  2. System overview (mechanical, actuation, sensing)
  3. Control architecture (block diagram, main loops)
  4. Modeling and design (key equations, stability)
  5. Experimental protocol (trajectories, runs, metrics)
  6. Results (plots, tables of metrics, discussion)
  7. Failure modes and future work

The flow below can guide your slide deck organization:

flowchart TD
  T["Title & task statement"] --> SYS["Robot system overview"]
  SYS --> CTRL["Control design summary"]
  CTRL --> EXP["Experimental protocol & metrics"]
  EXP --> RES["Results: plots & tables"]
  RES --> COMP["Compare model vs. experiment"]
  COMP --> FAIL["Failure modes & limitations"]
  FAIL --> FUT["Future improvements"]
        

Every plot or table in your slides should answer an explicit question (e.g. “Does the trajectory tracking RMS error satisfy the 2 cm requirement?”). Make that question visible in the slide title.

8. Mathematical Addendum — Finite Metrics for Stable Systems

A common theoretical question: under what conditions are IAE and ISE finite for a closed-loop system? A simple sufficient condition is exponential decay of the tracking error.

Theorem. Suppose the tracking error \( e(t) \) satisfies

\[ |e(t)| \le K \mathrm{e}^{-\alpha t}, \quad t \ge 0, \]

for some constants \( K > 0 \), \( \alpha > 0 \). Then both \( J_{\mathrm{IAE}} \) and \( J_{\mathrm{ISE}} \) over \( [0,\infty) \) are finite.

Proof. Using the bound,

\[ J_{\mathrm{IAE}} = \int_0^{\infty} |e(t)|\,\mathrm{d}t \le \int_0^{\infty} K \mathrm{e}^{-\alpha t}\,\mathrm{d}t = \left[-\frac{K}{\alpha}\mathrm{e}^{-\alpha t}\right]_0^{\infty} = \frac{K}{\alpha} < \infty. \]

For ISE we obtain

\[ J_{\mathrm{ISE}} = \int_0^{\infty} e(t)^2\,\mathrm{d}t \le \int_0^{\infty} K^2 \mathrm{e}^{-2\alpha t}\,\mathrm{d}t = \frac{K^2}{2\alpha} < \infty. \]

Thus any closed-loop design that yields an exponentially decaying error automatically yields finite IAE and ISE, which can be interpreted as total “energy” in the error signal. In linear control, such an exponential bound is guaranteed if all eigenvalues of \( A_{\mathrm{cl}} \) have strictly negative real part.

9. Problems and Solutions

Problem 1 (Evaluating a Second-Order Closed Loop). Consider a closed-loop transfer function approximated by \[ T(s) = \frac{\omega_n^2}{s^2 + 2\zeta \omega_n s + \omega_n^2} \] with \( \zeta = 0.7 \) and \( \omega_n = 4 \,\mathrm{rad/s} \). The specification is: overshoot \( M_p \le 10\% \) and settling time \( t_s(0.02) \le 2\,\mathrm{s} \). Check whether the design meets the specification under the standard formulas.

Solution. Using the approximation formulas,

\[ M_p = \exp\!\left( -\frac{\pi \zeta}{\sqrt{1 - \zeta^2}} \right), \quad t_s(0.02) \approx \frac{4}{\zeta \omega_n}. \]

First compute the denominator of the exponent: \( \sqrt{1 - \zeta^2} = \sqrt{1 - 0.49} = \sqrt{0.51} \approx 0.714 \). Then

\[ \frac{\pi \zeta}{\sqrt{1 - \zeta^2}} \approx \frac{3.1416 \cdot 0.7}{0.714} \approx \frac{2.199}{0.714} \approx 3.08, \quad M_p \approx \mathrm{e}^{-3.08} \approx 0.046. \]

Thus \( M_p \approx 4.6\% \le 10\% \). For the settling time,

\[ t_s(0.02) \approx \frac{4}{\zeta \omega_n} = \frac{4}{0.7 \cdot 4} = \frac{4}{2.8} \approx 1.43\,\mathrm{s}. \]

Since \( 1.43 \le 2 \,\mathrm{s} \), both requirements are met in the linear model. The experimental demo should compare measured \( M_p \) and \( t_s \) with these predictions.

Problem 2 (Continuous-Time ISE and RMS). Let the tracking error be \( e(t) = 0.5\,\mathrm{e}^{-2t} \) for \( t \ge 0 \). Compute the ISE and RMS error over \( [0,\infty) \).

Solution. For ISE,

\[ J_{\mathrm{ISE}} = \int_0^{\infty} e(t)^2 \,\mathrm{d}t = \int_0^{\infty} 0.25\,\mathrm{e}^{-4t}\,\mathrm{d}t = 0.25 \int_0^{\infty} \mathrm{e}^{-4t}\,\mathrm{d}t. \]

Using \( \int_0^{\infty} \mathrm{e}^{-a t}\,\mathrm{d}t = 1/a \) for \( a > 0 \), we obtain

\[ J_{\mathrm{ISE}} = 0.25 \cdot \frac{1}{4} = \frac{1}{16} = 0.0625. \]

To compute RMS error, interpret RMS over \( [0,\infty) \) via the limit of finite-horizon RMS:

\[ e_{\mathrm{RMS}}^2 = \lim_{T \to \infty} \frac{1}{T} \int_0^T e(t)^2 \,\mathrm{d}t = \lim_{T \to \infty} \frac{1}{T} \int_0^T 0.25\,\mathrm{e}^{-4t}\,\mathrm{d}t. \]

The integral in the numerator converges to \( J_{\mathrm{ISE}} = 1/16 \) while the denominator \( T \) grows unbounded, so \( e_{\mathrm{RMS}}^2 = 0 \) and thus \( e_{\mathrm{RMS}} = 0 \). Intuitively, the error becomes negligible when averaged over an infinitely long horizon. In practice, you would use a finite \( T \) matching your experiment.

Problem 3 (Discrete-Time Approximation Error). Let a continuous tracking error satisfy \( |e(t)| \le K \mathrm{e}^{-\alpha t} \) with \( K > 0, \alpha > 0 \). Consider sampling with period \( \Delta t \) and discrete samples \( e_k = e(k \Delta t) \). Show that the discrete ISE approximation \[ \widehat{J}_{\mathrm{ISE}} = \sum_{k=0}^{\infty} e_k^2 \Delta t \] is finite, and bound it in terms of \( K, \alpha, \Delta t \).

Solution. Using the bound,

\[ |e_k|^2 = |e(k\Delta t)|^2 \le K^2 \mathrm{e}^{-2\alpha k \Delta t}. \]

Thus

\[ \widehat{J}_{\mathrm{ISE}} = \sum_{k=0}^{\infty} e_k^2 \Delta t \le \sum_{k=0}^{\infty} K^2 \mathrm{e}^{-2\alpha k \Delta t} \Delta t = K^2 \Delta t \sum_{k=0}^{\infty} \big(\mathrm{e}^{-2\alpha \Delta t}\big)^k. \]

The series is geometric with ratio \( \rho = \mathrm{e}^{-2\alpha \Delta t} \in (0,1) \), so \( \sum_{k=0}^{\infty} \rho^k = 1/(1-\rho) \). Therefore

\[ \widehat{J}_{\mathrm{ISE}} \le K^2 \Delta t \frac{1}{1 - \mathrm{e}^{-2\alpha \Delta t}} < \infty. \]

Hence the discrete approximation of ISE is finite whenever the underlying continuous error decays exponentially.

Problem 4 (Convexity of a Weighted Score). Let \( \mathbf{m} \in \mathbb{R}^q \) represent performance metrics and define \[ S(\mathbf{m}) = \sum_{i=1}^q w_i m_i, \] with \( w_i \ge 0 \) and \( \sum_{i=1}^q w_i = 1 \). Show that the set \( \{\mathbf{m} : S(\mathbf{m}) \le S_{\max}\} \) is convex.

Solution. The function \( S \) is affine (hence convex) because it is a weighted sum of coordinates. Take any two vectors \( \mathbf{m}^{(1)}, \mathbf{m}^{(2)} \) satisfying \( S(\mathbf{m}^{(1)}) \le S_{\max} \), \( S(\mathbf{m}^{(2)}) \le S_{\max} \), and any \( \theta \in [0,1] \). Then

\[ S\big(\theta \mathbf{m}^{(1)} + (1-\theta)\mathbf{m}^{(2)}\big) = \theta S(\mathbf{m}^{(1)}) + (1-\theta) S(\mathbf{m}^{(2)}) \le \theta S_{\max} + (1-\theta) S_{\max} = S_{\max}. \]

Hence the convex combination is also in the set, proving convexity. This is useful if you later study optimization-based controller tuning or automated trade-off exploration.

10. Summary

In this lesson, you learned how to translate your capstone robot into a mathematically grounded final demo: by defining tracking errors and performance metrics, connecting them to linear control models, designing acceptance criteria, and computing them from logged data in Python, C++, Java, and MATLAB/Simulink. You also saw how to structure a technical presentation that clearly states requirements, explains design choices, and backs up claims with quantitative evidence. This combination of theory, data, and communication is a core skill for all future robotics courses and projects.

11. References

  1. Åström, K. J., & Murray, R. M. (2008). Feedback Systems: An Introduction for Scientists and Engineers. Princeton University Press.
  2. Doyle, J. C., Francis, B. A., & Tannenbaum, A. R. (1992). Feedback Control Theory. Macmillan.
  3. Skogestad, S., & Postlethwaite, I. (2005). Multivariable Feedback Control: Analysis and Design (2nd ed.). Wiley.
  4. Bryson, A. E., & Ho, Y.-C. (1975). Applied Optimal Control: Optimization, Estimation, and Control. Taylor & Francis.
  5. Zames, G. (1981). Feedback and optimal sensitivity: Model reference transformations, multiplicative seminorms, and approximate inverses. IEEE Transactions on Automatic Control, 26(2), 301–320.
  6. Kwakernaak, H., & Sivan, R. (1972). Linear Optimal Control Systems. Wiley-Interscience.
  7. Bertsekas, D. P. (1995). Nonlinear Programming. Athena Scientific. (For convexity and weighted sums of performance metrics.)