Pre-Start Ideas
Before the start of each match, you have 60 seconds to set up your robot
on the table. You will have to spend some of this time placing your
robot in the starting area, and aligning it so that it can see one of the
beacon signals. However, there should be plenty of time available for
doing other things. This page gives some examples.
Prestart function
The rrprestart() function allows your
robot to do things before the start of a match. This function will be run before the startup
sequence, and it is important that it ends within 60 seconds.
Typically, it will end when you press one of the buttons on the
Handyboard, or when you press a switch on your robot. You should not
use any infinite loop in this function!
In the startup procedure, you will be asked to arm your robot using
the START button on the Handyboard. If you also use this button in
your pre-start program, it is important to wait until the START button
is released before the rrprestart() function
ends - otherwise your robot could become armed and then start before you
intended! You can see how to do this properly in the examples
below.
Calibration - Timing
If your strategy relies on dead reckoning, the
timing of turns and moves will be important. Your 90° turns may be
only 80° if the battery is running low, or might be 100°
if the table surface has just been cleaned. You could do
some calibration before the start of each match, to improve the accuracy
of your moves.
Example - Turning:
Suppose you want your robot to learn how long it takes to turn through 90°.
You could press a switch to start it turning, then press a switch when it had turned far enough.
You could measure the time interval, and save it in a global variable, to be used in every
90° turn in your strategy - or better, in the left90()
and right90() functions which you should write.
Your program might look like this - note the prompts on the display to remind you what to do
in the heat of the competition:
float turn90; // global variable for 90 degree turn time
...
void rrprestart()
{
float start_time; // define a variable for timing
printf("Turn90: hit left to start & stop\n");
while (!digital(10)); // wait for left switch press
while (digital(10)); // wait for switch to be released
sleep(1.0); // give time to get your hand out of the way!
start_time = seconds(); // record the time
motor(1,50); // start turning
motor(2,-50);
while (!digital(10)); // wait for switch to be pressed again
turn90 = seconds() - start_time; // record the time interval
ao() // stop turning
printf("Turn90 = %f\n",turn90); // print result
sleep(4.0); // give time to read it
...
}
To improve accuracy, you could let the robot turn through 360°, and divide the measured time
by 4.
Pressing a switch on a spinning robot is not easy - you could put a spare switch on the top of
your robot to make this easier.
You could even remove the human involvement completely, by using the line detector or the
beacon receiver to tell when the robot has completed a full turn.
Calibration - Light
If you are using light sensors, especially using visible light, then
the lighting conditions on the table might affect the sensor
readings. For example, the lighting on the table in the competition
could be different from the lighting in the lab, and could cause your program
to make faulty decisions. You could calibrate your light sensors
before the start of each match to avoid this problem.
Example - Line detection:
Suppose your robot is using an optical sensor to detect the white
lines on the black table surface. It gets a value from the sensor,
and compares it with a threshold to decide whether it represents black
or white.
This calibration routine asks you to point the sensor at black and at
white parts of the table. It measures the sensor value for each,
and sets the threshold half-way between the white and black values.
Note that it uses the START button on the Handyboard, but it waits
for the button to be released before it continues.
int line_thresh; // global variable - threshold for line detection
...
void rrprestart()
{
int black, white; // define local variables
...
printf("Show me black!\n");
sleep(3.0); // give time to read that
while (!start_button()) // wait for start button
{
printf("Black = %d START to set\n", analog(6)); // show value
sleep(0.5); // avoid display flicker
}
black = analog(6); // get value for black from sensor
beep(); // acknowledge the press
while(start_button()); //wait for release
printf("Show me white!\n");
sleep(3.0); // give time to read that
while (!start_button()) // wait for start button
{
printf("White = %d START to set\n", analog(6)); // show value
sleep(0.5); // avoid display flicker
}
white = analog(6); // get value for white from sensor
beep(); // acknowledge the press
while(start_button()); //wait for release
line_thresh = (black + white) / 2; // calculate the threshold
printf("Threshold = %d\n", line_thresh); // and print it
sleep(4.0); // give time to read it
...
}
To improve accuracy, you could take a few different values for black and white,
and calculate averages.
Selecting Options
Another thing which you might want to do before the start of a match is to select some
options for your robot's behaviour. For example, you might want to use different strategies against
different opponents.
The example below shows how to select from a menu of four
options, using the START and STOP buttons. You could also use
the bump sensors or even optical sensors to do something
similar. There is another, simpler, example of selecting one
of two strategies in the example
program provided.
Example - Menu:
This example shows a simple menu which allows you to select one of 4 different strategies
using the STOP and START buttons on the Handyboard.
The STOP button steps through the options, and the START button selects
one and moves on to the next part of your pre-start program. Note
that it waits for the START button to be released before continuing -
this might be the last part of your pre-start program, and it is
important not to end this function while the START button is pressed.
int strategy = 0; // global variable, available to all functions
...
void rrprestart()
{
printf("Select strategy with STOP\n"); // message for user
while(!stop_button()); // wait for stop button
tone(1000.0, 0.2); // acknowledge STOP button
printf("Strategy = %d START to go\n",strategy);
while(stop_button()); // wait for release
while(!start_button()) // keep doing this until START pressed
{
if(stop_button()) // user wants next strategy
{
tone(1000.0, 0.2); // acknowledge STOP button
strategy = strategy + 1; // next strategy
if (strategy > 3) strategy = 0; // we only have 4 strategies
printf("Strategy = %d START to go\n",strategy);
sleep(0.8); // slow things down a bit
}
}
beep(); // acknowledge START button
while(start_button()); // wait for release
sleep(1.0); // extra delay for safety
...
}
This code is written so that if you hold the STOP button pressed, it cycles through all the
options, advancing every second.
You can also use it by pressing the STOP button briefly to advance to the next
option, but it can only respond once per second, due to the delays in
the loop.
The result is in the global variable strategy, which will have the
value 0, 1, 2 or 3. Your main program can use this to decide what
to do in different circumstances.
|