Using a Touch Sensor to Detect and Avoid Obstacles

From ROBOTC API Guide
Jump to: navigation, search
ArduinoArduino Tutorials and Guided ProjectsLego + Arduino mobile robotics platform → Using whisker switches to detect and avoid obstacles

Contents

Our robot avoiding walls using the touch sensor


Concepts

Now that we know how a touch sensor can be used to start a program, let's expand on that idea and use the same concepts to detect when the robot hits a wall. Since a touch sensor will be always be in the same state (in this case open) when not pressed, if we set up the button to be "pressed" whenever the robot body is about to hit the wall, we can use the state of the sensor to detect the wall and stop driving forward. With a little extra code, we can even make the robot back up and avoid the wall.

Setup

On a standard model, the touch sensor for the LEGO robot is already right where we want it, at the front of the robot. The wiring on the touch sensor is exactly the same as before as well, so you can just leave everything the way it was from when you used the touch sensor as a start switch.

Programming

The sensor configuration is the same as before: Port 2, Touch Sensor. For this program, you can name the touch sensor simply “touchSensor” since it is no longer functioning as a start button. You should get a configuration code like this:

#pragma config(CircuitBoardType, typeCktBoardUNO)
#pragma config(PluginCircuitBoard, typeShieldDFRobotMotor)
#pragma config(UART_Usage, UART0, uartSystemCommPort, baudRate200000, IOPins, dgtl1, dgtl0)
#pragma config(Sensor, dgtl2,  touchSensor,    sensorTouch)
#pragma config(Motor,  motor_5,         rightServo,    tmotorInternalHBridgeSinglePWM, openLoop, reversed, IOPins, dgtl5, dgtl4)
#pragma config(Motor,  motor_6,         leftServo,     tmotorInternalHBridgeSinglePWM, openLoop, reversed, IOPins, dgtl6, dgtl7)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

Now that everything is configured, we need to plan the behavior. We want the robot to start of driving forward at speed 100. If the robot detects a wall via the touch sensor, then it will back up for 0.5 seconds, make a left point turn for 0.5 seconds, then resume driving forward. The robot should continue doing this indefinitely, so we know we will need a while loop. But how do we make the code change what it is doing based on sensor inputs? To do this we need to use an if() statement. There are several forms of if() statements, but for this code we will be using the base form:

if (condition)
{
  //code to run if condition is true
}

By placing an if() statement inside the while loop, and checking the touch sensor states, we can make the program respond to a touch sensor detecting a wall.

task main()
{
  while(true)
  {
    if (SensorValue[touchSensor] == true)
    {
      //code to avoid the wall
    }
 
    //drive forward at speed 100
    motor[leftServo] = 100;
    motor[rightServo] = 100;
  }
}

Now we just place the "Avoid Wall" code inside the If statement, and we get the following code.

#pragma config(CircuitBoardType, typeCktBoardUNO)
#pragma config(PluginCircuitBoard, typeShieldDFRobotMotor)
#pragma config(UART_Usage, UART0, uartSystemCommPort, baudRate200000, IOPins, dgtl1, dgtl0)
#pragma config(Sensor, dgtl2,  touchSensor,    sensorTouch)
#pragma config(Motor,  motor_5,         rightServo,    tmotorInternalHBridgeSinglePWM, openLoop, reversed, IOPins, dgtl5, dgtl4)
#pragma config(Motor,  motor_6,         leftServo,     tmotorInternalHBridgeSinglePWM, openLoop, reversed, IOPins, dgtl6, dgtl7)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//
 
task main()
{
  while(true)
  {
    if (SensorValue[touchSensor] == true)
    {
      //drive backwards at speed 100 for 0.5 seconds
      motor[leftServo] = -100;
      motor[rightServo] = -100;
      wait1Msec(500);
 
      //left point turn at speed 100 for 0.5 seconds
      motor[leftServo] = -100;
      motor[rightServo] = 100;
      wait1Msec(500);
    }
 
    //drive forward at speed 100
    motor[leftServo] = 100;
    motor[rightServo] = 100;
  }
}

Problems with using the Touch Sensor

  • As you can see in the video, if the robot is not coming head on against the object, the touch sensor will not activate the turn until the robot is very close to the wall and may accidentally cause the robot to hit the wall as it turns, which can do one of two things: it can throw off the robot's turn so that it doesn't turn far enough away from the object, or it can cause the robot to get hung up on the object and become disabled.

The easy solution to this would be to back up farther at the end of each forward move, but as the footage in the corners should show, that can mess up the robot even more if there are other objects right behind it.

  • The touch sensor is not entirely reliable. Especially when it does not have anything attached to it, it will not register a glancing hit. Anything other than a direct 90 degree touch on the object, and the robot will get stuck on the object and continue forward for eternity.

A simple apparatus like the one on the sensor below may help the touch sensor react better in most situations, but even so, sometimes it will still miss an object or not push the sensor's button and thereby allow the robot to collide with the obstacle.

Lego Touch Sensor pushing aid.jpg

(Our touch sensor aid was made with a 3 length axle and a small gear from the Lego Mindstorms kit)

  • The touch sensor requires you to get very close to the object that you intend to avoid, which can lead to problems, like the crevice that the robot fell into in the video.

In general, other sensors covered elsewhere on this site can perform an avoidance program like this much more reliably than the touch sensor does. For now, however, the touch sensor will have to do.

Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox