Context
The motion DSL animates a single point: _PathNode.compile_frames / at_time (src/multicam_sim/dsl/motion.py:99,64) with LinearPath / CirclePath. The pose layer builds a PoseTrajectory from per-frame joint dicts (src/multicam_sim/pose.py:123, skeleton Skeleton.coco17() at pose.py:103). What's missing is anything that moves a skeleton: today you must hand-author 17 joint positions per frame.
What to do
Add a skeletal-motion layer that generates a PoseTrajectory over frames from a small set of parametric gaits driving the COCO-17 joints:
walk (translating body with periodic legs/arms), reach (arm extends to a target), wave (forearm oscillation).
Reuse the timing model from motion.py (over(seconds) / at_speed / compile_frames) so gaits share the same fps-aware frame compilation. A root path can translate the whole skeleton while the gait drives joint offsets. Keep it kinematic (no physics); parameters typed and validated.
Acceptance criteria
walk(...).to_pose_trajectory("p0") (or equivalent) returns a PoseTrajectory whose to_entity() yields all 17 COCO joints for every frame, and whose root translates over the requested duration.
- Joint positions are continuous frame-to-frame (no jumps) and deterministic for a fixed seed.
- Tests build each gait and assert joint count, continuity, and that a manifest round-trip labels every joint per camera.
ruff, mypy src, pytest -q green.
Pointers: dsl/motion.py:99,64, pose.py:103,123,155. See the pose extension in DESIGN.md.
Context
The motion DSL animates a single point:
_PathNode.compile_frames/at_time(src/multicam_sim/dsl/motion.py:99,64) withLinearPath/CirclePath. The pose layer builds aPoseTrajectoryfrom per-frame joint dicts (src/multicam_sim/pose.py:123, skeletonSkeleton.coco17()atpose.py:103). What's missing is anything that moves a skeleton: today you must hand-author 17 joint positions per frame.What to do
Add a skeletal-motion layer that generates a
PoseTrajectoryover frames from a small set of parametric gaits driving the COCO-17 joints:walk(translating body with periodic legs/arms),reach(arm extends to a target),wave(forearm oscillation).Reuse the timing model from motion.py (
over(seconds)/at_speed/compile_frames) so gaits share the same fps-aware frame compilation. A root path can translate the whole skeleton while the gait drives joint offsets. Keep it kinematic (no physics); parameters typed and validated.Acceptance criteria
walk(...).to_pose_trajectory("p0")(or equivalent) returns aPoseTrajectorywhoseto_entity()yields all 17 COCO joints for every frame, and whose root translates over the requested duration.ruff,mypy src,pytest -qgreen.Pointers:
dsl/motion.py:99,64,pose.py:103,123,155. See the pose extension in DESIGN.md.