Skip to content

feat Aruco/Apriltag generator#2037

Open
leshy wants to merge 11 commits into
mainfrom
apriltag-generator
Open

feat Aruco/Apriltag generator#2037
leshy wants to merge 11 commits into
mainfrom
apriltag-generator

Conversation

@leshy
Copy link
Copy Markdown
Contributor

@leshy leshy commented May 9, 2026

Problem

I wanted a nice PDF generator for april tags, quickly vibed.
Size ruler for validation, intelligent packing

getting ready for #2036

Solution

2026-05-09_22-08 2026-05-09_22-07

How to Test

dimos apriltag --help

example outputs

tags_50.pdf

tags_75.pdf

Contributor License Agreement

  • I have read and approved the CLA.

Comment thread dimos/utils/cli/apriltag.py
Comment thread dimos/utils/cli/apriltag.py Outdated
@leshy leshy added the PlzReview label May 9, 2026
@dimensionalOS dimensionalOS deleted a comment from greptile-apps Bot May 9, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 9, 2026

Greptile Summary

Adds a new dimos apriltag CLI command that generates printable AprilTag/ArUco PDFs with a calibration ruler, supporting all standard tag families, configurable page sizes, and a grid packing mode.

  • dimos/utils/cli/apriltag.py: new vector-PDF renderer using ReportLab; draws tag cells as merged rect runs to avoid hairline artefacts, with optional grid packing and centering logic.
  • dimos/robot/cli/dimos.py: thin Typer command that lazily imports the generator, preserving startup performance when the apriltag extra is absent.
  • pyproject.toml / uv.lock: new apriltag extra (opencv-contrib-python==4.10.0.84, reportlab>=4.5.0) correctly replaces the previously flagged pupil-apriltags dependency.

Confidence Score: 4/5

Safe to merge after adding upfront ID-range validation in generate_pdf.

The generator opens the output file via canvas.Canvas before any per-ID bounds check runs. An out-of-range ID raises mid-render, bypasses c.save(), and leaves a created-but-empty file at out_path with no cleanup. The fix is a single pre-flight loop before the Canvas constructor, consistent with the other validations already present.

dimos/utils/cli/apriltag.py — specifically generate_pdf, which needs per-ID bounds validation before Canvas construction.

Important Files Changed

Filename Overview
dimos/utils/cli/apriltag.py New PDF generator for AprilTag/ArUco markers. Core rendering logic is sound, but generate_pdf opens the output file via Canvas before validating individual IDs, meaning an out-of-range ID raises mid-render and leaves a corrupt file behind.
dimos/utils/cli/test_apriltag.py Good coverage of parse_id_spec, grid layout, PDF generation modes, and family variants; no test for the out-of-range ID mid-render scenario.
dimos/robot/cli/dimos.py New apriltag Typer command wires CLI options to generate_pdf; lazy import avoids startup overhead when the extra is absent.
pyproject.toml New apriltag extra correctly declares opencv-contrib-python==4.10.0.84 and reportlab>=4.5.0; types-reportlab added to dev.
.gitignore Adds /apriltags.pdf (default output path) to .gitignore.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    CLI["dimos apriltag CLI\n(dimos.py)"] -->|"parse_id_spec(ids)"| PARSE["ID list\n[0, 1, 2, ...]"]
    PARSE --> GEN["generate_pdf()"]
    GEN -->|validate family/page/size| VAL{Valid?}
    VAL -->|No| ERR1[raise ValueError]
    VAL -->|Yes| CANVAS["canvas.Canvas(out_path)"]
    CANVAS -->|pack=False| SINGLE["_draw_single_page()\nper tag"]
    CANVAS -->|pack=True| LAYOUT["_grid_layout()\ncols x rows"]
    LAYOUT --> PACKED["_draw_packed_page()\nper batch"]
    SINGLE --> TAG["_draw_tag()\n→ _cell_matrix()\n→ cv2.aruco.generateImageMarker"]
    PACKED --> TAG
    SINGLE --> RULER["_draw_ruler()"]
    PACKED --> RULER
    TAG --> SAVE["c.save() → PDF"]
    RULER --> SAVE
Loading

Comments Outside Diff (1)

  1. dimos/utils/cli/apriltag.py, line 330-337 (link)

    P1 Missing upfront ID range validation

    generate_pdf validates family, page size, and geometry before opening the output file, but never checks whether each ID is within the chosen family's valid range. The per-ID guard lives in _cell_matrix (line 157) and raises ValueError mid-render, after canvas.Canvas(str(out_path), ...) has already created the file. The exception bypasses c.save(), leaving an empty/corrupt file at out_path. For example, dimos apriltag --ids 0-600 with --family tag36h11 (max 586) silently creates a zero-byte PDF and exits with a traceback.

    Adding a pre-flight check like if any(i < 0 or i > max_id for i in ids): raise ValueError(...) before line 352 would be consistent with the other validations that precede Canvas construction.

Reviews (6): Last reviewed commit: "Merge branch 'main' into apriltag-genera..." | Re-trigger Greptile

leshy added 2 commits May 9, 2026 22:30
Switch from mypy-ignore to types-reportlab>=4.5.0 (matches reportlab 4.5
in deps), matching the project's pattern for the other ~15 types-* packages.
The stubs immediately caught a real bug — Canvas.setKeywords expects str |
None, not list[str].
@codecov
Copy link
Copy Markdown

codecov Bot commented May 9, 2026

Codecov Report

❌ Patch coverage is 93.54839% with 14 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
dimos/utils/cli/apriltag.py 93.33% 5 Missing and 5 partials ⚠️
dimos/robot/cli/dimos.py 33.33% 4 Missing ⚠️

📢 Thoughts on this report? Let us know!

Copy link
Copy Markdown
Contributor

@mustafab0 mustafab0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this to be a cli utility?

Can be just a regular utility function/script. Wouldn't hurt to have it but also use cases seem not as frequent to warrant a cli tool.

Comment thread dimos/utils/cli/apriltag.py
@mustafab0
Copy link
Copy Markdown
Contributor

Also, we should add support for ArucoTags (a separate family) and also very widely used.

@leshy
Copy link
Copy Markdown
Contributor Author

leshy commented May 10, 2026

Do we need this to be a cli utility?

Can be just a regular utility function/script. Wouldn't hurt to have it but also use cases seem not as frequent to warrant a cli tool.

good point, I kinda like that dimos something can quickly access all tooling we have, but it's a bit stupid to modify a single cli entrypoint file for this, I think maybe dimos something should just delegate to some tool/something.py dir of individual scripts

let us think about it, and let me merge this for now

@leshy leshy changed the title feat Apriltag generator feat Aruco/Apriltag generator May 10, 2026
@leshy
Copy link
Copy Markdown
Contributor Author

leshy commented May 10, 2026

Also, we should add support for ArucoTags (a separate family) and also very widely used.

added

@leshy leshy enabled auto-merge (squash) May 12, 2026 02:54
@mustafab0
Copy link
Copy Markdown
Contributor

--pack argument not working for me. I can only get 1 aruco/April tag on one page.

I run the following dimos apriltag --ids 4 --pack 5

Attached is the output
apriltags.pdf

@leshy
Copy link
Copy Markdown
Contributor Author

leshy commented May 12, 2026

dimos apriltag --ids 4 --pack 5

you selected only id 4 with this command

dimos apriltag --ids 4-10 --pack

also pack is default so you don't need to include it

dimos apriltag --help

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants