Move a wheeled robot base

You have three options for moving a mobile robot base:

  • Give direct commands such as Spin and MoveStraight using the base API
  • Send the base to a destination on a SLAM map or to a GPS coordinate using the motion planning service API’s MoveOnMap or MoveOnGlobe commands, respectively
  • Define waypoints and move your base along those waypoints while avoiding obstacles, using the navigation service API

Prerequisites

A running machine connected to the Viam app. Click to see instructions.
Add a new machine in the Viam app. On the machine’s page, follow the setup instructions to install viam-server on the computer you’re using for your project. Wait until your machine has successfully connected to the Viam app.

Configure and connect to your base

1. Configure the base’s motor components

First, connect the base’s motors to your machine.

Then, navigate to the CONFIGURE tab of your machine’s page in the Viam app. Click the + icon next to your machine part in the left-hand menu and select Component. Search for and select a model that supports your motor.

Complete the motor configuration and use the TEST panel in the configuration card to test that the motor is working.

Repeat this for each motor of your base.

2. Configure a base component

The base component allows you to more easily coordinate the motion of the motors to move the robot’s as a whole.

Use the + button again to add a base component. The wheeled-base model supports robotic bases with motors on both sides for differential steering.

3. Connect code to your base

Go to your machine’s CONNECT tab in the Viam app. Select your preferred programming language and copy the code snippet.

See Create a web app, Create a mobile app, or Create a headless app for more information, depending on your use case.

Move your base using the base API

The following example script drives a rover in a square. For code examples in more languages, see Drive a rover in a square.

import asyncio

from viam.components.base import Base
from viam.robot.client import RobotClient
from viam.rpc.dial import Credentials, DialOptions


async def connect():
    opts = RobotClient.Options.with_api_key(
        # Replace "<API-KEY>" (including brackets) with your machine's API key
        api_key='<API-KEY>',
        # Replace "<API-KEY-ID>" (including brackets) with your machine's
        # API key ID
        api_key_id='<API-KEY-ID>'
    )
    return await RobotClient.at_address('ADDRESS FROM THE VIAM APP', opts)


async def moveInSquare(base):
    for _ in range(4):
        # moves the rover forward 500mm at 500mm/s
        await base.move_straight(velocity=500, distance=500)
        print("move straight")
        # spins the rover 90 degrees at 100 degrees per second
        await base.spin(velocity=100, angle=90)
        print("spin 90 degrees")


async def main():
    machine = await connect()

    roverBase = Base.from_robot(machine, 'viam_base')

    # Move the rover in a square
    await moveInSquare(roverBase)

    await machine.close()

if __name__ == '__main__':
    asyncio.run(main())
package main

import (
    "context"

    "go.viam.com/rdk/components/base"
    "go.viam.com/rdk/logging"
    "go.viam.com/rdk/robot/client"
    "go.viam.com/rdk/utils")

func moveInSquare(ctx context.Context, base base.Base, logger logging.Logger) {
    for i := 0; i < 4; i++ {
        // moves the rover forward 600mm at 500mm/s
        base.MoveStraight(ctx, 600, 500.0, nil)
        logger.Info("move straight")
        // spins the rover 90 degrees at 100 degrees per second
        base.Spin(ctx, 90, 100.0, nil)
        logger.Info("spin 90 degrees")
    }
}

func main() {
    logger := logging.NewLogger("client")
    machine, err := client.New(
      context.Background(),
      "ADDRESS FROM THE VIAM APP",
      logger,
      client.WithDialOptions(utils.WithEntityCredentials(
      // Replace "<API-KEY-ID>" (including brackets) with your machine's API key ID
      "<API-KEY-ID>",
      utils.Credentials{
          Type:    utils.CredentialsTypeAPIKey,
          // Replace "<API-KEY>" (including brackets) with your machine's API key
          Payload: "<API-KEY>",
      })),
    )
    if err != nil {
        logger.Fatal(err)
    }
    defer machine.Close(context.Background())

    // Get the base from the rover
    roverBase, err := base.FromRobot(machine, "viam_base")
    if err != nil {
        logger.Fatalf("cannot get base: %v", err)
    }

    // Move the rover in a square
    moveInSquare(context.Background(), roverBase, logger)
}

Move your base using GPS

To move a base component directly to a destination GPS point, you can use the motion service API’s MoveOnGlobe command.

If you’d like to plan a more detailed path through a series of waypoints, use the navigation service API. The following tutorial demonstrates how to use GPS navigation with a robot base:

Move your base on a SLAM map

To move a base component to a destination pose on a SLAM map, use the motion service API’s MoveOnMap command.