Chapter 15: Safety, Standards, and Ethics

Lesson 1: Hazard Types in Robotics

This lesson introduces a rigorous, control-theoretic view of hazards in robotic systems. We classify mechanical, electrical, control-related, and software/logical hazards and formalize them using state-space models, safe sets, and simple risk metrics. Although this is an introductory robotics course, we leverage your prior knowledge of linear control to build mathematical notions of safety and hazard occurrence.

1. Conceptual Overview of Hazards

Informally, a hazard is any potential source of harm. In robotics, hazards arise because a controlled dynamical system interacts physically with humans and the environment. To reason about hazards mathematically, consider a robot with state \( \mathbf{x}(t) \in \mathbb{R}^n \), control input \( \mathbf{u}(t) \in \mathbb{R}^m \), and environment state \( \mathbf{e}(t) \in \mathbb{R}^p \). We define the combined state \( \mathbf{z}(t) = \begin{bmatrix} \mathbf{x}(t) \\ \mathbf{e}(t) \end{bmatrix} \).

A safe set is a subset of combined states in which the robot is considered safe:

\[ \mathcal{S} \subset \mathbb{R}^{n+p}, \quad \mathbf{z}(t) \in \mathcal{S} \; \text{means "safe"}, \; \mathbf{z}(t) \notin \mathcal{S} \; \text{means "hazardous"}. \]

Often we represent safety using a continuously differentiable safety function \( h : \mathbb{R}^{n+p} \to \mathbb{R} \):

\[ \mathcal{S} = \{ \mathbf{z} \in \mathbb{R}^{n+p} \mid h(\mathbf{z}) \ge 0 \}, \quad h(\mathbf{z}(t)) < 0 \Rightarrow \text{hazard present at time } t. \]

From this perspective, the goal of safety engineering is to design hardware, control laws, and supervisory logic so that starting from a safe initial state \( \mathbf{z}(0) \in \mathcal{S} \), the trajectory satisfies \( \mathbf{z}(t) \in \mathcal{S} \) for all future time. This is exactly the notion of set invariance that you have seen in linear control.

2. Taxonomy of Hazard Types in Robotics

We now classify the main hazard types for general-purpose robots. In later lessons we will connect these hazards to formal standards and risk assessment procedures. For a robot manipulator or mobile platform, typical hazard categories include:

  • Mechanical hazards: impacts, crushing, shearing, entanglement, pinching, and loss of stability. These relate to contact forces and energies exceeding safe thresholds.
  • Control and functional hazards: unintended motion, runaway behavior, instability, or violation of commanded constraints due to controller failures or incorrect models.
  • Electrical hazards: electric shock, burns, or fire due to insulation failure, short circuits, or incorrect grounding.
  • Thermal hazards: surfaces or effluents at unsafe temperatures (e.g., high-power actuators or electronics).
  • Radiation and sensor-related hazards: laser scanners, high-intensity LEDs, or other emitters that can harm humans.
  • Software and logical hazards: faults in decision logic, race conditions, or data corruption that cause unsafe trajectories even when hardware is functioning.

Mathematically, we can index hazard categories by \( k \in \{1,\dots, m\} \) and define indicator functions \( H_k(t) \in \{0,1\} \):

\[ H_k(t) = \begin{cases} 1, & \text{if hazard of type } k \text{ is active at time } t,\\ 0, & \text{otherwise}. \end{cases} \]

The overall hazard indicator is then \( H(t) = \max_k H_k(t) \), which is 1 if any hazard is active. The figure below shows a high-level classification flow.

flowchart LR
  ROOT["Robot hazards"] --> MECH["Mechanical (impact, crush, shear)"]
  ROOT --> CTRL["Control / functional (unintended motion, instability)"]
  ROOT --> ELEC["Electrical (shock, fire)"]
  ROOT --> THERM["Thermal (hot surfaces)"]
  ROOT --> RAD["Radiation / sensors (laser, light)"]
  ROOT --> SW["Software / logical (bugs, data faults)"]
        

3. Quantifying Risk: Probability and Severity

While a hazard is a possibility of harm, risk combines this possibility with the severity of the potential consequences. A simple, widely used quantitative abstraction is:

\[ R = \sum_{k=1}^m p_k \, c_k, \]

where \( p_k \in [0,1] \) is the probability of hazard type \( k \) occurring in a given mission or time interval, and \( c_k > 0 \) is a numerical severity or cost (e.g., related to injury level or financial damage).

If hazard occurrences of type \( k \) follow a Poisson process with rate \( \lambda_k \) (expected events per unit time), the probability of at least one event in time interval \( [0, T] \) is

\[ p_k(T) = \mathbb{P}\big(N_k(T) \ge 1\big) = 1 - e^{-\lambda_k T}. \]

For small \( \lambda_k T \), we have the approximation \( p_k(T) \approx \lambda_k T \), so the risk in that interval is

\[ R(T) \approx \sum_{k=1}^m \lambda_k T \, c_k. \]

Safety engineering then defines an acceptable risk bound \( R_{\max} \) and requires \( R(T) \le R_{\max} \) for the relevant operating horizon \( T \).

4. Safe Sets and Linear Safety Constraints

For many robots the underlying dynamics can be approximated locally by a linear system (or linearized model)

\[ \dot{\mathbf{x}}(t) = A \mathbf{x}(t) + B \mathbf{u}(t). \]

Imagine that safety specifications constrain the state to a polyhedral region described by linear inequalities:

\[ \mathcal{S} = \{ \mathbf{x} \in \mathbb{R}^n \mid C\mathbf{x} \le \mathbf{d} \}, \]

where \( C \in \mathbb{R}^{q \times n} \), \( \mathbf{d} \in \mathbb{R}^q \), and the inequality is understood elementwise. The faces of the safe set correspond to rows \( C_j \) such that \( C_j \mathbf{x} = d_j \).

We say that the safe set \( \mathcal{S} \) is forward invariant for a given feedback law \( \mathbf{u}(t) = K \mathbf{x}(t) \) if \( \mathbf{x}(0) \in \mathcal{S} \) implies \( \mathbf{x}(t) \in \mathcal{S} \) for all \( t \ge 0 \). A sufficient condition for invariance is:

\[ \text{If } C_j \mathbf{x} = d_j, \text{ then } C_j (A + BK) \mathbf{x} \le 0 \quad \text{for all faces } j. \]

Sketch of proof. On the boundary face \( C_j \mathbf{x} = d_j \), the scalar \( s_j(t) := C_j \mathbf{x}(t) - d_j \) satisfies

\[ \dot{s}_j(t) = C_j \dot{\mathbf{x}}(t) = C_j (A + BK) \mathbf{x}(t). \]

If \( \dot{s}_j(t) \le 0 \) whenever \( s_j(t) = 0 \), the trajectory cannot cross from \( s_j(t) \le 0 \) to \( s_j(t) > 0 \) through this boundary, and thus it cannot leave the safe set. This connects your prior knowledge of linear systems to the idea that “hazard = leaving the invariant safe set”.

In practice, safety constraints may limit joint positions, velocities, or torques. For instance, for a single joint with angle \( q(t) \), speed \( \dot{q}(t) \), and bounds \( q_{\min} \le q(t) \le q_{\max} \), leaving that interval corresponds to mechanical overtravel hazards.

5. Example – Speed and Separation Monitoring

A central mechanical hazard in human–robot collaboration is a collision between a moving robot and a human. One widely used conceptual safeguard is speed and separation monitoring, which enforces a minimum distance between robot and human depending on their relative speed.

Let \( d(t) \) be the distance between the robot and a human, \( v(t) \) the relative speed (positive when approaching), \( a_{\max} > 0 \) the maximum achievable (magnitude of) braking deceleration, and \( T_r \) the worst-case reaction time of the control system (sensing and computation delay). The stopping distance is

\[ d_{\text{stop}}(v) = v T_r + \frac{v^2}{2 a_{\max}}. \]

Here the first term accounts for the distance traveled during reaction time (constant speed), and the second term accounts for constant deceleration braking.

Suppose we allocate a fixed safety margin \( d_{\text{safe}} > 0 \). A natural safety function is

\[ h(d, v) = d - d_{\text{stop}}(v) - d_{\text{safe}}. \]

The system is safe when \( h(d(t), v(t)) \ge 0 \). If \( h(d(t), v(t)) < 0 \), then even maximal braking cannot prevent a collision, so the hazard is considered active and an emergency stop must already have been triggered. This kind of inequality appears explicitly in many safety guidelines.

6. Implementing a Simple Hazard Monitor

We now implement a simple runtime hazard monitor that periodically evaluates the safety function \( h(d, v) \) and triggers a stop command when \( h < 0 \). The logic is:

flowchart TD
  SENSE["Read distance d and relative speed v"] --> COMP["Compute h(d,v) = d - d_stop(v) - d_safe"]
  COMP --> DECIDE["Is h(d,v) negative?"]
  DECIDE -->|no| SAFE["Keep current motion"]
  DECIDE -->|yes| STOP["Trigger emergency stop / safe state"]
        

6.1 Python implementation


from dataclasses import dataclass

@dataclass
class SpeedSeparationConfig:
    reaction_time: float   # T_r in seconds
    max_decel: float       # a_max > 0 (m/s^2)
    safety_margin: float   # d_safe (m)

def stopping_distance(v: float, cfg: SpeedSeparationConfig) -> float:
    """
    Compute stopping distance given relative speed v.
    v: relative speed (m/s), assumed v >= 0 when approaching.
    """
    if cfg.max_decel <= 0.0:
        raise ValueError("max_decel must be positive")
    return v * cfg.reaction_time + 0.5 * v * v / cfg.max_decel

def safety_function(d: float, v: float, cfg: SpeedSeparationConfig) -> float:
    """
    Safety function h(d, v) = d - d_stop(v) - d_safe.
    Safe if h >= 0, hazardous if h < 0.
    """
    d_stop = stopping_distance(max(v, 0.0), cfg)
    return d - d_stop - cfg.safety_margin

def hazard_active(d: float, v: float, cfg: SpeedSeparationConfig) -> bool:
    h = safety_function(d, v, cfg)
    return h < 0.0

def emergency_stop():
    # In a real robot, this would send a message to a safety PLC or low-level controller.
    print("!!! EMERGENCY STOP !!!")

def monitor_step(d: float, v: float, cfg: SpeedSeparationConfig):
    """
    One monitoring step; call this in a periodic loop.
    """
    if hazard_active(d, v, cfg):
        emergency_stop()
      

6.2 C++ implementation


#include <stdexcept>

struct SpeedSeparationConfig {
    double reaction_time;  // T_r
    double max_decel;      // a_max > 0
    double safety_margin;  // d_safe
};

double stoppingDistance(double v, const SpeedSeparationConfig& cfg) {
    if (cfg.max_decel <= 0.0) {
        throw std::runtime_error("max_decel must be positive");
    }
    if (v < 0.0) v = 0.0;
    return v * cfg.reaction_time + 0.5 * v * v / cfg.max_decel;
}

double safetyFunction(double d, double v, const SpeedSeparationConfig& cfg) {
    double d_stop = stoppingDistance(v, cfg);
    return d - d_stop - cfg.safety_margin;
}

bool hazardActive(double d, double v, const SpeedSeparationConfig& cfg) {
    return safetyFunction(d, v, cfg) < 0.0;
}

// Placeholder for integration with low-level robot controller:
void emergencyStop() {
    // Send stop command over fieldbus (e.g., CAN, EtherCAT) or digital output.
}

void monitorStep(double d, double v, const SpeedSeparationConfig& cfg) {
    if (hazardActive(d, v, cfg)) {
        emergencyStop();
    }
}
      

6.3 Java implementation


public class SpeedSeparationConfig {
    public final double reactionTime;   // T_r
    public final double maxDecel;       // a_max > 0
    public final double safetyMargin;   // d_safe

    public SpeedSeparationConfig(double reactionTime, double maxDecel, double safetyMargin) {
        if (maxDecel <= 0.0) {
            throw new IllegalArgumentException("maxDecel must be positive");
        }
        this.reactionTime = reactionTime;
        this.maxDecel = maxDecel;
        this.safetyMargin = safetyMargin;
    }
}

public class HazardMonitor {

    public static double stoppingDistance(double v, SpeedSeparationConfig cfg) {
        if (v < 0.0) v = 0.0;
        return v * cfg.reactionTime + 0.5 * v * v / cfg.maxDecel;
    }

    public static double safetyFunction(double d, double v, SpeedSeparationConfig cfg) {
        double dStop = stoppingDistance(v, cfg);
        return d - dStop - cfg.safetyMargin;
    }

    public static boolean hazardActive(double d, double v, SpeedSeparationConfig cfg) {
        return safetyFunction(d, v, cfg) < 0.0;
    }

    public static void emergencyStop() {
        // Implement robot-specific stop behavior here
    }

    public static void monitorStep(double d, double v, SpeedSeparationConfig cfg) {
        if (hazardActive(d, v, cfg)) {
            emergencyStop();
        }
    }
}
      

6.4 MATLAB / Simulink implementation

In MATLAB, we can implement the same logic as a function that can be called from a Simulink block via a MATLAB Function block.


function [h, hazard] = speed_separation_monitor(d, v, reaction_time, max_decel, safety_margin)
%SPEED_SEPARATION_MONITOR Compute safety function and hazard flag.
%   d: distance (m)
%   v: relative speed (m/s), v >= 0 means approaching
%   reaction_time: T_r (s)
%   max_decel: a_max (m/s^2), must be > 0
%   safety_margin: d_safe (m)
%
%   h: safety function value
%   hazard: logical flag, true if h < 0

    if max_decel <= 0
        error('max_decel must be positive');
    end

    v = max(v, 0); % ignore negative (separating) speed for stopping distance
    d_stop = v * reaction_time + 0.5 * v.^2 / max_decel;
    h = d - d_stop - safety_margin;
    hazard = (h < 0);
end
      

In Simulink, a typical implementation places this function in a MATLAB Function block, with d and v connected to sensor inputs (e.g., from a laser scanner), and the Boolean output hazard feeding a safety channel that commands a stop state when true.

7. Problems and Solutions

Problem 1 (Poisson model of hazard occurrences). Assume mechanical collision hazards for a certain robot follow a Poisson process with rate \( \lambda = 10^{-4} \) collisions per hour. Compute the probability of at least one collision in a continuous 100-hour operating period. Use the first-order approximation for small \( \lambda T \) and compare it with the exact value.

Solution. The exact probability of at least one event in interval \( [0, T] \) for a Poisson process with rate \( \lambda \) is

\[ p(T) = 1 - e^{-\lambda T}. \]

Here \( \lambda = 10^{-4} \), \( T = 100 \), so \( \lambda T = 10^{-2} \). The first-order approximation gives

\[ p_{\text{approx}}(T) \approx \lambda T = 10^{-2}. \]

The exact value is

\[ p_{\text{exact}}(T) = 1 - e^{-0.01}. \]

Using the series expansion \( e^{-0.01} \approx 1 - 0.01 + 0.01^2/2 \), we obtain \( e^{-0.01} \approx 0.99005 \), hence \( p_{\text{exact}}(T) \approx 0.00995 \), which is within \( 0.00005 \) of the approximation.

Problem 2 (Risk metric for multiple hazard types). A collaborative robot has three dominant hazard types: (1) mechanical impact (M), (2) electrical shock (E), and (3) software malfunction (S). In a given mission, approximate probabilities and severities are: \( p_M = 10^{-3} \), \( p_E = 10^{-5} \), \( p_S = 5 \times 10^{-4} \), and severity costs \( c_M = 100 \), \( c_E = 1000 \), \( c_S = 50 \). Compute the total risk \( R \) and determine which hazard type dominates the risk.

Solution. By definition,

\[ R = p_M c_M + p_E c_E + p_S c_S. \]

Substituting the numbers:

\[ \begin{aligned} p_M c_M &= 10^{-3} \cdot 100 = 0.1, \\ p_E c_E &= 10^{-5} \cdot 1000 = 0.01, \\ p_S c_S &= 5 \times 10^{-4} \cdot 50 = 0.025. \end{aligned} \]

Thus \( R = 0.1 + 0.01 + 0.025 = 0.135 \). The largest contribution is from mechanical impact (0.1), so mechanical hazards dominate the risk, even though electrical shocks have higher severity, because their probability is much smaller.

Problem 3 (Safe interval invariance for a 1D motion). Consider a 1D prismatic joint with position \( x(t) \) and velocity \( v(t) \), modeled as \( \dot{x}(t) = v(t) \). The joint is controlled by choosing \( v(t) \) directly with \( |v(t)| \le v_{\max} \). The safe interval is \( [x_{\min}, x_{\max}] \). Define the control law

\[ v(t) = \begin{cases} -v_{\max}, & x(t) \ge x_{\max},\\ v_{\max}, & x(t) \le x_{\min},\\ v_{\text{cmd}}(t), & x_{\min} < x(t) < x_{\max}, \end{cases} \]

where \( v_{\text{cmd}}(t) \) is an arbitrary bounded command with \( |v_{\text{cmd}}(t)| \le v_{\max} \). Show that if \( x(0) \in [x_{\min}, x_{\max}] \), then \( x(t) \in [x_{\min}, x_{\max}] \) for all \( t \ge 0 \); that is, the safe interval is forward invariant.

Solution. The dynamics are \( \dot{x}(t) = v(t) \). Suppose first that \( x(t) = x_{\max} \). Then by the control law we have

\[ v(t) = -v_{\max} \quad \Rightarrow \quad \dot{x}(t) = -v_{\max} < 0, \]

so the state moves back into the interior \( x < x_{\max} \). Similarly, if \( x(t) = x_{\min} \), then

\[ v(t) = v_{\max} \quad \Rightarrow \quad \dot{x}(t) = v_{\max} > 0, \]

which moves the state back into the interior \( x > x_{\min} \). In the interior region \( x_{\min} < x(t) < x_{\max} \), the commanded velocity is arbitrary but bounded, and the control switches to the boundary law once the boundary is reached. Therefore, the trajectory cannot cross \( x_{\min} \) or \( x_{\max} \), and the interval is forward invariant.

Problem 4 (Maximum allowable speed for given distance). For the speed and separation monitoring example, suppose \( T_r = 0.1 \) s, \( a_{\max} = 5 \) m/s\(^2\), \( d_{\text{safe}} = 0.1 \) m, and current distance \( d = 0.8 \) m. Find the largest relative speed \( v_{\max}^{\text{safe}} \) such that \( h(d, v) \ge 0 \).

Solution. The safety condition is

\[ h(d, v) = d - \big( v T_r + \tfrac{v^2}{2 a_{\max}} \big) - d_{\text{safe}} \ge 0. \]

Equivalently,

\[ v T_r + \frac{v^2}{2 a_{\max}} \le d - d_{\text{safe}}. \]

Define \( D := d - d_{\text{safe}} = 0.8 - 0.1 = 0.7 \) m. Multiply through by \( 2 a_{\max} \):

\[ v^2 + 2 a_{\max} T_r v - 2 a_{\max} D \le 0. \]

With \( a_{\max} = 5 \) and \( T_r = 0.1 \), we get \( 2 a_{\max} T_r = 1 \) and \( 2 a_{\max} D = 2 \cdot 5 \cdot 0.7 = 7 \). Thus

\[ v^2 + v - 7 \le 0. \]

The roots of \( v^2 + v - 7 = 0 \) are

\[ v = \frac{-1 \pm \sqrt{1 + 28}}{2} = \frac{-1 \pm \sqrt{29}}{2}. \]

Only the positive root is relevant: \( v_{\max}^{\text{safe}} = \frac{-1 + \sqrt{29}}{2} \approx 2.19 \) m/s. Therefore, as long as the relative approaching speed satisfies \( v \le v_{\max}^{\text{safe}} \), the safety condition holds.

8. Summary

In this lesson we provided a structured view of hazard types in robotics, spanning mechanical, control, electrical, thermal, radiation, and software/logical origins. We formalized hazards as leaving a safe set in the state space and described how risk quantifies both probability and severity of hazardous events.

Using your background in linear control, we connected safety to set invariance and showed how linear inequalities and safety functions like \( h(d,v) \) define conditions under which a robot can operate without entering hazardous states. A simple speed and separation monitoring scheme was then implemented across Python, C++, Java, and MATLAB/Simulink as a runtime hazard monitor.

Subsequent lessons in this chapter will use these notions to build formal risk assessment procedures, introduce concepts of functional safety and redundancy, and relate them to concrete industrial standards.

9. References

  1. Blanchini, F. (1999). Set invariance in control. Automatica, 35(11), 1747–1767.
  2. Prandini, M., & Hu, J. (2006). Stochastic reachability: An overview. Annual Reviews in Control, 30(2), 101–110.
  3. Ames, A. D., Xu, X., Grizzle, J. W., & Tabuada, P. (2017). Control barrier function based quadratic programs for safety critical systems. IEEE Transactions on Automatic Control, 62(8), 3861–3876.
  4. De Luca, A., Albu-Schäffer, A., Haddadin, S., & Hirzinger, G. (2006). Collision detection and safe reaction with a manipulator arm. IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS), 1623–1630.
  5. Althoff, M., Stursberg, O., & Buss, M. (2009). Reachability analysis of nonlinear systems with uncertain parameters using conservative linearization. Proceedings of the 48th IEEE Conference on Decision and Control, 4042–4048.
  6. Knight, J. C. (2002). Safety critical systems: Challenges and directions. Proceedings of the 24th International Conference on Software Engineering, 547–550.