Previous
Arm
Add a base to your machine’s configuration to drive a mobile robot with movement commands like “move forward 300mm” or “spin 90 degrees.” A base wraps your robot’s drive system, whatever the motor layout, into a single interface that handles steering and speed for you.
A base component gives you a movement API (MoveStraight, Spin, SetVelocity, Stop) regardless of the underlying drive system. The most common model is wheeled, which handles differential steering for robots with left and right motors. Other models exist for different platforms, including sensor-controlled (adds IMU feedback to improve accuracy) and module-based models for specific hardware.
Browse all available base models in the Viam registry.
This page covers the wheeled model. You configure your motors first, then the base references them.
For accurate distance and angle calculations, the wheeled model needs two physical measurements:
my-base) and click Create.
{
"left": ["left-motor"],
"right": ["right-motor"],
"wheel_circumference_mm": 220,
"width_mm": 300
}
| Attribute | Type | Required | Description |
|---|---|---|---|
left | list of strings | Yes | Names of the motors on the left side. |
right | list of strings | Yes | Names of the motors on the right side. |
wheel_circumference_mm | int | Yes | Outer circumference of a drive wheel in mm. |
width_mm | int | Yes | Distance between left and right wheel centers in mm. |
spin_slip_factor | float | No | Correction factor for turning accuracy. Increase if the robot over-rotates during spins; decrease if it under-rotates. |
For robots with multiple motors per side (for example, six-wheel drive), list all motor names for that side:
{
"left": ["front-left-motor", "rear-left-motor"],
"right": ["front-right-motor", "rear-right-motor"],
"wheel_circumference_mm": 220,
"width_mm": 300
}
Click Save, then expand the TEST section.
MoveStraight with a specific distance to verify distance accuracy.Spin with a specific angle to verify turning accuracy.Ensure the robot has room to move and is either on a test stand or in a clear area. Start with low speeds.
Drive the base forward, spin it, and stop.
To get the credentials for the code below, go to your machine’s page in the Viam app, click the CONNECT tab, and select SDK code sample. Toggle Include API key on. Copy the machine address, API key, and API key ID from the code sample. If you’re using real hardware, you’ll see the robot drive forward and spin when you run the code below. With a fake base, the commands complete without physical motion.
pip install viam-sdk
Save this as base_test.py:
import asyncio
from viam.robot.client import RobotClient
from viam.components.base import Base
async def main():
opts = RobotClient.Options.with_api_key(
api_key="YOUR-API-KEY",
api_key_id="YOUR-API-KEY-ID"
)
robot = await RobotClient.at_address("YOUR-MACHINE-ADDRESS", opts)
base = Base.from_robot(robot, "my-base")
# Drive forward 300mm at 200mm/s
print("Driving forward 300mm...")
await base.move_straight(distance=300, velocity=200)
# Spin 90 degrees at 45 degrees/s
print("Spinning 90 degrees...")
await base.spin(angle=90, velocity=45)
# Stop
await base.stop()
print("Done")
await robot.close()
if __name__ == "__main__":
asyncio.run(main())
Run it:
python base_test.py
mkdir base-test && cd base-test
go mod init base-test
go get go.viam.com/rdk
Save this as main.go:
package main
import (
"context"
"fmt"
"go.viam.com/rdk/components/base"
"go.viam.com/rdk/logging"
"go.viam.com/rdk/robot/client"
"go.viam.com/rdk/utils"
)
func main() {
ctx := context.Background()
logger := logging.NewLogger("base-test")
robot, err := client.New(ctx, "YOUR-MACHINE-ADDRESS", logger,
client.WithCredentials(utils.Credentials{
Type: utils.CredentialsTypeAPIKey,
Payload: "YOUR-API-KEY",
}),
client.WithAPIKeyID("YOUR-API-KEY-ID"),
)
if err != nil {
logger.Fatal(err)
}
defer robot.Close(ctx)
b, err := base.FromProvider(robot, "my-base")
if err != nil {
logger.Fatal(err)
}
// Drive forward 300mm at 200mm/s
fmt.Println("Driving forward 300mm...")
if err := b.MoveStraight(ctx, 300, 200, nil); err != nil {
logger.Fatal(err)
}
// Spin 90 degrees at 45 degrees/s
fmt.Println("Spinning 90 degrees...")
if err := b.Spin(ctx, 90, 45, nil); err != nil {
logger.Fatal(err)
}
// Stop
if err := b.Stop(ctx, nil); err != nil {
logger.Fatal(err)
}
fmt.Println("Done")
}
Run it:
go run main.go
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!