Robot Hybrid Force and Position Control
A wiping tool must move along a surface while pressing into it. Hybrid control assigns motion and force to different contact directions so the two objectives don't fight over the same displacement.
Why Does This Exist?
A wiping robot needs to advance along a board and maintain contact pressure. An all-axis position controller cannot directly specify contact force: an uncertain surface position can turn a small displacement error into a large load. Hybrid force/position control assigns motion to directions permitted by the contact and force regulation to directions constrained by it.
Force is a push measured in newtons; position describes where the tool is. A rigid surface constrains normal motion while permitting tangential motion. Impedance control instead specifies a force–motion relationship, such as spring-like yielding. Hybrid control answers which directions regulate which quantity; compliance can still be useful inside its implementation.
Think of It Like This
Sliding a sponge over a window
Move a sponge sideways across a window while adjusting how hard you press. The glass determines the inward stopping surface, so you regulate the pressing force rather than demanding an arbitrary inward position. Your sideways movement follows a chosen path. Tilting the window rotates both directions together.
Sideways travel maps to motion control, pressing maps to force control and the window supplies the contact frame. The limit is the sponge's softness: the ideal derivation below treats contact as a rigid constraint, whereas real pads deform and friction resists sliding.
How It Actually Works
Define the contact directions before the controller
For a planar teaching model, let be the unit tangent along the board and the unit normal pointing from the tool into it. They are perpendicular: . Define the projectors
The transpose makes the outer product of a column vector with itself; is the planar identity matrix. Multiplying any vector by keeps only its tangential component; keeps only its normal component. In established rigid contact, the ideal normal velocity is , where is tool velocity.
Our simplified model uses only translation, equal Cartesian force units and orthogonal directions. Modern Robotics' hybrid-control treatment develops constrained spatial motion and wrench projections. Its general dynamics-based projection is not always the simple Euclidean projector used here. Spatial wrenches also include moments, and translation and rotation cannot be combined without attention to units and geometry.
Combine commands that have the same units
Suppose a motion controller computes a virtual Cartesian force from position and velocity errors. A force controller computes a Cartesian force request from desired and measured contact force. Then our planar combination is
Both terms are forces in the same frame. Adding a velocity directly to a force would be dimensionally wrong. For slow force-controlled contact, a simple normal request is , with desired normal force , measured normal magnitude , and dimensionless proportional gain . Here means the positive magnitude of robot-on-board force, inferred by negating the signed board-on-robot measurement if necessary.
The force-control chapter in Modern Robotics explains gravity compensation, Jacobian-transpose force commands and feedback corrections. For a planar force at the tool, joint torque is plus the required dynamics compensation, with the position Jacobian. A wrist sensor also sees payload gravity and inertial loads; its raw normal component is not automatically contact force.
Worked example: wipe a tilted board
Choose world x right and y up, with and inward . The board's angle is approximately . The projectors are
At desired tangential speed m/s, the velocity reference is m/s. Suppose the tangential position error is m and tangential proportional stiffness is N/m, with zero tangential velocity error. The motion controller requests N.
For N, N and , the normal force request is N. Thus
Projecting this result back gives N and N. The board reaction has the opposite normal sign. The diagram's tool rests on the tilted line. Its tangent arrow is the motion reference; its inward arrow is the normal force request. Their lengths use different declared units: speed and force are not being compared by length. The surrounding equations carry the combined force calculation.
Contact establishment changes the problem
A wrist wrench summarizes the load at its mounting frame. When contact location or edge loading matters, tactile sensing adds a local distribution: equal normal-force totals can have different centers of pressure.
The partition assumes a known contact frame and established contact. Before touching the board, a normal force target alone can accelerate the tool through free space. Use an approach mode with bounded speed, detect contact, then transition with suitable limits and without a discontinuous stored controller state. If contact breaks, the rigid equality constraint no longer holds. A surface supports compression, not arbitrary pulling; the chosen normal target must respect unilateral contact and friction.
Hybrid control offers explicit force regulation when a task has identifiable contact directions. The cost is constraint estimation, force sensing or inference, and transition design. It does not remove friction: maintaining tangential motion may require a substantial tangential force. When the surface is poorly known or compliant and smooth yielding matters more than precise force regulation, an impedance design may be a better starting point. High force gains, sensor filtering delay and a stiff environment must be evaluated as a coupled physical loop rather than tuned from static arithmetic alone.
Code
This standard-library calculation deliberately contaminates each controller with a component in the wrong direction. Projection removes those components and preserves the intended commands.
from math import isclose
Vec = tuple[float, float]t: Vec = (0.8, 0.6)n: Vec = (0.6, -0.8)
def dot(a: Vec, b: Vec) -> float: return sum(x*y for x, y in zip(a, b))
def project(axis: Vec, force: Vec) -> Vec: magnitude = dot(axis, force) return tuple(magnitude*x for x in axis)
def mix(a: float, b: float) -> Vec: return tuple(a*x+b*y for x, y in zip(t, n))
assert isclose(dot(t, n), 0.0, abs_tol=1e-14)motion_raw, force_raw = mix(2.0, 3.0), mix(7.0, 5.5)motion, force = project(t, motion_raw), project(n, force_raw)command = tuple(x+y for x, y in zip(motion, force))assert isclose(dot(t, command), 2.0)assert isclose(dot(n, command), 5.5)assert all(isclose(x, y) for x, y in zip(command, (4.9, -3.2)))print(f"command=({command[0]:.1f}, {command[1]:.1f}) N")print(f"normal={dot(n, command):.1f} N; tangent={dot(t, command):.1f} N")Output: command=(4.9, -3.2) N and normal=5.5 N; tangent=2.0 N.
This checks the decomposition, not force-loop stability or hardware tracking.
Watch Out For
The selection matrix stays in the world frame
Pressure varies as the board tilts because the controller still assigns force to world y. Build the tangent and normal from the estimated contact frame, rotate commands and sensor readings consistently, and verify force signs under a known load before closing the loop.
The normal position loop keeps pushing alongside force control
Contact force grows despite a modest force target because a position integrator keeps trying to drive into the surface. Remove conflicting normal motion authority in the contact mode, manage integral state across transitions and enforce force and actuator limits. A selection matrix cannot undo a second unaccounted controller acting downstream.
The Quick Version
- Hybrid control assigns motion to free contact directions and force regulation to constrained directions.
- Project forces expressed in one frame; never add a force command directly to a velocity reference.
- The tilted-board fixture combines a 2 N tangential request with a 5.5 N normal request to produce (4.9, -3.2) N.
- Contact sensing, friction, payload compensation and mode transitions determine whether the ideal partition remains useful.