Follow the Leader
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?