Move in Force Mode
SUMMARY
Move in Force Mode executes compliant robot motion by regulating force and/or torque behaviour during movement.
This skill is designed for force-interaction tasks such as polishing, insertion, constrained guidance, and adaptive contact control.
SUPPORTED ROBOTS
This skill is currently supported on Universal Robots only.
The Skill
# Called in a 2 ms control loop
robot.move_in_force_mode(
task_frame=task_frame,
selection_vector=selection_vector,
force=force,
force_mode_type=2,
limits_speed=limits,
)The Code
Example 1: Apply alternating Z-axis force in a control loop
Run a 2000-cycle loop at 2 ms per cycle. The first 1000 cycles push upward along Z; the remaining 1000 push downward.
import time
from loguru import logger
from telekinesis.synapse.robots.manipulators import universal_robots
robot_ip = "192.168.1.2" # replace with your robot's IP
robot = universal_robots.UniversalRobotsUR10E()
robot.connect(ip=robot_ip)
task_frame = [0, 0, 0, 0, 0, 0]
selection_vector = [0, 0, 1, 0, 0, 0]
wrench_up = [0, 0, 20, 0, 0, 0]
wrench_down = [0, 0, -1, 0, 0, 0]
force_mode_type = 2
limits = [2, 2, 1.5, 1, 1, 1]
period = 0.002
start_time = time.perf_counter()
for i in range(2000):
cycle_start = time.perf_counter()
wrench = wrench_up if i <= 1000 else wrench_down
robot.move_in_force_mode(
task_frame=task_frame,
selection_vector=selection_vector,
force=wrench,
force_mode_type=force_mode_type,
limits_speed=limits,
)
elapsed = time.perf_counter() - cycle_start
sleep_time = period - elapsed
if sleep_time > 0:
time.sleep(sleep_time)
logger.info(f"Force mode completed in {time.perf_counter() - start_time:.3f} s.")
robot.disconnect()The Explanation of the Code
move_in_force_mode applies one cycle of force-controlled motion and must be called repeatedly inside a control loop — typically at 500 Hz (2 ms period). Each call commands the robot controller to apply the specified wrench on compliant axes while holding pose on non-compliant axes.
Task frame. task_frame is a pose vector [x, y, z, rx, ry, rz] defining the frame in which forces and compliance are expressed, relative to the robot base frame. Position in metres; orientation in degrees. Pass [0, 0, 0, 0, 0, 0] to use the base frame directly.
Selection vector. selection_vector is a 6D binary vector where 1 marks a compliant axis and 0 marks a rigid axis. The example [0, 0, 1, 0, 0, 0] makes only the Z axis compliant — the robot moves freely along Z to track the force target while holding its X, Y, and orientation rigidly.
Force. force is a wrench [Fx, Fy, Fz, Tx, Ty, Tz] in Newtons and Newton-metres. The robot adjusts its position on compliant axes to converge toward these values. Values on non-compliant axes are ignored.
Force mode type. force_mode_type controls how the task frame is oriented during motion:
1— task-frame Y-axis aligns from TCP to force-frame origin2— task frame is fixed as defined bytask_frame3— task-frame X-axis aligns with the projection of TCP velocity onto the task-frame X-Y plane
Limits. limits_speed is a 6D vector of speed limits. On compliant axes it caps TCP speed (m/s for position, deg/s for rotation); on non-compliant axes it caps the allowed deviation from the commanded pose.
How to Tune the Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
task_frame | list[float] or np.ndarray | — | Force frame pose [x, y, z, rx, ry, rz] relative to base frame. Position in metres; orientation in degrees. |
selection_vector | list[int] or np.ndarray | — | 6D binary vector. 1 = compliant axis, 0 = rigid axis. |
force | list[float] or np.ndarray | — | Target wrench [Fx, Fy, Fz, Tx, Ty, Tz]. Forces in N; torques in N·m. |
force_mode_type | int | — | Task-frame interpretation: 1 Y-aligned, 2 fixed, 3 velocity-aligned. Integer in [1, 3]. |
limits_speed | list[float] or np.ndarray | — | 6D speed limits. Compliant axes: max TCP speed (m/s or deg/s). Non-compliant axes: max pose deviation (m or deg). |
Choosing limits
Start with conservative speed limits (e.g. 1.5 m/s on the compliant axis) and tighten them for delicate tasks. Loose limits allow larger motion excursions, which can cause unexpected collisions.
WARNING
move_in_force_mode must be called at a consistent rate (typically 500 Hz / 2 ms period). Irregular call timing can cause jerky motion or controller faults. Ensure your control loop maintains the required period.
Where to Use the Skill
- Surface following — Maintain constant contact force while tracking a curved surface (e.g. polishing, deburring)
- Compliant insertion — Guide a part into a socket with controlled insertion force to handle positional errors
- Constrained guidance — Allow the environment to deflect the robot on compliant axes while holding pose on rigid axes
- Force ramp-up — Gradually increase applied force to seat a component without impact
When Not to Use the Skill
Do not use Move in Force Mode when:
- Only a single contact event is needed — use Move Until Contact to approach and stop on contact without running a continuous loop
- Precise positioning is the goal — force mode trades position accuracy for force compliance; use Set Cartesian Pose for position-controlled moves
- The task does not require force regulation — force mode adds complexity and safety risk; only enable it when force control is genuinely needed

