Dynamics

Reference for DynamicScene, LinearTrajectory, RigidMotion, DeformationState and the Trajectory and Deformation protocols for time-varying scenes.

The motion classes live in witwin.core.dynamics and are exported from witwin.core (both import paths work). For examples, see Animate a scene.

from witwin.core import Deformation, DeformationState, DynamicScene, LinearTrajectory, RigidMotion, Trajectory

DynamicScene#

class DynamicScene(
    scene: Scene,
    *,
    structure_trajectories: Mapping[StructureId | int, Trajectory] | None = None,
    structure_deformations: Mapping[StructureId | int, Deformation] | None = None,
    endpoint_trajectories: Mapping[AntennaId | int, Trajectory] | None = None,
    dynamic_revision: int = 0,
)

A static scene plus motion descriptors. It does not compile anything; it produces snapshots. Immutable.

sceneScenerequired

The static scene. Other types raise TypeError.

structure_trajectoriesMapping[StructureId | int, Trajectory] | Nonedefault None

Rigid motion per structure ID.

structure_deformationsMapping[StructureId | int, Deformation] | Nonedefault None

Vertex deformation per structure ID.

endpoint_trajectoriesMapping[AntennaId | int, Trajectory] | Nonedefault None

Rigid motion per antenna ID.

dynamic_revisionintdefault 0

A counter you raise when the motion descriptors change in a way Core cannot see. Part of the snapshot's geometry_version. Must be at least 0.

Raises KeyError for a structure or antenna ID that is not in the scene, and TypeError for a value that does not implement the protocol.

The mappings are stored as read-only mappings keyed by StructureId and AntennaId under the attribute names above.

DynamicScene.at#

at(time_s: ScalarLike) -> SceneSnapshot

Returns the snapshot at time_s seconds. Each structure's StructureState carries trajectory.at(time_s) and deformation.at(time_s) where defined, else None; each endpoint's EndpointState carries its trajectory's motion. A tensor time_s must be 0-d (ValueError) and is passed to the descriptors as is.

RigidMotion#

class RigidMotion(*, translation=None, rotation=None, velocity=None, angular_velocity=None)

Rigid state added after the authored pose. All arguments are optional and keyword-only. Sequences become float32 tensors. Immutable.

translationTensor (..., 3) | Nonedefault None

World-frame displacement in metres, added last.

rotationTensor (3,) | Tensor (4,) | Nonedefault None

Local-to-world rotation composed on the left of the authored rotation. Euler (yaw, pitch, roll) or quaternion (w, x, y, z).

velocityTensor (..., 3) | Nonedefault None

Linear velocity in m/s, for solvers (for example Doppler).

angular_velocityTensor (..., 3) | Nonedefault None

Angular velocity, for solvers.

Raises ValueError when the tensors differ in device or dtype or have the wrong trailing shape, and TypeError for non-floating dtypes.

DeformationState#

class DeformationState(*, vertices=None, offsets=None)

Topology-preserving vertex state, in the structure's local frame. Give exactly one argument, otherwise ValueError.

verticesTensor (V, 3) | Nonedefault None

Absolute local vertices that replace the authored ones.

offsetsTensor (V, 3) | Nonedefault None

Offsets added to the authored local vertices.

The deformation is applied before the authored transform and before any RigidMotion.

Trajectory and Deformation#

@runtime_checkable
class Trajectory(Protocol):
    def at(self, time_s: ScalarLike) -> RigidMotion: ...
 
 
@runtime_checkable
class Deformation(Protocol):
    def at(self, time_s: ScalarLike) -> DeformationState: ...

Any object with a matching at method. Core calls at once per snapshot.

LinearTrajectory#

@dataclass(frozen=True)
class LinearTrajectory:
    origin: torch.Tensor
    velocity: torch.Tensor
    rotation: torch.Tensor | None = None
    angular_velocity: torch.Tensor | None = None
    reference_time_s: float = 0.0

Constant-velocity motion: at(t) returns a RigidMotion with translation = origin + velocity * (t - reference_time_s), and velocity, rotation and angular_velocity copied as given.

origin3 floats | Tensor (3,)required

Translation at reference_time_s, in metres.

velocity3 floats | Tensor (3,)required

Velocity in m/s.

rotation3 or 4 values | Tensor | Nonedefault None

A constant rotation, antenna convention.

angular_velocity3 floats | Tensor (3,) | Nonedefault None

Stored and passed through; not integrated.

reference_time_sfloatdefault 0.0

The time at which the translation equals origin.

All tensors must share one device and one dtype. A tensor time_s passed to at must match them, otherwise ValueError.

from witwin.core import LinearTrajectory
 
walk = LinearTrajectory(origin=(0.0, 0.0, 0.0), velocity=(1.2, 0.0, 0.0), reference_time_s=1.0)
print(walk.at(3.0).translation)
tensor([2.4000, 0.0000, 0.0000])