# Invoking HALCON on this machine Everything here is specific to this install. Read `SKILL.md` first for the one-paragraph environment summary; this file is the detailed, copy-paste reference. ## Fixed paths | What | Path | |------|------| | HALCON install | `C:\Users\NAURA\AppData\Local\Programs\MVTec\HALCON-24.11-Progress-Steady` | | Windows binaries | `\bin\x64-win64` (on Windows PATH: `hrun.exe`, `hdevelop.exe`, `hhostid.exe`) | | License dir | `\license\` — monthly `license_eval_halcon_progress_YYYY_MM.dat` | | Project | `C:\workspace\agent-studio\halcon-001` (WSL: `/mnt/c/workspace/agent-studio/halcon-001`) | | venv | `C:\workspace\agent-studio\halcon-001\.venv` (`mvtec-halcon==24111.0.0`) | | venv python (direct) | `C:\workspace\agent-studio\halcon-001\.venv\Scripts\python.exe` | | **uv (use this)** | `/mnt/c/Users/NAURA/.local/bin/uv.exe` | WSL has **no** Linux HALCON runtime. Every path above is Windows-side; drive it from WSL by calling the Windows `.exe` directly. ## Running Python (always via uv) `uv` is not on the WSL PATH — call it by full path. Run from the **project directory** so `uv` auto-detects `.venv` (there is no `pyproject.toml`; uv picks up the local `.venv`): ```bash cd /mnt/c/workspace/agent-studio/halcon-001 /mnt/c/Users/NAURA/.local/bin/uv.exe run python [args...] ``` Tested: `uv.exe run python -c "import halcon as ha; print(ha.get_system('version'))"` → `['24.11']`. If you prefer a shorter command, alias it: `alias uv=/mnt/c/Users/NAURA/.local/bin/uv.exe` (session-local). > Do **not** call `python`/`python3` directly (user rule). Use `uv run`. Direct > `.venv\Scripts\python.exe` also works but `uv` is preferred. ## Method 1 — HDevEngine from Python (preferred for automation) HDevEngine runs the exact `.hdev`/`.hdvp` logic HDevelop would, from Python, so you can pass inputs in and read variables back. Interactive `draw_*` operators are **not** supported here — supply those inputs as parameters (see ROI seam). ### Imports (ground truth from the tested project) ```python from halcon.hdevengine import ( HDevEngine, HDevProcedure, HDevProcedureCall, HDevProgram, HDevProgramCall, HDevEngineError, ) import halcon as ha # plain operators: read_image, list_files, tuple_*, ... ``` ### External procedure (`.hdvp`) ```python eng = HDevEngine() eng.set_procedure_path(r"C:\workspace\agent-studio\halcon-001") # dir holding the .hdvp proc = HDevProcedure.load_external("find_circles") # base name, no extension call = HDevProcedureCall(proc) call.reset() # before each iteration call.set_input_control_param_by_name("ImageFile", r"C:\data\a.png") call.set_input_control_param_by_name("RoiFile", r"C:\...\roi.hobj") call.execute() fit_row = call.get_output_control_param_by_name("FitRow") # -> native list/scalar ``` Wrap `call.execute()` in `try/except HDevEngineError` to skip bad images (the tested `find_circles.hdvp` `throw`s when the circle count != 16; the Python driver catches it and continues). Helper: values come back as scalars or lists — normalize with `list(v) if isinstance(v,(list,tuple)) else [v]`. Use the generic runner instead of hand-writing this: ```bash uv.exe run python .claude/skills/halcon/scripts/run_procedure.py \ --proc-path C:/workspace/agent-studio/halcon-001 \ --proc find_circles \ --set ImageFile=C:/data/a.png --set RoiFile=C:/workspace/agent-studio/halcon-001/roi.hobj \ --get FitRow --get FitCol --get MetroRow --get MetroCol # prints a JSON object of the requested outputs ``` ### Whole program (`.hdev`) ```python program = HDevProgram(r"C:\...\demo_prog.hdev") call = HDevProgramCall(program) call.execute() total = call.get_control_var_by_name("Total") # any control var by name ``` Generic runner: `scripts/run_program.py --program --get Total --get Area`. ## Method 2 — `hrun.exe` (headless batch) Runs a `.hdev` to completion without the GUI. The script must persist its own results (write to file). Launch from WSL with the working dir set so relative paths resolve: ```bash cd /path/to/script/dir "/mnt/c/Users/NAURA/AppData/Local/Programs/MVTec/HALCON-24.11-Progress-Steady/bin/x64-win64/hrun.exe" \ script.hdev | iconv -f GBK -t UTF-8 ``` Useful flags: | Flag | Meaning | |------|---------| | `-c ` | after the run, check a variable; nonzero/true = success | | `-D name=value` | preset a global control variable | | `-d` | dump all control variable values after the run | | `-j` | run procedures JIT-compiled | Gotchas: **no graphics window is opened** — if the script uses `dev_get_window`/`draw_*`, add `dev_open_window` first. Keep an hrun-runnable copy of interactive scripts (the project convention is a `*_hrun.hdev` variant with `dev_open_window` added and `stop()`/`draw_*` removed). ## Method 3 — HDevelop GUI (`hdevelop.exe`) For interactive runs / inspection. There is **no run-and-exit**; the window stays open until closed. `hdevelop.exe` is a GUI app, so **its stdout is not captured from WSL** — for any batch/convert/export use file outputs. - `hdevelop -run ` — open GUI and auto-run. - `-override_stop ` — replace every `stop()` with `wait_seconds(n)` (use `0`). - `-override_wait ` — override all `wait_seconds()` durations. - `-external_proc_path ""` — external procedure search path. Remote debugging: a running application calls `start_debug_server` (HALCON) / enables the debug server, then HDevelop attaches to it. See `hdevelop_users_guide.pdf` ch. 9 (Remote Debugging, p299). ### Convert / export (batch, no interaction — write to a FILE) - Convert: `hdevelop -convert ` — target type from `` extension (`.hdev/.dev/.hdvp/.dvp/.hdpl/.c/.cpp/.cs/.vb/.txt`). Add `-no_msg_box` to suppress GUI error dialogs in batch; `-external_procs_only_interfaces` for interface-only export. - Export project: `hdevelop -export_project` for a CMake C++/C# project. **`-namespace` is REQUIRED** — omitting it fails silently and writes nothing. Prefer absolute paths for input and output folder. Command-line reference: `hdevelop_users_guide.pdf` Appendix C (p323 HDevelop, p326 Hrun). ## The ROI seam (teach once → reuse headless) - **Teach:** `scripts/teach_roi.py` — shows a representative image, human drags a shape, `write_region` saves `roi.hobj`. Draw **tightly** (loose ROI → extra contours → count checks fail). - **Reuse:** in a procedure/program, `read_region(Roi, RoiFile)` then `reduce_domain(Image, Roi, ImageReduced)`. This is what unattended runs call instead of `draw_*`. ## Encoding & path gotchas (recap with fixes) - Chinese/Unicode paths: call the `.exe`/`uv.exe` **directly** from WSL (UTF-16 argv). Never wrap in `cmd.exe /c` (GBK → "syntax incorrect"). - Restore Chinese console output: `... | iconv -f GBK -t UTF-8`. - HALCON internally uses UTF-8 for strings since 18.11 (see `technical_updates.pdf`); the GBK issue is the Windows *console/cmd* layer, not HALCON itself. - HDevEngine: always pass **absolute** paths — no cwd ambiguity. ## License Monthly evaluation `.dat` in `\license\`, updated manually by the user. Stale/expired `.dat` files may linger; HALCON auto-selects a valid one. If you hit a license error, the current month's file is probably missing — **surface this to the user**, don't attempt to bypass it. Host id for a new license: run `hhostid.exe` (also a quick "can the binaries execute?" check). License details: `installation_guide.pdf` ch. 5 (p25).