Skip to content

Flow Base

✓ Python SDK✓ Omnidirectional✓ Remote Control✓ Raspberry Pi On-board

Flow Base is I2RT's omnidirectional holonomic mobile platform. Designed to pair with YAM arms, it enables precise whole-body mobile manipulation for tasks that demand exact positioning and free orientation.

Tagline

"It likes to move it move it" — precise, omnidirectional control for tasks where positioning and stability are critical.

Key Features

  • Holonomic drive — simultaneous XY translation and rotation with no kinematic constraints
  • On-board Raspberry Pi — pre-configured with i2rt SDK; SSH-accessible over Wi-Fi or Ethernet
  • CAN bus motor control — same DM-series protocol as YAM arms
  • Remote controller — joystick remote included for manual operation
  • API control — full network Python API via FlowBaseClient
  • Odometry — wheel odometry with reset; external sensor integration supported
  • Safety — E-stop, velocity timeout (0.25 s), remote override

Specifications

ParameterValue
DriveHolonomic (4-wheel)
Communication (external)Ethernet (static IP 172.6.2.20) / Wi-Fi
Communication (motors)CAN bus
On-board computerRaspberry Pi
PowerInternal battery
SSH credentialsi2rt / root
API port11323
Velocity timeout0.25 s

Photos & Videos

🎬
Video — Coming Soon
Flow Base driving around a lab environment — forward, lateral, diagonal, and rotation movements. 30–60 seconds, bird's-eye and side views.
🎬
Video — Coming Soon
YAM arm mounted on Flow Base, doing a mobile pick-and-place from a shelf. Showcases the full mobile manipulation capability.

Hardware Setup

Get the Flow Base omnidirectional mobile platform unboxed, powered, and joystick-ready.

Prerequisite

SW Setup is not required — the Flow Base ships with a Raspberry Pi pre-configured with the SDK. You only need network access to SSH in.

1. Unbox

  • [ ] Flow Base chassis
  • [ ] Battery pack (already installed)
  • [ ] Joystick remote controller
  • [ ] Ethernet cable (for wired SSH)
  • [ ] Charger

2. Power on

  • [ ] Twist the E-stop button counter-clockwise to release it
  • [ ] Set the CAN selector switch to UP position (selects the on-board Pi as CAN master)
  • [ ] Press the power button — the Pi display should light up
  • [ ] Wait ~30 seconds for the Pi to finish booting

3. Connect to the Pi

bash
# Wired (recommended) — static IP
ssh i2rt@172.6.2.20
# Password: root

Wi-Fi setup

If you prefer Wi-Fi, connect a keyboard + monitor to the Pi the first time and run sudo raspi-config to join your network.

4. Verify the SDK is current

bash
cd ~/i2rt && git pull

5. Test with the joystick

On the Pi:

bash
python i2rt/flow_base/flow_base_controller.py
  • [ ] Left joystick → base translates (XY)
  • [ ] Right joystick X → base rotates (yaw)
  • [ ] Press Left2 to override API commands (safety)

Quick Start Demo

Drive the Flow Base with the joystick remote, then control it programmatically.

1. Joystick demo (on the Pi)

bash
ssh i2rt@172.6.2.20
python i2rt/flow_base/flow_base_controller.py

See the Remote Control Layout below for the full button reference.

2. Python API — drive forward from a laptop

From your laptop (on the same network):

python
from i2rt.flow_base.flow_base_client import FlowBaseClient
import numpy as np
import time

client = FlowBaseClient(host="172.6.2.20")

# Drive forward at 0.1 m/s for 2 seconds
start = time.time()
while time.time() - start < 2.0:
    client.set_target_velocity(np.array([0.1, 0.0, 0.0]), frame="local")
    time.sleep(0.05)

# Read odometry
print(client.get_odometry())
client.close()

Velocity timeout

The base stops automatically if no command arrives within 0.25 seconds. The client maintains a heartbeat thread (20 ms) while connected.

For the full SDK (linear rail, frame conventions, advanced commands), see the API Reference section below.

Remote Control Layout

InputFunction
Left joystickXY translation
Right joystick XRotation (yaw)
Right joystick YLinear rail lift (if equipped)
Left1Reset odometry
ModeToggle local ↔ global frame
Left2Override API commands (safety)

Coordinate Systems

The base supports two control frames toggled with the Mode button on the remote:

ModeBehaviour
LocalXY motion is relative to the base's current heading
GlobalXY motion is relative to the world frame (headless mode)

Odometry drift

Wheel odometry accumulates error, especially during aggressive movements. For precise mobile manipulation, integrate a visual odometry sensor (RealSense T265, ZED Camera). Press Left1 to reset odometry at any time.


API Reference

The Flow Base SDK has two layers:

ClassLocationUse
Vehicleflow_base_controller.pyRuns on-board the Pi — joystick demo
FlowBaseClientflow_base_client.pyRuns remotely — network Python API

FlowBaseClient

For remote control from your development machine.

python
from i2rt.flow_base.flow_base_client import FlowBaseClient

client = FlowBaseClient(
    host="172.6.2.20",
    with_linear_rail=False,
)
ParameterTypeDefaultDescription
hoststr"localhost"IP address of the Flow Base Pi
with_linear_railboolFalseSet True if the linear rail module is installed

No port parameter

The port is hardcoded internally using BASE_DEFAULT_PORT. You only need to specify the host IP.

Movement Commands

set_target_velocity(velocity, frame)

python
import numpy as np

# 3D (base only)
client.set_target_velocity(np.array([vx, vy, omega]), frame="local")

# 4D (base + linear rail)
client.set_target_velocity(np.array([vx, vy, omega, rail_vel]), frame="local")
ParameterUnitDescription
vxm/sForward/backward
vym/sLeft/right (strafe)
omegarad/sRotation (yaw rate)
rail_velrad/sLinear rail speed (positive = up)
frame"local" (relative to base) or "global" (world frame)

Velocity must be a NumPy array

set_target_velocity() expects a np.ndarray with shape (3,) or (4,). Pass np.array([...]), not a plain Python list.

Velocity timeout

The base stops automatically if no command arrives within 0.25 seconds. FlowBaseClient maintains a heartbeat automatically while connected via a background thread (20 ms interval).

Odometry

get_odometry() → dict

python
odom = client.get_odometry()
# {'translation': array([x, y]), 'rotation': array(theta)}

Wheel odometry only. Errors accumulate over time — integrate visual odometry (RealSense T265, ZED) for precise localization.

reset_odometry() → None

Resets position and heading to zero.

Linear Rail API

Only available when with_linear_rail=True.

get_linear_rail_state() → dict

python
state = client.get_linear_rail_state()
# {
#   'position': float,
#   'velocity': float,
#   'upper_limit_triggered': bool,
#   'lower_limit_triggered': bool,
# }

set_linear_rail_velocity(velocity: float) → None

python
client.set_linear_rail_velocity(0.5)    # raise
client.set_linear_rail_velocity(0.0)    # stop
client.set_linear_rail_velocity(-0.5)   # lower

Combined base + rail command

python
client.set_target_velocity(np.array([vx, vy, omega, rail_vel]), frame="local")

Auto-homing

The rail homes to the lower limit switch on init. Ensure clearance below before powering on.

Cleanup

Always close the client when done to stop the background heartbeat thread:

python
client.close()

Command-line Client

Quick functional tests without writing Python:

bash
# Read odometry
python i2rt/flow_base/flow_base_client.py --command get_odometry --host 172.6.2.20

# Reset odometry
python i2rt/flow_base/flow_base_client.py --command reset_odometry --host 172.6.2.20

# Run a short movement test (base will move)
python i2rt/flow_base/flow_base_client.py --command test_command --host 172.6.2.20

# Test linear rail (rail will move)
python i2rt/flow_base/flow_base_client.py --command test_linear_rail --host 172.6.2.20

# Monitor linear rail state
python i2rt/flow_base/flow_base_client.py --command get_linear_rail_state --host 172.6.2.20

Vehicle (On-board Controller)

Runs directly on the Pi. Used for the joystick demo.

python
from i2rt.flow_base.flow_base_controller import Vehicle
import time

v = Vehicle()
v.start_control()

start = time.time()
while time.time() - start < 2.0:
    v.set_target_velocity((0.15, 0.0, 0.0), frame="local")

Coordinate Frames

FrameDescription
localRelative to the current base orientation. Joystick forward = robot forward regardless of heading.
globalWorld frame from odometry zero. Similar to drone headless mode. Accumulates error.

Switch frames at runtime via the remote Mode button, or programmatically by passing frame= to set_target_velocity.


External CAN Control

To bypass the on-board Pi and control the base from an external computer:

  1. Connect your CAN adapter to the external CAN connector
  2. Set the CAN selector switch to the DOWN position
  3. Clone the i2rt repo on your external machine and control via CAN directly

Troubleshooting

SymptomFix
Remote unresponsiveToggle remote off and on to wake from sleep
Slow bootNormal — screen firmware adds delay, SSH is available quickly
Inaccurate odometryExpected with wheel odometry; use external visual sensor for precision
Linear rail not homingCheck GPIO connections and limit switches
Linear rail stuck at limitRun get_linear_rail_state() to check switch status

See Also

Released under the MIT License. · Questions? support@i2rt.com