T3W5: Line+Distance Sensors

This week we will combine our work on the distance sensor and the line follower to allow multiple robots to drive along the same path without bumping into each other. The simplest way to do this is to stop the robot if it gets too close to the obstacle, and wait for the obstacle to move before starting up again. However this might not give us the smoothest ride!

If you haven't finished the line follower code from last week, that should be your first step since this week's project will build on it. Otherwise you can download last week's example program and then open it with the [Import] button on the MakeCode home page for the micro:bit.

Line + Distance Sensor Code

The plan is to use the line follower code from last week to steer the robot, but instead of going a constant speed (we used the variable FULLSPEED last week) we will pick the speed based on the readout from the distance sensor.

We will use the "on start" routine that waits for a button press before continuing to make it easier to handle the robot:

Program Constants and Variables

As before, we will make some constant variables that control how the robot works and insert them at the end of the "on start" code block. You can name them whatever makes sense to you, but these are the names and values I picked:

  • TOP_SPEED = 30 (sets the maximum speed the robot can go with no obstacles ahead)

  • TURN_MULT = 0.3 (fractional speed multiplier for the slower wheel when we do a turn)

  • MIN_DIST = 4 (object distance that makes us stop the robot)

We will also have two variables that are computed in the program: ObjDistance (from the sonar sensor) and Speed (set depending on ObjDistance).

Distance Sensing and Speed Setting

We will save the reading from the distance sensor in a variable called "ObjDistance" so we can refer to it multiple times in the program if needed without doing a new measurement each time.

Use an 'if/then/else' statement to set the Speed variable to 0 if the distance reading is closer than MIN_DISTANCE, or set Speed to TOP_SPEED if the reading is further than MIN_DISTANCE.

We can also change the headlight color to show us what is going on with the code - red for stop and green for go.

Line Following Code

We can use the line following code from last week with a couple of changes. We will set the speed for the wheels based on the Speed variable instead of the constants we had before. For full speed ahead, just change FULLSPEED to the Speed variable we set based on the object distance. For turning, instead of using the TURNSPEED constant we will compute the slower wheel speed by multiplying (Speed X TURN_MULT).

Final program version

Adding Features

The motion when the robot sees something in front of it is pretty jerky because the robot goes from full stop to full speed ahead repeatedly. Some people do drive this way, but most will start to slow down when they see traffic ahead and then gradually speed up as it clears. Try to program the robot to more gradually change the speed to smooth out the motion.

One way would be to add a third state based on the distance of the object where it slows down where it sees an object further ahead than the stopping distance.

You could add multiple states with different speeds for different distances to make it even smoother, or you could do some math to calculate the speed based on the distance rather than having a bunch of if/then/elseif statements.

Another way to smooth the motion would be to gradually change the speed over time instead of jumping between different speed values. Pick a target for the speed based on the distance to the object and change the speed toward the target by some constant increment (slew rate limited) or a fraction of the difference between the current speed and the target (exponential decay). Put a time delay in the forever loop to make sure the changes don't happen too fast to be useful.

In all these schemes you still need to have an emergency stop condition when the robot gets too close to the obstacle to avoid crashing!