Using Multiple Targets
Generally only users with an advanced / unusual setup will need to author their own object spaces as described below. For the majority of use cases, our premade targets and the target selection wizard will automatically account for any gotchas. This will provide you with both valid targets and a well-formed object space file.
MetriCal is designed to work with multiple targets. It doesn't require a surveyed room or exacting measurements; just a few targets in the field of view of each sensor will do. The most confusing part is just telling MetriCal which targets you're using!
Constructing the Object Space
Generating UUIDs
Each target should be assigned a different UUID (v4); this is how MetriCal keeps track of them,
similar to how it tracks components. If you're writing your own object space file, you can generate
a valid UUID using a site like UUID Generator or, if you're on
Linux, using the uuid
command:
$ sudo apt install uuid
$ uuid -v4
b5e4183c-d1ae-11ee-91e7-afd8bef1d15c # <--- a valid UUID
Format
Below, we have an example of a JSON object that describes two markerboards, elegantly named
24e6df7b-b756-4b9c-a719-660d45d796bf
and 7324938d-de4e-4d36-a25b-fbd8e6102026
:
{
"object_spaces": {
"24e6df7b-b756-4b9c-a719-660d45d796bf": {
"descriptor": {
"variances": [0.00004, 0.00004, 0.0004]
},
"detector": {
"markerboard": {
"checker_length": 0.1524,
"corner_height": 5,
"corner_width": 13,
"marker_dictionary": "Aruco4x4_1000",
"marker_id_offset": 0,
"marker_length": 0.1
}
}
},
"7324938d-de4e-4d36-a25b-fbd8e6102026": {
"descriptor": {
"variances": [0.00004, 0.00004, 0.0004]
},
"detector": {
"markerboard": {
"checker_length": 0.1524,
"corner_height": 5,
"corner_width": 13,
"marker_dictionary": "Aruco4x4_1000",
"marker_id_offset": 50,
"marker_length": 0.1
}
}
}
}
}
Differentiating Targets
Different Dictionaries
Careful observers will note that each target in the example above has a different
marker_id_offset
. This indicates the lowest tag ID on the target, with the rest of the tags
increasing sequentially. There should be no overlap in tag IDs between targets; all tags should be
unique. If this assumption is violated, horrible things will happen... mainly, your calibration
results may make absolutely no sense.
This goes for different dictionaries as well. Counterintuitively, users have reported misdetections when using aruco markers with different dictionaries, but identical IDs.
Bottom line: make sure that all of your targets have unique IDs, no matter what dictionary they use.
Circle Target Radii
When using multiple Circle targets, MetriCal requires that the radii of the circles be at least 10cm different from each other. If the radii are too similar, the calibration may fail or produce incorrect results.
Object Relative Extrinsics (OREs)
Since MetriCal runs a full optimization over all components and object spaces, it naturally derives
extrinsics between everything as well. You'll find that the spatial_constraints
field in the JSON
will be populated with the extrinsics between all targets post-calibration.
Just like any other data source, more object spaces mean more OREs; more OREs will add time to the
optimization. It's just more to solve for! If you're not interested in surveying the extrinsics
between object spaces, and are just worried about the component-side calibration, we recommend
setting --disable-ore-inference
:
metrical calibrate --disable-ore-inference ...
It's important to note that this flag's setting shouldn't dramatically change the component-side calibration. The only meaningful difference is that your results will report spatial constraints for all objects and components.
Mutual Construction Groups
Some targets are designed to be used together. For example, our LiDAR circle target is a single piece of hardware, but to MetriCal, it's actually two targets: a markerboard and a circle. We indicate this by assigning them to the same mutual construction group:
{
// The markerboard and circle targets
"object_spaces": {
"24e6df7b-b756-4b9c-a719-660d45d796bf": {
...
"detector": {
"markerboard": {
...
}
}
},
"34e6df7b-b756-4b9c-a719-660d45d796bf": {
...
"detector": {
"circle": {
...
}
}
}
},
// Our mutual construction group, indicating these are one and the same
"mutual_construction_groups": [
["24e6df7b-b756-4b9c-a719-660d45d796bf", "34e6df7b-b756-4b9c-a719-660d45d796bf"]
]
}
Currently, our LiDAR board is the only target that uses this feature, but it's a good example of how MetriCal is designed to be extensible and future-proof.