Tilt Controlled Rover

Learn how to use an accelerometer to control your Phidget Rover!

Prerequisites

Make sure you have completed the following projects before starting

Parts

Make sure you have all the parts before moving on.

Note: you can use any Phidget with an accelerometer for this project.

Phidget Rover

Phidget Cable

Spatial Phidget

USB Cable

VINT Hub Phidget

Setup

Step 1

You should have an assembled rover.

Step 2

Connect your Spatial Phidget to a wired VINT Hub. Connect the wired VINT Hub to your computer.

Do not connect the Spatial Phidget directly to your rover.

Write Code (Java)

Not your programming language? Set your preferences so we can display relevant code examples

  
package phidgetsrover;

//Add Phidgets Library
import com.phidget22.*;

public class PhidgetsRover {
  public static void main(String[] args) throws Exception{

        //Connect to wireless rover
        Net.addServer("", "192.168.100.1", 5661, "", 0);

        //Create
        DCMotor leftMotors = new DCMotor();
        DCMotor rightMotors = new DCMotor();
        Accelerometer acceleration = new Accelerometer();

        //Address
        leftMotors.setChannel(0);
        rightMotors.setChannel(1);

        //Open
        leftMotors.open(5000);
        rightMotors.open(5000);
        acceleration.open(1000);
        
        //Increase acceleration
        leftMotors.setAcceleration(leftMotors.getMaxAcceleration());
        rightMotors.setAcceleration(rightMotors.getMaxAcceleration());

        //Use your Phidgets
        while (true){
            //Get axis information
            double x = acceleration.getAcceleration()[0];
            double z = acceleration.getAcceleration()[2];

            //Calculate tilt angle
            double pitch = Math.round(Math.toDegrees(Math.atan(x/z)));
            System.out.println("Angle: " + pitch + "°");
            
            //Convert angle to value between -1 and 1
            double motorVelocity = pitch/90.0;

            //Move rover
            leftMotors.setTargetVelocity(motorVelocity);
            rightMotors.setTargetVelocity(motorVelocity);
            
            //Wait for 250 milliseconds
            Thread.sleep(250);
        }
    }
}
  
  
//Add Phidgets Library
import com.phidget22.*;

public class PhidgetsRover {
  public static void main(String[] args) throws Exception{

        //Connect to wireless rover
        Net.addServer("", "192.168.100.1", 5661, "", 0);

        //Create
        DCMotor leftMotors = new DCMotor();
        DCMotor rightMotors = new DCMotor();
        Accelerometer acceleration = new Accelerometer();

        //Address
        leftMotors.setChannel(0);
        rightMotors.setChannel(1);

        //Open
        leftMotors.open(5000);
        rightMotors.open(5000);
        acceleration.open(1000);
        
        //Increase acceleration
        leftMotors.setAcceleration(leftMotors.getMaxAcceleration());
        rightMotors.setAcceleration(rightMotors.getMaxAcceleration());

        //Use your Phidgets
        while (true){
            //Get axis information
            double x = acceleration.getAcceleration()[0];
            double z = acceleration.getAcceleration()[2];

            //Calculate tilt angle
            double pitch = Math.round(Math.toDegrees(Math.atan(x/z)));
            System.out.println("Angle: " + pitch + "°");
            
            //Convert angle to value between -1 and 1
            double motorVelocity = pitch/90.0;

            //Move rover
            leftMotors.setTargetVelocity(motorVelocity);
            rightMotors.setTargetVelocity(motorVelocity);
            
            //Wait for 250 milliseconds
            Thread.sleep(250);
        }
    }
}
  
  
//Add Phidgets Library 
import com.phidget22.*;

//Define
DCMotor leftMotors;
DCMotor rightMotors;
Accelerometer acceleration;

void setup(){
  try{
    
    //Connect to wireless rover
    Net.addServer("","192.168.100.1", 5661,"",0);
    
    //Create
    leftMotors = new DCMotor();
    rightMotors = new DCMotor();
    acceleration = new Accelerometer();
    
    //Address 
    leftMotors.setChannel(0);
    rightMotors.setChannel(1);
    
    //Open
    leftMotors.open(5000);
    rightMotors.open(5000);
    acceleration.open(5000);
    
    //Increase acceleration
    leftMotors.setAcceleration(leftMotors.getMaxAcceleration());
    rightMotors.setAcceleration(rightMotors.getMaxAcceleration());
    
  }catch(Exception e){
    //Handle Exceptions
    e.printStackTrace();
  }
}

void draw(){
  try{
    
    //Get axis information
    double x = acceleration.getAcceleration()[0];
    double z = acceleration.getAcceleration()[2];
    
    //Calculate tilt angles
    double pitch = Math.round(Math.toDegrees(Math.atan(x/z)));
    println("Angle: " + pitch + "°");
    
    //Convert angle to value between -1 and 1
    double motorVelocity = pitch/90.0;
    
    //Move Rover
    leftMotors.setTargetVelocity(motorVelocity);
    rightMotors.setTargetVelocity(motorVelocity);
    
    //Wait 250 milliseconds
    delay(250);
    
  }catch(Exception e){
    //Handle Exceptions
    e.printStackTrace();
  }
}
  

Write Code (Python)

Not your programming language? Set your preferences so we can display relevant code examples.

  
#Add Phidgets library
from Phidget22.Phidget import *
from Phidget22.Net import *
from Phidget22.Devices.Accelerometer import *
from Phidget22.Devices.DCMotor import *
#Required for sleep statement
import time
#Required for atan
import math

#Connect to your rover
Net.addServer("", "192.168.100.1", 5661, "", 0)

#Create
leftMotors = DCMotor()
rightMotors = DCMotor()
accel = Accelerometer()

#Address
leftMotors.setChannel(0)
rightMotors.setChannel(1)

#Open
leftMotors.openWaitForAttachment(5000)
rightMotors.openWaitForAttachment(5000)
accel.openWaitForAttachment(1000)

#Increase acceleration
leftMotors.setAcceleration(leftMotors.getMaxAcceleration())
rightMotors.setAcceleration(rightMotors.getMaxAcceleration())

#Use your Phidgets
while (True):
    #Get axes information
    x = accel.getAcceleration()[0]
    z = accel.getAcceleration()[2]

    #Calculate tilt angle
    pitch = round(math.degrees(math.atan(x/z)))
    print("Angle: " + str(pitch) + "°")
    
    #Convert angle to value between -1 and 1
    motorVelocity = pitch/90 

    #Move rover
    leftMotors.setTargetVelocity(motorVelocity)
    rightMotors.setTargetVelocity(motorVelocity)

    #Wait for 250 milliseconds
    time.sleep(0.25)
  

Write Code (C#)

Not your programming language? Set your preferences so we can display relevant code examples

  
//Add Phidgets Library
using Phidget22;

namespace PhidgetsRover
{
    class Program
    {
        static void Main(string[] args)
        {

            //Connect to wireless rover
            Net.AddServer("", "192.168.100.1", 5661, "", 0);

            //Create
            DCMotor leftMotors = new DCMotor();
            DCMotor rightMotors = new DCMotor();
            Accelerometer accel = new Accelerometer();

            //Address
            leftMotors.Channel = 0;
            rightMotors.Channel = 1;

            //Open
            leftMotors.Open(5000);
            rightMotors.Open(5000);
            accel.Open(1000);

            //Increase acceleration
            leftMotors.Acceleration = leftMotors.MaxAcceleration;
            rightMotors.Acceleration = rightMotors.MaxAcceleration;

            //Use your Phidgets
            while (true)
            {

                // Get axes information
                double x = accel.Acceleration[0];
                double z = accel.Acceleration[2];

                //calculate tilt angles
                double pitch = System.Math.Round((System.Math.Atan(x / z)) * (180.0 / System.Math.PI));
                System.Console.WriteLine("Angle: " + pitch + "°");

                //Convert angle to value between -1 and 1
                double motorVelocity = pitch / 90.0;

                //Move rover
                leftMotors.TargetVelocity = motorVelocity;
                rightMotors.TargetVelocity = motorVelocity;

                //Wait for 250 milliseconds
                System.Threading.Thread.Sleep(250);
            }
        }
    }
}
  

Write Code (Swift)

Swift code sample coming soon. Not your programming language? Set your preferences so we can display relevant code examples

Run Your Program

When you tilt your Spatial Phidget, your rover will respond by moving forward or backwards.

Calculating Tilt Angles

Your Spatial Phidget has an accelerometer that measures acceleration in three axes. You can use this data to calculate tilt angles which can then be used to control your rover.

As shown in the image, gravity remains constant when the position/acceleration values of each axis changes. We can use the constant position of gravity to find out the angle of the roll and pitch.

Pitch

Pitch is the side to side movement.

Roll

Roll is the forward and backward movement.

Equations

The following equations are used to calculate pitch and roll in the provided code sample.

Practice

  1. View the pitch values output from your program to understand how the equations work. What is the output range of the pitch and how is it modified to set the velocity?
  2. Try running the code below, and completing the next set of practice problems.

Write Code (Java)

Not your programming language? Set your preferences so we can display relevant code examples


package phidgetsrover;

//Add Phidgets Library
import com.phidget22.*;

public class PhidgetsRover {
    public static void main(String[] args) throws Exception{
        //Connect to wireless rover
        Net.addServer("", "192.168.100.1", 5661, "", 0);

        //Create
        DCMotor leftMotors = new DCMotor();
        DCMotor rightMotors = new DCMotor();
        Accelerometer acceleration = new Accelerometer();

        //Address
        leftMotors.setChannel(0);
        rightMotors.setChannel(1);

        //Open
        leftMotors.open(5000);
        rightMotors.open(5000);
        acceleration.open(1000);

        //Increase acceleration
        leftMotors.setAcceleration(leftMotors.getMaxAcceleration());
        rightMotors.setAcceleration(rightMotors.getMaxAcceleration());

        //Use your Phidgets
        while (true){

            //Get axes information
            double x = acceleration.getAcceleration()[0];
            double y = acceleration.getAcceleration()[1];
            double z = acceleration.getAcceleration()[2];

            //calculate tilt angles
            double roll = Math.round(Math.toDegrees(Math.atan(y/z)));
            double pitch = Math.round(Math.toDegrees(Math.atan(x/z)));
            
            System.out.println("Roll Angle: " + roll + "°");
            System.out.println("Pitch Angle: " + pitch + "°");
            
            //Convert angles into values between -1 and 1
            roll = roll/90.0;
            pitch = pitch/90.0;

            //Turning code
            double leftMotorsSpeed = pitch + roll;
            double rightMotorsSpeed = pitch - roll;

            //Make sure input to the target velocity is between -1 and 1
            if(leftMotorsSpeed > 1) leftMotorsSpeed = 1;
            if(leftMotorsSpeed < -1) leftMotorsSpeed = -1;
            if(rightMotorsSpeed > 1) rightMotorsSpeed = 1;
            if(rightMotorsSpeed < -1) rightMotorsSpeed = -1;

            //Move rover
            leftMotors.setTargetVelocity(leftMotorsSpeed);
            rightMotors.setTargetVelocity(rightMotorsSpeed);

            //Wait for 250 milliseconds
            Thread.sleep(250);
        }
    }
}
  

//Add Phidgets Library
import com.phidget22.*;

public class PhidgetsRover {
    public static void main(String[] args) throws Exception{
        //Connect to wireless rover
        Net.addServer("", "192.168.100.1", 5661, "", 0);

        //Create
        DCMotor leftMotors = new DCMotor();
        DCMotor rightMotors = new DCMotor();
        Accelerometer acceleration = new Accelerometer();

        //Address
        leftMotors.setChannel(0);
        rightMotors.setChannel(1);

        //Open
        leftMotors.open(5000);
        rightMotors.open(5000);
        acceleration.open(1000);

        //Increase acceleration
        leftMotors.setAcceleration(leftMotors.getMaxAcceleration());
        rightMotors.setAcceleration(rightMotors.getMaxAcceleration());

        //Use your Phidgets
        while (true){

            //Get axes information
            double x = acceleration.getAcceleration()[0];
            double y = acceleration.getAcceleration()[1];
            double z = acceleration.getAcceleration()[2];

            //calculate tilt angles
            double roll = Math.round(Math.toDegrees(Math.atan(y/z)));
            double pitch = Math.round(Math.toDegrees(Math.atan(x/z)));
            
            System.out.println("Roll Angle: " + roll + "°");
            System.out.println("Pitch Angle: " + pitch + "°");
            
            //Convert angles into values between -1 and 1
            roll = roll/90.0;
            pitch = pitch/90.0;

            //Turning code
            double leftMotorsSpeed = pitch + roll;
            double rightMotorsSpeed = pitch - roll;

            //Make sure input to the target velocity is between -1 and 1
            if(leftMotorsSpeed > 1) leftMotorsSpeed = 1;
            if(leftMotorsSpeed < -1) leftMotorsSpeed = -1;
            if(rightMotorsSpeed > 1) rightMotorsSpeed = 1;
            if(rightMotorsSpeed < -1) rightMotorsSpeed = -1;

            //Move rover
            leftMotors.setTargetVelocity(leftMotorsSpeed);
            rightMotors.setTargetVelocity(rightMotorsSpeed);

            //Wait for 250 milliseconds
            Thread.sleep(250);
        }
    }
}
  

//Add Phidgets Library 
import com.phidget22.*;

//Define
DCMotor leftMotors;
DCMotor rightMotors;
Accelerometer acceleration;

void setup(){
  try{
    
    //Connect to wireless rover
    Net.addServer("","192.168.100.1", 5661,"",0);
    
    //Create
    leftMotors = new DCMotor();
    rightMotors = new DCMotor();
    acceleration = new Accelerometer();
    
    //Address 
    leftMotors.setChannel(0);
    rightMotors.setChannel(1);
    
    //Open
    leftMotors.open(5000);
    rightMotors.open(5000);
    acceleration.open(5000);
    
    //Increase acceleration
    leftMotors.setAcceleration(leftMotors.getMaxAcceleration());
    rightMotors.setAcceleration(rightMotors.getMaxAcceleration());
    
  }catch(Exception e){
    //Handle Exceptions
    e.printStackTrace();
  }
}

void draw(){
  try{
    
    //Get axis information
    double x = acceleration.getAcceleration()[0];
    double y = acceleration.getAcceleration()[1];
    double z = acceleration.getAcceleration()[2];
    
    //Calculate tilt angles
    double roll = Math.toDegrees(Math.atan(y/z));
    double pitch = Math.toDegrees(Math.atan(x/z));
    
    println("Roll Angle: " + roll + "°");
    println("Pitch Angle: " + pitch + "°");
    
    //Convert angles into values between -1 and 1
    roll = roll/90.0;
    pitch = pitch/90.0;
    
    double leftMotorSpeed = pitch + roll;
    double rightMotorSpeed = pitch - roll;
    
    //Make sure input to the target velocity is between -1 and 1
    if(leftMotorSpeed > 1) leftMotorSpeed = 1;
    if(leftMotorSpeed < -1) leftMotorSpeed = -1;
    if(rightMotorSpeed > 1) rightMotorSpeed = 1;
    if(rightMotorSpeed < -1) rightMotorSpeed = -1;
    
    //Move Rover
    leftMotors.setTargetVelocity(leftMotorSpeed);
    rightMotors.setTargetVelocity(rightMotorSpeed);
    
    //Wait for 250 milliseconds
    delay(250);
    
  }catch(Exception e){
    //Handle Exceptions
    e.printStackTrace();
  }
}
  

Write Code (Python)

Not your programming language? Set your preferences so we can display relevant code examples.

  
#Add Phidgets Library
from Phidget22.Phidget import *
from Phidget22.Net import *
from Phidget22.Devices.Accelerometer import *
from Phidget22.Devices.DCMotor import *
#Required for sleep statement
import time
#Required for atan
import math

#Connect to your rover
Net.addServer("", "192.168.100.1", 5661, "", 0)

#Create
leftMotors = DCMotor()
rightMotors = DCMotor()
accel = Accelerometer()

#Address
leftMotors.setChannel(0)
rightMotors.setChannel(1)

#Open
leftMotors.openWaitForAttachment(5000)
rightMotors.openWaitForAttachment(5000)
accel.openWaitForAttachment(1000)

#Increase acceleration
leftMotors.setAcceleration(leftMotors.getMaxAcceleration())
rightMotors.setAcceleration(rightMotors.getMaxAcceleration())

#Use your Phidgets
while (True):
    #Get axes information
    x = accel.getAcceleration()[0]
    y = accel.getAcceleration()[1]
    z = accel.getAcceleration()[2]

    #Calculate tilt angles
    roll = round(math.degrees(math.atan(y/z)))
    pitch = round(math.degrees(math.atan(x/z)))
    
    print("Roll Angle: " + str(roll) + "°")
    print("Pitch Angle: " + str(pitch) + "°")
    
    #Convert angles to values between -1 and 1
    roll = roll/90
    pitch = pitch/90

    #Turning code
    leftMotorsSpeed = pitch + roll
    rightMotorsSpeed = pitch - roll

    #Make sure input to the target velocity is between -1 and 1
    if(leftMotorsSpeed > 1): leftMotorsSpeed = 1
    if(leftMotorsSpeed < -1): leftMotorsSpeed = -1
    if(rightMotorsSpeed > 1): rightMotorsSpeed = 1
    if(rightMotorsSpeed < -1): rightMotorsSpeed = -1

    #Move rover
    leftMotors.setTargetVelocity(leftMotorsSpeed)
    rightMotors.setTargetVelocity(rightMotorsSpeed)

    #Wait 250 milliseconds
    time.sleep(0.25)
  

Write Code (C#)

Not your programming language? Set your preferences so we can display relevant code examples

  
//Add Phidgets Library
using Phidget22;

namespace PhidgetsRover
{
    class Program
    {
        static void Main(string[] args)
        {

            //Connect to wireless rover
            Net.AddServer("", "192.168.100.1", 5661, "", 0);

            //Create
            DCMotor leftMotors = new DCMotor();
            DCMotor rightMotors = new DCMotor();
            Accelerometer accel = new Accelerometer();

            //Address
            leftMotors.Channel = 0;
            rightMotors.Channel = 1;

            //Open
            accel.Open(1000);
            leftMotors.Open(5000);
            rightMotors.Open(5000);

            //Increase acceleration
            leftMotors.Acceleration = leftMotors.MaxAcceleration;
            rightMotors.Acceleration = rightMotors.MaxAcceleration;

            //Use your Phidgets
            while (true)
            {

                //Get axes information
                double x = accel.Acceleration[0];
                double y = accel.Acceleration[1];
                double z = accel.Acceleration[2];

                //Calculate tilt angles
                double roll = ((System.Math.Atan(y / z)) * (180.0 / System.Math.PI));
                double pitch = ((System.Math.Atan(x / z)) * (180.0 / System.Math.PI));

                System.Console.WriteLine("Roll Angle: " + roll + "°");
                System.Console.WriteLine("Pitch Angle: " + pitch + "°");

                //Convert angles into values between -1 and 1
                roll = roll / 90.0;
                pitch = pitch / 90.0;

                //Turning code
                double leftMotorsSpeed = pitch + roll;
                double rightMotorsSpeed = pitch - roll;

                //Make sure input to the target velocity is between -1 and 1
                if (leftMotorsSpeed > 1) leftMotorsSpeed = 1;
                if (leftMotorsSpeed < -1) leftMotorsSpeed = -1;
                if (rightMotorsSpeed > 1) rightMotorsSpeed = 1;
                if (rightMotorsSpeed < -1) rightMotorsSpeed = -1;

                leftMotors.TargetVelocity = leftMotorsSpeed;
                rightMotors.TargetVelocity = rightMotorsSpeed;

                //Wait for 250 milliseconds
                System.Threading.Thread.Sleep(250);

            }
        }
    }
}
  

Write Code (Swift)

Swift code sample coming soon. Not your programming language? Set your preferences so we can display relevant code examples

Run Your Program

When you tilt your Spatial Phidget, your rover will move forward and backwards, and will also turn.

Practice

  1. Try understanding how the turning code works by completing the following table.
  
double leftMotorsSpeed = pitch + roll;
double rightMotorsSpeed = pitch - roll;

  
leftMotorsSpeed = pitch+ roll
rightMotorsSpeed = pitch- roll
  

  
double leftMotorsSpeed = pitch + roll;
double rightMotorsSpeed = pitch - roll;
  
pitch roll leftMotorsSpeed rightMotorsSpeed Result
1.0 0.0 1.0 1.0 Move Forward
-1.0 0.0 ? ? ?
0.0 1.0 ? ? ?
0.0 -1.0 ? ? ?

What are Phidgets?

Phidgets are programmable USB sensors. Simply plug in your sensor, write code in your favorite language and go!

Phidgets have been used by STEM professionals for over 20 years and are now available to students.

Learn more

Set your preferences

Windows

Mac OS

Raspberry Pi

Java

Python

C#

Swift

NetBeans

Processing

Eclipse

Thonny

PyCharm

PyScripter

Visual Studio

Xcode

Setting your preferred operating system, programming language and environment lets us display relevant code samples for the Getting Started Tutorial, Device Tutorials and Projects

Done