Rigs_CreateRig
const url = 'https://dev-api.qualiastudios.dev/v1/accounts/example/rigs';const options = { method: 'POST', headers: {'X-API-Key': '<X-API-Key>', 'Content-Type': 'application/json'}, body: '{"name":"example","displayName":"example","key":"example","kind":"KIND_UNSPECIFIED","robot":"example","mounts":[{"side":"SIDE_UNSPECIFIED","trackerPose":{"xyz":[1],"rpy":[1]},"openAngle":1,"closedAngle":1}],"etag":"example","gripper":"example"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://dev-api.qualiastudios.dev/v1/accounts/example/rigs \ --header 'Content-Type: application/json' \ --header 'X-API-Key: <X-API-Key>' \ --data '{ "name": "example", "displayName": "example", "key": "example", "kind": "KIND_UNSPECIFIED", "robot": "example", "mounts": [ { "side": "SIDE_UNSPECIFIED", "trackerPose": { "xyz": [ 1 ], "rpy": [ 1 ] }, "openAngle": 1, "closedAngle": 1 } ], "etag": "example", "gripper": "example" }'Registers a rig. A gripper is INVALID_ARGUMENT here: set it with
UpdateRig.
Authorizations
Section titled “Authorizations ”Parameters
Section titled “ Parameters ”Path Parameters
Section titled “Path Parameters ”The account id.
Query Parameters
Section titled “Query Parameters ”Idempotency key (AIP-155): a retry with the same id within 24 hours returns the first call’s result instead of creating a second one.
Request Body required
Section titled “Request Body required ”A capture rig: what episodes are recorded with. An arm rig drives a fleet
robot; a handheld (UMI) rig carries trackers whose fixed mount to each
gripper root belongs here, not to any robot (QUA-2337). Episodes name their
rig by key (Episode.rig).
The UMI handheld rig (key umi-handheld) is built in: every account lists
and reads it under its own name, and nobody edits or deletes it
(FAILED_PRECONDITION). An account rig with the same key takes its place, so
an account records its own calibration of its UMI pair by creating one, or
by setting a gripper on the built-in (UpdateRig), which makes that copy
itself. An account may delete its copy; it then lists the built-in again,
uncalibrated.
A handheld rig may carry the TCP calibration of its trackers (calibration)
and the design of its gripper (gripper, a Robot of kind GRIPPER): the
gripper’s URDF, with the calibration saying where on it the TCP is. Both are
a record on the rig: importing or replacing either changes no dataset.
Ingest reads only the calibration’s tracker_to_tcp, filename and
derive_date; the gripper design and the calibration’s end-effector fields
(ee_link, ee_to_tcp) are for display.
Served by fleet.
object
Accounts/{account}/rigs/{rig}
Human name.
What recordings carry as their rig id (meta/ingest.toml, LeRobot robot_type). Unique per account; 1 to 128 letters, digits, ’.’, ’_’, ’:’ or ’-’, starting with a letter or digit. Fixed at creation.
Arm or handheld.
Arm rig: accounts/{account}/robots/{robot} it drives, so its episodes get forward kinematics on that robot’s model. A robot (not a gripper design) of the rig’s own account; deleting the robot clears it. A handheld rig has none.
Handheld rig: one mount per tracked hand, at least one, at most one per side. An arm rig has none.
One tracker’s fixed mount.
object
Which hand.
The fixed mount: the tracker’s pose in its gripper root’s frame (x along
the fingers, y the way the jaw opens, z along the hinge): xyz in metres
and rpy in radians like every Transform. meta/ingest.toml’s
[rig.mount.
object
X, y, z in metres.
Roll, pitch, yaw in radians.
The gripper’s closure calibration: the raw angle fully open.
The raw angle shut.
When it was created.
When it last changed.
Sent back on UpdateRig.
Handheld rig: where each tracker’s TCP is, from the last ImportCalibration. Unset until one is imported, and never set on the built-in rig. Not editable through UpdateRig.
object
The uploaded file’s name, e.g. “tcp_calibration.json”.
When the calibration was made, “YYYY-MM-DD”: the leading date of the
file’s calibrated or else its derived text. Empty when the file gives
none.
Both hands, left then right.
One hand’s transform.
object
Which hand.
The TCP’s pose in the tracker’s frame: xyz in metres and rpy in radians (URDF convention, extrinsic XYZ), the file’s rotation matrix converted. A rotation whose pitch is within a hair of +-90 degrees has no unique roll and yaw; it is stored with roll 0. (— api-linter: core::0140::prepositions=disabled aip.dev/not-precedent: a transform is named by its direction, as the calibration file’s own controller_to_tcp is. —)
object
X, y, z in metres.
Roll, pitch, yaw in radians.
The same TCP in the frame of the gripper design’s ee_link for this
hand, in the form of tracker_to_tcp (so the same pitch limit). Display
only. Set with ee_link or not at all, and only when it composes with
the file’s controller_to_ee to the file’s controller_to_tcp, which is
what makes the TCP drawn the TCP used.
(— api-linter: core::0140::prepositions=disabled
aip.dev/not-precedent: a transform is named by its direction, as
the calibration file’s own ee_to_tcp is. —)
object
X, y, z in metres.
Roll, pitch, yaw in radians.
The link of the rig’s gripper design that Hand.ee_to_tcp is a pose in,
with {side} for “left” or “right” (the gripper joint’s convention in
RobotModel.Gripper), e.g. “openarm_{side}_ee_base_link”. Read from the
file’s own description of its end-effector frame. Empty when the file
names none, lacks the end-effector poses, or they disagree with its
controller_to_tcp (then no ee_to_tcp is set either). Display only.
ee_to_tcp is drawn in this link’s own frame, which must be the plain
end-effector frame the file means. An export whose link sits elsewhere
draws the TCP off by the difference: an OpenArm exported with the xacro
default collapse_internal_empty_links puts openarm_
Whether this is a built-in rig (the UMI handheld rig): read only, the same in every account. Setting a gripper on one makes the account’s own copy.
Handheld rig: accounts/{account}/robots/{robot} of kind GRIPPER, the design of its gripper (a URDF, imported as a robot model). A design of the rig’s own account; deleting the design clears it. A design lives in one workspace, like any robot, and a rig in none, so this may name a design of any workspace of the account, and Robots.GetRobot finds it only from that workspace. Set with UpdateRig (CreateRig refuses it); on the built-in rig that makes the account’s own copy, uncalibrated. An arm rig has none; it names a robot.
Responses
Section titled “ Responses ”OK
A capture rig: what episodes are recorded with. An arm rig drives a fleet
robot; a handheld (UMI) rig carries trackers whose fixed mount to each
gripper root belongs here, not to any robot (QUA-2337). Episodes name their
rig by key (Episode.rig).
The UMI handheld rig (key umi-handheld) is built in: every account lists
and reads it under its own name, and nobody edits or deletes it
(FAILED_PRECONDITION). An account rig with the same key takes its place, so
an account records its own calibration of its UMI pair by creating one, or
by setting a gripper on the built-in (UpdateRig), which makes that copy
itself. An account may delete its copy; it then lists the built-in again,
uncalibrated.
A handheld rig may carry the TCP calibration of its trackers (calibration)
and the design of its gripper (gripper, a Robot of kind GRIPPER): the
gripper’s URDF, with the calibration saying where on it the TCP is. Both are
a record on the rig: importing or replacing either changes no dataset.
Ingest reads only the calibration’s tracker_to_tcp, filename and
derive_date; the gripper design and the calibration’s end-effector fields
(ee_link, ee_to_tcp) are for display.
Served by fleet.
object
Accounts/{account}/rigs/{rig}
Human name.
What recordings carry as their rig id (meta/ingest.toml, LeRobot robot_type). Unique per account; 1 to 128 letters, digits, ’.’, ’_’, ’:’ or ’-’, starting with a letter or digit. Fixed at creation.
Arm or handheld.
Arm rig: accounts/{account}/robots/{robot} it drives, so its episodes get forward kinematics on that robot’s model. A robot (not a gripper design) of the rig’s own account; deleting the robot clears it. A handheld rig has none.
Handheld rig: one mount per tracked hand, at least one, at most one per side. An arm rig has none.
One tracker’s fixed mount.
object
Which hand.
The fixed mount: the tracker’s pose in its gripper root’s frame (x along
the fingers, y the way the jaw opens, z along the hinge): xyz in metres
and rpy in radians like every Transform. meta/ingest.toml’s
[rig.mount.
object
X, y, z in metres.
Roll, pitch, yaw in radians.
The gripper’s closure calibration: the raw angle fully open.
The raw angle shut.
When it was created.
When it last changed.
Sent back on UpdateRig.
Handheld rig: where each tracker’s TCP is, from the last ImportCalibration. Unset until one is imported, and never set on the built-in rig. Not editable through UpdateRig.
object
The uploaded file’s name, e.g. “tcp_calibration.json”.
When the calibration was made, “YYYY-MM-DD”: the leading date of the
file’s calibrated or else its derived text. Empty when the file gives
none.
Both hands, left then right.
One hand’s transform.
object
Which hand.
The TCP’s pose in the tracker’s frame: xyz in metres and rpy in radians (URDF convention, extrinsic XYZ), the file’s rotation matrix converted. A rotation whose pitch is within a hair of +-90 degrees has no unique roll and yaw; it is stored with roll 0. (— api-linter: core::0140::prepositions=disabled aip.dev/not-precedent: a transform is named by its direction, as the calibration file’s own controller_to_tcp is. —)
object
X, y, z in metres.
Roll, pitch, yaw in radians.
The same TCP in the frame of the gripper design’s ee_link for this
hand, in the form of tracker_to_tcp (so the same pitch limit). Display
only. Set with ee_link or not at all, and only when it composes with
the file’s controller_to_ee to the file’s controller_to_tcp, which is
what makes the TCP drawn the TCP used.
(— api-linter: core::0140::prepositions=disabled
aip.dev/not-precedent: a transform is named by its direction, as
the calibration file’s own ee_to_tcp is. —)
object
X, y, z in metres.
Roll, pitch, yaw in radians.
The link of the rig’s gripper design that Hand.ee_to_tcp is a pose in,
with {side} for “left” or “right” (the gripper joint’s convention in
RobotModel.Gripper), e.g. “openarm_{side}_ee_base_link”. Read from the
file’s own description of its end-effector frame. Empty when the file
names none, lacks the end-effector poses, or they disagree with its
controller_to_tcp (then no ee_to_tcp is set either). Display only.
ee_to_tcp is drawn in this link’s own frame, which must be the plain
end-effector frame the file means. An export whose link sits elsewhere
draws the TCP off by the difference: an OpenArm exported with the xacro
default collapse_internal_empty_links puts openarm_
Whether this is a built-in rig (the UMI handheld rig): read only, the same in every account. Setting a gripper on one makes the account’s own copy.
Handheld rig: accounts/{account}/robots/{robot} of kind GRIPPER, the design of its gripper (a URDF, imported as a robot model). A design of the rig’s own account; deleting the design clears it. A design lives in one workspace, like any robot, and a rig in none, so this may name a design of any workspace of the account, and Robots.GetRobot finds it only from that workspace. Set with UpdateRig (CreateRig refuses it); on the built-in rig that makes the account’s own copy, uncalibrated. An arm rig has none; it names a robot.
Example
{ "kind": "KIND_UNSPECIFIED", "mounts": [ { "side": "SIDE_UNSPECIFIED" } ], "calibration": { "hands": [ { "side": "SIDE_UNSPECIFIED" } ] }}default
Section titled “default ”Default error response
The Status type defines a logical error model that is suitable for different programming environments, including REST APIs and RPC APIs. It is used by gRPC. Each Status message contains three pieces of data: error code, error message, and error details. You can find out more about this error model and how to work with it in the API Design Guide.
object
The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code].
A developer-facing error message, which should be in English. Any user-facing error message should be localized and sent in the [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client.
A list of messages that carry the error details. There is a common set of message types for APIs to use.
Contains an arbitrary serialized message along with a @type that describes the type of the serialized message.
object
The type of the serialized message.
Example generated
{ "code": 1, "message": "example", "details": [ { "@type": "example" } ]}