print_loop
print_loop
Section titled “print_loop”-- The closed-loop WAAM print cycle, orchestrated.print_loop :: PrintJobConfig -> IO ()-- For each layer N in [start..end]:-- 1. record_bag + execute_gcode :: GCode -> IO BagDirectory-- 2. map_surface_error :: BagDirectory -> (HTML, CSV)-- 3. proportional_correction :: (CSV, GCode_next) -> GCode_corrected-- [operator inspects HTML, confirms]-- loop.Interactive CLI orchestrator that drives the three-step WAAM print loop from a single YAML config file. Eliminates manual path copy-pasting between steps; the only human input required is a visual sanity-check of the error-map plot before each subsequent layer prints.
# from ros2_ws/lib/control/print_loop/uv run python print_loop.py my_job.yamlVerify path resolution without touching the robot:
uv run python print_loop.py my_job.yaml --dry-runWhat it automates
Section titled “What it automates”| Manual step you used to do | Now handled by |
|---|---|
Compose ros2 bag record with ~10 topic flags | Config YAML topics list |
| Copy-paste long gcode paths | Auto-resolved from slices_dir using *_layers_{N}-{N}_1layers.gcode naming convention |
| Remember bag dir name, feed to Step 2 | Derived: {bag_output_dir}/L{N}_Z{nominal_z} |
| Derive CSV path from HTML output | Derived: {state_dir}/L{N}.csv |
| Increment layer numbers, compute nominal Z | nominal_z(layer) = z_base + layer * z_per_layer |
Run Step 2 + Step 3 as manual uv run invocations | Subprocess orchestration with error handling |
Config
Section titled “Config”Copy example_config.yaml and fill in your job parameters:
job_name: mayor_1slices_dir: /path/to/layer_slices/bag_output_dir: /path/to/BAGS/state_dir: ~/PhotogrammetryWAAM/STATE/ERR/start_layer: 21end_layer: 43z_base: 5.0z_per_layer: 2.0
error_mapping: smooth: 12 trim_first: 32 trim_last: 32
control: k_p: 0.25 lower_bounds_corrected_feed: 4.2Operator interaction
Section titled “Operator interaction”Per layer, the orchestrator runs Steps 1-2 automatically, then:
Error map: ~/STATE/ERR/L21.html Opening in browser...
Review the error map. Continue? [Y/n/q]On confirmation it runs Step 3 and prompts once more before printing the
next layer. Answering q at any prompt saves state and exits; rerunning
the same command resumes from where you left off.
Resumable state
Section titled “Resumable state”Progress is persisted to {state_dir}/{job_name}_state.json after every
step. If the process is interrupted (Ctrl-C, SSH drop, power loss),
relaunch the same command and it picks up at the last incomplete step.
Architecture
Section titled “Architecture”The orchestrator calls the existing scripts as subprocesses (uv run
/ ros2 run) rather than importing them, keeping the uv environments
independent:
- Step 1:
ros2 bag record(Popen + SIGINT) andros2 run gcode_file_parser_client - Step 2:
uv run python map_surface_err_to_xyz_pos.py(inshared/rosbag_parser/) - Step 3:
uv run python simple_proportional.py(inros2_ws/lib/control/simple_proportional/)
| File | Purpose |
|---|---|
print_loop.py | Main orchestrator CLI |
models.py | PrintJobConfig, LayerState, PrintLoopState (Pydantic) |
example_config.yaml | Template job configuration |
tests/test_print_loop.py | Config loading, path resolution, state persistence |