Rigid Body Constraints¶
Rigid body constraints restrict and drive rigid body motion: they attach bodies, build joints, add springs, and control velocity.
Each add_constraint_*() call returns a handle for adjusting parameters, enabling/disabling, labeling, or querying the constraint violation.
// Global defaults used by subsequently created hard constraints.
simulation.rigidbodies->set_default_constraint_stiffness(1e6);
simulation.rigidbodies->set_default_constraint_distance_tolerance(1e-3); // m
simulation.rigidbodies->set_default_constraint_angle_tolerance(1.0); // deg
// Example: a hinge joint between two rigid bodies.
auto hinge = simulation.rigidbodies->add_constraint_hinge(
body_a,
body_b,
pivot_point, // world-space point at creation time
hinge_axis // world-space direction at creation time
);
hinge.set_stiffness(1e8);
hinge.set_tolerance_in_m(1e-4);
hinge.set_tolerance_in_deg(0.1);
hinge.set_label("main_hinge");
How constraints work¶
STARK rigid body constraints are implemented as energy terms in the global optimization problem. Most rigid body constraints are defined from points or directions given in world coordinates at creation time.
Hard constraints use finite stiffness with a tolerance. After convergence, STARK checks the violation and hardens stiffness if the tolerance is exceeded, avoiding the need to manually tune very large stiffness values.
There are two important categories:
Primitive constraints are the actual energy terms registered in SymX.
Composed constraints are convenience joints built by combining primitive constraints.
Common handle operations¶
All constraint handles support basic operations such as:
constraint.set_label("name"); // Used for traceability
constraint.enable(true); // activate
constraint.enable(false); // deactivate
Hard positional constraints usually provide:
constraint.set_stiffness(1e8);
constraint.set_tolerance_in_m(1e-4);
Hard directional constraints usually provide:
constraint.set_stiffness(1e8);
constraint.set_tolerance_in_deg(1.0);
Velocity controllers and springs expose their physical parameters directly, such as target velocity, maximum force, maximum torque, damping, or rest length.
Primitive Constraints¶
Primitive constraints are the low-level constraint energies implemented by STARK. The higher-level joints later in this page are built from these pieces.
Global Point¶
Fixes one body-local point to a target point in world space.
auto c = simulation.rigidbodies->add_constraint_global_point(
body,
world_point
);
Global Direction¶
Aligns one body-local direction with a target direction in world space.
auto c = simulation.rigidbodies->add_constraint_global_direction(
body,
world_direction
);
Point¶
Constrains one point on body A to coincide with one point on body B. This is the primitive ball-joint constraint.
auto c = simulation.rigidbodies->add_constraint_point(
body_a,
body_b,
world_point
);
Point on Axis¶
Constrains a point on body B to lie on an axis attached to body A.
auto c = simulation.rigidbodies->add_constraint_point_on_axis(
body_a,
body_b,
world_point,
world_axis
);
Distance¶
Constrains the distance between two body-local points to remain equal to the distance at creation time.
auto c = simulation.rigidbodies->add_constraint_distance(
body_a,
body_b,
point_on_a_world,
point_on_b_world
);
Distance Limits¶
Constrains the distance between two body-local points to remain inside an interval.
auto c = simulation.rigidbodies->add_constraint_distance_limits(
body_a,
body_b,
point_on_a_world,
point_on_b_world,
min_distance,
max_distance
);
Direction¶
Aligns one body-local direction on body A with one body-local direction on body B.
auto c = simulation.rigidbodies->add_constraint_direction(
body_a,
body_b,
world_direction
);
Angle Limit¶
Restricts the angle between two body-local directions.
auto c = simulation.rigidbodies->add_constraint_angle_limit(
body_a,
body_b,
world_direction,
admissible_angle_deg
);
Damped Spring¶
Adds a damped linear spring between two body-local points.
auto spring = simulation.rigidbodies->add_constraint_spring(
body_a,
body_b,
point_on_a_world,
point_on_b_world,
stiffness,
damping // optional, default 0.0
);
Linear Velocity¶
Drives the relative linear velocity of body B with respect to body A along a direction attached to body A.
auto c = simulation.rigidbodies->add_constraint_linear_velocity(
body_a,
body_b,
world_direction,
target_v, // m/s
max_abs_force, // N
delay // optional, default 0.01 s
);
Angular Velocity¶
Drives the relative angular velocity of body B with respect to body A around a direction attached to body A.
auto c = simulation.rigidbodies->add_constraint_angular_velocity(
body_a,
body_b,
world_axis,
target_w, // rad/s
max_abs_torque, // Nm
delay // optional, default 0.01 s
);
Composed Constraints¶
Composed constraints are convenience APIs that combine primitive constraints. They return composed handles that forward stiffness, tolerance, label, and activation changes to the underlying primitives.
Fix¶
Fixes a rigid body in world space by combining one global point constraint with two global direction constraints.
auto fix = simulation.rigidbodies->add_constraint_fix(body);
The body is fixed at its current pose at creation time.The typical scripting pattern: create a fix, then update its target transformation each step.
auto fix = simulation.rigidbodies->add_constraint_fix(body);
simulation.add_time_event(0.0, duration, [&](double t) {
fix.set_transformation(
Eigen::Vector3d(0.0, 0.0, 0.2 * t), // target translation
30.0 * t, // angle in degrees
Eigen::Vector3d::UnitZ() // rotation axis
);
});
Attachment¶
Rigidly attaches two bodies together, producing a zero-DOF joint.
auto attachment = simulation.rigidbodies->add_constraint_attachment(
body_a,
body_b
);
The attachment is created at the midpoint between the current body translations and locks the relative orientation with two direction constraints.
Point with Angle Limit¶
Combines a point constraint with an angular range limit.
auto joint = simulation.rigidbodies->add_constraint_point_with_angle_limit(
body_a,
body_b,
pivot_point,
limit_axis,
admissible_angle_deg
);
Conceptually, this behaves like a ball joint with an angular cone limit.
Hinge¶
Creates a one-DOF hinge joint: the bodies share a pivot point and may rotate relative to each other around the hinge axis.
auto hinge = simulation.rigidbodies->add_constraint_hinge(
body_a,
body_b,
pivot_point,
hinge_axis
);
Hinge with Angle Limit¶
Creates a hinge joint with a symmetric angular limit around the hinge axis.
auto hinge = simulation.rigidbodies->add_constraint_hinge_with_angle_limit(
body_a,
body_b,
pivot_point,
hinge_axis,
admissible_angle_deg
);
Spring with Limits¶
Adds a damped spring and additionally constrains its length to remain inside a prescribed interval.
auto spring = simulation.rigidbodies->add_constraint_spring_with_limits(
body_a,
body_b,
point_on_a_world,
point_on_b_world,
spring_stiffness,
min_length,
max_length,
damping // optional, default 0.0
);
The spring stiffness and the hard distance-limit stiffness are independent. The composed handle exposes set_spring_stiffness() for the spring and set_stiffness() for the distance limits.
Slider¶
Creates a slider-like joint where a point on one body can move along an axis attached to the other body.
auto slider = simulation.rigidbodies->add_constraint_slider(
body_a,
body_b,
pivot_point,
slide_axis
);
This permits sliding along the axis while keeping the corresponding body directions aligned.
Prismatic Slider¶
Creates a stricter prismatic joint by adding an additional orthogonal direction lock to the slider.
auto slider = simulation.rigidbodies->add_constraint_prismatic_slider(
body_a,
body_b,
pivot_point,
slide_axis
);
This keeps the bodies aligned as a prismatic pair while allowing translation along the slide axis.
Prismatic Press¶
Creates a prismatic slider driven by a force-limited linear velocity controller.
auto press = simulation.rigidbodies->add_constraint_prismatic_press(
body_a,
body_b,
pivot_point,
slide_axis,
target_v,
max_force,
delay // optional, default 0.01 s
);
This is useful for grippers, presses, pistons, and other constrained linear actuators.
Motor¶
Creates a hinge driven by a torque-limited angular velocity controller.
auto motor = simulation.rigidbodies->add_constraint_motor(
body_a,
body_b,
pivot_point,
rotation_axis,
target_w,
max_torque,
delay // optional, default 0.01 s
);
This is the standard rigid body rotational motor.