P2 Task 1 - Obstacle Avoidance (Advanced)

Note

Practice 2 is optional. You don’t have to do it if you don’t feel like it. But its way more challenging and hence fun

The objective of this task is to design a controller, that on average solves the “Obstacle Avoidance” challenge at least 5 seconds quicker than the default controller, which is 61 s. So again, the time you have to beat is 61 s - 5 s = 56 s and your controller’s performance should be evaluated on at least 15 samples (run your best controller for 15 times). In this case we rule out any lucky shots. Scroll down for further instructions and tips.

After you are done with your controller, submit the following things in Moodle:
  • your Robotbenchmark username
  • the code of your controller (just a simple copy/paste)

After the submission deadline, the student who submitted the best controller will get a prize!

Note

You have to be logged in to the Robotbenchmark.net to save your results

_images/webots_task_1.png

Figure. 1: Environment for the obstacle avoidance taks

Getting You Going

The default controller already might seem too complicated, but take your time and examine what’s going on in the code line-by-line. Make sure you read the instructions provided in the simulator. Over there you will be told, that the robot has 5 distance sensors which are used for detecting obstacles. Each sensor will output a number that signifies the distace between the sensor and the closest object in front of it.

The default controller is already avoiding obstacles, but it does not know where it’s supposed to go (the robot has to cross the red line in the other side of the room). For that, the instructions give you a hint that you can use a compass that’s “built-in” to the robot. Yet for some it might be bit tricky to set-up the compass in the Python code.

Therefore you will be given a slight advantage: below you can find the default controller with the compass related code already included into the script. It’s up to you how you use it.

"""Braitenberg-based obstacle-avoiding robot controller."""

import math                    # Import math Library, we need it to calculate the tangent
from controller import Robot   # Import the Robot class
from controller import Compass # import Compass module

# Get reference to the robot.
robot = Robot()

# Get simulation step length.
timeStep = int(robot.getBasicTimeStep())

# get robot's Compass device
compass = robot.getCompass("compass")

# enable the Compass
compass.enable(timeStep)

# Constants of the Thymio II motors and distance sensors.
maxMotorVelocity = 9.53
distanceSensorCalibrationConstant = 360

# Get left and right wheel motors.
leftMotor = robot.getMotor("motor.left")
rightMotor = robot.getMotor("motor.right")

# Get frontal distance sensors.
outerLeftSensor = robot.getDistanceSensor("prox.horizontal.0")
centralLeftSensor = robot.getDistanceSensor("prox.horizontal.1")
centralSensor = robot.getDistanceSensor("prox.horizontal.2")
centralRightSensor = robot.getDistanceSensor("prox.horizontal.3")
outerRightSensor = robot.getDistanceSensor("prox.horizontal.4")

# Enable distance sensors.
outerLeftSensor.enable(timeStep)
centralLeftSensor.enable(timeStep)
centralSensor.enable(timeStep)
centralRightSensor.enable(timeStep)
outerRightSensor.enable(timeStep)

# Disable motor PID control mode.
leftMotor.setPosition(float('inf'))
rightMotor.setPosition(float('inf'))

# Set ideal motor velocity.
initialVelocity = 0.7 * maxMotorVelocity

# Set the initial velocity of the left and right wheel motors.
leftMotor.setVelocity(initialVelocity)
rightMotor.setVelocity(initialVelocity)

while robot.step(timeStep) != -1:

    # Read the raw values from the compass and convert them to a heading angle
    compass_raw_values = compass.getValues()
    heading_raw = math.atan2(compass_raw_values[0], compass_raw_values[2]);
    heading = (heading_raw - 1.5708) / 3.1416 * 180.0

    if (heading < 0.0):
        heading = heading + 360.0

    # It is up to you how you use the "heading" to direct the robot. You can print the values to the
    # console but this slows the simulation down significantly. Just have a look at the vaules and then
    # comment it out

    # print ("heading = " + str(heading))

    # Read values from four distance sensors and calibrate.
    outerLeftSensorValue = outerLeftSensor.getValue() / distanceSensorCalibrationConstant
    centralLeftSensorValue = centralLeftSensor.getValue() / distanceSensorCalibrationConstant
    centralSensorValue = centralSensor.getValue() / distanceSensorCalibrationConstant
    centralRightSensorValue = centralRightSensor.getValue() / distanceSensorCalibrationConstant
    outerRightSensorValue = outerRightSensor.getValue() / distanceSensorCalibrationConstant

    # Set wheel velocities based on sensor values, prefer right turns if the central sensor is triggered.
    leftMotor.setVelocity(initialVelocity - (centralRightSensorValue + outerRightSensorValue) / 2)
    rightMotor.setVelocity(initialVelocity - (centralLeftSensorValue + outerLeftSensorValue) / 2 - centralSensorValue)