The object model file

An object's metadata: anchors, articulations, and parts, paired with a URDF.

Every object in a project is two files: the URDF (geometry and joints) and the object_model.yaml (the Zeon metadata that sits on top of it). Both come from the shared mesh database.

You rarely author these by hand; they arrive from the catalog. This page is for reading them, and for the occasional local edit.

Example

A simple object, coldblock_holder.object_model.yaml, in full:

urdf: coldblock_holder.urdf
articulations:
  default:
    description: All joints at rest position
    joints: {}
anchors:
  object:
    parent_link: world
    description: Table placement frame, origin at (+X, +Y, -Z) bbox corner
    link_T_anchor:
      xyz: [0.238, 0.0, 0.0]
      wxyz: [-0.707107, 0.0, 0.0, 0.707107]

A plate has the same structure with far more anchors, one per well. A centrifuge adds parts and a second articulation.

Top-level fields

FieldTypeRequiredDescription
urdfstringyesThe URDF this YAML pairs with, resolved relative to the YAML's own directory.
anchorsmapyesNamed frames on the object that skills can target. Must include object.
articulationsmapyesNamed joint configurations. Must include default.
partsmapnoNamed groups of URDF links (see below).

anchors

An anchor is a named pose attached to a link in the URDF. Skills use anchors to know where to grab, dispense, place, or align.

From coldblock_small:

anchors:
  hole_1:
    parent_link: body
    description: hole 1 xyz location
    link_T_anchor:
      xyz: [-0.0397037, 0.00730662, 0.020485]
      wxyz: [0.986324, -5.82899e-33, -3.07483e-34, 0.164815]
FieldTypeDescription
parent_linkstringThe URDF link this anchor is attached to. Must exist in the URDF.
descriptionstringFree text: what this anchor represents, and which frame convention it follows.
link_T_anchor.xyz[x, y, z]Translation from parent_link to the anchor, in metres.
link_T_anchor.wxyz[w, x, y, z]Quaternion from parent_link to the anchor, scalar first. Normalized on load.

Every object must have an anchor named object, the object's own reference frame, used for placement.

Well anchors on a plate are named for the well itself, in uppercase and with no prefix: wellplate_pcr has anchors A1 through H12, all parented to its body link. Workflows and skills reference them by those names.

Beyond those three required fields, an anchor may carry any combination of four optional blocks:

BlockWhat it is
graspGripper parameters. width is required, in metres. standoff defaults to 0.05, the distance retracted along -Z for the pre-grasp pose. gripper_variant defaults to "stock".
viewpointA spherical camera distribution around the anchor. Angles are written in degrees and converted to radians on load.
prior_weightsA penalty matrix for pose fitting. Written as either a 6-element diagonal shorthand or a symmetric 6×6 nested list.
samplingMulti-start seed configuration for ICP: a covariance matrix in the same two shapes, plus num_samples.

A convention key is also accepted on an anchor and silently ignored; it exists for backward compatibility with older catalog files.

articulations

An articulation is a named joint configuration. Static objects need only a default with no joints:

articulations:
  default:
    description: All joints at rest position
    joints: {}

Movable objects have more. The real centrifuge (platefuge) has a closed and an open state:

articulations:
  default:
    description: Lid closed, rotor at home
    joints:
      lid_joint: 0.0
      rotor_joint: 0.0
  open:
    description: Lid fully open, rotor at home
    joints:
      lid_joint: 1.69
      rotor_joint: 0.0
FieldTypeDescription
descriptionstringFree text.
jointsmapJoint name from the URDF → value. Radians for revolute joints, metres for prismatic.

The default articulation is special: it must list exactly every actuated joint in the URDF. Missing one, or naming a joint that doesn't exist, fails the load. Other articulations may be partial, but may still only name actuated joints.

parts

A part is a named group of URDF links, a way to refer to a piece of an object without naming its links individually. The centrifuge:

parts:
  body:
    links: [body]
    description: Centrifuge base
  lid:
    links: [lid]
    description: Hinged lid
  rotor:
    links: [rotor]
    description: Spinning rotor that carries the microplate
FieldTypeDescription
linkslist of stringsURDF link names belonging to this part. Always a list, even for one link.
descriptionstringHuman-readable label. Also usable as a segmentation prompt.

Parts are optional and many objects skip them entirely. Every link named in a part must exist in the URDF.

Coordinate convention

Three things always hold:

  • XYZ is in metres.
  • Quaternions are [w, x, y, z], scalar first, and are normalized on load.
  • Anchors are expressed in the frame of their parent_link.

The axis triad does not always hold, and nothing enforces it at run time. Which way +Z points depends on what the anchor is for:

Convention+Z is
worldUp. Used for anchors fixed relative to the world, like support surfaces.
tcpThe approach direction into the grasp. The pre-grasp pose retracts along -Z.
cameraThe optical axis, pointing toward the scene. Follows the OpenCV convention.
look_atThe preferred viewing direction, outward from the target surface.

This is why anchor description fields are expected to say which frame they mean. The centrifuge's view_rotor anchor opens its description with "Camera view (OpenCV convention) looking down at the rotor disk, ~25 cm above", naming the convention before anything else. Read the description rather than assuming +Z is up.

When the file is wrong

The object won't load, and the platform validates more than YAML syntax. These all fail:

  • A missing urdf, anchors.object, or articulations.default.
  • An anchor whose parent_link isn't in the URDF.
  • An anchor whose name collides with a URDF link name.
  • A part naming a link that isn't in the URDF.
  • A default articulation that doesn't list exactly the actuated joints.
  • A quaternion with a near-zero norm.

A stale urdf value self-heals: if the named file isn't there, the loader falls back to the sibling URDF with the same basename.

Editing by hand

Three reasons to touch this file:

  1. Add anchors: when the catalog's version lacks one you need. A custom well, a non-standard pour point. The anchors already there stay as the catalog shipped them.
  2. Add articulations: same idea, for a joint configuration the catalog didn't define.
  3. Clarify descriptions: particularly to state an anchor's frame convention.

Leave the URDF alone unless you're rebuilding the geometry. Nearly every edit belongs in the YAML.

See also


Did this page help you?