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.
Usage
# from ros2_ws/lib/control/print_loop/
uv run python print_loop.py my_job.yaml
Verify path resolution without touching the robot:
uv run python print_loop.py my_job.yaml --dry-run
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
Copy example_config.yaml and fill in your job parameters:
job_name: mayor_1
slices_dir: /path/to/layer_slices/
bag_output_dir: /path/to/BAGS/
state_dir: ~/PhotogrammetryWAAM/STATE/ERR/
start_layer: 21
end_layer: 43
z_base: 5.0
z_per_layer: 2.0
error_mapping:
smooth: 12
trim_first: 32
trim_last: 32
control:
k_p: 0.25
lower_bounds_corrected_feed: 4.2
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
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
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/)
Files
| 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 |