Quickstart

SDK modules

The Python and TypeScript SDKs talk to the same appliance gRPC control plane, and follow a similar module structure.

Module

Purpose

olo

Contains olo.Client, the entry point for appliance connections, plus typed SDK errors.

olo.core

ROS-facing operations: Robot namespace discovery, topic inspection, publishers/subscribers, and parameter handling.

olo.spatial

Spatial maths (poses, transforms) and TF tree access.

olo.kinematics

MoveIt-backed robot model/state, trajectory planning/execution, and gripper/end-effector control.

olo.locomotion

Finite local driving and turning using odometry feedback.

olo.navigation

Nav2-backed robot navigation.

olo.vision

Camera geometry, depth deprojection, image alignment, and position-error helpers.

olo.ai

ONNX model inference, tensor helpers, and YOLOX detection adapters.

olo.archive

Local archive: image/video capture and rosbag record/playback.

olo.platform

Server-stored artifact access: navigation configs, maps, and cloud archive catalogs.

Module

Purpose

olo

Contains Client, the entry point for appliance connections, plus typed SDK errors.

olo/core

ROS-facing operations: Robot namespace discovery, topic inspection, publishers/subscribers, and parameter handling.

olo/spatial

Spatial maths (poses, transforms) and TF tree access.

olo/kinematics

MoveIt-backed robot model/state, trajectory planning/execution, and gripper/end-effector control.

olo/locomotion

Finite local driving and turning using odometry feedback.

olo/navigation

Nav2-backed robot navigation.

olo/vision

Camera geometry, depth deprojection, image alignment, and position-error helpers.

olo/ai

ONNX model inference, tensor helpers, and YOLOX detection adapters.

olo/archive

Local archive: image/video capture and rosbag record/playback.

olo/platform

Server-stored artifact access: navigation configs, maps, and cloud archive catalogs.

Client

The SDK uses gRPC to talk to the appliance over a shared protobuf contract. olo.Client owns that connection: it opens a channel on first use, exposes module service wrappers, and closes the channel when you exit a with block or call olo.Client.close().

In the browser SDK Playground, Client() can be left blank. In an external Python process, pass the gRPC target explicitly or set the OLO_SDK_GRPC_TARGET environment variable.

from olo import Client

with Client() as client:
    topics = client.core.list_topics(timeout=2.0)
    for topic in topics:
        print(topic.name, topic.msg_type)

# Outside SDK Playground:
with Client("192.168.1.10:50151") as client:
    ...

The SDK uses gRPC to talk to the appliance over a shared protobuf contract. Client owns the Connect transport session and exposes module service wrappers.

In the SDK Playground, connect() can be left blank. Outside the Playground, pass the appliance base URL to connect() when needed, for example connect("http://192.168.1.10:50151").

import { connect } from "olo/web";

const client = connect();
const topics = await client.core.listTopics({ timeoutMs: 2000 });
for (const topic of topics) {
  console.log(topic.name, topic.msgType);
}

// Outside SDK Playground:
const client = connect("http://192.168.1.10:50151");
...

Robot namespaces

OLO typically uses explicit robot namespaces to support multi-robot deployments. client.robot() returns a robot handle that resolves relative topic and frame names under that namespace. In a single-robot deployment, calling client.robot() without an argument resolves the namespace automatically when it is unambiguous. See Robot Namespaces for the resolution rules, the global fallback, and multi-robot usage.

from olo import Client
from olo.core import TopicInfo

with Client() as client:
    robot = client.robot()
    print(robot.namespace or "<global>")

    joint_states = TopicInfo("joint_states", "sensor_msgs/msg/JointState")
    print(robot.core.get_latest(joint_states))
import { connect } from "olo/web";
import type { TopicInfo } from "olo/core";

const client = connect();
const robot = await client.robot();
console.log(robot.namespace || "<global>");

const jointStates: TopicInfo = { name: "joint_states", msgType: "sensor_msgs/msg/JointState" };
console.log(await robot.core.getLatest(jointStates));

Example usage

from olo import Client, OloError, OloTimeoutError, OloUnavailable
from olo.spatial import Point, Pose

try:
    with Client() as client:
        robot = client.robot()

        current_pose = robot.kinematics.pose()
        target_pose = Pose(
            position=Point(
                x=current_pose.position.x + 0.1,
                y=current_pose.position.y,
                z=current_pose.position.z,
            ),
            orientation=current_pose.orientation,
        )

        result = robot.kinematics.move_pose(target_pose)
        print(f"Planned {result.duration:.2f}s of motion")

except OloTimeoutError as exc:
    print(f"The appliance did not respond in time: {exc}")

except OloUnavailable as exc:
    print(f"Could not connect to the appliance: {exc}")

except OloError as exc:
    print(f"SDK call failed: {exc}")
import { OloError, OloTimeoutError, OloUnavailable } from "olo";
import { connect } from "olo/web";
import { Point, Pose } from "olo/spatial";

try {
  const client = connect();
  const robot = await client.robot();

  const currentPose = await robot.kinematics.pose();
  const targetPose = new Pose(
    new Point(
      currentPose.position.x + 0.1,
      currentPose.position.y,
      currentPose.position.z,
    ),
    currentPose.orientation,
  );

  const result = await robot.kinematics.movePose(targetPose);
  console.log(`Planned ${result.duration.toFixed(2)}s of motion`);
} catch (exc) {
  if (exc instanceof OloTimeoutError) {
    console.log(`The appliance did not respond in time: ${exc.message}`);
  } else if (exc instanceof OloUnavailable) {
    console.log(`Could not connect to the appliance: ${exc.message}`);
  } else if (exc instanceof OloError) {
    console.log(`SDK call failed: ${exc.message}`);
  } else {
    throw exc;
  }
}

See Examples for more in-depth examples.