The ROS2 Foundation

OLO exists to make robot programming easier and faster. While ROS2 is powerful, it has a steep learning curve and requires significant infrastructure setup. OLO wraps ROS2 complexity behind a simple SDK, letting you program robots in JavaScript or Python without needing to understand DDS, message serialization, or ROS2 build systems. The OLO Portal provides development tools (visualization, simulation, deployment), while the OLO Appliance runs your code locally on - or on the same network as - the robot itself.

The Developer Experience Gap

If you're coming from web development, mobile apps, or general software engineering, your first encounter with ROS2 can be frustrating. You might think: "I just want the robot to move forward. Why do I need to set up a workspace, understand DDS domains, define message types, configure QoS policies, and source environment files before I can send a simple velocity command?"

This isn't a criticism of ROS2 - it's designed for building complex, production-grade robotic systems where that infrastructure matters. But when you're learning, prototyping, or just want to get something working quickly, the gap between "I have an idea" and "the robot is moving" can feel unnecessarily wide.

ROS2 also isn't structured like a typical API. There's no robot.moveForward() method you can call. Instead, you work with a distributed system of nodes publishing and subscribing to topics. To move a robot, you create a publisher, construct a properly-typed Twist message, and publish it to /cmd_vel - repeatedly, because most robot bases expect continuous velocity commands. Understanding why this architecture exists (and its benefits for complex systems) takes time.

OLO provides a different entry point. The SDK gives you that moveForward() style of interface - await oloClient.core.moveFor({ linear: 0.5 }, 2000) moves your robot forward for 2 seconds - while the Portal shows you what topics exist, what data is flowing, and what your robot is doing. You can start simple, see results immediately, and learn ROS2 concepts as you need them rather than all at once upfront.

The underlying ROS2 system is still there. Every node, topic, service, parameter and action - you have full access to all of it through the SDK. OLO doesn't hide ROS2; it provides a more approachable way to work with it.

What You Need to Know About ROS2

ROS2 is the industry-standard middleware for robotics. It provides a structured way for different parts of a robot system to communicate - sensors, actuators, planning algorithms, and user interfaces all exchange data through ROS2.

Two Core Concepts:

1. Topics - Named channels for streaming data

Topics are publish/subscribe channels where data flows continuously. Any node can publish messages to a topic, and any number of nodes can subscribe to receive those messages.

Examples of common topics:
  /camera/image_raw     - Camera frames (sensor_msgs/Image)
  /scan                 - LiDAR distance readings (sensor_msgs/LaserScan)
  /odom                 - Robot position/velocity (nav_msgs/Odometry)
  /cmd_vel              - Movement commands (geometry_msgs/Twist)
  /joint_states         - Arm joint positions (sensor_msgs/JointState)
  /tf                   - Coordinate transforms (tf2_msgs/TFMessage)

2. Nodes - Independent processes that do work

Nodes are individual programs that perform specific functions. A typical robot has many nodes running simultaneously:

Example robot system:
  camera_node           - Captures and publishes images
  lidar_node            - Reads laser scanner, publishes /scan
  navigation_node       - Subscribes to /scan, plans paths
  motor_controller      - Subscribes to /cmd_vel, drives wheels
  arm_controller        - Manages joint trajectories
  state_publisher       - Broadcasts robot transforms to /tf

Nodes communicate exclusively through topics, services, and actions - they don't call each other directly. This loose coupling means you can add, remove, or replace nodes without affecting others.

Traditional ROS2 Development

For context, here's what traditional ROS2 development typically involves:

Traditional ROS2 Development Workflow
┌─────────────────────────────────────────────────────────────────────────┐
│                                                                         │
│   1. Set up ROS2 workspace      colcon build, source setup.bash         │
│   2. Define message types       .msg/.srv files, rebuild                │
│   3. Write C++/Python nodes     rclcpp/rclpy, callbacks, executors      │
│   4. Configure launch files     XML/Python launch system                │
│   5. Manage dependencies        package.xml, CMakeLists.txt             │
│   6. Handle QoS policies        Reliability, durability, history        │
│   7. Set up simulation          Gazebo/Isaac Sim, URDF/SDF models,      │
│                                 world files, sensor plugins             │
│   8. Debug with CLI tools       ros2 topic echo, ros2 node list         │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

This workflow is well-suited for building production robot systems but requires understanding ROS2's build system, message definitions, and execution model, and you are mandated to use Linux and the ROS2 suite of desktop tools that have been created by the open source community. OLO provides an alternative approach for rapid development and scripting, all through a friendly web browser.

How OLO Simplifies ROS2 Programming

OLO addresses these challenges with two components working together:

1. The OLO SDK - A simple programming interface that wraps ROS2 complexity:

JS
// OLO SDK - Simple, async JavaScript/Python const topics = await oloClient.core.listTopics(); await oloClient.core.sendVelocity('/cmd_vel', { linear: 0.5 }); await oloClient.navigation.navigateTo({ x: 2, y: 1, yaw: 0 });

2. The OLO Appliance - Software that runs on or near your robot:

┌─────────────────────────────────────────────────────────────────────────┐
│                              ROBOT SIDE                                 │
│                                                                         │
│  ┌───────────────────────────────────────────────────────────────────┐  │
│  │                         OLO APPLIANCE                             │  │
│  │                                                                   │  │
│  │  ┌─────────────────────────────────────────────────────────────┐  │  │
│  │  │              SCRIPT EXECUTION ENGINE                        │  │  │
│  │  │                                                             │  │  │
│  │  │   Your JavaScript/Python code runs locally                  │  │  │
│  │  │   - Optional scheduled execution, script chaining           │  │  │
│  │  │                                                             │  │  │
│  │  └──────────────────────────┬──────────────────────────────────┘  │  │
│  │                             │                                     │  │
│  │  ┌──────────────────────────┴──────────────────────────────────┐  │  │
│  │  │                    OLO SDK (Local)                          │  │  │
│  │  │   Wraps ROS2 complexity into simple async API calls         │  │  │
│  │  └──────────────────────────┬──────────────────────────────────┘  │  │
│  │                             │                                     │  │
│  └─────────────────────────────┼─────────────────────────────────────┘  │
│                                │                                        │
│                                ▼                                        │
│  ┌───────────────────────────────────────────────────────────────────┐  │
│  │                          ROS2 / DDS                               │  │
│  │    /camera/image_raw    /scan    /cmd_vel    /tf    /joint_states │  │
│  └───────────────────────────────────────────────────────────────────┘  │
│                                │                                        │
│             ┌──────────────────┼──────────────────┐                     │
│             ▼                  ▼                  ▼                     │
│        ┌─────────┐       ┌──────────┐      ┌──────────┐                 │
│        │ Sensors │       │ Actuators│      │ Planning │                 │
│        └─────────┘       └──────────┘      └──────────┘                 │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

Once code is deployed to the appliance, it runs locally with direct ROS2 access. The robot can navigate, manipulate objects, and execute behaviors without an internet connection.

The OLO Portal - Development and Deployment

The OLO Portal is where you develop, test, and deploy code.

┌────────────────────────────────────────────────────────────────────────┐
│                          OLO PORTAL (Cloud)                            │
│                                                                        │
│   ┌─────────────────┐  ┌─────────────────┐  ┌─────────────────────┐    │
│   │  SDK Playground │  │   Visualization │  │    Cloud Sim        │    │
│   │                 │  │                 │  │                     │    │
│   │  - Write code   │  │  - 3D URDF view │  │  - Test without     │    │
│   │  - AI assistant │  │  - Camera feeds │  │    real robot       │    │
│   │  - Live testing │  │  - Sensor data  │  │  - Iterate quickly  │    │
│   └─────────────────┘  └─────────────────┘  └─────────────────────┘    │
│                                                                        │
│   ┌─────────────────┐  ┌─────────────────┐  ┌─────────────────────┐    │
│   │   Deployment    │  │    Scheduling   │  │   Fleet Management  │    │
│   │                 │  │                 │  │                     │    │
│   │  - Save scripts │  │  - Timed runs   │  │  - Multiple robots  │    │
│   │  - Push to robot│  │  - Recurring    │  │  - Remote monitoring│    │
│   │  - Version ctrl │  │    tasks        │  │  - Team access      │    │
│   └─────────────────┘  └─────────────────┘  └─────────────────────┘    │
│                                                                        │
└────────────────────────────────────────────────────────────────────────┘
                                   │
                     Internet (for development workflow)
                                   │
                                   ▼
┌────────────────────────────────────────────────────────────────────────┐
│                         OLO APPLIANCE (Robot)                          │
│   Receives deployed scripts, runs them locally, reports status back    │
└────────────────────────────────────────────────────────────────────────┘

When Internet Connectivity Matters:

ActivityRequires Internet?
Writing and testing code in SDK PlaygroundYes
Visualizing robot state remotelyYes
Running Cloud SimYes
Deploying scripts to the applianceYes
Robot executing deployed scriptsNo
Robot navigating autonomouslyNo
Robot running scheduled tasksNo

How Remote Connectivity Works

When you do need remote access (development, monitoring, remote control), OLO handles the networking complexity:

ProtocolUsed ForWhy
WebSocketControl messages, topic data, servicesReliable delivery through firewalls; JSON-based rosbridge protocol
WebRTCVideo streaming, high-bandwidth topicsPeer-to-peer when possible, adaptive bitrate, hardware-accelerated encoding

WebSocket (via ROSBridge):

  • Provides a standard JSON-RPC interface to ROS2
  • Handles topic subscriptions, publishing, service calls, and parameters
  • Works through any firewall that allows outbound HTTPS
  • Includes intelligent throttling to manage bandwidth

WebRTC (for Video and Large Data):

  • Establishes peer-to-peer connections when network topology allows
  • Falls back to TURN relay servers when direct connection isn't possible
  • Hardware-accelerated H.264/VP8/VP9 video encoding
  • Adaptive bitrate adjusts quality based on network conditions

ROS2 Domains - Isolation and Organization

ROS2 uses Domain IDs to isolate communication. Nodes on the same domain can discover and communicate with each other; nodes on different domains cannot.

Domain 0 (Default)              Domain 1                    Domain 2
┌─────────────────┐         ┌─────────────────┐         ┌─────────────────┐
│  Robot A        │         │  Robot B        │         │  Simulation     │
│  - /cmd_vel     │         │  - /cmd_vel     │         │  - /cmd_vel     │
│  - /scan        │         │  - /scan        │         │  - /scan        │
│  - /odom        │         │  - /odom        │         │  - /odom        │
└─────────────────┘         └─────────────────┘         └─────────────────┘
     No cross-domain communication - topics are isolated

Key Points:

  • The OLO Appliance connects to a specific ROS2 domain (configurable, default is 0)
  • Topics, nodes, and services are only visible within their domain
  • Use different domains to run multiple isolated robot systems on the same network
  • Set via ROS_DOMAIN_ID environment variable

Namespaces - Multiple Robots, One Domain

While domains provide hard isolation, namespaces allow multiple robots to coexist within the same domain with organized, prefixed topic names:

Single Domain with Namespaced Robots
┌─────────────────────────────────────────────────────────────────────────┐
│                            Domain 0                                     │
│                                                                         │
│  Robot 1 (namespace: /robot1)      Robot 2 (namespace: /robot2)         │
│  ┌──────────────────────────┐      ┌──────────────────────────┐         │
│  │  /robot1/cmd_vel         │      │  /robot2/cmd_vel         │         │
│  │  /robot1/scan            │      │  /robot2/scan            │         │
│  │  /robot1/odom            │      │  /robot2/odom            │         │
│  │  /robot1/camera/image    │      │  /robot2/camera/image    │         │
│  └──────────────────────────┘      └──────────────────────────┘         │
│                                                                         │
│  Shared Topics (no namespace)                                           │
│  ┌──────────────────────────────────────────────────────────────┐       │
│  │  /tf  /tf_static  (transforms from ALL robots)               │       │
│  │  /clock           (simulation time, if used)                 │       │
│  └──────────────────────────────────────────────────────────────┘       │
└─────────────────────────────────────────────────────────────────────────┘

Benefits of Namespaces:

  • Multiple robots share one ROS2 domain without topic name conflicts
  • Shared topics like /tf aggregate data from all robots
  • One appliance can access all robots in its domain
  • The OLO SDK's discoverRobots() function automatically detects namespaced robots

How OLO Handles Namespaces:

When you call discoverRobots(), OLO analyzes TF frames and topics to identify distinct robot instances:

JS
// Discover all robots in the ROS environment const robots = await oloClient.core.discoverRobots(); // Example output: // [ // { namespace: 'robot_1', name: 'Robot 1', type: 'mobile_robot', signals: { hasCmdVel: true, ... } }, // { namespace: 'robot_2', name: 'Robot 2', type: 'mobile_robot', signals: { hasCmdVel: true, ... } }, // { namespace: '', name: 'Global', type: 'robot_arm', signals: { hasJointStates: true, ... } } // ] // Control a specific robot by including its namespace in topic names await oloClient.core.sendVelocity('/robot1/cmd_vel', { linear: 0.5 }); await oloClient.core.sendVelocity('/robot2/cmd_vel', { linear: -0.5 });

Why the OLO SDK Wraps ROS2

The OLO SDK provides a higher-level API over ROS2 operations:

1. Async/Await Patterns - All operations return promises for clean sequential code:

JS
const topics = await oloClient.core.listTopics(); await oloClient.core.subscribe('/scan', (msg) => console.log(msg)); await oloClient.core.publish('/cmd_vel', { linear: 0.5, angular: 0 });

2. Automatic Topic Type Resolution - No need to specify message types:

JS
// Message type detected automatically from the ROS2 topic await oloClient.core.publish('/cmd_vel', { linear: 0.5, angular: 0 });

3. Built-in Safety Patterns - Robot control with automatic cleanup:

JS
// Velocity hold - stops automatically if script is cancelled const handle = await oloClient.core.startVelocityHold( { linear: 0.5 }, { abortSignal } ); // Timed movement - robot stops after duration OR if aborted await oloClient.core.moveFor({ linear: 0.5 }, 3000, { abortSignal });

4. Cross-Language Consistency - Same API in JavaScript and Python:

JS
await oloClient.core.sendVelocity('/cmd_vel', { linear: 0.5, angular: 0 }); await oloClient.navigation.navigateTo({ x: 2, y: 1, yaw: 0 });

Appliances and Load Distribution

A single OLO Appliance connects to one ROS2 domain and provides access to all robots (namespaces) within that domain. For advanced deployments, multiple appliances can distribute load:

                              INTERNET
                                 │
          ┌──────────────────────┼──────────────────────┐
          │                      │                      │
          ▼                      ▼                      ▼
   ┌─────────────┐        ┌─────────────┐       ┌─────────────┐
   │   Browser   │        │  OLO Portal │       │  Your App   │
   └──────┬──────┘        └──────┬──────┘       └──────┬──────┘
          │                      │                     │
          └──────────────────────┼─────────────────────┘
                                 │
                    ┌────────────┴────────────┐
                    │                         │
                    ▼                         ▼
          ┌─────────────────┐       ┌─────────────────┐
          │   Appliance A   │       │   Appliance B   │
          │                 │       │                 │
          │ Handles:        │       │ Handles:        │
          │ - Navigation    │       │ - Arm Control   │
          │ - Base movement │       │ - Gripper       │
          │ - LiDAR/Cameras │       │ - Vision AI     │
          └────────┬────────┘       └────────┬────────┘
                   │                         │
                   └────────────┬────────────┘
                                │
                                ▼
                   ┌─────────────────────────┐
                   │    ROS2 Domain 0        │
                   │                         │
                   │  /cmd_vel  /scan  /tf   │
                   │  /joint_states  /camera │
                   └─────────────────────────┘
                                │
                                ▼
                   ┌─────────────────────────┐
                   │    Mobile Manipulator   │
                   │    (Base + Arm)         │
                   └─────────────────────────┘

When to Use Multiple Appliances:

ScenarioConfiguration
Single robot, simple tasksOne appliance handles everything
Complex robot (mobile base + arm)Separate appliances for navigation vs manipulation
High video bandwidthDedicated appliance for video streaming
Redundancy requirementsMultiple appliances for failover
Team isolationDifferent teams connect to different appliances

Key Points:

  • All appliances in the same domain see the same topics
  • Each appliance can run scripts independently
  • No special configuration needed - appliances automatically share the ROS2 topic space

Using Multiple Domains for Isolation:

Another approach is to run separate ROS2 domains, each with its own appliance. This provides complete isolation - robots in different domains cannot see each other's topics, even if they're on the same network. This is useful for running independent robot systems, separating production from testing, or isolating different customer deployments:

                              OLO Portal
                                  │
           ┌──────────────────────┼──────────────────────┐
           │                      │                      │
           ▼                      ▼                      ▼
   ┌───────────────┐      ┌───────────────┐      ┌───────────────┐
   │  Appliance A  │      │  Appliance B  │      │  Appliance C  │
   │  (Domain 0)   │      │  (Domain 1)   │      │  (Domain 2)   │
   └───────┬───────┘      └───────┬───────┘      └───────┬───────┘
           │                      │                      │
           ▼                      ▼                      ▼
   ┌───────────────┐      ┌───────────────┐      ┌───────────────┐
   │ ROS2 Domain 0 │      │ ROS2 Domain 1 │      │ ROS2 Domain 2 │
   │               │      │               │      │               │
   │  Warehouse    │      │  Lab Testing  │      │  Customer X   │
   │  Fleet        │      │  Environment  │      │  Deployment   │
   └───────────────┘      └───────────────┘      └───────────────┘
           │                      │                      │
     No cross-domain communication - complete isolation

Each appliance is configured with a ROS_DOMAIN_ID in its settings that determines which ROS2 domain it joins. You set this through the appliance configuration.

Summary: How It All Fits Together

┌─────────────────────────────────────────────────────────────────────────┐
│                        DEVELOPMENT TIME                                 │
│                                                                         │
│   Your Browser                    OLO Portal                            │
│   ┌───────────────┐               ┌───────────────┐                     │
│   │ SDK Playground│ ◄──────────►  │ Cloud Services│                     │
│   │ Write code    │   Internet    │ - Sim         │                     │
│   │ Test & debug  │               │ - Viz         │                     │
│   └───────────────┘               └──────┬────────┘                     │
│                                         │                               │
│                                    Deploy scripts                       │
│                                         │                               │
└─────────────────────────────────────────┼───────────────────────────────┘
                                          │
                                          ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                          RUNTIME (Robot)                                │
│                                                                         │
│   ┌───────────────────────────────────────────────────────────────────┐ │
│   │                       OLO APPLIANCE                               │ │
│   │                                                                   │ │
│   │   Your Code ──► OLO SDK ──► ROS2 ──► Motors/Sensors               │ │
│   │                                                                   │ │
│   └───────────────────────────────────────────────────────────────────┘ │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

With this foundation, you're ready to understand how the OLO Appliance works and start programming robots!