Add a base
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.
Concepts
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:
- Wheel circumference: how far the robot travels per wheel revolution.
- Width: the distance between the left and right wheel centers.
Steps
1. Prerequisites
- Your machine is online in the Viam app.
- Left and right motor components are configured and tested.
- You’ve measured your wheel circumference and track width in millimeters.
2. Add a base component
- Click the + button.
- Select Configuration block.
- Search for the base model that matches your hardware. For a differential-drive robot with left and right motors, search for wheeled.
- Name your base (for example,
my-base) and click Create.
3. Configure base attributes
{
"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
}
4. Save and test
Click Save, then expand the Test section.
- Use the directional controls to drive the base forward, backward, left, and right.
- Test
MoveStraightwith a specific distance to verify distance accuracy. - Test
Spinwith a specific angle to verify turning accuracy.
Safety
Ensure the robot has room to move and is either on a test stand or in a clear area. Start with low speeds.
Try it
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 API keys. Copy the API key and API key ID. Copy the machine address from the same tab. 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
Troubleshooting
What’s next
- Base API reference: full method documentation.
- Add a Movement Sensor: add GPS or odometry to track where the base is.
- Add an Encoder: add encoders to your motors for better accuracy.
- What is a module?: write a module that drives the base based on sensor input.
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!