"Physics does not negotiate. A motion constraint is not a preference; it is the boundary of what the robot is allowed to want."
A Constrained Optimizer
This section assumes familiarity with joint angle representation from section 5.1 and with the inverse kinematics framework introduced in section 5.6. The constraint formulations developed here are extended in section 6.1, where dynamics add force and torque bounds to the kinematic limits. They resurface in Part VI alongside motion planning, particularly in section 30.3, where the Open Motion Planning Library (OMPL) and MoveIt 2 enforce these same constraint types at the trajectory-planning level.
A surgical robot reaches for a tool tray, finds a valid IK solution (inverse kinematics, the joint angles that place the end-effector at a target pose), and then destroys a nearby instrument when its elbow sweeps through a workspace it was never told to avoid. The math was correct. The constraint was missing. Motion constraints are the layer that converts "mathematically reachable" into "physically legal": joint angle limits, velocity and acceleration caps, collision clearance margins, and task-level requirements such as keeping a tray level, as Figure 5.8A illustrates. As embodied AI moves from isolated arms into shared human spaces, constraint violations are no longer recoverable errors but safety incidents. Here you will formalize these limits, learn how planners enforce them, and implement constraint-checking code you can wire directly into a robot controller.
Your IK solver returns a flawless joint configuration, and the simulation replays it without complaint. Then, 340 milliseconds into execution, the real arm slams into a protective stop (a safety halt the robot's firmware triggers when a commanded position, velocity, or torque exceeds a rated limit): the cubic blend between two legal waypoints (a smooth cubic-polynomial interpolation the controller runs between successive setpoints) quietly hit 2.1 rad/s on a joint rated for 1.5. This is the gap between a configuration the solver can compute and one the hardware is permitted to execute. We define the four constraint families that matter on real hardware (joint bounds, rate limits, collision margins, and task-equality constraints), connect each to the controller that enforces it, then verify them with a dense-sampling check that catches the violations endpoint-only validation misses.
The key question is concrete: when a MoveIt 2 plan satisfies \(q_{\min}\le q\le q_{\max}\) at every waypoint, will the Franka Panda's joint_trajectory_controller still trip a protective stop on the cubic blend between them, and what logged signal would tell you before the arm freezes mid-task?
A representation earns its place when it changes the measurable action interface. In Motion constraints, the reader should keep asking which decision becomes easier, safer, or more reliable.
Theory
The practical design rule is to make the interface inspectable before optimization begins: inputs, outputs, units, latency, bounds, and failure labels should all be visible in the saved artifact.
To see why that inspectable interface is worth the trouble, follow a single placement task from a clean IK solution to a dropped part.
From valid solution to dropped part
Consider a Universal Robots UR5 placing a circuit board in a tight enclosure. The IK solver returns a mathematically valid configuration, but the path between waypoints cuts through a cabinet wall and peaks at 3.2 rad/s on joint 2, more than double the 1.5 rad/s actuator limit. The controller receives an infeasible command, trips a safety stop, and drops the board. Constraint-unaware planning produces exactly this: plans that look correct in simulation and fail at the first motor command. A plan that ignores actuator limits is not a motion plan; it is a wish list.
Motion constraints turn "move there" into "move there while staying legal." Some constraints are hard safety limits, such as joint bounds, collision clearance, and maximum speed. Others are task constraints, such as keeping a camera pointed at an object or keeping a carried cup upright. A planner that ignores the distinction may find a mathematically short path that the robot must reject at execution time.
A useful constraint is stated in a form that both the solver and the evaluator can check: equality constraints \(h(q)=0\), inequality constraints \(g(q)\le 0\), velocity limits \(\dot q_{\min}\le \dot q\le \dot q_{\max}\), and acceleration or jerk limits for smooth execution. The same definitions should appear in the logs, not only inside the solver setup. The Technical Core section later in this page details the mechanism, projecting a candidate configuration onto the equality-constraint manifold by Newton iteration on \(h\).
Checkpoint
So far: motion constraints replace a bare IK solution with a checkable contract (equality constraints for task requirements, inequality constraints for forbidden regions, and rate limits for what the actuator can execute), and the next sections show how each type is enforced and verified.
Joint-bound constraints (\(q_{\min} \le q \le q_{\max}\)) are always active and prevent hardware damage; violating them on a real arm triggers an emergency stop. Equality constraints like \(h(q)=0\) are task-specific: a welding torch must stay tangent to a seam, or a waiter robot must keep its tray horizontal. Velocity and acceleration limits matter most during dynamic motion: a Boston Dynamics Spot leg moving at 12 m/s in simulation will shear its gearbox at 3 m/s in hardware. The key design decision is classifying each constraint as hard (reject the plan) or soft (penalize in the objective) before the solver runs, not after it returns a result.
The mechanism in Motion constraints is the contract between representation and action. Name what enters the module, what leaves it, which assumptions make that transformation valid, and which log would reveal a bad handoff.
Worked Example
The example clamps a candidate joint configuration into its bounds (constraint projection), then samples velocity along a cubic interpolation between two waypoints. The endpoint speeds are zero, yet the mid-segment speed peaks well above the limit. Checking only the knots accepts a trajectory the actuator cannot execute.
import numpy as np
q_min, q_max = np.array([-2.0, -2.0]), np.array([2.0, 2.0])
qd_max = 1.5 # rad/s per joint velocity limit
# Constraint projection: clamp an out-of-bounds candidate into joint limits
candidate = np.array([2.4, -0.3])
clamped = np.clip(candidate, q_min, q_max)
print("candidate clamped:", candidate, "->", clamped)
# Cubic (Hermite) blend q0 -> q1 over duration T, zero endpoint velocity.
# Endpoint speed is 0, but interior speed peaks at 1.5 * |q1-q0| / T.
q0, q1, T = np.array([0.0, 0.0]), np.array([1.2, 0.0]), 1.0
def q_of_t(t):
s = t / T
return q0 + (q1 - q0) * (3*s**2 - 2*s**3)
def speed(t, h=1e-5):
return np.max(np.abs((q_of_t(t + h) - q_of_t(t - h)) / (2*h)))
v_endpoints = max(speed(1e-4), speed(T - 1e-4))
ts = np.linspace(0, T, 200)
v_dense = max(speed(t) for t in ts[1:-1])
print(f"speed at endpoints : {v_endpoints:.3f} rad/s -> ok? {v_endpoints <= qd_max}")
print(f"peak speed (dense) : {v_dense:.3f} rad/s -> ok? {v_dense <= qd_max}")
# Endpoints pass; the dense check catches the mid-segment overspeed.
assert v_dense > v_endpoints, "dense check must reveal the interior peak"
np.clip plus an endpoint-versus-dense velocity check on a cubic Hermite blend: the two knots read zero speed while 200 interior samples expose the 1.8 rad/s mid-segment peak that exceeds the 1.5 rad/s actuator limit.The dense re-sample is the cheap guard that turns a "looks fine at the knots" plan into a verified one. Checking only the two endpoint knots passes the trajectory. Checking 200 interior samples catches a mid-segment peak that would trip the actuator safety stop the moment the command reaches hardware. In practice, on cubic-blend trajectories with tight velocity margins, a planner that checks only waypoints can accept a substantial fraction of trajectories that a controller running at 1 kHz would immediately abort (the exact rate depends on blend duration and margin, but the failure mode itself is structural, not incidental): the math looks clean at two points while the actuator fails somewhere in the 999 steps between them. This is the knots-only blindspot. A velocity limit imposed only at waypoints is not the limit the actuator experiences along the blend, so the evaluation script must sample the same trajectory the controller will track.
Step-Through: dense velocity check on a cubic blend
Trace the worked example by hand with \(q_0=0\), \(q_1=1.2\) rad, \(T=1.0\) s, and a velocity limit \(\dot q_{\max}=1.5\) rad/s. The cubic position profile is \(q(s)=q_1\,(3s^2-2s^3)\) with \(s=t/T\), and its speed is \(\dot q(s)=\frac{q_1}{T}(6s-6s^2)\).
Evaluate at sampled times:
- \(t=0.0\) (knot): \(s=0\), \(\dot q = 1.2\cdot 6(0-0) = 0.000\) rad/s -> ok (0.000 <= 1.5).
- \(t=0.25\): \(s=0.25\), \(6s-6s^2 = 1.5-0.375 = 1.125\), \(\dot q = 1.2\cdot 1.125 = 1.350\) rad/s -> ok.
- \(t=0.50\) (midpoint): \(s=0.5\), \(6s-6s^2 = 3-1.5 = 1.5\), \(\dot q = 1.2\cdot 1.5 = 1.800\) rad/s -> VIOLATION (1.800 > 1.5).
- \(t=0.75\): same as \(t=0.25\) by symmetry, \(\dot q = 1.350\) rad/s -> ok.
- \(t=1.0\) (knot): \(s=1\), \(6s-6s^2 = 6-6 = 0\), \(\dot q = 0.000\) rad/s -> ok.
Both knots report 0.000 rad/s, so an endpoint-only check passes the trajectory. The interior peak at the midpoint is \(1.5\cdot|q_1-q_0|/T = 1.5\cdot 1.2/1.0 = 1.800\) rad/s, which exceeds the 1.5 rad/s limit by 20%. The dense sample is what surfaces the overspeed the controller would actually hit.
In Drake's DirectCollocation, calling AddConstraintToAllKnotPoints with a joint-position bound does not impose velocity limits; you must add a separate prog.AddBoundingBoxConstraint on the velocity decision variables, or those limits are silently absent from the transcription. A quick diagnostic: after solving, call ReconstructInputTrajectory and numerically differentiate the resulting positions at 10x the collocation resolution; if any joint exceeds qd_max, your collocation mesh is too coarse or the velocity constraint was never added. MoveIt 2 users face the same gap: moveit_msgs/Constraints enforces joint-position bounds but trajectory velocity parameterization is a separate time_optimal_trajectory_generation step that must be run explicitly before execution.
The fragment should expose velocity, acceleration, curvature, collision, and actuator constraints as first-class limits. OMPL, MoveIt 2, and Drake can enforce them at scale once the constraint semantics are unambiguous.
Practical Recipe
- Write the observation, action, and success metric before choosing a model.
- Build a baseline that is simple enough to debug by inspection.
- Add the library implementation only after the baseline behavior is understood.
- Record failures as structured cases: perception error, state error, planning error, control error, or evaluation error.
- Run at least one perturbation test before trusting the result.
The common mistake in Motion constraints is to celebrate the component score before checking the closed-loop handoff. The failure usually appears at the boundary: stale state, wrong frame, delayed action, saturated actuator, or metric that ignores the real task cost.
When deploying a Franka Panda on a bin-picking cell, log the full per-timestep record, not just grasp success. Capture joint positions and velocities at 1 kHz, the active constraint set at each planner call, collision distances from MoveIt 2's occupancy voxels, and any velocity-limit clamp events from the joint_trajectory_controller. In one documented failure mode, the robot passed all waypoint checks. The cubic blend between two waypoints then peaked at 2.1 rad/s on joint 4, exceeding the hardware limit of 1.5 rad/s and triggering a protective stop 340 ms into execution. That stop appeared only as a discontinuity in the /joint_states topic, not in the planner's success flag. Without dense trajectory logging at controller resolution, the constraint violation stays invisible at the task-outcome level.
Real-World Application: surgical robotics (Intuitive da Vinci)
The Intuitive da Vinci surgical system enforces a remote-center-of-motion (RCM) constraint: every instrument must pivot through the fixed trocar point (the small fixed incision port through which the instrument shaft enters the body) where it enters the patient's body, expressible as an equality constraint \(h(q)=0\) on the configuration. The control system projects every commanded motion onto this constraint manifold in real time, so even if the surgeon's hand command would violate it, the instrument shaft never tears the incision. This is exactly the hard equality constraint of this section, deployed on hardware where a violation is a patient-safety event rather than a dropped board.
Treat motion constraints like a control-room label. If the label does not tell a future debugger what moved, what sensed, or what failed, it is decoration rather than engineering knowledge.
Learning constraint manifolds from demonstration (2024-2026). Rather than hand-coding equality constraints, recent work learns task constraint manifolds directly from human demonstrations. The LASA lab and collaborators (Figueroa et al., "Constrained Dynamical Systems from Demonstrations," ICRA 2024) show that a robot can recover and generalize a level-surface constraint such as keeping a tray horizontal by fitting a learned Riemannian metric to demonstration data, then projecting motions onto the inferred manifold at runtime. This removes the need to analytically derive \(h(q)=0\) for each new task.
Differentiable constraint layers in model-predictive control (2024-2025). Groups at ETH Zurich and CMU (including the work behind TrajOpt 2 and MPINETS) are embedding constraint projections as differentiable layers inside neural MPC policies. The constraint layer solves a small quadratic program (QP) at each forward pass, making joint limits and collision margins part of the gradient graph. Carvalho et al. ("Motion Planning Diffusion," CoRL 2024) apply this to diffusion-based trajectory generation, enforcing hard constraints without post-hoc rejection sampling.
Contact-implicit constraint discovery for manipulation (2025-2026). Contact forces introduce inequality constraints that switch on and off unpredictably. The Locomotion and Manipulation lab at MIT and collaborators are extending contact-implicit trajectory optimization (CITO) to learn which contact modes are feasible before committing to a plan, combining complementarity constraints (the pairwise condition that contact force and separation distance cannot both be positive, which is what makes contact switch on and off) with learned contact models. This closes the gap between rigid-body constraint solvers and deformable or uncertain contact geometry.
Open problem for PhD students. Current constraint-projection methods assume a fixed constraint manifold known at planning time. An open problem is online constraint identification: given only proprioceptive feedback and task-outcome signals during execution, can a robot infer that a previously unknown equality constraint (an unseen balance requirement, an unmodeled linkage) became active, update the constraint set, and replan within a single manipulation episode without human intervention? The gap is connecting constraint-violation detection in the joint-state stream to efficient manifold re-estimation without restarting the solver from scratch.
Can you name the observation, state estimate, action, success metric, and most likely failure mode for Motion constraints? If not, the system boundary is still too vague.
Production Pattern
Motion constraints sits inside the Part II robotics contract: geometry defines where things are, kinematics defines what motion is possible, dynamics defines what motion costs, control defines how errors are corrected, and sensing defines what the agent can know on time.
If the planner checks joint limits only at waypoints and the controller interpolates freely between them, who is actually enforcing the constraint?
Write motion constraints as equations or inequalities that the solver and the evaluation script both see. This makes the treatment useful to readers approaching from theory, implementation, or research: the idea has an intuitive role, a formal interface, a runnable check, and a failure mode that can be reproduced.
Kinematics maps joint or body motion into task-space motion without explaining forces. Preserve joint limits, frame conventions, velocity units, and singularity margins in the artifact.
| Tool or Library | What It Handles | Verification Check |
|---|---|---|
| Pinocchio | computes articulated-body kinematics, dynamics, and derivatives | Verify model frames, joint ordering, and derivative convention against the URDF. |
| Robotics Toolbox for Python | supports practical work on Motion constraints | Verify the library output against the hand-built baseline on one small case. |
| MoveIt 2 | supports practical work on Motion constraints | Verify the library output against the hand-built baseline on one small case. |
| Drake | models dynamical systems, multibody plants, optimization, and controllers | Verify scalar type, plant finalization, frame convention, and solver status. |
| ROS 2 control | supports practical work on Motion constraints | Verify the library output against the hand-built baseline on one small case. |
Use this recipe when turning Motion constraints into code, a simulator experiment, or a robot diagnostic. The point is not to use every library. The point is to keep the hand-built baseline and the maintained-tool path comparable.
- Write the joint vector, frame target, velocity convention, and constraint set before solving.
- Check forward kinematics on a known posture, then perturb one joint and inspect the end-effector delta.
- Compare an analytic or numerical Jacobian with Pinocchio, Robotics Toolbox, or Drake on the same robot model.
- Log residual error, joint-limit distance, manipulability, and solver iteration count in one artifact.
- Treat singularities and infeasible targets as design signals, not as solver annoyances.
Compare methods only through one saved artifact that preserves the inputs, outputs, units, timestamps, latency budget, configuration, seed, metric definition, and failure labels relevant to this section. The comparison is meaningful only when the same script evaluates the same panel.
Extend the section exercise by adding one perturbation specific to Motion constraints and one latency or uncertainty check. Save the result in the EvidenceRecord schema, then explain which library output you trust and why.
Kinematic failures often arrive as a plausible pose with an impossible motion. Inspect which constraints were enforced during planning, which were checked only after planning, and which were hidden inside a controller. For this section, first reproduce one constrained update by hand, then rerun it through Drake, MoveIt 2, Pinocchio, Robotics Toolbox for Python, or a small NumPy projection. If the two disagree, inspect conventions and timing before changing the model.
Technical Core
Motion constraints needs a topic-native core: variables, equations or system contracts, an algorithmic procedure, an expected output, and a failure diagnosis. Figure 5.8.T summarizes the chain this section must preserve when moving from a teaching example to a real embodied system.
The technical core for Motion constraints connects assumptions, model, algorithm, evidence, and failure analysis. This is the same diagram introduced as Figure 5.1.T.
\(h(q)=0,\quad g(q)\le 0,\quad q_{\min}\le q\le q_{\max},\quad \dot q_{\min}\le \dot q\le \dot q_{\max}\)
Equality constraints define surfaces the motion must stay on, inequality constraints define forbidden regions, and rate limits define whether a geometrically valid path can be executed by real actuators. Treat all three as part of the motion contract.
Why equality constraints matter in embodied AI: a robot carrying liquid, welding a seam, or handing an object to a person must maintain a specific geometric relationship throughout motion, not just at start and end. Violating \(h(q)=0\) mid-trajectory spills the cup or breaks weld contact even when the endpoint pose is correct. This is the gap between task success in simulation and task success on hardware.
How they work: \(h(q)=0\) defines a constraint manifold in configuration space. Planners enforce it by projecting each candidate configuration onto this manifold via Newton iterations on \(h\), or by parameterizing motion directly on the manifold's tangent space using the constraint Jacobian \(\partial h/\partial q\). Violating configurations are pulled back to the nearest feasible point before any velocity or collision check runs.
Concretely, for a tray-leveling constraint \(h(q)=z_{ee}(q)-z_{tray}=0\) (the end-effector's tilt must equal a fixed target tilt), one Newton projection step updates a drifted candidate \(q_k\) by \(q_{k+1}=q_k-J_h(q_k)^{+}\,h(q_k)\), where \(J_h=\partial h/\partial q\) is the constraint Jacobian and \(J_h^{+}\) its pseudoinverse; this single line, repeated until \(\lvert h(q)\rvert\) falls below a tolerance (for example \(10^{-6}\) rad), is the numerical enforcement mechanism behind every equality constraint described in this section, including the da Vinci RCM example and the tray-leveling task constraint above.
Think of the equality constraint manifold like a hiking trail on a hillside. The full hillside is configuration space: every point is reachable in principle. The marked trail is the constraint surface \(h(q)=0\): the robot must stay on it to keep the cup level, the welding torch tangent, or the handoff safe. If a gust of wind (a small numerical error or disturbance) nudges you a step off the trail, you do not abandon the hike; you take the shortest step back to the trail and continue. That "shortest step back" is exactly what constraint projection does: Newton iterations on \(h\) pull the configuration perpendicularly back onto the manifold before any other check runs.
- Classify each constraint as equality, inequality, joint bound, velocity limit, acceleration limit, collision margin, or task-space requirement.
- State whether the constraint is enforced during planning, projected after each update, or checked only during validation.
- After every candidate update, log maximum violation, active constraints, and any clamped joint or velocity.
- Reject trajectories whose replay violates a constraint even if the endpoint and task residual look good.
| Contract Field | What To Specify | Why It Matters |
|---|---|---|
| State and observation | Variables, units, timestamps, frames, and uncertainty. | Prevents a model score from being mistaken for robot capability. |
| Action interface | Command type, limits, update rate, and safety fallback. | Makes the learned or planned output executable. |
| Evidence artifact | Trace, metric, configuration, seed, and failure label. | Allows baseline and library path to be compared in one pass. |
| Tool path | Modern Robotics, Pinocchio, Drake, ROS 2 tf2, MoveIt, NumPy | Shows the practical library route after the mechanism is understood. |
Expected output is a trajectory artifact with task residuals, maximum constraint violation, active-constraint labels, and replay validation on the same time grid used by the controller. A plan that satisfies constraints only at waypoints can still collide or exceed velocity limits between them.
A constrained-motion result fails when constraints are checked at endpoints only, collision distance is evaluated in stale frames, velocity limits are ignored during interpolation, or a soft penalty is mistaken for a hard safety guarantee.
Section References
Core references for Motion constraints: Modern Robotics; Murray, Li, and Sastry; Siciliano et al.; LaValle; and official documentation for Drake, MuJoCo, Pinocchio, CasADi, python-control, GTSAM, ROS 2, and OpenCV as applicable.
Use these references to check joint conventions, DH-parameter choices, and Jacobian definitions when your kinematics disagree with a library.
Motion constraints is useful when it makes the perception-action loop more reliable, not when it merely adds a more impressive model name.
Design a method-matched experiment for Motion constraints. Specify the environment, observations, actions, metric, one perturbation, and the library output you would compare against the hand-built baseline.
Lab: catch the mid-segment overspeed in PyBullet
Goal: reproduce the knots-only blindspot on a real robot model and confirm that dense sampling catches a velocity violation that endpoint checking misses.
Tools needed: Python with pybullet and numpy (pip install pybullet numpy); the Franka Panda or KUKA iiwa URDF that ships with pybullet_data.
Steps: Load the arm with p.loadURDF and read each joint's velocity limit from p.getJointInfo (field index 11). Pick two configurations \(q_0\) and \(q_1\) that differ on one joint, and generate a cubic (Hermite) blend with zero endpoint velocity over a duration \(T\). First check velocity only at the two knots, then resample the same trajectory at 200 interior points and numerically differentiate position to get speed.
What to vary: shrink the duration \(T\), and increase the joint travel \(|q_1-q_0|\); both raise the interior peak by the factor \(1.5\,|q_1-q_0|/T\).
What to observe: the endpoint check keeps reporting near-zero speed while the dense check crosses the URDF velocity limit as \(T\) shrinks. Find the largest \(T\) at which the trajectory is still infeasible, then command the blend in PyBullet position-control and watch the joint lag behind the setpoint once the limit is exceeded.
Project Ideas
Beginner (weekend): Joint-limit constraint visualizer in PyBullet. Load a URDF robot model (such as a UR5 or Franka Panda) in PyBullet, sample random joint configurations, and build a real-time dashboard that color-codes each joint by proximity to its position and velocity limits. The key challenge is numerically differentiating the recorded joint trajectory at fine resolution to expose mid-segment velocity peaks that endpoint-only checking misses.
Intermediate (1-2 weeks): Constraint-aware motion planner in MuJoCo with ROS 2 visualization. Implement a sampling-based planner (RRT or RRT-Connect) on a MuJoCo robot model that enforces joint bounds, velocity limits, and a single equality constraint (keep the end-effector tray level throughout the trajectory) by projecting each candidate configuration onto the constraint manifold via Newton iterations. The key challenge is making projection reliable enough that the planner does not stall on narrow constraint manifolds, then streaming the validated trajectory to RViz2 via a ROS 2 joint-state publisher so constraint violations are visible in 3D.
What's Next?
Continue to Chapter 6: Dynamics and Simulation Math, where this contract becomes the input to the next embodied capability.