Now that you can measure centimeter distances with the PING))) sensor, and know which kinds of objects it can sense, let’s combine the sensor's input with the servo motor's output.
Our goal is for the ActivityBot to roam and avoid objects using sound with the PING))) sensor. In one way, this is an improvement over whisker-switch navigation, because the ActivityBot does not have to bump into objects to detect them.
But, there is a key difference: there were two whisker switches. With whiskers, the ActivityBot could tell whether an obstacle was on the left or the right, and then turn away in the opposite direction. The PING))) sensor returns a distance value but does not indicate whether the obstacle is more to the left or the right.
Let's start with test code that makes the ActivityBot turn right or left at random when an object comes within 20 cm. Once that is working and tuned, then you'll add blocks for roaming.
This example program makes the ActivityBot stay still until the PING))) measured distance is 20 cm or less. Then, it turns in place until it measures more than 20 cm, which means the robot turned until the object is no longer visible.
Since this code makes the robot drive, it begins with a frequency out block for the brownout indicator piezospeaker on P4. Next comes the required Robot ActivityBot initialize block. The Robot set acceleration block is set to a moderate 600 ticks/s2 to start.
The rest of the code is in a repeat forever loop. It begins with a repeat while loop. The while condition is a compare values block, checking to see if the value provided by the Ping distance block is greater than or equal to 20. If the answer is true, the code executes the pause 5 (ms) block and then checks the PING))) sensor again. This action will keep repeating, effectively putting code execution on standby until the while condition is no longer true.
When that happens, code execution drops down to the next block. The set variable block makes turn equal to a random number from 1 to 2. That's the BlocklyProp way of flipping a coin to decide which way the ActivityBot should turn. The "coin flip" is checked in the if...do...else...if block. If turn = 1 is true, then the block Robot drive speed left 64, right -64 gets executed, and the ActivityBot turns right. If turn = 1 is not true, then the block next to else is executed, and Robot drive speed left -64, right 64 makes the ActivityBot turn left.
The if...then...else...if block is followed by another repeat while loop. This time, the while condition checks if the Ping distance measurement is less than 20. The code execution stays in standby mode as long as this is true. Staying in standby mode allows the ActivityBot to continue its rotation maneuver until the PING))) sensor reports a measurement greater than 20, meaning that it has turned past the obstacle. Then, code execution continues to the Robot drive stop block which makes the ActivityBot quit turning.
Finally, the code execution returns to the top of the repeat forever loop, where it once again will sit still and check the PING))) distance every 5 ms until an object comes closer than 20 cm.
Redundant subsystems - Whiskers switches rely on touch, and the PING))) sensor relies on ultrasound. As you may have noticed, each one has advantages and disadvantages. In real-world control systems, different types of sensors that depend on various physical properties are often used together, which can help make the system more reliable under a wider variety of conditions. Where risk is low, redundant sub-systems can seem silly, like wearing a belt with a pair of suspenders. But where risk is high, redundant subsystems are critically important. Can you think of any examples?
By adding just two blocks, the example code above can free the ActivityBot to roam. Right now, the ActivityBot stays still unless it detects an object within 20 cm. All that is needed is a block that allows it to drive forward unless an object is detected within 20 cm. If an object is detected that close, it must stop driving forward before performing the turn-away maneuver.