guidance_rollout — guidance-only rollout (no controller dynamics)
Purpose
Roll the guidance tower forward over the orbit windows without running the controller or robot
dynamics: a cheap coverage/selection oracle. A fake motion state stands in for the plant —
desired CoM/base motion plus the previous step’s desired EE command — so the loop never asks for a
wrench, an integration, or a dynamics cache.
Role in the system
- Module-level functions, not a class — drives an ee_guidance instance (
EEGuidance→ base_guidance → com_guidance) directly. - Called by
analysis/runner.py, which orchestrates BOTH this fast path and the full dynamics path through breve_controller. - Counterpart to breve_controller’s per-step loop: same
add_ee_goal/ FOV-marking calls, but the plant is faked instead of integrated. - Runs the live candidate selection + FOV-marking each step (no offline schedule sweep).
Inputs / Outputs
- In: a
traj(EEGuidance) with atarget_finderenabled,cfg, an orbit-window range (start_idx/end_idx), and optional step / time caps (steps,debug_time_limit). - Out: a
Package(logger=…, log_path=None)— the per-stepStepLogs carrying desired pose, guidance diagnostics, andinspection.area_coverage_frac. No NPZ is written.
Key methods
build_guidance_only_rollout— the loop: resolve windows → walk arclength atdesired_speed→ sample CoM/base/EE goal → mark FOV every stride → log —GNC/guidance/guidance_rollout.py:90guidance_fake_motion_state— fake plant: desired base motion carrying the previous desired EE command —:60append_guidance_payload— assemble + append theStepLog(desired + guidance + coverage) —:72_sample_nominal_com— desired CoM(p, v, a)from arclength progress;v = speed·t̂,a = speed²·κ—:45_resolve_guidance_windows— slice the assembled orbit windows; raises if none / out of range —:16VISIBILITY_MARK_STRIDE = 5— FOV-marking stride (module constant,:13).
Footguns
The motion state is faked, not simulated
The EE pose comes from the previous desired command (
guidance_fake_motion_statecopies
des_prev’sp_e/z_e/R_e/nu_e), never from a dynamics solve. This path studies selection and
coverage in isolation — it is NOT a controller validation and says nothing about tracking error or
the derate stack. (GNC/INSIGHTS.mdguidance_rollout)
Warning
Marking raycast cost is dominated by ~6–14 ms per-call overhead (not ray count), so a short
VISIBILITY_MARK_STRIDEis the real speedup — the camera moves negligibly across a few 100 Hz steps,
so coverage still reaches ~1.0 (legacy used 10). Marking resolution is a separate, orthogonal knob
(camera.resolution, independent ofscoring.pixel_distance_max). (GNC/INSIGHTS.mdguidance_rollout)
Coverage is a traversal artifact, not a tuning knob
area_coverage_fracis driven by how far the CoM sweeps the helix, not by selection. A short run only
covers the southern cap (~0.47) and looks like a plateau; the full helix reaches 1.0. Size the rollout
by progress-to-completion, not step count. (GNC/INSIGHTS.mdCoverage marking)
Pseudocode (one rollout)
windows = resolve(traj, start_idx, end_idx) # raise if none
reset progress to window start; n_steps from orbit_duration / dt (capped)
for k in range(n_steps):
s = min(k·dt · desired_speed, s_end) # arclength clock
progress = interp(s) over the window
des_com = sample CoM (p, v=speed·t̂, a=speed²·κ)
des_base = sample_base_goal_on_interval(des_com)
fake = guidance_fake_motion_state(des_base, des_prev) # carry prev EE command
des = traj.add_ee_goal(fake, des_base, des_prev)
if k % VISIBILITY_MARK_STRIDE == 0 and pose valid:
target_finder.compute_triangle_camera_visibility(CameraPose(des))
append_guidance_payload(logger, des)
des_prev = des.copy()
return Package(logger, log_path=None)
Equations & references
Key equation mirrored from current_sota — the math source of truth; see there for derivations.
Nominal CoM kinematics at step (tangent + centripetal) — §5.2, eq (5.3):
References:
- CoM reference kinematics (
v = speed·t̂,a = speed²·κ) and the arclength clock follow the guidance sheet — see current_sota §5 and com_guidance. - Coverage / pointing metrics (§7): the per-triangle FOV marking it drives lives in target_finder; the versine metric lives in the measurement layer, not here.
Related
ee_guidance · base_guidance · com_guidance · target_finder · breve_controller · guidance_classes · terminology · orbit_com_path