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

Autonomous Light Tracking Rover

Some light autonomy


by Ben

Introduction

Prerequisites

This project assumes you have completed the following guides:

  • Getting Started Kit
  • Rover Kit

For more information, check out the Student Page.

Hardware Overview

Starting with a fully assembled Rover Kit, the two light sensors will be mounted in place of the Sonar Phidget. Mount the sensors on the front of the rover facing outward at an angle to increase the field of vision of the robot.

Software Overview

Goal

When you complete this project, your rover will be able to turn itself towards the brightest light source in its field of view. Later, more advanced behaviours such as approaching or following a light source can easily be added.

Interpreting Light Data

Since this is an autonomous vehicle, the motor commands for the rover must be derived entirely from the on board light-sensing Phidgets.

In the example above, the left light sensor recieves a greater share of the light. The control algorithm should interpret this as a signal to turn to the left.

You can create a simple algorithm to complete this task by measuring the difference between the intensities of the lights and turning towards the brighter side. A larger difference in readings should result in a larger magnitude of turning correction.

Configuring Motors

Because we are controlling the motors directly from a control algorithm, we want the motors to be as responsive as possible. This can be accomplished through setting the motor acceleration to its maximum value.

The Light Phidget returns new values every 125 milliseconds, or 8 times per second. Limiting the target velocity range to [-0.5, 0.5] will help your Rover move more smoothly based on this update rate.

Implementation

Step 1: Setup

Here we need to setup the phidgets.

    


public static void main(String[] args) throws PhidgetException {

    Net.addServer("", "192.168.100.1", 5661, "", 0);

    LightSensor leftLight = new LightSensor();
    LightSensor rightLight = new LightSensor();
    DCMotor leftMotors = new DCMotor();
    DCMotor rightMotors = new DCMotor();

    // TODO: Address Objects, Register for Events, Open Objects,
    //       Set Light Objects Data Interval to Min,
    //       Set DCMotor Objects Acceleration to Min

}

    

def main():

    Net.addServer("hub5000", "192.168.100.1", 5661, "", 0)

    leftLight = LightSensor()
    rightLight = LightSensor()
    leftMotors = DCMotor()
    rightMotors = DCMotor()
    
    # TODO: Address Objects, Register for Events, Open Objects,
    #       Set Light Objects Data Interval to Min,
    #       Set DCMotor Objects Acceleration to Min

main()    

    
    
class Program
{
    // Define these variables here so they can be accessed anywhere
    static DCMotor rightMotor;
    static DCMotor leftMotor;
    static double luxValueRight;
    static double luxValueLeft;
    const double SENSITIVITY = 1.0 / 300.0; //Used in Control Loop
    const double MAX_TARGET_VELOCITY = 0.5; //Used in Control Loop

    static void Main(string[] args)
    {
        bool programIsRunning = true;

        rightMotor = new DCMotor();
        leftMotor = new DCMotor();
        LightSensor lightRight = new LightSensor();
        LightSensor lightLeft = new LightSensor();

        Net.AddServer("hub5000", "192.168.100.1", 5661, "", 0);
        // TODO: Configure Phidget Devices. Ensure Motors are set to max acceleration
        //       and light sensors to min data interval.

Step 2: Events

In your Illuminance Change Events, you will have to store the light value for use in your main loop.

    


leftLight.addIlluminanceChangeListener(new LightSensorIlluminanceChangeListener() {
    public void onIlluminanceChange(LightSensorIlluminanceChangeEvent e) {
        System.out.println("Left Illuminance: " + e.getIlluminance());
        //TODO: Store illuminance for use in main loop
    }
});

rightLight.addIlluminanceChangeListener(new LightSensorIlluminanceChangeListener() {
    public void onIlluminanceChange(LightSensorIlluminanceChangeEvent e) {
        System.out.println("Right Illuminance: " + e.getIlluminance());
        //TODO: Store illuminance for use in main loop
    }
});


    

def onIlluminanceChangeLeft(self, illuminance):
    print("Illuminance Left: " + str(illuminance))
    # TODO: Store illuminance value for use in control loop

def onIlluminanceChangeRight(self, illuminance):
    print("Illuminance Right: " + str(illuminance))
    # TODO: Store illuminance value for use in control loop

    


private static void Left_IlluminanceChange(object sender, LightSensorIlluminanceChangeEventArgs e)
{
    Console.WriteLine("Illuminance Left: " + e.Illuminance);
    // TODO: Store illuminance for use in main loop
}
private static void Right_IlluminanceChange(object sender, LightSensorIlluminanceChangeEventArgs e)
{
    Console.WriteLine("Illuminance Right: " + e.Illuminance);
    // TODO: Store illuminance for use in main loop
}

Step 3: Main Loop

In your main loop, you will use the illuminance values to move your motors.

    


//previous code above ...

while(programIsRunning) {
    //TODO: define programIsRunning at the top of main
    //TODO: Update Motors Target Velocity based on illuminance values

    if (System.in.available() > 0) {
        System.out.println("Ending Program");
        programIsRunning = false;
    }

    Thread.sleep(50) //TODO: determine if this sleep time is adequate
}

//TODO: Close phidgets before program exits


    


def main():

    #previous code above ...
    
    try:

        while True:
            #TODO: Update Motors Target Velocity based on illuminance values
            time.sleep(0.05) #TODO: determine if this sleep time is adequate
        
    except KeyboardInterrupt:
        print("Ending Progam")

    # TODO: Close Phidgets

main()

    


//previous code above ...

while (programIsRunning)
{
    //TODO: define programIsRunning at the top of main
    //TODO: Update Motors Target Velocity based on illuminance values

    if (System.Console.KeyAvailable)
    {
        Console.WriteLine("Ending Program");
        programIsRunning = false;
    }

    System.Threading.Thread.Sleep(20); //TODO: determine if this sleep time is adequate
} 

// TODO: close Phidgets

Conclusion

You now have the basics of an autonomous light tracking rover! Next, try adding additional autonomous functionality to the rover like following a light source.

Have you made an autonomous rover? We'd love to hear about it at education@phidgets.com