Chapter 17: Applications and Case Studies
Lesson 2: Healthcare and Assistive Robotics
This lesson introduces healthcare and assistive robots from a systems and control perspective. We focus on the mathematical modeling of a single-degree-of-freedom assistive joint interacting with a human, discuss impedance and safety constraints, and design linear controllers that respect comfort and safety. Short multi-language code snippets illustrate how such controllers can be implemented in practice.
1. Conceptual Overview of Healthcare and Assistive Robotics
Healthcare and assistive robots are deployed to support human users in diagnosis, therapy, mobility, and activities of daily living. From a systems viewpoint, they are cyber–physical systems tightly coupled to a human body. Broad categories include:
- Rehabilitation robots: exoskeletons and end-effector devices that guide or assist limbs during repetitive rehabilitation exercises.
- Mobility-assistive robots: powered wheelchairs, robotic walkers, stair-climbing devices.
- Assistive manipulators: arms mounted on wheelchairs or beds that help with grasping and manipulation tasks.
- Companion and monitoring robots: social robots and mobile platforms that monitor vital signs or remind users about medication.
A key difference from industrial manipulators is the physical human–robot interaction (pHRI): the human is not just an operator but also a mechanical subsystem. If we denote the human and robot as two coupled dynamical subsystems \( \mathcal{H} \) and \( \mathcal{R} \), the closed-loop behavior depends on both dynamics. A simple conceptual view is:
\[ \mathcal{H}: \quad \mathbf{x}_h^{\prime}(t) = f_h(\mathbf{x}_h(t), \mathbf{u}_h(t), \mathbf{y}_r(t)), \quad \mathcal{R}: \quad \mathbf{x}_r^{\prime}(t) = f_r(\mathbf{x}_r(t), \mathbf{u}_r(t), \mathbf{y}_h(t)) \]
where \( \mathbf{y}_h(t) \) and \( \mathbf{y}_r(t) \) are interaction variables (e.g., joint angles, forces), and the prime denotes time derivative. In this lesson we restrict attention to linear models of a single joint, exploiting your background in linear control.
flowchart TD
H["Human limb / user intent"] --> S["Sensors (angle, velocity, force, EMG)"]
S --> EST["State & intent estimation"]
EST --> CTRL["Assistive controller (e.g. PD / impedance)"]
CTRL --> SAF["Safety layer (limits, checks)"]
SAF --> ACT["Actuators (motors, transmissions)"]
ACT --> INT["Physical interface (cuff, orthosis)"]
INT --> H
Any mathematically grounded design in this domain must start from a model of the robot joint and its coupling to the user, a topic we develop next.
2. Dynamic Model of a 1-DOF Assistive Joint
Consider a single actuated revolute joint (e.g., elbow exoskeleton) with equivalent inertia \( J > 0 \) and viscous damping \( B \ge 0 \). Let \( \theta(t) \) be the joint angle and \( \tau_m(t) \) the motor torque. The human applies a torque \( \tau_h(t) \) (e.g., voluntary motion). A standard linear model is
\[ J \,\ddot{\theta}(t) + B \,\dot{\theta}(t) = \tau_m(t) + \tau_h(t). \]
Defining the total input torque \( \tau(t) = \tau_m(t) + \tau_h(t) \), we obtain in the Laplace domain:
\[ J s^2 \Theta(s) + B s \Theta(s) = \tau(s) \quad \Rightarrow \quad \frac{\Theta(s)}{\tau(s)} = \frac{1}{J s^2 + B s}. \]
A state-space representation (with state \( \mathbf{x}(t) = [\theta(t)\;\; \dot{\theta}(t)]^{\mathsf{T}} \)) and input \( u(t) = \tau(t) \) is
\[ \mathbf{x}^{\prime}(t) = \underbrace{\begin{bmatrix} 0 & 1 \\ 0 & -\dfrac{B}{J} \end{bmatrix}}_{\mathbf{A}} \mathbf{x}(t) + \underbrace{\begin{bmatrix} 0 \\[4pt] \dfrac{1}{J} \end{bmatrix}}_{\mathbf{B}} u(t), \quad y(t) = \begin{bmatrix}1 & 0\end{bmatrix}\mathbf{x}(t) = \theta(t). \]
The eigenvalues of \( \mathbf{A} \) are \( \lambda_1 = 0 \) and \( \lambda_2 = -\dfrac{B}{J} \le 0 \), i.e., the free dynamics without control are marginally stable (due to the integrator in position) and will not track a desired reference. This motivates the design of a stabilizing and assistive controller.
3. Impedance and Physical Human–Robot Interaction
Let \( \theta_h(t) \) denote the human joint angle (which may or may not coincide exactly with the robot joint angle due to soft tissues and straps). The relative motion between human and robot is \( \theta_r(t) = \theta(t) - \theta_h(t) \). The interaction torque felt by the human can be modeled as \( \tau_{\text{int}}(t) = -\tau_h(t) \).
A common design goal is to shape the mechanical impedance \( Z(s) \), defined as
\[ Z(s) \;=\; \frac{\tau_{\text{int}}(s)}{\Theta_r(s)} \;=\; \frac{\tau_{\text{int}}(s)}{\Theta(s) - \Theta_h(s)}. \]
For comfortable interaction, designers often target a virtual mass–spring–damper model:
\[ Z_{\text{des}}(s) = J_v s^2 + B_v s + K_v, \quad J_v, B_v, K_v \ge 0, \]
which corresponds in the time domain to \( \tau_{\text{int}}(t) = J_v \ddot{\theta}_r(t) + B_v \dot{\theta}_r(t) + K_v \theta_r(t) \). For simplicity, and since we are in an introductory course, we will focus on spring–damper behavior with \( J_v = 0 \), i.e.
\[ \tau_{\text{int}}(t) = B_v \dot{\theta}_r(t) + K_v \theta_r(t). \]
Impedance control aims to choose the motor torque \( \tau_m(t) \) such that this relation is approximately satisfied despite unknown human dynamics. A basic strategy is to define a desired trajectory \( \theta_d(t) \) and use a virtual spring–damper in the error coordinates \( e(t) = \theta(t) - \theta_d(t) \). This connects naturally to PD control.
4. PD / Impedance Control for a 1-DOF Assistive Joint
Let \( \theta_d(t) \) be a desired joint angle generated from a higher-level therapeutic protocol (e.g., sinusoidal flexion–extension). Define the tracking error \( e(t) = \theta_d(t) - \theta(t) \), \( \dot{e}(t) = \dot{\theta}_d(t) - \dot{\theta}(t) \). A torque-commanding PD controller is
\[ \tau_m(t) = K_p e(t) + K_d \dot{e}(t), \quad K_p > 0,\; K_d \ge 0. \]
Substituting into the joint dynamics (and temporarily setting \( \tau_h(t) = 0 \) to analyze tracking):
\[ J \ddot{\theta}(t) + B \dot{\theta}(t) = K_p(\theta_d(t) - \theta(t)) + K_d(\dot{\theta}_d(t) - \dot{\theta}(t)). \]
Rearranging and collecting terms in \( \theta \):
\[ J \ddot{\theta}(t) + \bigl(B + K_d\bigr)\dot{\theta}(t) + K_p \theta(t) = K_p \theta_d(t) + K_d \dot{\theta}_d(t). \]
For constant references (or slowly varying ones), we can approximate the error dynamics by setting the right-hand side to zero:
\[ J \ddot{e}(t) + \bigl(B + K_d\bigr)\dot{e}(t) + K_p e(t) = 0. \]
The characteristic polynomial is \( J s^2 + (B+K_d)s + K_p \). Since the system is second-order, Routh–Hurwitz reduces to requiring all coefficients to be positive:
\[ J > 0,\quad B + K_d > 0,\quad K_p > 0 \quad \Longrightarrow \quad \text{Re}(s_{1,2}) < 0. \]
Thus any \( K_p > 0 \), \( K_d > -B \) ensures asymptotic stability of the error dynamics.
4.1 Matching to Standard Second-Order Form
To obtain more interpretable parameters, we match the characteristic polynomial to the normalized second-order form \( s^2 + 2\zeta\omega_n s + \omega_n^2 \). Divide by \( J \):
\[ s^2 + \frac{B+K_d}{J} s + \frac{K_p}{J} = 0 \quad \Rightarrow \quad 2\zeta\omega_n = \frac{B+K_d}{J},\;\; \omega_n^2 = \frac{K_p}{J}. \]
Given desired \( \omega_n > 0 \) and \( \zeta > 0 \), we can choose gains as
\[ K_p = J \omega_n^2, \quad K_d = 2\zeta\omega_n J - B. \]
4.2 Lyapunov Perspective (Impedance View)
Consider the error energy candidate
\[ V(e, \dot{e}) = \tfrac{1}{2} J \dot{e}^2 + \tfrac{1}{2} K_p e^2. \]
Differentiating along trajectories:
\[ \dot{V} = J \dot{e}\ddot{e} + K_p e \dot{e} = \dot{e}\bigl(J\ddot{e} + K_p e\bigr) = - (B+K_d)\dot{e}^2 \le 0, \]
where we used the error dynamics. Hence, for \( B+K_d > 0 \), the closed-loop system is (globally) asymptotically stable and passive with respect to the external torque input and velocity output. This property is crucial in healthcare robots: it guarantees that the system does not inject unbounded energy into the human limb.
flowchart TD
START["Start cycle k"] --> READ["Read theta, theta_dot from sensors"]
READ --> REF["Read theta_d, theta_d_dot from therapy protocol"]
REF --> ERR["Compute e = theta_d - theta, e_dot approx"]
ERR --> TOR["Compute tau_cmd = Kp*e + Kd*e_dot"]
TOR --> LIM["Apply safety limits (saturation)"]
LIM --> ACT["Send tau_cmd to motor driver"]
ACT --> START
5. Safety Constraints: Force, Power, and Energy
In assistive robotics, stability is necessary but not sufficient: the interaction must also respect force, power, and energy limits. Suppose the joint interface radius (distance from rotation center to contact point) is \( r > 0 \). The contact force magnitude is approximately
\[ F_{\text{contact}}(t) \approx \frac{|\tau_{\text{int}}(t)|}{r}. \]
To enforce a maximum allowable force \( F_{\max} \), we limit the interaction torque via
\[ |\tau_{\text{int}}(t)| \le \tau_{F,\max} := F_{\max} r. \]
Similarly, the instantaneous mechanical power at the joint is
\[ P(t) = \tau_{\text{int}}(t) \,\dot{\theta}(t), \]
and the kinetic energy of the joint is
\[ E_{\text{kin}}(t) = \tfrac{1}{2} J \dot{\theta}^2(t). \]
If we enforce limits \( |\dot{\theta}(t)| \le \dot{\theta}_{\max} \) and \( |\tau_{\text{int}}(t)| \le \tau_{\max} \), then
\[ |P(t)| \le \tau_{\max}\,\dot{\theta}_{\max}, \]
and the kinetic energy at any time satisfies
\[ E_{\text{kin}}(t) \le \tfrac{1}{2} J \dot{\theta}_{\max}^2. \]
Thus, choosing \( \dot{\theta}_{\max} \) to satisfy \( \tfrac{1}{2} J \dot{\theta}_{\max}^2 \le E_{\max} \) yields
\[ \dot{\theta}_{\max} = \sqrt{\frac{2E_{\max}}{J}}. \]
In implementation, these limits become simple saturation blocks on velocity and torque commands, as already suggested in the control flow above.
6. Implementation Snippets in Python, C++, Java, and MATLAB/Simulink
We now sketch controller implementations for a single assistive joint. These snippets assume access to functions that read joint state and send torque commands; hardware and communication details (e.g., ROS or fieldbus drivers) are abstracted away.
6.1 Python Implementation (Discrete-Time PD with Saturation)
import time
import math
# Physical and control parameters (example values)
J = 0.5 # kg m^2
B = 0.1 # N m s/rad
omega_n = 4.0 # rad/s
zeta = 0.7
Kp = J * omega_n**2
Kd = 2.0 * zeta * omega_n * J - B
tau_max = 10.0 # N m, safe torque limit
Ts = 0.005 # 5 ms control period
def sat(x, xmin, xmax):
return max(xmin, min(xmax, x))
# Placeholder I/O functions
def read_joint_state():
"""
Returns (theta, theta_dot) in radians and rad/s.
In a real system, this reads encoders and a velocity estimator.
"""
# TODO: replace with actual sensor reading
return 0.0, 0.0
def write_joint_torque(tau_cmd):
"""
Sends torque command tau_cmd (N m) to the motor driver.
"""
# TODO: replace with actual actuator interface
pass
# Simple time-varying reference: sinusoidal trajectory
def desired_motion(t):
theta_d = 0.4 * math.sin(0.5 * t) # rad
theta_d_dot = 0.4 * 0.5 * math.cos(0.5 * t)
return theta_d, theta_d_dot
e_prev = 0.0
while True:
t_now = time.time()
theta, theta_dot = read_joint_state()
theta_d, theta_d_dot = desired_motion(t_now)
e = theta_d - theta
# naive derivative of error (could be low-pass filtered in practice)
e_dot = theta_d_dot - theta_dot
tau_cmd = Kp * e + Kd * e_dot
tau_cmd = sat(tau_cmd, -tau_max, tau_max)
write_joint_torque(tau_cmd)
time.sleep(Ts)
6.2 C++ Implementation (Bare-Bones Loop)
#include <cmath>
#include <chrono>
#include <thread>
struct JointState {
double theta; // rad
double theta_dot; // rad/s
};
JointState read_joint_state(); // hardware-specific
void write_joint_torque(double tau_cmd); // hardware-specific
int main() {
const double J = 0.5;
const double B = 0.1;
const double omega_n = 4.0;
const double zeta = 0.7;
const double Kp = J * omega_n * omega_n;
const double Kd = 2.0 * zeta * omega_n * J - B;
const double tau_max = 10.0;
const double Ts = 0.005; // 5 ms
auto t0 = std::chrono::steady_clock::now();
while (true) {
auto t_now = std::chrono::steady_clock::now();
double t =
std::chrono::duration_cast<std::chrono::duration<double> >(
t_now - t0).count();
JointState js = read_joint_state();
// sinusoidal reference
double theta_d = 0.4 * std::sin(0.5 * t);
double theta_d_dot = 0.4 * 0.5 * std::cos(0.5 * t);
double e = theta_d - js.theta;
double e_dot = theta_d_dot - js.theta_dot;
double tau_cmd = Kp * e + Kd * e_dot;
if (tau_cmd > tau_max) tau_cmd = tau_max;
if (tau_cmd < -tau_max) tau_cmd = -tau_max;
write_joint_torque(tau_cmd);
std::this_thread::sleep_for(
std::chrono::duration<double>(Ts));
}
return 0;
}
6.3 Java Implementation (Controller Class)
public class AssistiveJointController {
private final double Kp;
private final double Kd;
private final double tauMax;
public AssistiveJointController(double J, double B,
double omegaN, double zeta,
double tauMax) {
this.Kp = J * omegaN * omegaN;
this.Kd = 2.0 * zeta * omegaN * J - B;
this.tauMax = tauMax;
}
private double saturate(double x) {
if (x > tauMax) return tauMax;
if (x < -tauMax) return -tauMax;
return x;
}
public double computeTorque(double theta, double thetaDot,
double thetaD, double thetaDDot) {
double e = thetaD - theta;
double eDot = thetaDDot - thetaDot;
double tauCmd = Kp * e + Kd * eDot;
return saturate(tauCmd);
}
}
6.4 MATLAB / Simulink Sketch
% Physical and control parameters
J = 0.5;
B = 0.1;
omega_n = 4.0;
zeta = 0.7;
Kp = J * omega_n^2;
Kd = 2*zeta*omega_n*J - B;
tau_max = 10;
% Continuous-time closed-loop error dynamics:
% J*e_ddot + (B + Kd)*e_dot + Kp*e = 0
A_e = [0 1; -Kp/J -(B+Kd)/J];
B_e = [0; 0];
C_e = [1 0];
D_e = 0;
sys_e = ss(A_e,B_e,C_e,D_e);
% Example: step in reference
t = 0:0.001:5;
u = zeros(size(t)); % error system has zero input
[y, t_out] = lsim(sys_e, u, t, [0; 0]); % free response
figure;
plot(t_out, y);
xlabel('Time (s)');
ylabel('Tracking error e(t)');
title('Error dynamics for PD-controlled assistive joint');
% In Simulink, one would typically use:
% - a "Sum" block to compute e = theta_d - theta
% - a "Derivative" or filtered differentiator for e_dot
% - "Gain" blocks for Kp and Kd
% - a "Saturation" block with limits [-tau_max, tau_max]
% - a plant block J*theta_ddot + B*theta_dot = tau_total
In a robotics software stack, these controllers are often embedded inside middleware (e.g., as ROS/ROS2 controller nodes), but the underlying mathematics is always a linear control loop of the form derived above.
7. Problems and Solutions
Problem 1 (Error Dynamics and Stability Conditions). Consider the 1-DOF joint model \( J \ddot{\theta}(t) + B \dot{\theta}(t) = \tau_m(t) \) (no human torque) with PD control \( \tau_m(t) = K_p(\theta_d - \theta(t)) + K_d(\dot{\theta}_d - \dot{\theta}(t)) \). Derive the error dynamics for \( e(t) = \theta_d - \theta(t) \) and show that the system is asymptotically stable if and only if \( K_p > 0 \) and \( B+K_d > 0 \).
Solution. Substitute the control law:
\[ J \ddot{\theta} + B \dot{\theta} = K_p(\theta_d - \theta) + K_d(\dot{\theta}_d - \dot{\theta}). \]
Rearranging,
\[ J \ddot{\theta} + (B+K_d)\dot{\theta} + K_p \theta = K_p \theta_d + K_d \dot{\theta}_d. \]
With constant reference \( \theta_d \), \( \dot{\theta}_d = 0 \), we have \( e = \theta_d - \theta \), \( \dot{e} = -\dot{\theta} \), \( \ddot{e} = -\ddot{\theta} \), so substituting \( \theta = \theta_d - e \) gives
\[ J (-\ddot{e}) + (B+K_d)(-\dot{e}) + K_p(\theta_d - e) = K_p \theta_d. \]
Simplifying,
\[ -J \ddot{e} - (B+K_d)\dot{e} + K_p \theta_d - K_p e = K_p \theta_d \quad \Rightarrow \quad J \ddot{e} + (B+K_d)\dot{e} + K_p e = 0. \]
The characteristic polynomial is \( J s^2 + (B+K_d)s + K_p \). For a second-order polynomial \( a_2 s^2 + a_1 s + a_0 \) with \( a_2 > 0 \), the roots have negative real part if and only if \( a_1 > 0 \) and \( a_0 > 0 \). Here \( a_2 = J > 0 \), \( a_1 = B+K_d \), \( a_0 = K_p \), hence the stability condition is \( B+K_d > 0 \), \( K_p > 0 \).
Problem 2 (Gain Design for Desired Natural Frequency and Damping). For a joint with \( J = 0.5 \,\text{kg m}^2 \) and \( B = 0.1 \,\text{N m s/rad} \), design PD gains that give approximately \( \omega_n = 4 \,\text{rad/s} \) and \( \zeta = 0.7 \).
Solution. From the matching in Section 4,
\[ K_p = J \omega_n^2, \quad K_d = 2\zeta\omega_n J - B. \]
Substitute numerical values:
\[ K_p = 0.5 \cdot 4^2 = 0.5 \cdot 16 = 8 \,\text{N m/rad}, \]
\[ K_d = 2 \cdot 0.7 \cdot 4 \cdot 0.5 - 0.1 = (2.8) - 0.1 = 2.7 \,\text{N m s/rad}. \]
These gains yield the desired natural frequency and damping ratio (up to modeling approximations).
Problem 3 (Velocity Limit from Energy Constraint). A rehabilitation robot joint has inertia \( J = 0.5 \,\text{kg m}^2 \). For safety, the kinetic energy stored in the joint must not exceed \( E_{\max} = 5 \,\text{J} \). Determine the maximum allowed joint speed \( \dot{\theta}_{\max} \) (in rad/s).
Solution. The kinetic energy is \( E_{\text{kin}} = \tfrac{1}{2} J \dot{\theta}^2 \). Imposing \( E_{\text{kin}} \le E_{\max} \) gives
\[ \tfrac{1}{2} J \dot{\theta}_{\max}^2 \le E_{\max} \quad \Rightarrow \quad \dot{\theta}_{\max} = \sqrt{\frac{2E_{\max}}{J}}. \]
Substituting:
\[ \dot{\theta}_{\max} = \sqrt{\frac{2 \cdot 5}{0.5}} = \sqrt{\frac{10}{0.5}} = \sqrt{20} \approx 4.47 \,\text{rad/s}. \]
Thus the controller should enforce \( |\dot{\theta}(t)| \le 4.47 \,\text{rad/s} \).
Problem 4 (Safe Torque Saturation Logic). Suppose the safe torque limit is \( \tau_{\max} = 10 \,\text{N m} \), and the PD controller outputs an unsaturated command \( \tau_{\text{raw}}(t) \). Write a piecewise definition of the saturated torque \( \tau_{\text{sat}}(t) \) and sketch the corresponding decision logic.
Solution. The saturation nonlinearity is
\[ \tau_{\text{sat}}(t) = \begin{cases} -\tau_{\max}, & \tau_{\text{raw}}(t) < -\tau_{\max}, \\[4pt] \tau_{\text{raw}}(t), & -\tau_{\max} \le \tau_{\text{raw}}(t) \le \tau_{\max}, \\[4pt] \tau_{\max}, & \tau_{\text{raw}}(t) > \tau_{\max}. \end{cases} \]
The logic can be visualized as:
flowchart TD
A["Compute tau_raw from PD"] --> B{"tau_raw > tau_max?"}
B -->|yes| C["tau_sat = tau_max"]
B -->|no| D{"tau_raw < -tau_max?"}
D -->|yes| E["tau_sat = -tau_max"]
D -->|no| F["tau_sat = tau_raw"]
Such a saturation block is standard in assistive robot controllers to enforce hardware and safety limits.
8. Summary
In this lesson we treated healthcare and assistive robots as human–robot coupled systems and focused on a single actuated joint. We derived a simple linear model of the joint, designed PD/impedance controllers using familiar second-order system concepts, and proved stability via Routh–Hurwitz and Lyapunov arguments. We also showed how safety constraints on forces, power, and energy translate into explicit limits on torque and velocity, and how these are implemented with saturation blocks. Finally, we illustrated multi-language controller implementations that form the core of many assistive robotic devices.
9. References
- Hogan, N. (1985). Impedance control: An approach to manipulation. ASME Journal of Dynamic Systems, Measurement, and Control, 107(1), 1–24.
- Colgate, J. E., & Schenkel, G. G. (1994). Passivity of a class of sampled-data systems: Application to haptic interfaces. Journal of Robotic Systems, 11(7), 487–501.
- Pratt, G., & Williamson, M. (1995). Series elastic actuators. In Proceedings of the IEEE/RSJ International Conference on Intelligent Robots and Systems, 399–406.
- Slotine, J.-J. E., & Li, W. (1991). Applied Nonlinear Control. Prentice Hall. (Chapters on robot arm control and passivity-based designs.)
- Khatib, O. (1987). A unified approach for motion and force control of robot manipulators: The operational space formulation. IEEE Journal of Robotics and Automation, 3(1), 43–53.
- De Santis, A., Siciliano, B., De Luca, A., & Bicchi, A. (2008). An atlas of physical human–robot interaction. Mechanism and Machine Theory, 43(3), 253–270.
- Villani, V., Pini, F., Leali, F., & Secchi, C. (2018). Survey on human–robot collaboration in industrial settings: Safety, intuitive interfaces and applications. Mechatronics, 55, 248–266.