Frame system API reference
The RPCs for querying and transforming frame system poses live on the robot service, not on a dedicated FrameSystemService. New users often look for a separate service matching the concept; there is none. All four methods below belong to RobotService in api/proto/viam/robot/v1/robot.proto.
| Method | Purpose |
|---|---|
FrameSystemConfig | Return the list of frame parts that make up the machine’s frame system. |
GetPose | Return a component’s pose in any reference frame. |
TransformPose | Convert a pose between reference frames. |
TransformPCD | Convert a point cloud between reference frames. |
The SDK client classes surface these as methods on the robot or
machine client object (machine.transform_pose, machine.get_pose,
and so on). You do not instantiate a separate frame system client.
Service names
Inside RDK, the frame system is registered under two names: builtin (the default instance that ships with viam-server) and $framesystem (the name modules use to resolve a dependency on the frame system). SDK callers do not reference either; the RPCs on the robot/machine client hit the frame system transparently.
FrameSystemConfig
Returns the list of frame parts configured on the machine. Each part
has a name, parent, translation, orientation, and optional geometry.
This is what the CLI’s
print-config
command prints.
parts = await machine.get_frame_system_config()
for part in parts:
print(part.name, "parent:", part.pose_in_parent_frame.reference_frame)
parts, err := machine.FrameSystemConfig(ctx)
if err != nil {
logger.Fatal(err)
}
for _, part := range parts.Parts {
logger.Infof("%s parent: %s", part.FrameConfig.Name(), part.FrameConfig.Parent())
}
GetPose
Returns a component’s pose in the specified destination frame.
| Parameter | Description |
|---|---|
component_name | The component whose pose to return. |
destination_frame | The reference frame to express the pose in. Default: "world". |
supplemental_transforms | Optional additional frame relationships not stored in the machine’s configuration. |
extra | Optional map for implementation-specific extras. |
Returns a PoseInFrame.
The Python RobotClient does not expose GetPose. Call get_pose on
the motion service client instead:
from viam.services.motion import MotionClient
motion_service = MotionClient.from_robot(machine, "builtin")
gripper_in_world = await motion_service.get_pose(
component_name="my-gripper",
destination_frame="world",
)
gripperInWorld, err := machine.GetPose(
ctx,
"my-gripper",
referenceframe.World,
nil, // supplemental_transforms
nil, // extra
)
Python goes through the motion service, Go through the robot service
GetPose exists on two services in the proto: the robot service (current) and the motion service (older, deprecated, same parameter shape). The Go SDK surfaces the robot service version as RobotClient.GetPose; Go callers go through the robot service. The Python SDK never wrapped the robot service version, so Python callers use MotionClient.get_pose and hit the deprecated motion service path.
The two paths return equivalent results today. The underlying API
surface will eventually consolidate, but until then Python callers
stay on the motion-service path. The CLI’s print-status, get-pose,
and set-pose commands also invoke the deprecated motion-service
method internally.
TransformPose
Convert a pose expressed in one reference frame into the equivalent
pose in another. Unlike GetPose, the starting pose can be any point
you choose, not just a component origin.
| Parameter | Description |
|---|---|
source | The input PoseInFrame (pose plus its reference frame name). |
destination | The reference frame to express the pose in. |
supplemental_transforms | Optional additional frame relationships not stored in the machine’s configuration. |
Returns a PoseInFrame in the destination frame.
from viam.proto.common import PoseInFrame, Pose
detected_in_camera = PoseInFrame(
reference_frame="my-camera",
pose=Pose(x=50, y=30, z=400),
)
detected_in_world = await machine.transform_pose(detected_in_camera, "world")
detectedInCamera := referenceframe.NewPoseInFrame("my-camera",
spatialmath.NewPoseFromPoint(r3.Vector{X: 50, Y: 30, Z: 400}))
detectedInWorld, err := machine.TransformPose(ctx, detectedInCamera, "world", nil)
Supplemental transforms
Use supplemental_transforms to augment the machine’s configured frame
system for a single call. A common case: an object the camera has
detected whose pose you know relative to the camera, but which is not
configured as a component. Pass the object’s frame relationship as a
supplemental transform, then call TransformPose or GetPose to
compute poses involving that object.
Supplemental transforms apply only to the current call. They do not modify the stored frame system configuration.
Python kwarg naming. In Python, MotionClient.get_pose takes supplemental_transforms; RobotClient.transform_pose and RobotClient.get_frame_system_config take additional_transforms. The proto field and all Go methods use supplemental_transforms. Pass the kwarg that matches the client class you call.
TransformPCD
Transform a point cloud from one reference frame to another. Useful for aligning point clouds from multiple cameras into a common frame, or for expressing lidar scans in world coordinates.
| Parameter | Description |
|---|---|
source | The source point cloud (bytes, PCD format). |
source_frame | The reference frame the source point cloud is expressed in. |
destination | The reference frame to express the point cloud in. |
Returns the transformed point cloud (bytes).
Point cloud transforms are computationally expensive for large clouds. Consider down-sampling before calling.
Common patterns
- Verify frame configuration: transform a component’s origin to the world frame and compare against physical measurements.
- Convert camera detections to world coordinates: transform a detection pose from the camera frame to the world frame before commanding an arm to that pose.
- Compare poses across frames: transform each pose to a common
frame (typically
"world"), then compare. - Carry dynamic frame relationships: pass objects the machine picks up or detects as supplemental transforms so the planner and your code agree on their position.
What’s next
- Frame system: the concept these RPCs operate on.
- Motion CLI commands: CLI wrappers around the same RPCs.
- Motion service API: the motion
RPCs, which take
supplemental_transformsthrough the sameWorldStatemechanism.
Was this page helpful?
Glad to hear it! If you have any other feedback please let us know:
We're sorry about that. To help us improve, please tell us what we can do better:
Thank you!