project report for the slider robot · pdf fileproject report for the slider robot ... a...
TRANSCRIPT
2D1426 Robotics and Autonomous Systems
Group 6: ”The Slider”
Project Report for The Slider robot
Team Members
Fredrik Bengtsson [email protected] Petter Flodström [email protected] Michael Roterman [email protected]
Abstract This document gives a detailed description of the function and design of our robot Slider, which was built as a project in the course 2D1426 Robotics and Autonomous Systems at the Royal Institute of Technology, Stockholm. The goal was to construct a robot that could play hockey by itself on a small hockey rink. It was largely constructed from scratch and presented several interesting challenges, both regarding design and construction of hardware and software. Ending up as a peculiar combination of Meccano, LEGO, electronics and Velcro strip, the end result described in this document actually performed very well in the final competitions.
Robotics and Autonomous Systems project report Group 6: The Slider
2
Index
Index _____________________________________________________________________ 2 Introduction _______________________________________________________________ 3 Rules and Setup ____________________________________________________________ 3 Hardware _________________________________________________________________ 8
Motherboard ____________________________________________________________ 8 PIC:s ___________________________________________________________________ 9 DIP switches_____________________________________________________________ 9 Driver circuits ___________________________________________________________ 9 Power switches__________________________________________________________ 10 Other important components______________________________________________ 10
IR sensing ________________________________________________________________ 11 Ground detectors ________________________________________________________ 12 Microswitches __________________________________________________________ 13 LCD display ____________________________________________________________ 13 IR driver board _________________________________________________________ 13
Strategy & Programming____________________________________________________ 14 Problems and solutions _____________________________________________________ 16 Conclusions ______________________________________________________________ 16 Appendix I – Circuitry ______________________________________________________ 18 Appendix II – Component List________________________________________________ 20 Appendix III – The C-code __________________________________________________ 21 Appendix IV – Image of the motherboard_______________________________________ 30 Appendix V – Additional robot images _________________________________________ 31 Appendix VI - References ___________________________________________________ 32
Robotics and Autonomous Systems project report Group 6: The Slider
3
Introduction
Each spring a course on Robotics and Autonomous Systems is held at the Royal Institute of
Technology. The objective of the course is to introduce the basic concepts of robotics. Along
with the course is a project where we, the students, get to construct a simple hockey-playing
autonomous robot from handed out material such as LEGO pieces, motors, IR-sensors and a
PIC 16F877 microcontroller board. By constructing our own robot we are introduced to how
an autonomous system works and the difficulties around constructing it. The controller
program is coded in C.
At the beginning of the course all the students are divided into groups of three, thus resulting
in seven project groups. We are also given the basic rules to how the robot should behave in
the final hockey tournament, and its physical limitations. Taking these rules into account, we
started constructing our robot, which we ended up calling “The Slider”.
For more information regarding this course, please refer to the course homepage 1.
Rules and Setup
The idea of the final hockey tournament is for the robots to move a puck towards the goals.
Each match consists of two players competing against each other. The robots are able to
navigate through the use of infrared emitting diodes that are located at each goal, and on the
puck. Each player also emits infrared light that gives each robot, if required, the ability to
sense its opponent.
The hockey rink has a white surface with black goal zones at both ends. The hockey rink
basically has the same proportions as a real ice hockey rink and measures an approximate
length of 2.5 m (7.5 ft).
1 URL: http://www.nada.kth.se/kurser/kth/2D1426, working 2001-05-31
Robotics and Autonomous Systems project report Group 6: The Slider
4
A goal is scored whenever the puck is within two centimeters of the goal aluminum plate (se
fig.1, white line in goal areas). As the robots are only allowed to enter within two centimeters
of the goal area, the robot must push in the puck without entering the goal area itself. This is
one of the challenges that must be overcome in order to score a goal.
After the robot has scored it must also play a pre-defined tune on its speaker.
Figure 1 – The rink
Image 1 – Goal area
Puck
Goal Area Score Area
Robotics and Autonomous Systems project report Group 6: The Slider
5
There are a number constraints imposed on the robot, that will affect its design:
• The diameter of the robot is restricted to 250 mm (this does not include the stick)
• May not have any concave parts on the body.
• The stick may not extend more than one puck diameter from the robot body.
• The stick may not be wider than one-half puck radius.
• The stick may not have any actively controlled rotary joints.
• The stick must not occlude the IR LEDs of the puck when guiding it.
For complete rules regarding the project, please refer to 2.
Design
After carefully reading the rules and studying the setup of the hockey rink, we started
discussing various ideas for how the robot would score. We wanted a solution that was solid
and would guarantee our robot of always scoring when approaching the goal.
As seen in previous years, there are many different solutions that can be used, the most
popular being a stiff or flexible stick. However, this solution will require the robot to swing
the puck into the goal, and implies that the robot will require speed and some free space to
score a goal. Another approach is to catapult the puck into the goal area; this solution requires
a complex mechanism and was therefore rejected by our group.
We decided to go for a design that had not been attempted before and would guarantee a
100% chance of scoring a goal.
Our design was based on the idea that the puck would roll off the stick when being pushed
towards the scoring area. This idea required the robot to get as close as possible to the goal.
2 URL: http://www.nada.kth.se/kurser/kth/2D1426/L3_2001.pdf, working 2001-05-31
Robotics and Autonomous Systems project report Group 6: The Slider
6
To realize our idea we finally constructed the stick from a metal plate that we custom built to
our liking. We fitted the stick with the 6V motor that would “catapult/move” the puck slowly
into the scoring area. See images 2, 3 and 4.
Image 2 – The stick
Image 3 – 6V motor
Our design does however have some downsides. By using our stick, which has a fixed angle,
it is hard for our robot to make an effective turn, thus resulting in a large turning radius to
prevent the robot from losing the puck.
Robotics and Autonomous Systems project report Group 6: The Slider
7
Image 4 – Scoring Sequence
We were also keen on keeping the robot small and simple, so that it could easily use the full
capacity of the motors. We decided to go with a modular design where all the crucial parts of
the robot where easily accessible for replacement. To build the base frame of the robot we
used meccano, this gives us a solid and firm structure in order to be able to withstand external
shocks from other robots and self inflicted collisions.
Robotics and Autonomous Systems project report Group 6: The Slider
8
To keep our robot fast and agile we decided to place
the DC motors directly connected to the wheels to
guarantee maximum torque. We therefore placed the
motors in the middle of the robot to obtain a balance
between the heavy NiCad batteries in the back, and
the stick arrangement in the front. Since we only used
two wheels we placed a screwdriver in the back to
keep the robot correctly balanced.
Hardware
In this chapter the hardware parts of the robot is discussed. A complete list of all hardware
such as accumulators, DC motors, etc. can be found in appendix II.
Motherboard
The center of the robot is its motherboard where all important electronics and hardware is
connected. A circuit diagram over the motherboard is found in appendix IV. Here is a picture
of the motherboard showing where different parts are located and where peripheral hardware
is connected.
The motherboard was insulated from the Meccano with small pieces of LEGO in order not to
be short-circuited. Some of the most important parts are the PIC:s, the driver circuits, the
power switches and the DIP switches.
Robotics and Autonomous Systems project report Group 6: The Slider
9
PIC:s
The “brain” of the robot is the main PIC, PIC16F87X. It’s a 40-pin 8-bit CMOS Flash micro
controller. The main PIC controls everything that the robot is supposed to do. Some pins read
values from switches and IR sensors, others control motor directions and speed. All this is
programmed via a serial RS232-interface and a piece of code in the main PIC called the
Bootloader. The interface is connected to the serial port of ordinary PC.
The other PIC is similar but only has 28 pins and is programmed only to handle the IR
processing. It continuously computes the different IR readings and provides them to the main
PIC.
DIP switches
On the motherboard there were six dipswitches. These had two states, on and off. The
switches were active low, so the off state gave 5V out and the on state gave 0V. Three of the
switches were already connected via the motherboard to different pins on the PIC. One of
these was used to tell the robot which goal was offensive and which was defensive. The last
three were unused and were free for us by us. The only DIP switch we used was number six,
which we connected to a pin on the PIC in order to be able to tell the PIC when to go to
downloading mode.
Driver circuits
On the motherboard there were four driver circuits - two for 12V and two for 6V. These were
of course used for the two 12V motors for the wheels and the 6V motor for the club. Each
driver circuit had two input pins, one for direction and one for controlling speed.
In our application the speed was regulated by PWM (Pulse Width Modulation) instead of an
analogue input voltage.
Robotics and Autonomous Systems project report Group 6: The Slider
10
Power switches
There were two different power switches: one for the main power where all power to the
motherboard was turned on or off, and one for the 12V driver circuits. This was very useful
when downloading to the PIC and debugging the robot. In those cases one wanted the robot to
stand still in order to measure values, check readings and uploading a new program.
Other important components
Some other parts are worth mentioning. There was one reset button used to restart the
program without turning the power off. There were also five sockets for connecting the IR
sensors.
One the motherboard there were numerous LEDs that by default were used for debugging.
We didn’t have any use for these since we used an LCD display which can give more
information.
Robotics and Autonomous Systems project report Group 6: The Slider
11
IR sensing
In order for the robot to orientate itself on the rink there were IR transmitters on the two
goals, the puck and on each robot. To separate the signals the different IR transmitters had
unique frequencies - one frequency for each goal and another for the puck. All playing robots
though used the same frequency. To detect the signals IR sensors were used. The detected
signals were then handled by a special PIC (see above), which can separate the different
signals and tell how strong they are on different sensors.
On the robot we mounted five IR sensors. Four of them were placed on the sides of a piece of
LEGO. This was done to achieve 360-degree vision, with each sensor covering a 90-degree
quadrant each (See Figure 2).
Figure 2 - Mounting of IR-sensors
The fifth IR sensor was mounted looking straight ahead in order to determine the distance to
the puck and goals. The reason to why an extra IR sensor was needed was because they were
very dependent on the angle towards the source of the signal. For example if the sensor was
looking at the source with an angle of 45 degrees the signal strength was approximately one
tenth of the strength compared to when it was looking straight at the source.
IR-detectors
Front of robot
Lego-
piece
Robotics and Autonomous Systems project report Group 6: The Slider
12
Ground detectors
To detect whether we were inside the goal zone or not, reflex detecors were used. Reflex
detectors consist of an IR transmitter and an IR sensor placed very close to each other. The
sensor then detects how much of the transmitted signal is reflected. Since the goal zone is
black and the rest of the rink save the centerline is white, the reflection differs and thus the
goal zone can be detected. The IR signals from the sensor are handled by the same PIC as for
the other IR sensors.
Image 5 shows how the reflex detectors were placed. Since they are able to work at distances
of 0.5 to 7 mm and the robot was quite flexible, all detectors were mounted so that they could
be easily adjusted. Detectors 0, 1 and 3 were mounted with Velcro strip and detector 2 was
placed with its connecting wires within at piece of LEGO so tight that no glue was needed but
it still was adjustable.
Image 5 – Reflex detectors
0
2
3
1
Robotics and Autonomous Systems project report Group 6: The Slider
13
Microswitches
In order to detect when we are holding the puck and knowing when the stick had reached its
end positions, a total of three micro switches were used. Micro switches are simply small
switches, which close an electrical circuit when pressed.
The switches were connected to the PIC via a large resistor as shown in Figure 3. This was
done to get distinct values of zero and five volts. If the resistor is not used one could get a
floating potential at the input.
Figure 3 – Micro switch connection to PIC pin
LCD display
An LCD display was used to monitor values from the different IR sensors. It was also very
useful in debugging. The display was connected on the 8 lowest pins on the D register of the
PIC.
IR driver board
The driver circuit for the IR transmitters was located on a separate daughter board. It gave
power to the IR beacon as well as to the transmitters on the reflex detectors. There was one
separate connection for the IR beacon and two connections for reflex detectors. Since all four
transmitters on the reflex detectors were connected in series we only used one of the
connections for these.
+5V
R
Input pin gnd
Robotics and Autonomous Systems project report Group 6: The Slider
14
Strategy & Programming
Logically, the robot was basically following a chase the puck, go for the goal, score scheme –
although it was broken down into several parts and special cases (see Figure 4). The robot
was almost purely reactive, except in a few special circumstances such as when scoring.
The programming of the robot had ignored the opponent’s IR beacon during development,
and actually still did during the final tournament. This might seem like a big weakness, but it
really wasn’t: the factors it did take into account did work very well when there was an
opponent on the field and had been designed to do so. For example: when the robot couldn’t
see the puck, it assumed it was obscured by the opponent and rushed home to defend its own
goal, and be in the best possible position to continue when it could see the puck. Immediately
when the puck came into view again, the robot headed for it as usual. One could imagine
trying to make evasive maneuvers with the puck around an opponent who is trying to defend
its goal, but this would be very difficult to get to work in reality and also the robot’s physical
design didn’t allow extreme turns when pushing the puck. Remember, this is a relatively fast-
paced game.
We had ever since the beginning of the project taken several steps when designing the robot
to avoid time penalties, which, we realized, could become one of the greatest problems. It was
of course built to be robust since having to interfere manually even the least bit in the play
gives a 30 second penalty – during which the opponent easily would score several goals
without our opposition. This robustness was not only physical, but also in software. For
example, we built in checks that would ensure that the robot would never get stuck against a
wall or opponent. Also, the first thing the robot considered in its main loop is whether it
seemed to have stepped into its own goal area. If it had, it immediately backed away and tried
again, since there is a ten second time penalty for doing so.
Robotics and Autonomous Systems project report Group 6: The Slider
15
One important early strategy/design choice was of course the way the robot was supposed to
score. Immediately when the robot had the puck and one of the ground reflectivity sensors
entered the opponent’s goal area, it entered a state where it constantly adjusted itself, trying to
get into the best possible position along the border of the goal area in order to score. This loop
was exited once the scoring was complete. This process also made sure the robot was
constantly trying to back out of the goal area if the opponent pushed it in – which is a
requirement for the goal still to be considered legal.
Figure 4 – Flowchart of the main program loop
Yes
No
No
No
No
Yes
No
No
Yes
Yes
Yes
Yes Have we entered our
own goal area?
Do we have the puck
or are we about to
score?
Are we too close to
our own goal?
Are we sufficiently
close to the
opponent’s goal?
Have we entered the
goal area yet?
Do we see the puck?
Start scoring Go for opponent’s goal
Stop moving
Go for the puck
Back up quickly
Adjust position and
score!
Go to own goal
Robotics and Autonomous Systems project report Group 6: The Slider
16
Problems and solutions
One problem occurred after we had designed the stick. It became clear that we had missed one
rule that limited the size of the stick. It had to be low enough not to cover the IR diodes on the
puck. In our first design the stick was as high as the puck and thereby covered its diodes. In
this design we had made a very rough construction with two bent iron plates sticking into
tracks in the plate. There was also a third track where the motor axis went through the plate.
At first we thought that we had to completely redesign the stick construction, but after
discussions and experimenting we came up with an easier solution. We simply cut off the
lowest part of the stick and plate, and a little bit on the top of the stick.
Now we only had one iron plate left that kept the club in position but we found it to be stable
enough to withstand the stress of the tournament.
The new design did have some minor problems though. It sometimes got stuck when
“sliding” along the plate. This luckily didn’t happen very often and was easily remedied by
reducing friction.
Conclusions
Our robot was a great success, considering that we placed second in the hockey tournament.
No other robot came close to our 100% scoring accuracy. Our sliding stick mechanism
performed almost flawlessly and guaranteed the success of our robot. We hope our unique
design concept will inspire future groups for their projects.
During the construction of our robot we learned the basic concepts of robotics and its
difficulties. Some of the biggest challenges with robot construction are the different aspects
that must be taken into account when programming the robot, compared to “normal” software
programming. The programmer must be able to visualize the real world factors from the
robot’s point of view. This is a difficult task, partly because everything executes at 20MHz or
less. It was very fun to actually be able to witness the code translate into physical motion.
Robotics and Autonomous Systems project report Group 6: The Slider
17
As the result of the final match in the tournament was almost coincidental due to several
factors, we believe that we easily could have won the competition. Our biggest disadvantage
was probably that we hadn’t been able to fully test our robot in real life conditions, prior to
the tournament. This was basically due to the lack of opponents willing to compete with us
before the tournament.
If our robot would be given any future modifications it would probably require some
improvement to its code, in order to remove any bugs (if any). Other than software
modifications we believe it to have performed as it was originally intended to.
Robotics and Autonomous Systems project report Group 6: The Slider
18
Appendix I – Circuitry
Robotics and Autonomous Systems project report Group 6: The Slider
19
Here is a list over where all pins on the main PIC are connected.
1) Not used 2) Back left ground detector 3) Front left ground detector 4) Back right ground detector 5) Front right ground detector 6) Not used 7) Not used 8) Speaker 9) Speaker 10) Not used 11) Not used 12) Not used 13) Not used 14) Not used 15) Download pin 16) PWM right motor 17) PWM left motor 18) Not used 19) Not used 20) Not used 21) Not used 22) Puck detector 23) Club endpoint detector right 24) Club endpoint detector left 25) Direction club motor 26) Club motor 27) Direction left motor 28) Direction right motor 29) Not used 30) Not used 31) Not used 32) Not used 33) Not used 34) LSC connection 35) LSC connection 36) LSC connection 37) LSC connection 38) LSC connection 39) LSC connection 40) LSC connection
Robotics and Autonomous Systems project report Group 6: The Slider
20
Appendix II – Component List
4 reflex detectors ITR8307 Subminiature High Sensitivity Photo Interrupter.
Manufacturer: Everlight. Part no: ITR8307.
1 PIC (for IC) PIC16F876 20-pin 8-Bit CMOS FLASH Micro controller.
Manufacturer: Microchip Technology Inc. Part no: PIC16F876.
1 PIC (main) PIC16F877 40-pin 8-Bit CMOS FLASH Micro controller.
Manufacturer: Microchip Technology Inc. Part no: PIC16F877.
4 IR diodes SFH485P GaAlAs Infrared Emitter.
Manufacturer:Siemens.Part no: SFH485P.
5 IR sensors TSL261 IR Light-to-Voltage Optical Sensor.
Manufacturer: Texas Advanced Optoelectronic Solutions (TAOS).
Part no: TSL261.
2 12Vmotors HL149 12V 10:1 Motor
Manufacturer: Micromotors. Part no: HL149.
1 6V motor
2 7.2V NiCd accumulator packs
Robotics and Autonomous Systems project report Group 6: The Slider
21
Appendix III – The C-code
#include <pic.h> #include <conio.h> #include "defines.h" #include "lcd.h" #include "adc.h" #include "button.h" #include "sprint.h" #include "debug.h" #include "ir_comm.h" #include "eeprom.h" #include "pwm.h" #include "intr.h" #include "serialio.h" // Function declarations void go_for(const unsigned int[], char, char, char); char get_max(const unsigned int[]); /* * * These are global variables containing various sensor readings. * They are set by the void update_*() procedures below and are * used throughout the program when making decisions about how to * act next. * * The IR variables contain the signal strength from the puck (p), * offensive goal (go), defensive goal (gd) or opponent (o), as read * by the IR sensors. * */ // Front IR sensor, off and def goal strength respectively bank2 static int front_ir[2]; // The four IR sensors on top of the robot bank2 static unsigned int irp[4]; bank2 static unsigned int irgo[4]; bank2 static unsigned int irgd[4]; bank2 static unsigned int iro[4]; // Index of sensor with the strongest reading of each kind bank1 static char irpmax; bank1 static char irgomax; bank1 static char irgdmax; bank2 static char iromax; // Ground reflectivity sensors bank2 static unsigned char ground_det[4]; // Temporary buffer mainly for printing numbers static char buffer[7]; // These are critical thresholds for the sensor readings #define THRESH_SEES_PUCK 25 // Do we see the puck? #define THRESH_SEES_GOAL 10 // Do we see the goal? #define THRESH_NEAR_GOAL 300 // Are we close to the goal? #define THRESH_DARK 245 // Are we in the goal area? // True if ground detector i is over a dark area #define DET_DARK(i) (ground_det[(i)] > THRESH_DARK) // True if button i is down #define BUTTON_DOWN(i) (bittst(buttons[(i)], IS_DOWN)) // True if button i has been pressed since the last update_buttons (flank)
Robotics and Autonomous Systems project report Group 6: The Slider
22
#define BUTTON_PRESSED(i) (bittst(buttons[(i)], PRESSED)) // no code protect, no WDT, no BOD, power up timer, HS Xtal __CONFIG(0x3FB2); /* * * These functions take care of updating the global variables * with new sensor readings from the IR sensors, buttons and * ground reflectivity detectors, respectively. * */ void update_ir() { bank2 static int i; ir_wait(); for (i = 0; i < 4; i++) { irp[i] = ir_value(i, PUCK); if (irp[i] == 0) irp[i] = 1; irgo[i] = ir_value(i, OFF_GOAL); if (irgo[i] == 0) irgo[i] = 1; irgd[i] = ir_value(i, DEF_GOAL); if (irgd[i] == 0) irgd[i] = 1; iro[i] = ir_value(i, OPPONENT); if (iro[i] == 0) iro[i] = 1; } irpmax = get_max(irp); irgomax = get_max(irgo); irgdmax = get_max(irgd); iromax = get_max(iro); front_ir[0] = ir_value(4, OFF_GOAL); front_ir[1] = ir_value(4, DEF_GOAL); } void update_buttons() { clear_button_events(); handle_button(0); handle_button(1); handle_button(2); handle_button(3); } void update_ground() { ground_det[0] = sample_ad_channel(0); ground_det[1] = sample_ad_channel(1); ground_det[2] = sample_ad_channel(2); ground_det[3] = sample_ad_channel(3); } /* * * Here goes the main program. * */ int main() { bank2 static int i; bank1 static char scoring; bank1 static char sensor; bank1 static char sample; bank1 static char tmp; bank1 static char has_puck; bank1 static char display_mode = 0; bank2 static char slow; bank2 static int left; bank2 static int right; bank1 static long sometime;
Robotics and Autonomous Systems project report Group 6: The Slider
23
// "blues_notes", the tune to play after having scored bank2 static const char tune[]= { 0x3C,20, 0x3A,20, 0x37,20, 0x36,20, 0x35,20, 0x33,20, 0x30,20, 0x2A,20, 0x27,20, 0x26,20, 0x25,20, 0x23,20, 0x20,20, 0x1A,20, 0x17,20, 0x16,20, 0x15,20, 0x13,20, 0x10,20, 0x0A,20, 0x07,20, 0x06,20, 0x05,20, 0x03,20, 0x00,80, 0,0 }; // Reg A: Pin 5, 6, 7 are digital, all others analog ADCON1 = 0b00000010; TRISA = 0b00011111; TRISB = 0b11110000; // Read deafult ir sensor from eeprom adress 00h sensor = eeprom_read(0x00); ir_init(); // Initialise IR co-processor communication init_buttons(); // Initialise buttons init_pwm(); // Initialise pwm for motor control init_uart(); // Initialise serial I/O init_soft_tmr(); // Initialise the software timer interrupt init_sound(); // Initialise sound generator PEIE=1; // Peripheral interrupts enable ei(); // Global interrupt enable lcd_was_off = 1; // Required before first set_lcd_power(1); set_lcd_power(1); // Turn on lcd scoring = 0; // The main loop! for (;;) { if (lcd_was_off) { init_lcd(); lcd_was_off=0; } // Update all sensor readings update_ir(); update_ground(); update_buttons(); // Button 3 is used to change display modes if (BUTTON_PRESSED(3)) display_mode = (display_mode + 1) & 0b11; // Button 2 is the puck detector on the stick if (BUTTON_DOWN(2)) has_puck = 1; else has_puck = 0; // Sample A/D sample = (sensor <= 3) ? ground_det[sensor] : 0; switch (display_mode) { case 0: sprint16(buffer, sample); lcd_print1("A/D: ", 0); break; case 1: sprint16(buffer, sensor); lcd_print1("sens#", 0); break; case 2: sprint16(buffer, get_servo(0)); lcd_print1("serv", 0); break; case 3: sprint16(buffer, soft_time()); lcd_print1("time", 0); break;
Robotics and Autonomous Systems project report Group 6: The Slider
24
default: // This should never happen. buffer[0] = 0; lcd_print1("default", 0); break; } lcd_print_at_cursor(buffer); // Append value string stored in buffer lcd_print_at_cursor(" "); // Spaces to make sure previous value is covered // Checks whether the stick is to the far right. // If it isn't, move it there. if (BUTTON_DOWN(1)) RB2 = 0; else { RB3 = 0; RB2 = 1; } // The robot always moves a bit more slowly close to the offensive // goal area, in order to be able to stop in time. if (front_ir[0] > THRESH_NEAR_GOAL) slow = 1; else slow = 0; if ((front_ir[1] > THRESH_NEAR_GOAL || irgd[irgdmax] > THRESH_NEAR_GOAL) && (DET_DARK(1) || DET_DARK(3))) { // We seem to have stepped into our own goal area! // Immediately back up and try again. motors(-127, -127); for (i = 0; i < 32000; i++) ; } else if (has_puck || scoring) { // We either have the puck or are in the process of scoring if (front_ir[1] > THRESH_NEAR_GOAL) { // If we have the puck and are too near our own goal, there // is no chance we're going to be able to turn around with the // puck. Just stop. :-) motors(0, 0); } else if (front_ir[0] > THRESH_NEAR_GOAL) { // We have the puck, and we are approaching the offensive goal. // Now enter a state where we ignore the puck sensor (since the // puck sometimes glides a bit along the front of the robot) // and just make sure we get in the best position possible to // score. scoring = 1; if (DET_DARK(1) || DET_DARK(3)) { // One of the frontmost sensors has registered that we have // entered the goal area. Now score! // First brake violently, we don't want to step too far // into the goal area. motors(-100, -100); for (i = 0; i < 12000; i++) ; motors(0, 0); // Inside this loop, the robot positions itself optimally // before it starts moving the club. Since this loop is // active until the club has reached its leftmost possible // position, it will always try to stay in the opimal // position - so it will e.g try to back up if it is pushed // too far into the goal area. while (!BUTTON_PRESSED(0))
Robotics and Autonomous Systems project report Group 6: The Slider
25
{ update_ground(); update_buttons(); if (!DET_DARK(0) && DET_DARK(1) && !DET_DARK(2) && DET_DARK(3)) { // We have a perfect position! FIRE! RB2 = RB3 = 1; } // Per default, don't move at all left = right = 0; // The following conditions make sure that the two // sensors on both sides of the robot front always // staty on either side of the goal area border. if (DET_DARK(2)) right = -80; if (RB2 != 1) { if (!DET_DARK(3)) right = 90; else right = -90; } if (DET_DARK(0)) left = -100; else if (!DET_DARK(1)) left = 100; motors((char) left, (char) right); } // Start moving the club back to the right RB3 = 0; // Play our victory tune play_tune(tune); // Back up until we are sufficiently far away from the goal motors(-127, -127); while (front_ir[0] > THRESH_NEAR_GOAL) update_ir(); // Then finally go home to the defensive goal (if we can // see it) to be in an optimal position for when the puck // is dropped again. while (irgd[irgdmax] > THRESH_SEES_GOAL && ir_value(4, DEF_GOAL) < THRESH_NEAR_GOAL) { update_buttons(); update_ir(); update_ground(); if (bittst(buttons[1], PRESSED)) RB2 = 0; go_for(irgd, irgdmax, 0, 0); } // Stop the club, stop moving and stop scoring! :-) RB2 = 0; motors(0, 0); scoring = 0; } else { // We are close to the defensive goal but haven't entered // the goal area yet. Head straight for the goal. go_for(irgo, irgomax, 1, 1); } } else {
Robotics and Autonomous Systems project report Group 6: The Slider
26
// We have the puck but are not close to the goal yet. // Go for the goal! go_for(irgo, irgomax, slow, has_puck); } } else { // We do not have the puck, try to find it. if (irp[irpmax] > THRESH_SEES_PUCK) { // If we see the puck, go for it! go_for(irp, irpmax, slow, has_puck); } else { // We don't see the puck, so we assume the opponent has it, // obscuring its IR transmitters. Go home to defend! if (ir_value(4, DEF_GOAL) < THRESH_NEAR_GOAL) { go_for(irgd, irgdmax, 0, 0); } else { // We are already home. Stop and wait until the puck // can be seen again. motors(0, 0); } } } // Print IR values to lcd sprint16(buffer, ir_value(sensor, PUCK)); lcd_print1("P", 10); lcd_print_at_cursor(buffer); lcd_print_at_cursor(" "); sprint16(buffer, ir_value(sensor, OFF_GOAL)); lcd_print2("G", 0); lcd_print_at_cursor(buffer); lcd_print_at_cursor(" "); sprint16(buffer, ir_value(sensor, OPPONENT)); lcd_print2("O",5); lcd_print_at_cursor(buffer); lcd_print_at_cursor(" "); sprint16(buffer, ir_value(sensor, UNMODULATED)); lcd_print2(PEAK_SIGN, 10); // See lcd.h on PEAK_SIGN lcd_print_at_cursor(buffer); lcd_print_at_cursor(" "); tmp = getch(); switch (tmp) { // 0-4 will change the current sensor case '0': sensor = 0; break; case '1': sensor = 1; break; case '2': sensor = 2; break; case '3': sensor = 3; break; case '4': sensor = 4; break; // ? will return the current sensor case '?': sprint16(buffer,sensor); print("Current sensor: "); print(buffer); putch('\r'); break;
Robotics and Autonomous Systems project report Group 6: The Slider
27
// s will write the current sensor to 00h in eeprom case 's': if (write_eebyte(sensor, 0x00) == 1) print("wrote sensor\r"); else print("write failure\r"); break; default: break; } // Go to debug state if menu button is pressed if(BUTTON_PRESSED(CANCELB)) debug(); } } /* * * go_for is a function which given a vector of sensor readings moves towards * a certain goal. For example, if we send in the readings for the puck signal, * it will head towards the puck. * * The function also contains code which will attempt to break free if the robot * seems to be stuck. * * Parameters: * - ir: A vector of IR sensor readings. * - max: Index of 'ir' with the strongest reding. * - slow: If nonzero, the robot will move slower. This is * used when the robot is close to a goal area. * - has_puck: Specifies whether the robot has the puck or not. * This is used when making certain decisions about * how to move. * */ void go_for(const unsigned int ir[], char max, char slow, char has_puck) { bank2 static int left; bank2 static int right; bank2 static int kvot; bank2 static int count; bank2 static int old; bank2 static int diff; // This is a scaling factor used when calculating the turning // speed of the robot. #define SCALE 2 // Take different actions depending on which sensor // has the strongest signal. switch (max) { // In the first two cases, the puck is in front of us. A quota // is calculated which corresponds to how much one of the wheels // should slow down. This gives a smooth turning curve. case 0: if (ir[3] > ir[1]) kvot = 190; // The puck is almost behind us. Turn sharply. else kvot = (ir[0]<<SCALE)/ir[1] - 1<<SCALE; left = 127; right = 127 - kvot; break; case 1: if (ir[0] > ir[2]) kvot = (ir[1]<<SCALE)/ir[0] - 1<<SCALE; else
Robotics and Autonomous Systems project report Group 6: The Slider
28
kvot = 190; // The puck is almost behind us. Turn sharply. left = 127 - kvot; right = 127; break; // In these two cases, the puck is behind us. Turn around on the spot // in the proper direction. // If we have the puck, always turn left because the robot is designed // in such a fashion that it is almost impossible to keep the puck while // turning right. case 2: left = -127; right = 127; break; case 3: if (has_puck) { left = -127; right = 127; } else { left = 127; right = -127; } break; default: left = right = -127; // This should never happen. } // Clamp the motor values to signed bytes if (left < -127) left = -127; if (left > 127) left = 127; if (right < -127) right = -127; if (right > 127) right = 127; // This is the routine which checks whether the robot seems to be stuck. We // do this by summing the difference between a ground sensor reading and a // reference value. If it hasn't changed much in 10 periods, we assume that // we haven't moved at all and take evasive action. if (count >= 10 && diff < 6) { // Not much change in the sensor reading. Assume we are stuck. // If we are told to move slowly, just give the robot a small push to // get it moving again. Otherwise, back up just a bit and then twist // around to break free. if (slow) { motors(127, 127); for (count = 0; count < 32000; count++) ; count = diff = 0; } else { motors(-127, -127); for (count = 0; count < 5000; count++) ; motors(-127, 127); for (count = 0; count < 32000; count++) ; for (count = 0; count < 32000; count++) ; count = diff = 0; } } else if (count >= 0 && count <= 9) { // 10 cycles haven't passed yet, add the absolute difference // between the reading and the reference to our diff variable. if (ground_det[0] > old) diff += ground_det[0] - old; else
Robotics and Autonomous Systems project report Group 6: The Slider
29
diff += old - ground_det[0]; // Also tell the motors to move. left and right are calculated above. if (slow) motors((char)(left)-45, (char)(right)-45); else motors((char)(left), (char)(right)); // Update the reference old = ground_det[0]; count++; } else { // Otherwise, just keep going and update readings count = diff = 0; old = ground_det[0]; motors((char)(left), (char)(right)); } } /* * * get_max returns the index of the greatest reading in an IR vector * */ char get_max(const unsigned int ir[]) { bank2 static char max; bank2 static char i; max = 0; for (i = 1; i < 4; i++) if (ir[i] > ir[max]) max = i; return max; }
Robotics and Autonomous Systems project report Group 6: The Slider
30
Appendix IV – Image of the motherboard
Image 6 – Motherboard, without PICs inserted
Robotics and Autonomous Systems project report Group 6: The Slider
31
Appendix V – Additional robot images
Appendix VI - References
1. Course homepage, URL: http://www.nada.kth.se/kurser/kth/2D1426 (Working 2001-05-31) 2. Project rules, URL: http://www.nada.kth.se/kurser/kth/2D1426/L3_2001.pdf (Working
2001-05-31) 3. Datasheet for IR Light-to-Voltage Optical Sensor TSL261. Texas Instruments. URL:
http://www.taosinc.com/pdf/tsl260.pdf (Working 2001-09-24) 4. Datasheet for Subminiature High Sensitivity Photo Interrupter ITR8307. Everlight. URL:
http://www.everlight.com/pdf/ITR-8307.PDF (Working 2001-09-24) 5. Datasheet for 20-pin 8-Bit CMOS FLASH Micro controller PIC 16F876. Microchip. URL:
http://www.microchip.com/download/lit/pline/picmicro/families/16f87x/devices/16f876/30292c.pdf (Working 2001-09-24)
6. Datasheet for 40-pin 8-Bit CMOS FLASH Micro Controller PIC 16F877. Microchip. URL: http://www.microchip.com/download/lit/pline/picmicro/families/16f87x/devices/16f877/30292c.pdf (Working 2001-09-24)
7. Datasheet for Diode GaAlAs Infrared Emitter SFH485P. Siemens. URL: http://www.infineon.com/cmc_upload/0/000/008/496/sfh484_5.pdf (Working 2001-09-24)
8. Data for 12 V motor http://www.stegia.se/Produkter/Micromotors/pages/hv149.htm (Working 2001-09-24)
9. Data for 6 V motor http://www.stegia.se/english/Products/Micromotors/pages/l149.htm (Working 2001-09-24)
10. MPLAB Manual. MPLAB™ IDE, Simulator, Editor – User’s Guide. Microchip.