Up to this point in the tutorial, your cyber:bot been been programmed to look slightly upwards and take evasive maneuvers when an object is detected. The component position and code can also be modified to look downward and take evasive maneuvers when an object is not detected, such as the surface it is driving on.
This capability would allow your cyber:bot to roam on a table without driving over the edge. However, driving off a table accidentally while experimenting could certainly be harmful to your cyber:bot. So, we will take advantage of a property of infrared light. Infrared light is absorbed by most black surfaces, and reflects off of most light-colored surfaces. By making a wide black border around a white surface, we can simulate a drop-off without putting the cyber:bot in any danger of falling.
Recommended Materials for a Simulated Drop-off
(1) Roll of black vinyl electrical tape, ¾″ (19 mm) wide, or black tempera paint and brush.
(1) Sheet of white poster board, 22 x 28 in (56 x 71 cm).
Ther are no new components or circuit changes needed for this application, just an adjustment to the position of the existing parts.
A sheet of white poster board with a border made of electrical tape or black tempera paint makes for a handy way to simulate the drop-off presented by a table edge, with much less risk to your cyber:bot.
#test_both_IR_indicators from cyberbot import * bot(22).tone(3000, 1000) while True: irL = bot(14, 13).ir_detect(37500) irR = bot(1, 2).ir_detect(37500) bot(20).write_digital(irL) bot(21).write_digital(irR)
If the cyber:bot still "sees" the electrical tape too clearly, here are a few remedies:
If you are using older IR LEDs, the cyber:bot might actually be having problems with being too nearsighted. Here are some remedies that will make it more far sighted:
For the most part, programming your cyber:bot to navigate around the virtual drop-off without going over the simulated edge is a matter of adjusting the if statements from the script fast_IR_roaming.
First of all, instead of backing up, it will need to go forward 20 ms at a time when it sees objects with both detectors.
It will also need to turn toward objects instead of away from them, and it will need to turn for more than 20 ms when it sees the drop-off. 375 ms turns seem to work well, but it will be up to you to adjust that value for best performance.
# avoid_table_edge from cyberbot import * def forward(): bot(18).servo_speed(75) bot(19).servo_speed(-75) sleep(20) def backwards(): bot(18).servo_speed(-75) bot(19).servo_speed(75) sleep(250) def right(): bot(18).servo_speed(75) bot(19).servo_speed(None) sleep(375) def left(): bot(18).servo_speed(None) bot(19).servo_speed(-75) sleep(375) while True: irL = bot(14, 13).ir_detect(37500) irR = bot(1, 2).ir_detect(37500) if irL == 0 and irR == 0: forward() elif irL == 1 and irR == 0: right() elif irL == 0 and irR == 1: left() else: backwards()
The script avoid_table_edge is just the script fast_IR_roaming with a modified if statement in its while True loop.
The condition that used to go forward for 20 ms now backs up for 250 ms. Likewise, the condition that used to back up now goes forward for 20 ms. Also, the condition that used to call for a 20 ms right turn now calls for a 375 ms left turn, and the condition that used to call for a 20 ms left turn now calls for a 375 ms right turn.
Let’s look at the two statements side by side:
In response to if irL == 0 and irR == 0, the script fast_IR_roaming backs up because both IR detectors see an obstacle. In contrast, the script avoid_table_edge goes forward because both IR detectors see the table, which means it’s safe to move forward for another 20 ms.
In response to else if irL == 0 and and irR == 1, the script fast_IR_roaming turns right for 20 ms, taking a step toward avoiding an obstacle on the left, while avoid_table_edge turns away from a drop-off that must be on its right.
Also, irR == 0 and irL == 1, fast_IR_roaming turns left for 20 ms, taking an incremental step toward avoiding an obstacle on the right while avoid_table_edge has the cyber:bot turning right.
Lastly, any other condition has the fast_IR_roaming driving forward while the avoid_table_edge goes backwards away from the table’s edge.
The turns to avoid the table edge can be adjusted for different applications. For example, if the cyber:bot is supposed to hug the edge of the table, smaller turns might be useful. In a contest where the cyber:bot is supposed to push objects out of an area, a larger turn (but not too large) would be better so that it zigzags back and forth across the table.
You can modify the code to make shallower turns by using a smaller sleep function argument. For example, if you change the 375 in the left()function to 300, it will make shallower left turns. If you change it to 450, it will make sharper left turns.
Drive your cyber:bot on an actual tabletop at your own risk!If you try a tabletop after success with the electrical tape or paint course: