Fix StopExecAtGoal async restart and combined stage order - #22
Draft
cursor[bot] wants to merge 15 commits into
Draft
Fix StopExecAtGoal async restart and combined stage order#22cursor[bot] wants to merge 15 commits into
cursor[bot] wants to merge 15 commits into
Conversation
Point site_url and the README docs links at the new domain, which also gives MkDocs canonical URLs and a sitemap. Material omits Open Graph tags without the optional social plugin, so declare them in a theme override and add robots.txt for crawlers. The hero logo now emits a faint rising ASCII plume driven by a small particle sim. It grows into the hero's existing top padding so it costs no layout height, and the box is sized with max-content so letter-spacing does not push it off-centre. Co-authored-by: Cursor <cursoragent@cursor.com>
gh-deploy force-pushes site/ as the entire gh-pages tree, so the CNAME file GitHub writes when you set a custom domain was being deleted on every deploy, clearing the Pages domain setting. Ship CNAME from docs/ so each build reproduces it at the site root. Co-authored-by: Cursor <cursoragent@cursor.com>
…a demo video. Always extrapolate along the segment instead of snapping to the previous waypoint, and speed up landing first paint (lazy MathJax/js-yaml, overrides under docs/).
Persist c40_start_pose via factory and the Execution UI; State.set_start uses polymorphic copy; BasicSim.reset restores ego/NPCs; publish project.urls for PyPI.
Perception, planning, and control each called world.get_sensor_frame() independently, so a single step() could act on three different world instants. This was silently safe only because BasicSim never mutates state between the fetches; any bridge whose sensors evolve on their own (CARLA in async mode) would let control act on a snapshot that perception never saw, with nothing detecting the mismatch. The tick helpers no longer reach into the world for sensors: the caller owns the snapshot and passes it in. Each executer loop resolves its pacing and module-presence gates first, then fetches at most once, so an idle tick or an unassembled stage costs no fetch at all. In the async executer the atomic unit is one worker iteration, since step() there is a no-op and the stages run in their own threads. Closes #14
Mirrors the community registry: display_name carries the human-readable title so `name` can stay the install-folder and import identifier, and site_url points at a project site. Both are optional and fall back to existing behavior when omitted.
AVLite keeps all spatial data in the world frame: the bridge transforms LiDAR points before they reach SensorFrame, and ego/agent states are world frame already, so no frame graph is needed. An image is the one payload that cannot be pre-transformed that way, being a 2D projection through specific optics at a specific pose. Projecting world-frame LiDAR into the image, the core operation of any fusion strategy, needs the camera intrinsic and the world-to-camera extrinsic at capture time, and neither existed anywhere: SensorFrame carried raw pixels with no geometric metadata, and WorldBridge exposed no calibration surface. CameraParams carries the (3,3) intrinsic K, the (4,4) world_to_camera extrinsic, and the resolution K is valid for; SensorFrame.camera_params holds it for the camera that produced rgb/depth. The extrinsic targets the OpenCV optical frame (x right, y down, z forward) so K applies directly as u = fx*X/Z + cx, and it belongs on the frame rather than in config because it changes every tick as the ego moves. The LiDAR mounting pose is still not needed: the bridge already consumed it. Purely additive. WorldBridge.get_camera_params() defaults to None, so every existing bridge is unchanged, and bridges declaring CAMERA_RGB or CAMERA_DEPTH override it. The capability filter nulls camera_params when both camera toggles are off, so a filtered frame stays self-consistent. Also picks up incidental profile rewrites from local runs: materialized c40_pace_* and c40_execution_tasks defaults, a captured c40_start_pose in default.yaml, and a frenet zoom change. Closes #15 Co-authored-by: Cursor <cursoragent@cursor.com>
update_waypoint_by_wp used `current_wp + 1 % n`, which due to operator precedence left next_wp == len(path) at the last waypoint and crashed plot/step_wp. Clamp next_wp at the end instead. Also correct the quintic SD b-vector so end 1st / start 2nd derivatives match the constraint matrix. Co-authored-by: Majid Khonji <majid-khonji@users.noreply.github.com>
Align only wrote stack PM pose, which GT localization overwrote from the plant on the next tick. Teleport plant ego and sync stack PM, matching VisualizerApp.teleport_ego. Co-authored-by: Majid Khonji <majid-khonji@users.noreply.github.com>
Fix Control Align ego split regression and TrajectoryTracker final-waypoint crash
slice_trajectory_horizon at the last global wp built a single-point TrajectoryTracker; convert_xy_path_to_sd_path assumed next_wp=1 and IndexError'd, crashing VelocityLocalPlanner.replan at path end. Co-authored-by: Majid Khonji <majid-khonji@users.noreply.github.com>
Manual control only moved the plant after the world/stack ego split, leaving pm.ego_vehicle stale; dual-write via apply_world_control. Save Start now snapshots velocity 0 so Reset matches a cold start. Co-authored-by: Majid Khonji <majid-khonji@users.noreply.github.com>
Fix VelocityLocalPlanner end-of-path crash and Control Step ego desync
AsyncThreadedExecuter.step no longer recreates workers while stopped is set, and the Tk execution loop mirrors cooperative stop into exec_running. Combined async planning localizes and perceives before replan on the shared snapshot. Co-authored-by: Majid Khonji <majid-khonji@users.noreply.github.com>
Wait for a localize→perceive→replan subsequence and assert perceive is always followed by replan once the perception stall gate has cleared. Co-authored-by: Majid Khonji <majid-khonji@users.noreply.github.com>
This was referenced Aug 1, 2026
Draft
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bug and impact
GoalArrivalMonitor+StopExecAtGoalTask,executer.stop()setsstoppedand tears down workers, but the Tk_exec_looponly watchesexec_running. The next poll calledAsyncThreadedExecuter.step(), which sawthreads_started=False, recreated workers, and clearedstoppedviastart_threads()— the vehicle kept driving past the goal.Root cause
executer.stopped; GUI and async auto-restart ignored it.Fix
AsyncThreadedExecuter.stepreturns early whilestoppedis set (Start clears the flag)._exec_loopmirrorsexecuter.stoppedinto Stop UI /exec_running.Validation
19 passed.
Not re-reporting open PR #21 (closed-loop
path_s/ Frenet CTE). Removed merged PR #18 from automation memory.