Control a Robot Dog with a Custom Viam Base Component

The base component type is useful for controlling mobile robots because it gives users intuitive steering controls to use in code as well as from the Viam app remote control interface.

Viam natively supports a wheeled base model, but if you have a quadruped or other form of rover that isn’t compatible with the wheeled model, you have two options:

  1. Use Viam’s Go SDK to create a custom component as a modular resource.
  2. Use another Viam SDK (for example, the Python SDK) to create a custom resource server.

This tutorial demonstrates option two, using this robot dog kit and its open source code as an example.

By the end of the tutorial, you will be able to drive this dog around using the Viam base methods: MoveStraight, Spin, SetPower, SetVelocity, and Stop. You will also be able to use the Control tab in the Viam app to remotely drive the dog around using your keyboard while viewing the camera feed. You’ll learn to implement a custom component type in Viam, and you’ll be equipped to implement other sorts of custom components in the future for whatever robots you dream up.

Code used in this tutorial

Hardware requirements

Raspberry Pi setup

Freenove documentation includes Raspberry Pi setup instructions but we recommend the following steps to make sure the Pi is set up for this tutorial:

  1. Follow the steps in our Raspberry Pi Setup Guide to install Raspberry Pi OS Lite (64 bit).
  1. Install viam-server and connect your robot to the Viam app.

  2. SSH into the Pi to complete the following steps.

  3. Install pip and then git:

    sudo apt install pip
    
    sudo apt install git
    
  4. Navigate to the directory on the Pi where you’d like to install the Freenove robot dog code (for example /home/fido/). Get the code by running the following command:

    git clone https://github.com/Freenove/Freenove_Robot_Dog_Kit_for_Raspberry_Pi
    
  1. Check which version of Python you have installed on the Pi:

    python --version
    

    If it isn’t Python 3.8 or later, install an updated version of Python and double-check that you’re running the latest Raspberry Pi OS.

  2. Install the Viam Python SDK:

    pip install viam-sdk
    
  3. Enable I2C per the instructions in the Raspberry Pi Setup Guide.

  4. Alter the I2C baud rate according to Chapter 1, Step 2 in the Freenove instructions (page 40 as of January 24, 2023).

  5. Install smbus so that the servo code works:

    sudo apt-get install python3-smbus
    
  6. Follow Chapter 1, Step 3 (page 42 as of January 24, 2023) of the Freenove tutorial to complete the software installation:

    cd /home/fido/Freenove_Robot_Dog_Kit_for_Raspberry_Pi/Code
    sudo python setup.py
    
  7. Restart the Raspberry Pi:

    sudo reboot
    

Hardware setup

Follow the Freenove hardware assembly instructions, including servo setup (all of Chapters 2 and 3, and the section of Chapter 4 about calibration) before proceeding.

Check connection between the robot dog server and the midlayer

Before proceeding with the custom component implementation, follow the instructions in this section to test the connection between the Freenove server running on your robot dog and the code running on your development machine (laptop or desktop). This way, you can isolate any client-server connection problems if you encounter one.

Create a connection test file

In a convenient directory on your development machine, create a Python file and open it in your favorite IDE. We named ours “dog_test.py” and opened it in Visual Studio Code.

Paste the following code snippet into the file you created:

# dog_test.py is for testing the connection

import socket, time

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("PASTE DOG IP ADDRESS HERE", 5001))

cmd = "CMD_MOVE_FORWARD#8"
s.send(cmd.encode("utf-8"))
time.sleep(8)
cmd = "CMD_MOVE_STOP"
s.send(cmd.encode("utf-8"))
cmd = "CMD_RELAX"
s.send(cmd.encode("utf-8"))

Save the file.

Find IP address

Go to the robot page for your robot dog that you created when installing viam-server on the Pi.

In the banner towards the top of the page, the IP address of the robot dog Pi is displayed under ips. Copy the IP to your clipboard. Inside dog_test.py, replace PASTE DOG IP ADDRESS HERE with the copied IP. Save the file.

Test the connection

Place the robot dog on a flat, open surface where it has room to take a few steps.

Now you are ready to run the connection test file.

Open two terminal windows on your development machine: one for the robot dog Pi and one for the development machine.

In one terminal, SSH into the Pi using the username and hostname you set up when imaging the Pi, for example:

ssh fido@robotdog.local

Navigate to the /home/fido/Freenove_Robot_Dog_Kit_for_Raspberry_Pi/Code/Server directory.

Start the robot dog server by running:

sudo python main.py -tn

In the other terminal window, navigate to the directory on your development machine where you saved dog_test.py. Run the connection test file with the following command:

python dog_test.py

If the dog walks forward for a few seconds and then stops, the connection works and you can successfully send commands to the robot dog server. Continue on to implement the base.

If the robot dog did not respond, double check your IP address, make sure the robot dog server is still running, and make sure the robot has adequate power. You can also try turning the robot off and on again, and then retrying the process.

Implement the custom base code

From the Raspberry Pi terminal, create a directory inside the home directory to hold your custom code files:

mkdir RobotDog

Define the custom base interface

To create a custom base model, you need to subclass the base component type. In other words, you need a script that defines what each base component method (for example set_power) makes the robot dog do.

Take a look at my_robot_dog.py. It creates a “RobotDog” model of the base component type, and defines the set_power, stop, is_moving, and do methods by specifying which corresponding commands to send to the Freenove dog server when each of these methods is called. For example, the stop method sends a command (CMD_MOVE_STOP#8) to the robot dog server to stop the dog from moving:

    async def stop(self, extra: Optional[Dict[str, Any]] = None, **kwargs):
        self.is_stopped = True

        command = "CMD_MOVE_STOP#8\n"
        self.send_data(command)

Feel free to tweak the specific contents of each of these method definitions, and add support for other base methods like spin. You can read about the base API here.

Save my_robot_dog.py into the RobotDog directory you created.

Register the custom component

Now that you defined the methods for the custom component, you need to make your custom component available to any robots trying to connect to it.

Save python_server.py into the RobotDog directory. The python_server.py file creates an RPC server that forwards gRPC requests from viam-server (or elsewhere) to the custom component.

Configure the custom component server as a remote

You need to tell your robot how to access the custom component server you created. This is accomplished by configuring the custom component server as a remote.

Back over on the Viam app, go to your robot’s Config tab. Click the Remotes subtab. Name your remote “my-custom-base” and click Create Remote. In the Address field put localhost: 9090. Click Save Config at the bottom of the page.

Screenshot of the Viam app CONFIG tab with the Remotes subtab open, showing my-custom-base configured as a remote.

Configure the components

Now that the custom base code is set up, you need to configure all your hardware components. Navigate to the Components subtab of the Config tab.

Configure the base

In the Create Component field, give your base a name. We called ours “quadruped”. In the Type drop-down select base. In the Model field, type in “RobotDog”. Click Create Component.

You don’t need to add any attributes to the base component.

Click Save Config.

Configure the camera

Configure the ribbon camera on the dog as a webcam following our webcam documentation.

Start the servers

To operate the dog, you need to start the two servers in order:

  • First, the Freenove robot dog server (which you saved as /home/fido/Freenove_Robot_Dog_Kit_for_Raspberry_Pi/Code/Server/main.py).
  • Then, the custom component server (/home/fido/RobotDog/python-server.py). This one must be started second because it sends requests to the Freenove dog server, so it will throw errors if it can’t find that server when it tries to start.

From the home/fido/Freenove_Robot_Dog_Kit_for_Raspberry_Pi/Code/Server/ directory start the Freenove robot dog server:

sudo python main.py -tn

Then, open another terminal, SSH to the Pi, and navigate to the directory where you saved your custom Viam component code (for example, /home/fido/RobotDog/). Start the custom component server by running:

python python_server.py

Driving the robot from the Viam app

Navigate to the Control tab.

Click the my-custom-base:my-robot-dog component panel to expand it and reveal the controls.

Screenshot of the Control tab with the custom base card expanded to reveal arrow control buttons.

  1. Enable the camera stream from the Select Cameras drop-down.
  2. Toggle the Keyboard Disabled switch to Keyboard Enabled to use the WASD keys on your keyboard.
  3. Use the W, A, S and D buttons to make the robot walk forward, turn left, walk backward or turn right.

Troubleshooting

  • If your servos aren’t moving as expected or at all, try turning the whole robot off for a while to let them cool down.

  • Make sure the robot’s batteries have adequate charge. If you have otherwise unexplained connection errors, try powering things off and charging the batteries for a while before attempting to SSH to the Pi again.

  • If certain sensors or servos aren’t being found by the software, turn off the robot and make sure all wires are fully connected before turning it back on.

  • If you want to send commands directly to the dog server instead of running my_robot_dog.py (which may be helpful for debugging specific commands, especially if you’re adding your own functionality and need to calibrate servo speeds/positions) you can do the following:

    1. Install Netcat if it isn’t already installed:

      sudo apt install netcat
      
    2. Connect directly to the robot dog by running the following command (replacing with the correct IP address, for example nc 10.0.0.123) from the command line while SSHed into the Pi:

      nc <DOG IP ADDRESS> 5001
      
    3. You can now type commands (see the list of available commands here) and hit enter to send them to the Freenove robot dog server. For example:

      CMD_TURN_LEFT#30
      CMD_STOP
      

Next steps

In this tutorial you learned how to implement a custom component model and control it using the Viam app. You learned about configuring remotes and processes. You drove the robot dog around using the Viam Control tab.

To add more functionality, try defining more of the base API methods for this model. You could also use the Viam Vision Service with the robot dog’s camera component. For example, you could write code to tell the robot dog to move towards a colored target or to follow a colored line, similarly to how these tasks are done with wheeled bases in the tutorials linked here.

You can also ask questions in the Community Discord and we will be happy to help.



Have questions, or want to meet other people working on robots? Join our Community Discord.