Chapter 1: Control Prerequisites for Robotics
Lesson 2: State-Space Modeling for Mechanical Systems (using given models)
In this lesson we take the mechanical models you already know from robot dynamics (e.g. Lagrange or Newton–Euler equations of manipulators) and rewrite them in state-space form. This is the canonical representation used in modern control design, simulation, and implementation. We move from second-order equations in joint coordinates to first-order vector equations in state variables, and we show how to implement these models in Python, C++, Java, MATLAB/Simulink, and Wolfram Mathematica.
1. Conceptual Overview of State-Space Models
A state-space model describes a system by a set of first-order differential equations in variables that encode all dynamically relevant information at time \( t \). For a general (possibly nonlinear) system we write
\[ \dot{\mathbf{x}}(t) = f(\mathbf{x}(t), \mathbf{u}(t)), \qquad \mathbf{y}(t) = h(\mathbf{x}(t), \mathbf{u}(t)), \]
where \( \mathbf{x}(t) \in \mathbb{R}^{n} \) is the state, \( \mathbf{u}(t) \in \mathbb{R}^{m} \) is the input (e.g. motor torques), and \( \mathbf{y}(t) \in \mathbb{R}^{p} \) is the measured output. For manipulators you already know the standard dynamics
\[ \mathbf{M}(\mathbf{q})\,\ddot{\mathbf{q}} + \mathbf{C}(\mathbf{q},\dot{\mathbf{q}})\,\dot{\mathbf{q}} + \mathbf{g}(\mathbf{q}) = \boldsymbol{\tau}, \]
with joint coordinates \( \mathbf{q} \), inertia matrix \( \mathbf{M}(\mathbf{q}) \), Coriolis/centrifugal term \( \mathbf{C}(\mathbf{q},\dot{\mathbf{q}})\dot{\mathbf{q}} \), gravity \( \mathbf{g}(\mathbf{q}) \), and torque input vector \( \boldsymbol{\tau} \). State-space modeling amounts to choosing a suitable state \( \mathbf{x} \), usually \( \mathbf{x} = [\mathbf{q}^{\top}, \dot{\mathbf{q}}^{\top}]^{\top} \), and rewriting the dynamics as a first-order system in \( \mathbf{x} \).
flowchart TD
A["Robot dynamics: M(q) q_ddot + C(q,q_dot) q_dot + g(q) = tau"] --> B["Choose state x = [q; q_dot]"]
B --> C["Rewrite as x_dot = f(x,u) with u = tau"]
C --> D["Choose output y = h(x,u) (e.g., joints or end-effector)"]
D --> E["Use state-space model for analysis, control design, simulation"]
In later chapters we will design controllers (e.g. PD, computed torque, LQR) directly on \( f(\mathbf{x},\mathbf{u}) \). Here our goal is purely representational: starting from given mechanical models, construct mathematically correct state-space equations.
2. From Second-Order Dynamics to First-Order State-Space (1-DOF)
Consider a single rotational joint with inertia \( J > 0 \), viscous friction \( b \), and possibly an elastic term with stiffness \( k \). The equation of motion is
\[ J\,\ddot{q}(t) + b\,\dot{q}(t) + k\,q(t) = \tau(t). \]
We define the state components
\[ x_1(t) = q(t), \qquad x_2(t) = \dot{q}(t), \]
so that the state vector is \( \mathbf{x}(t) = [x_1(t),\, x_2(t)]^{\top} \). The first-order dynamics follow directly:
\[ \dot{x}_1(t) = x_2(t), \qquad \dot{x}_2(t) = -\frac{k}{J} x_1(t) - \frac{b}{J} x_2(t) + \frac{1}{J}\tau(t). \]
Writing this in vector–matrix form with input \( u(t) = \tau(t) \), we obtain the linear time-invariant (LTI) state-space model
\[ \dot{\mathbf{x}}(t) = \mathbf{A}\,\mathbf{x}(t) + \mathbf{B}\,u(t), \qquad y(t) = \mathbf{C}\,\mathbf{x}(t) + \mathbf{D}\,u(t), \]
\[ \mathbf{A} = \begin{bmatrix} 0 & 1 \\ -\dfrac{k}{J} & -\dfrac{b}{J} \end{bmatrix}, \quad \mathbf{B} = \begin{bmatrix} 0 \\[4pt] \dfrac{1}{J} \end{bmatrix}, \quad \mathbf{C} = \begin{bmatrix} 1 & 0 \end{bmatrix}, \quad \mathbf{D} = \begin{bmatrix} 0 \end{bmatrix}. \]
Equivalence argument. Given the state-space form above, we can recover the original second-order equation by eliminating \( x_1, x_2 \): from \( x_1 = q \) and \( x_2 = \dot{q} \), we have \( \dot{x}_2 = \ddot{q} \). Substituting into the second equation yields
\[ J\,\ddot{q}(t) = -k\,q(t) - b\,\dot{q}(t) + \tau(t), \]
which is exactly the original dynamics. Thus the second-order scalar equation and the two-dimensional first-order state-space model are mathematically equivalent descriptions of the same joint.
3. Multi-DOF Manipulator State-Space Structure
For an \( n \)-DOF manipulator with configuration \( \mathbf{q} \in \mathbb{R}^{n} \) and dynamics
\[ \mathbf{M}(\mathbf{q})\,\ddot{\mathbf{q}} + \mathbf{C}(\mathbf{q},\dot{\mathbf{q}})\,\dot{\mathbf{q}} + \mathbf{g}(\mathbf{q}) = \boldsymbol{\tau}, \]
we choose the canonical mechanical state
\[ \mathbf{x} = \begin{bmatrix} \mathbf{q} \\[2pt] \dot{\mathbf{q}} \end{bmatrix} \in \mathbb{R}^{2n}. \]
The first-order dynamics follow from the algebraic solution for \( \ddot{\mathbf{q}} \):
\[ \ddot{\mathbf{q}} = \mathbf{M}(\mathbf{q})^{-1} \left( \boldsymbol{\tau} - \mathbf{C}(\mathbf{q},\dot{\mathbf{q}})\,\dot{\mathbf{q}} - \mathbf{g}(\mathbf{q}) \right). \]
Hence
\[ \dot{\mathbf{x}} = \begin{bmatrix} \dot{\mathbf{q}} \\[4pt] \mathbf{M}(\mathbf{q})^{-1} \left( \boldsymbol{\tau} - \mathbf{C}(\mathbf{q},\dot{\mathbf{q}})\,\dot{\mathbf{q}} - \mathbf{g}(\mathbf{q}) \right) \end{bmatrix} = f(\mathbf{x}, \boldsymbol{\tau}). \]
This is a nonlinear state-space model and, more specifically, a control-affine system of the form
\[ \dot{\mathbf{x}} = f(\mathbf{x}) + G(\mathbf{x})\,\boldsymbol{\tau}, \]
where the input matrix field \( G(\mathbf{x}) \) is determined by \( \mathbf{M}(\mathbf{q})^{-1} \). This compact form is what most robot control algorithms will assume.
flowchart TD
Q["Joint positions: q1,...,qn"] --> XD["Define x1,...,xn from q"]
QD["Joint velocities: q1_dot,...,qn_dot"] --> XD2["Define x(n+1),...,x(2n) from q_dot"]
XD --> X["State vector x in R^(2n)"]
XD2 --> X
X --> F["Compute x_dot using M(q)^(-1)*(tau - C(q,q_dot) q_dot - g(q))"]
Note that we did not need explicit components of \( \mathbf{M},\mathbf{C},\mathbf{g} \); the construction works for any manipulator whose dynamics are available from your robotics course or symbolic tools.
4. Output Models and Choice of States
A state-space model is completed by specifying measured outputs \( \mathbf{y}(t) \). Typical sensor models in robotics are:
- Joint encoders: \( \mathbf{y}(t) = \mathbf{q}(t) \).
- Joint encoders + numerical differentiation: \( \mathbf{y}(t) = [\mathbf{q}(t)^{\top}, \dot{\mathbf{q}}(t)^{\top}]^{\top} \).
- End-effector pose: \( \mathbf{y}(t) = h(\mathbf{q}(t)) \) with forward kinematics \( h \).
For example, if the output is joint position only, we have
\[ \mathbf{y}(t) = \begin{bmatrix} \mathbf{I}_n & \mathbf{0} \end{bmatrix} \mathbf{x}(t), \]
so that the output matrix is \( \mathbf{C} = [\mathbf{I}_n \ \mathbf{0}] \) and \( \mathbf{D} = \mathbf{0} \). Many different choices of state are mathematically possible, but the joint–velocity state is physically meaningful and directly connected to your dynamics.
5. Python Implementation of State-Space Manipulator Models
In Python we typically use numpy for vectors/matrices and
scipy.integrate for simulation. For control-oriented work,
the python-control library and
roboticstoolbox-python (for getting
\( \mathbf{M},\mathbf{C},\mathbf{g} \)) are common
choices.
The following code defines the 1-DOF state-space model from Section 2
and shows how to pack it into a python-control system
object.
import numpy as np
from scipy.integrate import solve_ivp
# Optional: python-control for state-space objects
try:
import control
except ImportError:
control = None
# Parameters of 1-DOF joint
J = 0.02 # kg m^2
b = 0.1 # N m s/rad
k = 1.0 # N m/rad
def joint_dynamics(t, x, u_func):
"""
x = [q, q_dot]
u_func: function of time returning tau(t)
"""
q, q_dot = x
tau = u_func(t)
q_dot_dot = (tau - b*q_dot - k*q) / J
return np.array([q_dot, q_dot_dot])
def step_torque(t):
# Constant 1 N m torque
return 1.0
# Simulate
t_span = (0.0, 5.0)
x0 = np.array([0.0, 0.0])
sol = solve_ivp(
fun=lambda t, x: joint_dynamics(t, x, step_torque),
t_span=t_span, y0=x0, max_step=1e-3
)
# Optionally create an LTI state-space object for linear analysis
A = np.array([[0.0, 1.0],
[-k/J, -b/J]])
B = np.array([[0.0],
[1.0/J]])
C = np.array([[1.0, 0.0]])
D = np.array([[0.0]])
if control is not None:
ss_sys = control.ss(A, B, C, D)
# ss_sys can be used later for linear control design, frequency analysis, etc.
For a full manipulator model, roboticstoolbox-python can
provide
\(
\mathbf{M}(\mathbf{q}),\mathbf{C}(\mathbf{q},\dot{\mathbf{q}}),\mathbf{g}(\mathbf{q})
\), and you can implement f(x, tau) exactly as in Section 3.
6. C++ Implementation Using Eigen
In C++ we commonly use the Eigen library for linear
algebra. Robotics frameworks such as ROS 2, ros2_control,
and Drake internally rely on similar state-space formulations, but here
we focus on a minimal Eigen-based implementation of the 1-DOF joint
model.
#include <Eigen/Dense>
#include <functional>
struct Joint1DOFStateSpace {
double J;
double b;
double k;
// x = [q; q_dot]
Eigen::Vector2d f(double t,
const Eigen::Vector2d& x,
const std::function<double(double)>& u) const {
double q = x(0);
double qdot = x(1);
double tau = u(t);
double qddot = (tau - b * qdot - k * q) / J;
Eigen::Vector2d xdot;
xdot << qdot, qddot;
return xdot;
}
Eigen::Matrix2d A() const {
Eigen::Matrix2d A;
A << 0.0, 1.0,
-k / J, -b / J;
return A;
}
Eigen::Vector2d B() const {
Eigen::Vector2d B;
B << 0.0, 1.0 / J;
return B;
}
Eigen::RowVector2d C() const {
Eigen::RowVector2d C;
C << 1.0, 0.0;
return C;
}
double D() const { return 0.0; }
};
// Example usage (integration would be done by your ODE integrator of choice)
Extending this to an \( n \)-DOF manipulator uses
Eigen::VectorXd for
\( \mathbf{q},\dot{\mathbf{q}} \) and
Eigen::MatrixXd for
\( \mathbf{M},\mathbf{C} \). The function
f then assembles \( \dot{\mathbf{x}} \)
as in Section 3 using your existing implementations of the dynamics.
7. Java Implementation with Linear Algebra Libraries
In Java, matrix operations can be handled by libraries such as
Apache Commons Math or EJML. Robot frameworks
for Java (e.g. those used in educational robotics) often embed similar
state-space models. Below is a simple 1-DOF joint as a Java class using
primitive arrays; in practice you would wrap these in a matrix library.
public class Joint1DOFStateSpace {
private final double J;
private final double b;
private final double k;
public interface TorqueFunction {
double value(double t);
}
public Joint1DOFStateSpace(double J, double b, double k) {
this.J = J;
this.b = b;
this.k = k;
}
/**
* x = [q, q_dot]
* returns x_dot
*/
public double[] f(double t, double[] x, TorqueFunction u) {
double q = x[0];
double qdot = x[1];
double tau = u.value(t);
double qddot = (tau - b * qdot - k * q) / J;
return new double[]{ qdot, qddot };
}
public double[][] getA() {
return new double[][]{
{ 0.0, 1.0 },
{ -k / J, -b / J }
};
}
public double[][] getB() {
return new double[][]{
{ 0.0 },
{ 1.0 / J }
};
}
public double[][] getC() {
return new double[][]{
{ 1.0, 0.0 }
};
}
public double[][] getD() {
return new double[][]{
{ 0.0 }
};
}
}
Using Apache Commons Math or EJML, you can
turn these arrays into RealMatrix objects and build generic
state-space simulation and analysis tools that mirror MATLAB or Python
work flows.
8. MATLAB/Simulink Implementation
MATLAB, with the Control System Toolbox and Robotics System Toolbox, is a natural environment for state-space modeling of robots. The following code constructs the 1-DOF system matrices and a state-space object.
J = 0.02;
b = 0.1;
k = 1.0;
A = [ 0, 1;
-k/J, -b/J ];
B = [ 0;
1/J ];
C = [ 1, 0 ];
D = 0;
sys = ss(A, B, C, D);
% Example: simulate step torque using lsim
t = linspace(0, 5, 1001);
u = ones(size(t)); % tau(t) = 1
x0 = [0; 0];
[y, t, x] = lsim(sys, u, t, x0);
In Simulink, you can drop a State-Space block and enter
A, B, C, and D. For
a multi-DOF manipulator, you can generate
\( \mathbf{M},\mathbf{C},\mathbf{g} \)
using Robotics System Toolbox (or your own functions) and implement
\( \dot{\mathbf{x}} \) using
MATLAB Function
blocks connected to integrators.
9. Wolfram Mathematica Implementation
Wolfram Mathematica has built-in support for symbolic derivation of equations of motion and for state-space models. The 1-DOF example can be represented as:
J = 0.02;
b = 0.1;
k = 1.0;
A = { {0, 1},
{-k/J, -b/J} };
B = { {0},
{1/J} };
C = { {1, 0} };
D = { {0} };
sys = StateSpaceModel[{A, B, C, D}];
(* Solve dynamics with step input tau(t) = 1 *)
u[t_] := 1.0;
sol = SystemsModelSolve[sys, u, {t, 0, 5}];
qSol[t_] = OutputResponse[sys, u, t][[1]];
For more complex manipulators, symbolic mechanics functions can be used
to obtain \( \mathbf{M},\mathbf{C},\mathbf{g} \), which
can then be transformed into numerical state-space models via
StateSpaceModel.
10. Problems and Solutions
Problem 1 (Mass–Spring–Damper State-Space): A translational mass–spring–damper system satisfies \( m\,\ddot{x}(t) + c\,\dot{x}(t) + k\,x(t) = u(t) \). Construct a state-space model with state \( \mathbf{x}(t) = [x(t),\dot{x}(t)]^{\top} \), input \( u(t) \), and output \( y(t) = x(t) \).
Solution: Define \( x_1(t) = x(t) \), \( x_2(t) = \dot{x}(t) \). Then
\[ \dot{x}_1(t) = x_2(t), \qquad \dot{x}_2(t) = -\frac{k}{m} x_1(t) - \frac{c}{m} x_2(t) + \frac{1}{m} u(t). \]
The matrices are
\[ \mathbf{A} = \begin{bmatrix} 0 & 1 \\ -\dfrac{k}{m} & -\dfrac{c}{m} \end{bmatrix}, \quad \mathbf{B} = \begin{bmatrix} 0 \\[4pt] \dfrac{1}{m} \end{bmatrix}, \quad \mathbf{C} = \begin{bmatrix} 1 & 0 \end{bmatrix}, \quad \mathbf{D} = \begin{bmatrix} 0 \end{bmatrix}. \]
Problem 2 (2-DOF Manipulator State Vector): A 2-DOF planar arm has dynamics \( \mathbf{M}(\mathbf{q})\ddot{\mathbf{q}} + \mathbf{C}(\mathbf{q},\dot{\mathbf{q}})\dot{\mathbf{q}} + \mathbf{g}(\mathbf{q}) = \boldsymbol{\tau} \). Define a state vector and write the corresponding expression for \( \dot{\mathbf{x}} \) in terms of \( \mathbf{M},\mathbf{C},\mathbf{g},\boldsymbol{\tau} \).
Solution: Take \( \mathbf{q} = [q_1,q_2]^{\top} \), \( \dot{\mathbf{q}} = [\dot{q}_1,\dot{q}_2]^{\top} \), and
\[ \mathbf{x} = \begin{bmatrix} \mathbf{q} \\[2pt] \dot{\mathbf{q}} \end{bmatrix} = \begin{bmatrix} q_1 \\ q_2 \\ \dot{q}_1 \\ \dot{q}_2 \end{bmatrix}. \]
Solving the dynamics for \( \ddot{\mathbf{q}} \) and stacking, we obtain
\[ \dot{\mathbf{x}} = \begin{bmatrix} \dot{\mathbf{q}} \\[4pt] \mathbf{M}(\mathbf{q})^{-1} \left( \boldsymbol{\tau} - \mathbf{C}(\mathbf{q},\dot{\mathbf{q}})\,\dot{\mathbf{q}} - \mathbf{g}(\mathbf{q}) \right) \end{bmatrix}. \]
Problem 3 (Equivalence of Second-Order and First-Order Models): Consider a general scalar second-order system \( a_2 \ddot{q}(t) + a_1 \dot{q}(t) + a_0 q(t) = u(t) \) with \( a_2 \neq 0 \). Show that the transformation \( x_1 = q \), \( x_2 = \dot{q} \) yields a first-order model that is equivalent to the original one.
Solution: Define
\[ \mathbf{x} = \begin{bmatrix} x_1 \\ x_2 \end{bmatrix} = \begin{bmatrix} q \\ \dot{q} \end{bmatrix}. \]
Then by differentiation \( \dot{x}_1 = \dot{q} = x_2 \) and \( \dot{x}_2 = \ddot{q} \). Solving the original equation for \( \ddot{q} \) gives
\[ \ddot{q} = -\frac{a_1}{a_2}\dot{q} -\frac{a_0}{a_2}q + \frac{1}{a_2} u. \]
Substituting \( q = x_1 \), \( \dot{q} = x_2 \) yields
\[ \dot{x}_1 = x_2, \qquad \dot{x}_2 = -\frac{a_0}{a_2} x_1 - \frac{a_1}{a_2} x_2 + \frac{1}{a_2} u. \]
Conversely, any solution \( \mathbf{x}(t) \) of this first-order system defines \( q(t) = x_1(t) \), which automatically satisfies the original second-order equation. Thus the two models are equivalent.
Problem 4 (Dimension of State Space): A robot arm has 7 revolute joints. Using the canonical choice \( \mathbf{x} = [\mathbf{q}^{\top}, \dot{\mathbf{q}}^{\top}]^{\top} \), what is the dimension of the state space? How would this change if you also included motor currents as additional states (one per joint)?
Solution: With 7 joints we have \( \mathbf{q} \in \mathbb{R}^{7} \), \( \dot{\mathbf{q}} \in \mathbb{R}^{7} \), so \( \mathbf{x} \in \mathbb{R}^{14} \). If we add 7 motor currents, the augmented state has size \( 7 + 7 + 7 = 21 \), so the state space is \( \mathbb{R}^{21} \).
Problem 5 (Joint Position Output Matrix): For an \( n \)-DOF manipulator with state \( \mathbf{x} = [\mathbf{q}^{\top}, \dot{\mathbf{q}}^{\top}]^{\top} \), derive the output matrix \( \mathbf{C} \) and feedthrough matrix \( \mathbf{D} \) for the case \( \mathbf{y} = \mathbf{q} \).
Solution: We want \( \mathbf{y} = \mathbf{C}\mathbf{x} + \mathbf{D}\boldsymbol{\tau} \). Since \( \mathbf{y} = \mathbf{q} \) and \( \mathbf{x} = [\mathbf{q}^{\top}, \dot{\mathbf{q}}^{\top}]^{\top} \), we choose
\[ \mathbf{C} = \begin{bmatrix} \mathbf{I}_n & \mathbf{0} \end{bmatrix}, \qquad \mathbf{D} = \mathbf{0}_{n \times n}. \]
Then \( \mathbf{y} = \mathbf{C}\mathbf{x} \) extracts the first \( n \) entries of the state, corresponding exactly to joint positions.
11. Summary
In this lesson we converted mechanical models of robot joints and manipulators into state-space form. For 1-DOF systems we showed the explicit mapping from a second-order equation to a 2-dimensional LTI state-space model. For general manipulators, we used the compact dynamics \( \mathbf{M}(\mathbf{q})\ddot{\mathbf{q}} + \mathbf{C}(\mathbf{q},\dot{\mathbf{q}})\dot{\mathbf{q}} + \mathbf{g}(\mathbf{q}) = \boldsymbol{\tau} \) to construct a \( 2n \)-dimensional nonlinear, control-affine state-space model. We then implemented these models in Python, C++, Java, MATLAB/Simulink, and Mathematica, preparing the ground for subsequent lessons on linearization, stability, and controller design.
12. References
- Kalman, R. E. (1960). A new approach to linear filtering and prediction problems. Journal of Basic Engineering, 82(1), 35–45.
- Luenberger, D. G. (1964). Observing the state of a linear system. IEEE Transactions on Military Electronics, 8(2), 74–80.
- Brockett, R. W. (1972). System theory on group manifolds and coset spaces. SIAM Journal on Control, 10(2), 265–284.
- Spong, M. W. (1987). On the robust control of robot manipulators. IEEE Transactions on Automatic Control, 32(2), 157–163.
- Ortega, R., & Spong, M. W. (1989). Adaptive motion control of rigid robots: A tutorial. Automatica, 25(6), 877–888.
- Isidori, A. (1985). Nonlinear control systems: An introduction. IEEE Transactions on Automatic Control, 30(5), 487–489. (Review of foundational nonlinear state-space theory.)
- Sastry, S., & Bodson, M. (1989). Adaptive control of linearizable systems. IEEE Transactions on Automatic Control, 34(11), 1123–1128.