Multiple Targets
Target Configuration
MetriCal works with multiple calibration targets simultaneously. You don't need a specially measured room or precise target positioning—just a few targets visible to each sensor is sufficient.
For most users, our premade targets combined with the target selection wizard will handle all technical details automatically. This approach provides you with both suitable targets and a correctly formatted object space file.
Custom object space configuration is typically only necessary for specialized setups or non-standard calibration requirements. The sections below explain how to configure custom object spaces if your application requires it.
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:
In a mutual construction group, one target is designated as the "parent," while the other targets are defined relative to this parent. The relative position and orientation of each target in the group are specified using a translation and rotation (Quaternion). This setup allows MetriCal to understand that these targets are part of a single physical entity.
For targets that are physically constructed together (such as our LiDAR circle target), the transform is often just a simple offset in the XY plane. In this example, the offset is a translation between the visual target's origin (the top-left corner of the markerboard) and the LiDAR target's origin (the center of the circle).
This feature is also used to support consolidated object spaces wherein multiple distinct targets with
known relative transforms are treated as a single target. This additional information can help MetriCal
in challenging scenarios. In that case, the relative transforms are usually non-trivial and determined by
a surveying process. See the consolidate-object-spaces
command and the narrow field-of-view camera guide for more
details.
{
// 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": "parent",
"34e6df7b-b756-4b9c-a719-660d45d796bf": {
"parent_from_object": {
"translation": [
0.37,
0.37,
0.0
],
"rotation": [
0.0,
0.0,
0.0,
1.0
]
}
}
}
]
}