tests.PrismaticConstraintTest
Prismatic Constraint (closed loop with a spring)
A body is connected to the world by the implicit PrismaticConstraint at one end and pulled back to a fixed world point by a Spring at the other end, forming a closed loop.
The constraint locks the relative orientation completely and locks translation along z, while releasing the x and y directions (x_locked = false, y_locked = false). The body can therefore only translate in the world x/y plane, driven by gravity (along -y) and the spring load.
The free body carries its own (absolute) Euler body coordinates and world position/velocity as states. Because the released x/y translations are genuine degrees of freedom, the body is given concrete initial conditions for its full state – orientation phi = [0, 0, 0], phid = [0, 0, 0] and position r_0 = [0, 0, 0], v_0 = [0, 0, 0] – so the initialization is fully determined and reproducible (cf. the RevoluteConstraintTest rationale; here the free translational degrees of freedom must also be pinned, otherwise the initialization is rank-deficient).
Usage
MultibodyComponents.tests.PrismaticConstraintTest()
Behavior
Source
"""
# Prismatic Constraint (closed loop with a spring)
A body is connected to the world by the implicit `PrismaticConstraint` at one end
and pulled back to a fixed world point by a `Spring` at the other end, forming a
closed loop.
The constraint locks the relative orientation completely and locks translation
along `z`, while releasing the `x` and `y` directions (`x_locked = false`,
`y_locked = false`). The body can therefore only translate in the world `x`/`y`
plane, driven by gravity (along `-y`) and the spring load.
The free body carries its own (absolute) Euler body coordinates and world
position/velocity as states. Because the released `x`/`y` translations are
genuine degrees of freedom, the body is given concrete initial conditions for
its full state -- orientation `phi = [0, 0, 0]`, `phid = [0, 0, 0]` and position
`r_0 = [0, 0, 0]`, `v_0 = [0, 0, 0]` -- so the initialization is fully determined
and reproducible (cf. the `RevoluteConstraintTest` rationale; here the free
translational degrees of freedom must also be pinned, otherwise the
initialization is rank-deficient).
"""
example component PrismaticConstraintTest
world = MultibodyComponents.World() {}
constraint = MultibodyComponents.PrismaticConstraint(x_locked = false, y_locked = false) {}
body = MultibodyComponents.Body(m = 1, r_cm = [0.2, 0, 0], I_11 = 0.1, I_22 = 0.1, I_33 = 0.1, orientation_state = OrientationState.Euler(), sequence = [1, 2, 3], phi(initial = nothing), phid(initial = nothing)) {}
rod = MultibodyComponents.FixedTranslation(r = [0.4, 0, 0]) {}
spring = MultibodyComponents.Spring(c = 20, s_unstretched = 0) {}
mount = MultibodyComponents.FixedTranslation(r = [0.8, 0, 0.3]) {}
relations
connect(world.frame_b, constraint.frame_a) {}
connect(constraint.frame_b, body.frame_a, rod.frame_a) {}
connect(rod.frame_b, spring.frame_b) {}
connect(world.frame_b, mount.frame_a) {}
connect(mount.frame_b, spring.frame_a) {}
# The released x/y translations are the only free degrees of freedom; pin them
# (and only them) so the initialization is exactly determined. The orientation
# and the locked z translation are fixed by the constraint itself, so their
# default initial conditions are unset (`initial nothing`) to avoid an
# over-determined initialization.
initial body.r_0[1] = 0
initial body.r_0[2] = 0
initial body.v_0[1] = 0
initial body.v_0[2] = 0
endFlattened Source
"""
# Prismatic Constraint (closed loop with a spring)
A body is connected to the world by the implicit `PrismaticConstraint` at one end
and pulled back to a fixed world point by a `Spring` at the other end, forming a
closed loop.
The constraint locks the relative orientation completely and locks translation
along `z`, while releasing the `x` and `y` directions (`x_locked = false`,
`y_locked = false`). The body can therefore only translate in the world `x`/`y`
plane, driven by gravity (along `-y`) and the spring load.
The free body carries its own (absolute) Euler body coordinates and world
position/velocity as states. Because the released `x`/`y` translations are
genuine degrees of freedom, the body is given concrete initial conditions for
its full state -- orientation `phi = [0, 0, 0]`, `phid = [0, 0, 0]` and position
`r_0 = [0, 0, 0]`, `v_0 = [0, 0, 0]` -- so the initialization is fully determined
and reproducible (cf. the `RevoluteConstraintTest` rationale; here the free
translational degrees of freedom must also be pinned, otherwise the
initialization is rank-deficient).
"""
example component PrismaticConstraintTest
world = MultibodyComponents.World() {}
constraint = MultibodyComponents.PrismaticConstraint(x_locked = false, y_locked = false) {}
body = MultibodyComponents.Body(m = 1, r_cm = [0.2, 0, 0], I_11 = 0.1, I_22 = 0.1, I_33 = 0.1, orientation_state = OrientationState.Euler(), sequence = [1, 2, 3], phi(initial = nothing), phid(initial = nothing)) {}
rod = MultibodyComponents.FixedTranslation(r = [0.4, 0, 0]) {}
spring = MultibodyComponents.Spring(c = 20, s_unstretched = 0) {}
mount = MultibodyComponents.FixedTranslation(r = [0.8, 0, 0.3]) {}
relations
connect(world.frame_b, constraint.frame_a) {}
connect(constraint.frame_b, body.frame_a, rod.frame_a) {}
connect(rod.frame_b, spring.frame_b) {}
connect(world.frame_b, mount.frame_a) {}
connect(mount.frame_b, spring.frame_a) {}
# The released x/y translations are the only free degrees of freedom; pin them
# (and only them) so the initialization is exactly determined. The orientation
# and the locked z translation are fixed by the constraint itself, so their
# default initial conditions are unset (`initial nothing`) to avoid an
# over-determined initialization.
initial body.r_0[1] = 0
initial body.r_0[2] = 0
initial body.v_0[1] = 0
initial body.v_0[2] = 0
metadata {}
endTest Cases
No test cases defined.
Related
Examples
Experiments
Analyses