Sie sind auf Seite 1von 6

Equations, Part Models, Schematics, Algorithmic Descriptions

Our robot had a rather simple design. We did not perform any calculations in determining
aspects of its components, but rather, went with our gut instinct and past experience to fabricate
the robot. The only external parts that we bought were the Associated Wheels/Tires RC18LM (2)
from Tower Hobbies (Stock number LXZKK4), the MOSFET N-CH 60V 17.2A IPAK (Stock
number FQU20N06LTUFS-ND) from Digikey, and the MOSFET P-CH 55V 14A TO220FP
(Stock number IRLIB9343PBF-ND) also from Digikey. Everything else, we made by hand.
Please see the next section regarding more detail behind the design.
The algorithm for our robot was relatively simple. We wanted to keep the coding for our
robot, while extremely important, as simple and straightforward as possible so that we didnt get
lost in the code ourselves while trying to formulate it. The premise for it was simple: our robot
would rotate in place until the sonars detected an object (the other robot) within a certain range,
at which point our robot would begin to approach it. When the other robot was 1-2 inches in
front of our robot (whether it be us moving to them or them moving to us), our active element
would trigger in an attempt to flip the other robot. Since our active element could only be used
once, the rest of the fight would be us trying to push them out. The QTIs were programmed to
detect white, and depending on which QTI was fired, the robot would respond accordingly. We
had a total of 4 QTIs: two in the front, one in the middle, and one in the back. If either of the
front QTIs were triggered, we programmed our robot to move backward slightly, turn away from
the white, and then move forward back into the arena. If our back QTI was triggered, we
programmed the robot to simply move forward, since triggering the back was indicative of the
robot being pointed in the proper direction back into the ring. Finally, if the middle QTI was
triggered, by the rules of the competition, we shut down all motor control and turned on our red
LED.
One issue we did notice was that since our robot would automatically rotate CCW, if the
left QTI sensor was triggered on our robot, it would get stuck in an endless loop trying to move
away from the white line, but then simply turning back onto it. We solved this issue with a
simple fix:
if (!(PINB & 0b00000010) && a==1) //LEFT QTI
{
PORTD &= 0b00000000;
PORTD |= 0b10010000; //Robot backward
_delay_ms(200);
PORTD &= 0b00000000;
PORTD |= 0b01010000; //Turns robot right, PRESERVES pins 2-3 as high
_delay_ms(1750);
PORTD &= 0b00000000;
PORTD |= 0b01100000; //Robot forward
_delay_ms(4000);
}
else if (!(PINB & 0b00000100) && a==1) //Right QTI
{
PORTD &= 0b00000000;
PORTD |= 0b10010000; //Robot backward
_delay_ms(200);
PORTD &= 0b00000000;
PORTD |= 0b10100000; //Turns robot left, PRESERVES pins 2-3 as high
_delay_ms(500);
PORTD &= 0b00000000;
PORTD |= 0b01100000; //Robot forward
_delay_ms(100);

We simply asked the robot to turn CW for a longer duration if the left QTI was triggered, and to
move forward for a longer time. This allowed for the robot to reset its position by driving it
back to the middle of the arena, and thus, eliminating the issue of it becoming stuck at the white
line. Compared to what we programmed for the right QTI, the movements and durations of the
robot after the left QTI is triggered is much longer and more controlled.
Flow Chart Describing Strategy

Statement of Work
Tim Lai primarily worked on the coding of the robot. He wrote the vast majority of the code by
himself, but took advice/help from the other group members throughout the process. He worked
well in coordinating with Jon and Natasha on the placement of the sensors into the Arduino, and
how they would work. Tim also cut hand-cut the wooden parts for the body of the robot.

Appendix
Code:
/*
* GccApplication1.c
*
* Created: 12/1/2014 6:08:59 PM
* Author: EN-MA-3780
*/
#include <avr/io.h>
#include <avr/io.h>
#define F_CPU 16000000UL
#include <avr/io.h>
#include "serial.h"
#include <avr/interrupt.h>
#include <util/delay.h>
volatile uint16_t a; //FLAG: a=1 allows for motor control, a=0 shuts down EVERYTHING
volatile uint16_t i; //Sonar time
volatile uint16_t d; //Sonar distance
volatile uint16_t x; //Sonar "flag"
volatile uint16_t q; //Active element counter -> when another object within 1-2 inches of our robot is
detected for a prolonged period of time, active element will trigger
volatile uint16_t v; //Active element flag -> allows for active element code to only run ONCE
//MASTER LIST OF SENSORS AND PIN LOCATIONS
//MIDDLE QTI:
PINS 2
//BACK QIT:
PINS 3
//RIGHT MOTOR:
PINS 4-5
//LEFT MOTOR:
PINS 6-7
//ACTIVE ELEMENT:
PINS 8
//SONAR:
PINS A0
//RED LED:
PINS 12
//FRONT LEFT QTI:
PINS 9
//FRONT RIGHT QTI: PINS 10
void initpinchange() //Initialization of all pin changes
{
PCICR |= 0b00000111; //Initialize Group 0, 1, 2 (PINS 2-7, A0-15, 8-13 respectively)
PCMSK0 |= 0b00000110; //Initialize PINS 9-10 (Front QTIs)
PCMSK1 |= 0b00000001; //Initialize PIN A0 (Sonar)
PCMSK2 |= 0b00001100; //Initialize PINS 2-3 (Middle and back QTI)
TCCR1B |= 0b00000011; //Set prescalar = 64
sei();
}
void startsonarmeasurement() //Initial pulse for sonar
{
PCMSK1 &= 0b00000000;
DDRC = 0b00000001; //Set output
PORTC |= 0b00000001; //Set high
_delay_us(5);
PORTC &= 0b00000000; //Reset all
DDRC = 0b00000000; //Set input
PCMSK1 |= 0b00000001;

}
void startpinD()
{
DDRD = 0b11110000; //Set PINS 2-3 as input (QTIs), PINS 4-7 as output (Motor control)
PORTD |= 0b00001100; //Set PINS 2-3 as high
}
void startpinB()
{
DDRB = 0b00010001; //Set PIN 12 as output (red LED), PIN 9-10 as input (QTIs)
PORTB |= 0b00000110; //Set PIN 9-10 as high
}
ISR (PCINT0_vect) //Interrupt for PINS 8-13 (QTI Control)
{
if (!(PINB & 0b00000010) && a==1) //IF LEFT QTI IS TRIGGERED...
{
PORTD &= 0b00000000;
PORTD |= 0b10010000; //Robot backward
_delay_ms(200);
PORTD &= 0b00000000;
PORTD |= 0b01010000; //Turns robot right, PRESERVES pins 2-3 as high
_delay_ms(1750);
PORTD &= 0b00000000;
PORTD |= 0b01100000; //Robot forward
_delay_ms(4000);
}
else if (!(PINB & 0b00000100) && a==1) //IF RIGHT QTI IS TRIGGERED...
{
PORTD &= 0b00000000;
PORTD |= 0b10010000; //Robot backward
_delay_ms(200);
PORTD &= 0b00000000;
PORTD |= 0b10100000; //Turns robot left, PRESERVES pins 2-3 as high
_delay_ms(500);
PORTD &= 0b00000000;
PORTD |= 0b01100000; //Robot forward
_delay_ms(100);
}
else if (a==0) //IF A=0, SHUT EVERYTHING DOWN. Must be iterated in each interrupt so that
this takes priority
{
cli();
PORTD &= 0b00000000; //Robot shut down
PORTB |= 0b00010000; //Turn on RED LED
}
}
ISR(PCINT1_vect) //Sonar interrupt
{
if (x==0)
{
unsigned char sreg; //reset timer
sreg = SREG;
cli();
TCNT1 = 0;
SREG = sreg;
x=1;

}
else
{

unsigned char sreg;


sreg = SREG;
cli();
i = TCNT1;
SREG = sreg;
x = 0;

}
void getSonar() //Function to get distance from sonar
{
startsonarmeasurement();
_delay_ms(10);
d=0.027*i;
if (d<=2 && q<=20 && a==1 && v==1) //IF OBJECT DETECTED IS WITHIN 2 INCHES OF
ROBOT, INCREASE Q
{
q = q+1;
}
else if (d>=2 && q<=20 && a==1 && v==1) //IF OBJECT DETECTED IS GREATER THAN 2
INCHES AWAY FROM ROBOT, RESET Q
{
q = 0;
}
else if (q>=20 && a==1 && v==1) //IF Q HAS BEEN INCREASED BEYOND A CERTAIN
THRESHOLD (object has been in front of our robot for some time now), TRIGGER ACTIVE ELEMENT
{
PORTB |= 0b00000001; //Activate flip (triggered by motor)
_delay_ms(1000);
PORTB &= 0b11111110; //Shut down active
v = 3;
}
}
ISR (PCINT2_vect) //Interrupt for Middle and back QTIs
{
if (!(PIND & 0b00000100)) //MIDDLE QTI
{
cli();
a = 0; //MASTER FLAG. SHUT EVERYTHING DOWN
PORTD &= 0b00000000; //Robot shut down
PORTB |= 0b00010000; //Turn on RED LED
}
else if (!(PIND & 0b00001000) && a==1) //BACK QTI
{
PORTD &= 0b00000000;
PORTD |= 0b01100000; //Robot forward
_delay_ms(50);
}
}
int main(void) //MAIN CODE
{
//Initialize everything, preset any variables if needed
x = 0;
init_uart();

startpinB();
startpinD();
initpinchange();
_delay_ms(500);
a = 1;
d = 10000;
q = 0;
v = 1;
while(1) //WHILE LOOP
{
getSonar();
if (a==1 && d>=30) //This runs when trying to detect enemy robot
{
PORTD &= 0b00000000;
PORTD |= 0b10100000; //Turns robot left, PRESERVES pins 2-3 as high
_delay_ms(100);
}
else if (a==1 && d<30) //ENEMY DETECTED
{
PORTD &= 0b00000000;
PORTD |= 0b01100000; //Robot forward
_delay_ms(50);
}
else if (a==0) //SHUT DOWN
{
cli();
PORTD &= 0b00000000; //Robot shut down
PORTB |= 0b00010000; //Turn on RED LED
}
}
}

Das könnte Ihnen auch gefallen