Here's a leader BOE Shield-Bot followed by a shadow BOE Shield-Bot. The lead robot is running a modified version of FastIrRoaming (with maneuver speeds reduced to +/- 40). The shadow BOE Shield-Bot is running FollowingShieldBot. One lead robot can string along a chain of 6 or 7 shadow robots. Just add the paper panel to the rest of the shadow BOE Shield-Bots in the chain.
- If you are working on your own with one BOE Shield-Bot, you will be the leader! The leader-object can be a book, bottle or even just your hand.
- If you are part of a class with two or more BOE Shield-Bots, mount a paper panel around the tail and both sides of a lead robot to make it more visible to the shadow robots, like in the picture. If you are making a chain of shadow robots, put a paper panel on each of them too.
- Program the lead BOE Shield-Bot with SlowerIrRoamingForLeaderBot.
- Program each shadow BOE Shield-Bot with FollowingShieldBot. Each shadow robot’s IR LEDs should be pointing slightly to the left and right, and level with horizontal (not up or down).
- Place a shadow BOE Shield-Bot behind the lead BOE Shield-Bot or other leader-object. The shadow BOE Shield-Bot should follow the leader at a fixed distance, so long as it is not distracted by another object such as a hand or a nearby wall.
/* * Robotics with the BOE Shield - SlowerIrRoamingForLeaderBot * Adaptation of RoamingWithWhiskers with IR object detection instead of * contact switches */ #include <Servo.h> // Include servo library Servo servoLeft; // Declare left and right servos Servo servoRight; void setup() // Built-in initialization block { pinMode(10, INPUT); pinMode(9, OUTPUT); // Left IR LED & Receiver pinMode(3, INPUT); pinMode(2, OUTPUT); // Right IR LED & Receiver tone(4, 3000, 1000); // Play tone for 1 second delay(1000); // Delay to finish tone servoLeft.attach(13); // Attach left signal to pin 13 servoRight.attach(12); // Attach right signal to pin 12 } void loop() // Main loop auto-repeats { int irLeft = irDetect(9, 10, 38000); // Check for object on left int irRight = irDetect(2, 3, 38000); // Check for object on right if((irLeft == 0) && (irRight == 0)) // If both sides detect { maneuver(-40, -40, 20); // Backward 20 milliseconds } else if(irLeft == 0) // If only left side detects { maneuver(40, -40, 20); // Right for 20 ms } else if(irRight == 0) // If only right side detects { maneuver(-40, 40, 20); // Left for 20 ms } else // Otherwise, no IR detects { maneuver(40, 40, 20); // Forward 20 ms } } int irDetect(int irLedPin, int irReceiverPin, long frequency) { tone(irLedPin, frequency, 8); // IRLED 38 kHz for at least 1 ms delay(1); // Wait 1 ms int ir = digitalRead(irReceiverPin); // IR receiver -> ir variable delay(1); // Down time before recheck return ir; // Return 1 no detect, 0 detect } void maneuver(int speedLeft, int speedRight, int msTime) { // speedLeft, speedRight ranges: Backward Linear Stop Linear Forward // -200 -100......0......100 200 servoLeft.writeMicroseconds(1500 + speedLeft); // Set left servo speed servoRight.writeMicroseconds(1500 - speedRight); // Set right servo speed if(msTime==-1) // if msTime = -1 { servoLeft.detach(); // Stop servo signals servoRight.detach(); } delay(msTime); // Delay for msTime }
Your Turn – Experiment with the Constants
You can adjust the setpoint and proportionality constants to change the shadow BOE Shield-Bot’s behavior. Use your hand or a piece of paper to lead the shadow BOE Shield-Bot while doing these exercises:
- Try running FollowingShieldBot using values of kpr and kpl constants, ranging from 15 to 100. Note the difference in how responsive the BOE Shield-Bot is when following an object.
- Try making adjustments to the value of the setpoint constant. Try values from 0 to 4.
You might notice some odd behaviors. For example, if the set point is 0, it won’t back up. Want to figure out why?
- Repeat the control loop exercises from Activity #1 with the set point at zero. Can any measured distance cause it to back up with a set point of zero?