refactor(halcon): single-skill plugin layout → invoke as /halcon (not /halcon:halcon)
Move SKILL.md + references/ scripts/ evals/ from skills/halcon/ up to the plugin root. Per Claude Code plugins-reference, a plugin with SKILL.md at its root and no skills/ subdir is auto-loaded as a single-skill plugin (v2.1.142+), so the invocation name = frontmatter name = halcon → clean /halcon. Bump plugin.json 2.0.0 → 2.0.1 so existing installs receive the update. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,179 @@
|
||||
# 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 | `<install>\bin\x64-win64` (on Windows PATH: `hrun.exe`, `hdevelop.exe`, `hhostid.exe`) |
|
||||
| License dir | `<install>\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 <script.py> [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 <path.hdev> --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 <var>` | 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 <prog.hdev>` — open GUI and auto-run.
|
||||
- `-override_stop <n>` — replace every `stop()` with `wait_seconds(n)` (use `0`).
|
||||
- `-override_wait <n>` — override all `wait_seconds()` durations.
|
||||
- `-external_proc_path "<dir1;dir2>"` — 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 <src> <dst>` — target type from `<dst>` 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 `<install>\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).
|
||||
Reference in New Issue
Block a user