trusty.subspace¶
Subspace (reduced-order) runtime + offline precompute.
The offline tooling at :mod:trusty.subspace.precompute produces a
.basis file (modal eigenmodes packed against a hex mesh). At
runtime, attach a subspace body to the world with
:func:add_hex_body / :func:add_tet_body; the composer scans the
world for SubspaceBody components and wires the subspace module
automatically. Contact for any subspace body (subspace floor, FEM
floor, cross-block subspace<->FEM) is governed by the single
trusty.contact.enable knob shared by every module in the simulator.
Basis
¶
actuation
¶
Current actuation (alpha) of body's muscle.
add_hex_body
¶
add_hex_body(
world: World,
rest_mesh: HexMesh,
material: StableNeoHookean
| Corotational
| StableFung
| NeohookeanBW
| ARAP
| QuadraticVolume,
density: float,
basis: Basis,
*,
project_positive_definite: bool = True,
friction_mu: float = 0.0,
) -> int
Add a Q1 hex subspace body carrying basis (from subspace.load). The composer activates the subspace module automatically when any world body has this tag.
add_muscle
¶
add_muscle(
world: World,
body: int,
directions: ndarray[float64, (N, 3)],
stiffness: float,
) -> int
Attach a muscle fiber field to body. directions is the rest-frame fiber, (num_elements, 3) for curved fibers or (1, 3) to broadcast one direction; stiffness is the fixed gain. Returns the muscle's index (its handle for set_actuation / actuation). The live actuation starts at 0.
Call before building the body's basis -- the basis precompute reads the world's muscles to build the operator it decomposes.
add_tet_body
¶
add_tet_body(
world: World,
rest_mesh: TetMesh,
material: StableNeoHookean
| Corotational
| StableFung
| NeohookeanBW
| ARAP
| QuadraticVolume,
density: float,
basis: Basis,
*,
project_positive_definite: bool = True,
friction_mu: float = 0.0,
) -> int
Tet counterpart of add_hex_body.
deformed_positions
¶
Current deformed node positions of subspace body as an (N, 3) numpy array. The rest mesh before the first step.
fem_rest_operator
¶
Full-space rest stiffness operator (3N, 3N) of the world's single FEM solid: the elastic K plus every muscle (add_muscle) the world declares, at the gain it is simulated with. This is the operator the basis is decomposed from, so declaring a muscle on the precompute world is all it takes for the basis to account for it. Attachments are deliberately excluded -- a bond is a both-sided coupled term whose stiffness on the follower depends on how freely its anchor moves, so folding a grounded k I3 would delete the follower motion a movable anchor exists to permit.
fem_elastic_stiffness_matrix
¶
Elastic stiffness (3N, 3N) at the rest configuration of the world's single FEM solid -- the elastic block of fem_rest_operator.
fem_muscle_stiffness_matrix
¶
Muscle stiffness (3N, 3N) at rest: sum_muscles A_musc, without the elastic block. Only the activation-mode solve needs this alone (its rest contraction force is -A_musc x0); the eigenproblem wants fem_rest_operator.
fem_mass_matrix
¶
Lumped nodal mass of the world's single FEM solid as a length-3N diagonal, each node's mass repeated 3 times (scalar-DOF indexable).
fem_pinned_dofs
¶
Sorted scalar DOF indices the world pinned via fem.pin_face. Slice these out before a generalised eigensolve.
load
¶
Parse a .basis file into an opaque Basis handle. Pass the result to add_hex_body / add_tet_body. Cache the handle to share one basis across multiple bodies without re-parsing.
num_muscles
¶
Number of muscles attached to subspace body.
read_state
¶
Reduced state z of subspace body after the last accepted step. Returns a length-r numpy array, zero before the first step.
set_actuation
¶
Set the actuation (alpha) of body's muscle. Scales the precomputed muscle force/stiffness; takes effect on the next step.