Skip to content
8 changes: 4 additions & 4 deletions agent_context/topics/atomic-actions/atomic-actions.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,10 +169,10 @@ from the source after adaptation, including near-identical zero-time joins.
Original action joins and intervals are restored before replay so callbacks
retain their source indices. MoveJoint compiles each required joint target as
a separate invocation, preserving its ordered waypoints as action boundaries
through control-grid retiming and spatial expansion. Pour's single
rotation/return segment is protected from spatial perturbation because its
required interior target has no exported
waypoint boundary; its preceding PickUp free phases remain editable. Slide
through control-grid retiming and spatial expansion. Pour exports rotation,
apex dwell and return boundaries; its constrained held-object phases are
protected from spatial perturbation while the preceding PickUp free phases
remain editable. Slide
replans its push from each row's robot/handle observations after pull. Every
Slide reference remains row-local through expansion and replay, including its
start, locked contact path, timing and sampling provenance; shared affordance
Expand Down
59 changes: 38 additions & 21 deletions agent_context/topics/atomic-actions/execution.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,19 +111,15 @@ resample fractional durations.

`MotionPolicy` forwards the explicit strategy unchanged. `ik_interp` rejects
backend `plan_opts`; `motion_gen` always invokes the backend. Segments requesting
`cartesian_linear=True` preserve caller-supplied Cartesian samples and currently
require `ik_interp`, as used by Slide. A planner policy for such a segment
raises instead of silently bypassing backend timing. OpenDoor and PushObject
request straight contact segments only under `ik_interp`; under `motion_gen`
they send each contact segment's endpoint to the backend.
Press supports both strategies: `ik_interp` preserves the contact/press/retract
Cartesian samples; `motion_gen` sends approach/contact/press/retract targets to
the selected backend in one ordered request, then aligns the three internal
boundaries chronologically on native samples.
`cartesian_linear=True` preserve caller-supplied Cartesian samples and require
`ik_interp`. PushObject, Slide, Press, OpenDoor and Twist fail closed under
`motion_gen`: endpoint-only backend planning cannot certify their straight-line
or articulated contact paths, and the action must not silently fall back to IK.
Each phase retains its native time profile while retiming to the control grid;
requested phase counts are minima, so long phases expand rather than speeding
up. Press validates its final assembled arm samples through a capable backend
and rejects collision-aware backend paths without that validation capability.
up. Composite phases use terminal holds to align lengths; they do not
distance-resample a longer native plan back into the requested count. Press
validates its final assembled arm samples through a capable backend.
Exact validation needs poses for every configured dynamic obstacle. Missing
poses fail the plan with diagnostics; they never permit unchecked success.
`dynamic_collision_mode=off` forbids filling missing poses from the scene, so
Expand All @@ -135,11 +131,28 @@ endpoints, or a fallback to IK.
Primitive planner results are explicitly retimed before their controlled-joint
paths are embedded into a full-robot `TimedTrajectory`. Off-grid duration rounds
up to a whole control interval, qvel is recomputed from the executed samples,
and now-invalid native acceleration samples are discarded. Composite primitives
that combine planner output with fixed-length hand or multi-part phases may
also resample the planner's position path to the phase count before assembly;
the final composite trajectory then derives its velocity targets from the
assembled positions and timing.
and now-invalid native acceleration samples are discarded. Default `ik_interp`
policies use rest-to-rest minimum-jerk joint segments. Omitted velocity follows
the Robot's ordered per-joint caps, while an explicit scalar request is
intersected with those caps; acceleration remains a planner-owned scalar budget.
`sample_count` remains a lower bound. Exact Cartesian
paths use one global minimum-jerk progress law and batch IK for every expanded
sample, so enforcing limits does not replace contact geometry with joint-space
interpolation. Articulated paths whose geometry cannot be reconstructed from
Cartesian chords provide an exact normalized-progress sampler; OpenDoor and
Twist regenerate every expanded pose around their configured external axis.
CoordinatedPickment
uses sparse IK only as a seed, then batch-projects every shared-object waypoint
for both arms so joint interpolation cannot break the closed chain.

HandOver plans the two arm assignments from independent phase-length maps. A
mixed batch terminal-pads corresponding phases to their shared maximum before
selecting rows, which preserves handover boundaries when one assignment needs
more retimed samples. It holds both closed hands for `hold_steps` before source
release. Pour
splits rotation and return at the poured pose and inserts a physical-time dwell.
Actions preserving an existing grasp command the observed hand state until an
explicit release; free-hand approaches interpolate from the observed state.

Tracking recovery is separate from task-level semantic recovery:

Expand All @@ -154,14 +167,18 @@ Tracking recovery is separate from task-level semantic recovery:
default) or `zero` (explicit position-only control).
Configured execution policies decode the same field under `motion`.
`AtomicAction.build_plan` derives missing velocities after composite skills
have assembled their final full-robot positions and timing. Stationary joint
intervals and terminal settling commands use zero velocity; failed rows remain
held. MoveHeldObject and Pour preserve native arm derivatives when embedding
unchanged timed planner output. Differentiation does not retime composite
paths to enforce robot velocity/acceleration limits.
have assembled their final full-robot positions and timing. The first command,
both ends of every stationary joint interval, and terminal settling commands
use zero velocity; failed rows remain held.

`SimulationExecutionAdapter` always clears absent velocity references to zero;
it never substitutes observed velocities or depends on peer active masks.
It writes position and velocity targets through the existing `set_qpos` and
`set_qvel` APIs. Inactive rows hold observed positions with zero target velocity.
A nonzero damping gain is needed for the velocity error to contribute to tracking.
Active rows in one runtime frame must share one positive hold duration; zero is
reserved for terminal padding. The runner rejects mismatched durations instead
of choosing the maximum. Simulation control periods and sleeps must be integer
multiples of `physics_dt`; the adapter never rounds a motion-command request
upward. Passive runner polling, including physical-effect waits, rounds the
configured minimum cycle up to an advertised clock quantum before sleeping.
13 changes: 9 additions & 4 deletions agent_context/topics/ik-solvers/ik-solvers.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,11 @@ transforms over those axes without materializing per-target copies.

Concrete `get_ik()` APIs retain their own candidate and failure shapes. Pink
returns `(N, 1, dof)`. Pytorch's normal nearest path retains a singleton
candidate axis and its all-solutions path returns `(N, samples, dof)`, but its
early all-targets-failed path returns `(N, dof)`. Do not squeeze blindly or
assume all-solutions masks share one universal shape. Preserve batch size one;
prefer the batch adapter when only the nearest solution is needed.
candidate axis when successful and returns `(N, dof)` when every target fails.
Its all-solutions path always returns validity `(N, samples)` and positions
`(N, samples, dof)`, including the early all-targets-failed path. Do not squeeze
blindly or assume all-solutions masks share one universal shape. Preserve batch
size one; prefer the batch adapter when only the nearest solution is needed.

## Continuous batch IK

Expand All @@ -71,6 +72,10 @@ A supporting solver supplies all-candidate IK and `_select_continuous_ik_path`.
The hook consumes candidates `(B, N, K, dof)`, validity `(B, N, K)` and initial
seeds `(B, dof)`, returning validity `(B, N)` and a path `(B, N, dof)`.
Candidate count `K` belongs to the solver; OPW implements this capability.
Pytorch also implements it by choosing each valid multi-start candidate nearest
to the preceding selected posture under `ik_nearest_weight`; this continuous
path selection is independent of its ordinary per-target
`ik_solution_selection` policy.

## Computation and state ownership

Expand Down
6 changes: 4 additions & 2 deletions agent_context/topics/motion-planning/motion-planning.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,10 @@ Whenever positions exist, `dt` contains per-sample arrival intervals `(B, N)`;
Timing does not alter simulator `physics_dt`.

`MotionGenOptions.strategy` selects the timing owner. `motion_gen` invokes the
backend; `ik_interp` requires explicit start/count/dt, rejects backend options
and derivative limits, and supports joint/EEF moves. Required Cartesian IK
backend; `ik_interp` requires explicit start/count/dt, rejects backend-specific
options, consumes optional scalar velocity/acceleration limits, and supports
joint/EEF moves. Limited interpolation uses minimum-jerk rest-to-rest segments
and treats the requested count as a lower bound. Required Cartesian IK
failures fail the row; waypoints are never discarded to salvage success.
Unsupported routes raise instead of silently selecting another strategy.

Expand Down
15 changes: 14 additions & 1 deletion agent_context/topics/motion-planning/planner-details.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,12 @@ Unconfirmed starts and later poses still require successful IK and FK consistenc
`interpolate_trajectory()` raises
on any failed row; `generate()` carries per-row success in a normalized
`PlanResult`. Fixed Cartesian sample preservation requires explicit `ik_interp`;
it is not an implicit fallback from backend planning.
it is not an implicit fallback from backend planning. When velocity or
acceleration limits expand such a path, `MotionGenOptions.cartesian_path_sampler`
may regenerate poses from normalized minimum-jerk progress. The callback must
end at the requested target, begin within the active IK solver's accepted pose
tolerance, and preserve the batch, dtype, and device. Without it, the facade
resamples the caller-supplied Cartesian polyline.

Preserve these coupled result rules in `motion_generator.py`:

Expand Down Expand Up @@ -115,6 +120,14 @@ row's duration up to the destination clock, samples uniform source-path phase,
and recomputes qvel with zero first/last-valid and padded-hold velocities.
Source `PlanResult.dt` remains planner timing.

`compute/trajectory/interpolation.py::interpolate_minimum_jerk()` expands joint
keyframes onto a fixed control interval while preserving every keyframe. The
requested sample count is a minimum; per-segment counts grow to satisfy scalar
or ordered per-joint velocity and acceleration limits, and spare samples are
distributed by joint displacement rather than equally across unequal moves.
The emitted dtype is checked on the destination grid so float32 cancellation
cannot silently violate those derivative limits.

`motion/execution.py::play_joint_trajectory()` requires `control_dt` to be an
integer multiple of `physics_dt` and advances that many unchanged substeps.
Position-plus-velocity command mode is opt-in. Gym execution instead owns its
Expand Down
7 changes: 7 additions & 0 deletions agent_context/topics/task-programs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,13 @@ Ownership is explicit rather than a generic deep merge:
effect-assurance policy. Planner collision objects are attached from the
selected live scene and are not serialized in the policy.

Configured `motion` policies accept optional finite, strictly positive
`velocity_limit` and `acceleration_limit` values. Configured Pour action options
accept a finite, non-negative `dwell_duration`; unknown timing keys still fail
the closed-field decoder. Omitting `velocity_limit` preserves the Robot's
ordered per-joint speed caps; an explicit scalar request is intersected with
those caps rather than replacing them.

Grasp generators select toolkit-owned geometry with a string `model` ID;
an inline mapping is a custom calibration and its `model_id` does not trigger
catalog lookup. The catalog is owned by
Expand Down
Loading