-
Notifications
You must be signed in to change notification settings - Fork 618
Ivan/feat/cameracalibrator go2 #2123
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 65 commits
Commits
Show all changes
71 commits
Select commit
Hold shift + click to select a range
c7b15b5
first pass on apriltag generator
leshy 9c92334
good spacing
leshy 7b3f657
Merge branch 'main' into apriltag-generator
leshy 43047b9
fixes, tests
leshy a684f01
Merge branch 'apriltag-generator' of github.com:dimensionalOS/dimos i…
leshy 40087f5
real reportlab type stubs
leshy a1edd38
Merge branch 'main' into apriltag-generator
leshy 795883f
impl_init: AprilTag marker 3D detector #2036
bogwi 6ccca17
add aruco families and letter page size to apriltag generator
leshy 671d475
Merge remote-tracking branch 'origin/main' into apriltag-generator
leshy 8deedbe
add: new integ test; small improv
bogwi dc1ed54
Merge feat/2036-apriltag-marker into feat/2036-with-2037 (#2037 integ…
bogwi 0f0f99e
Pin family and size to `DICT_APRILTAG_36h11` in `MarkerTfModuleConfig`
bogwi 9d38d4f
Fail loud at import time when contrib is missing
bogwi 8fd2138
CI: minimal aruco smoke test
bogwi e313790
Create the package skeleton to ship `dimos cameracalibrate` cli
bogwi fd83e02
Pure function: serialize calibration to ROS YAML
bogwi c93aa07
Test: YAML round-trip
bogwi c796f38
Pure function: corner detection on a single frame
bogwi 0d7f2fc
Pure function: calibrate from a list of frames
bogwi 3779de1
Test: synthetic calibration
bogwi 3b52b6d
Frame source: image folder
bogwi 4216540
Frame source: live webcam capture (interactive)
bogwi 3921024
Typer command + `dimos cameracalibrate` registration
bogwi e27e032
Save preview overlay PNG next to YAML
bogwi 10df129
Lint and CI guard
bogwi a3c6c72
Add Camera calibration runbook
bogwi a158641
Add test: calib YAML works DimosCameraInfo.from_yaml(str(out))
bogwi 51e4560
Write "Capture practice" section
bogwi e4b27b3
Write "Run `dimos cameracalibrate`" section
bogwi b8d81ac
Update cameracalibrate on e2e test; add debug logger
bogwi b96788d
Write "Verify the YAML" section && Cross-link runbook from code
bogwi a58be3a
Static TF publisher helper
bogwi 4ba5f11
Wire `Webcam` -> `CameraModule`; fixed bug in topic.py::def on_msg(ch…
bogwi a656949
Wire `MarkerTfModule` into desk blueprint
bogwi 8d46b52
rename assets to fixtures
bogwi e3e71a4
add fixtures for apriltag detection verification
bogwi d09783e
add new testing
bogwi 3a4edcd
cleanup
bogwi 86ae3a4
Merge upstream/main into feat/2036-with-2037
bogwi 1f5efa7
Move manual frame camera stub under fiducial/testing for worker pickling
bogwi f48184f
fix: ci failures
bogwi 62c737e
[autofix.ci] apply automated fixes
autofix-ci[bot] 5633f70
fix: test_marker_tf_deploy_lcm_tf_integration
bogwi 0bb720c
fix: paul's cmt
bogwi 3efdd41
add limit in camera read loop
bogwi 9ef0649
Ignore layout.tags for false positive; ruff
bogwi e299d1c
add `except (ValueError, RuntimeError)` to collect `RuntimeError` re…
bogwi 4570f82
optimize: boost cameracalibrate.py performance; various improvs
bogwi 168f99d
Merge upstream/main into feat/2036-with-2037
bogwi cc50ce3
camera calibrator supports LCM topics
leshy 2d2ce4a
new go2 distortion model for calibrator, new go2 calibration
leshy eeea606
go2 marker blueprint
leshy fd066db
identity transform from tf service
leshy 1355edc
tf module fisheye models
leshy 3b358ca
time is now
leshy 573e291
Merge remote-tracking branch 'origin/main' into ivan/feat/cameracalib…
leshy 0c07236
markers_go2 recording
leshy 5d815db
topic echo fix
leshy 4c9a921
tf module WARN
leshy bbcf3a9
removed refernece to base_link from marker module
leshy 13818f7
type fixes
leshy 52e08ff
small types/tests cleanup
leshy 4ad1766
tf.get kwargs-safe warning + jpeg_shm test skip on missing libturbojpeg
leshy 9c74095
mini fix
leshy e47ab84
small fix
leshy aa27c95
better resources import
leshy 8c53501
Merge branch 'main' into ivan/feat/cameracalibrator_go2
leshy 82eb779
tf fix
leshy 65dfeea
Merge branch 'ivan/feat/cameracalibrator_go2' of github.com:dimension…
leshy 77c8222
Merge branch 'main' into ivan/feat/cameracalibrator_go2
leshy File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Git LFS file not shown
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,171 @@ | ||
| # Copyright 2025-2026 Dimensional Inc. | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
|
|
||
| """Pubsub URI registry: ``"<proto>:<topic>[#<msg_type>]"`` -> started ``PubSubTransport``. | ||
|
|
||
| Maps user-facing protocol names onto the concrete transport classes in | ||
| ``dimos.core.transport``. Used by CLIs and config files that need to accept | ||
| a single string describing both how and where to subscribe. | ||
|
|
||
| URI grammar:: | ||
|
|
||
| <proto>:<topic>[#<msg_type>] | ||
|
|
||
| - ``<proto>``: registry key, e.g. ``lcm``, ``jpeg_lcm``, ``plcm``, ``pshm``, | ||
| ``shm``, ``jpeg_shm``. | ||
| - ``<topic>``: channel/key, passed verbatim to the transport constructor. | ||
| - ``<msg_type>``: optional ``module.ClassName`` resolved via | ||
| ``dimos.msgs.helpers.resolve_msg_type`` (e.g. ``sensor_msgs.Image``). | ||
|
|
||
| Typed protos (``lcm``, ``jpeg_lcm``) require a message type — either from the | ||
| ``#``-suffix or the ``msg_type`` kwarg. Pickled / self-describing protos | ||
| (``plcm``, ``pshm``, ``shm``, ``jpeg_shm``) don't. | ||
| """ | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| from typing import TYPE_CHECKING, Any | ||
|
|
||
| if TYPE_CHECKING: | ||
| from collections.abc import Callable | ||
|
|
||
| from dimos.core.transport import PubSubTransport | ||
|
|
||
|
|
||
| def _make_lcm(topic: str, msg_type: type | None) -> Any: | ||
| if msg_type is None: | ||
| raise ValueError("proto 'lcm' requires a message type (URI '#suffix' or msg_type kwarg)") | ||
| from dimos.core.transport import LCMTransport | ||
|
|
||
| return LCMTransport(topic, msg_type) | ||
|
|
||
|
|
||
| def _make_jpeg_lcm(topic: str, msg_type: type | None) -> Any: | ||
| if msg_type is None: | ||
| raise ValueError( | ||
| "proto 'jpeg_lcm' requires a message type (URI '#suffix' or msg_type kwarg)" | ||
| ) | ||
| from dimos.core.transport import JpegLcmTransport | ||
|
|
||
| return JpegLcmTransport(topic, msg_type) | ||
|
|
||
|
|
||
| def _make_plcm(topic: str, msg_type: type | None) -> Any: | ||
| # pickled LCM: receivers unpickle Python objects, no type registration needed. | ||
| from dimos.core.transport import pLCMTransport | ||
|
|
||
| return pLCMTransport(topic) | ||
|
|
||
|
|
||
| def _make_pshm(topic: str, msg_type: type | None) -> Any: | ||
| # pickled shared memory: same shape as plcm but over /dev/shm. | ||
| from dimos.core.transport import pSHMTransport | ||
|
|
||
| return pSHMTransport(topic) | ||
|
|
||
|
|
||
| def _make_shm(topic: str, msg_type: type | None) -> Any: | ||
| # raw-bytes shared memory: subscribers receive bytes; caller decodes. | ||
| from dimos.core.transport import SHMTransport | ||
|
|
||
| return SHMTransport(topic) | ||
|
|
||
|
|
||
| def _make_jpeg_shm(topic: str, msg_type: type | None) -> Any: | ||
| # JPEG-encoded shared memory: subscribers receive decoded Image objects. | ||
| from dimos.core.transport import JpegShmTransport | ||
|
|
||
| return JpegShmTransport(topic) | ||
|
|
||
|
|
||
| _REGISTRY: dict[str, Callable[[str, type | None], Any]] = { | ||
| "lcm": _make_lcm, | ||
| "jpeg_lcm": _make_jpeg_lcm, | ||
| "plcm": _make_plcm, | ||
| "pshm": _make_pshm, | ||
| "shm": _make_shm, | ||
| "jpeg_shm": _make_jpeg_shm, | ||
| } | ||
|
|
||
|
|
||
| def supported_protos() -> list[str]: | ||
| """Return the sorted list of registered proto names.""" | ||
| return sorted(_REGISTRY.keys()) | ||
|
|
||
|
|
||
| def parse_pubsub_uri(uri: str) -> tuple[str, str, str | None]: | ||
| """Split ``"<proto>:<topic>[#<msg_type>]"`` into its three parts. | ||
|
|
||
| Returns ``(proto, topic, msg_type_name_or_None)``. Raises ``ValueError`` | ||
| on malformed input or an unknown proto. | ||
| """ | ||
| if ":" not in uri: | ||
| raise ValueError( | ||
| f"Invalid pubsub URI {uri!r}: expected '<proto>:<topic>'. " | ||
| f"Supported protos: {supported_protos()}" | ||
| ) | ||
| proto, rest = uri.split(":", 1) | ||
| if not proto: | ||
| raise ValueError(f"Invalid pubsub URI {uri!r}: empty proto") | ||
| if proto not in _REGISTRY: | ||
| raise ValueError(f"Unsupported proto {proto!r}; supported: {supported_protos()}") | ||
| msg_type_name: str | None | ||
| if "#" in rest: | ||
| topic, suffix = rest.split("#", 1) | ||
| msg_type_name = suffix or None | ||
| else: | ||
| topic, msg_type_name = rest, None | ||
| if not topic: | ||
| raise ValueError(f"Invalid pubsub URI {uri!r}: empty topic") | ||
| return proto, topic, msg_type_name | ||
|
|
||
|
|
||
| def make_pubsub_transport( | ||
| uri: str, | ||
| *, | ||
| msg_type: type | None = None, | ||
| ) -> PubSubTransport[Any]: | ||
| """Build a ``PubSubTransport`` from a URI (does not call ``start()``). | ||
|
|
||
| The ``#``-suffix in the URI wins over the ``msg_type`` kwarg if both are | ||
| present. Pickled / self-describing protos ignore ``msg_type``. | ||
| """ | ||
| proto, topic, msg_type_name = parse_pubsub_uri(uri) | ||
| resolved = msg_type | ||
| if msg_type_name is not None: | ||
| from dimos.msgs.helpers import resolve_msg_type | ||
|
|
||
| resolved = resolve_msg_type(msg_type_name) | ||
| if resolved is None: | ||
| raise ValueError(f"Could not resolve message type {msg_type_name!r} from URI {uri!r}") | ||
| transport: PubSubTransport[Any] = _REGISTRY[proto](topic, resolved) | ||
| return transport | ||
|
|
||
|
|
||
| def subscribe_pubsub_uri( | ||
| uri: str, | ||
| callback: Callable[[Any], Any], | ||
| *, | ||
| msg_type: type | None = None, | ||
| ) -> tuple[PubSubTransport[Any], Callable[[], None]]: | ||
| """Construct + start + subscribe in one step. | ||
|
|
||
| Returns ``(transport, unsubscribe)``. The caller is responsible for | ||
| calling ``transport.stop()`` (and ``unsubscribe()`` if it needs to stop | ||
| receiving messages before the transport itself stops). | ||
| """ | ||
| transport = make_pubsub_transport(uri, msg_type=msg_type) | ||
| transport.start() | ||
| unsub = transport.subscribe(callback) | ||
| return transport, unsub |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.