Products for USB Sensing and Control
Products for USB Sensing and Control

Tilt Controlled Rover

Using the Spatial Phidget as a Tilt Sensor


by Ben

Introduction

Prerequisites

This project assumes you have completed the following guides:

Hardware Overview

Controller

Attach the Spatial Phidget to your VINT Hub.

Open the Phidget Control Panel and verify everything is connected properly.

Rover

You can reuse your rover from the Rover Kit.

Software Overview

The Controls

The Rover is controlled by the orientation of the Spatial Phidget while it is being held in someone's hand. Tilting forward or back will move the rover forward or back. Tilting the Phidget left or right will result in the rover turning to the left or right.

Converting Sensor Data

The Spatial Phidget's accelerometer can measure all accelerations experienced by the sensor, including the acceleration due to gravity. As this acceleration always points down, it can be used to calculate orientation. Read the Calculating Tilt Angles Tutorial for a detailed explanation.

Once you have read the tutorial here are the relevant equations for reference:

`theta = tan^-1 (M_y/M_z) " " phi = tan^-1 (M_x/M_z)`


`theta = "roll angle "phi = "pitch angle"`
`M_x = "Measured x-axis acceleration"`
`M_y = "Measured y-axis acceleration"`
`M_z = "Measured z-axis acceleration"`

Implementation

In your Rover Kit, you converted thumbstick values into motor commands. In this project, you can retrofit that code by plugging in our Spatial data in place of the thumbstick commands.

Setup

Here you'll need to create Phidget Objects, attach Phidget Listeners and begin the control loop. Use this code snippet and flowchart to get started.

Don't worry if your programming language is not displayed below. The flowcharts are all you need to complete this project.

def main():
    accelerometer = Accelerometer()
    rightMotor = DCMotor()
    leftMotor = DCMotor()
                    
    # TODO: Configure Phidget devices 
                    
public static void main(String[] args) throws PhidgetException, java.io.IOException, InterruptedException{
    boolean programIsRunning = true;
                            
    Accelerometer accelerometer = new Accelerometer();
    DCMotor leftMotors = new DCMotor();
    DCMotor rightMotors = new DCMotor();
                            
    //TODO: Configure Phidget devices
                        
static void Main(string[] args)
{
    bool programIsRunning = true;

    DCMotor rightMotor = new DCMotor();
    DCMotor leftMotor = new DCMotor();
    Accelerometer accel = new Accelerometer();
    // TODO: Configure Phidget Devices

Events

Here you will update the tilt values in the listener and store them for later use. First the raw accelerometer data must be converted to a tilt angle. Next rescale the control value such that a 90 tilt forward will correspond to a control input of 1.

Note: accelerometer data comes in an array of three values, one for each axis.

def onAccelChange(self, accelerations, timestamp):
    global yAxis, xAxis

    xAcceleration = accelerations[0]
    yAcceleration = accelerations[1]
    zAcceleration = accelerations[2]

    #TODO: Convert and save tilt values to accessible variables
private static AccelerometerAccelerationChangeListener accelerationListener = new AccelerometerAccelerationChangeListener() {
	@Override
	public void onAccelerationChange(AccelerometerAccelerationChangeEvent ev) {
		double xAcceleration = ev.getAcceleration()[0];
		double yAcceleration = ev.getAcceleration()[1];
		double zAcceleration = ev.getAcceleration()[2];

		//TODO: Convert and save tilt values to accessible variables
	}
};
static void onAccelChange(object sender, AccelerometerAccelerationChangeEventArgs e)
{
    double xAcceleration = e.Acceleration[0];
    double yAcceleration = e.Acceleration[1];
    double zAcceleration = e.Acceleration[2];

    //TODO: Convert and save tilt values to accessible variables
}

Control Loop

Update the motors target velocity using the accelerometer tilt data.

try:
    while True:
        # TODO: Update Motors
except KeyboardInterrupt:
    # TODO: Quit Program and close phidgets
while (programIsRunning) {
	//TODO: Update Motors
	if (System.in.available() > 0) {
        System.out.println("Ending Program");
        programIsRunning = false;
    }
    Thread.sleep(20);
}
//TODO: Quit program and close phidgets
while (programIsRunning)
{
    //TODO: Update Motors
    if (System.Console.KeyAvailable)
    {
        Console.WriteLine("Ending Program");
        programIsRunning = false;
    }
}
// TODO: Close Phidgets

Conclusion

The Rover's path is now in your hands.

Have a cool project or suggestions for future education projects? Let us know at education@phidgets.com