The Robot: Pac-Man

Picture
The winning robot of the 2011 6.270 competition!
Quick Specs:
   2-Wheel Tank Drive w/ 125:1 Gear Ratio
   Motor Driven Intake Roller w/ 125:1 Gear Ratio
  Continuous-Servo Driven Chain Lift w/ 1:1 Gear Ratio



Below the Cardboard

Picture
Overview of system:  Rollers in front draw tennis balls onto tray.

Elevator system in back lifts entire tray to rift height.  Rollers reverse to score balls.

Starting Position

Picture
Roller Arm begins vertically to meet starting size restrictions.  Motion of robot as match begins causes roller arm to fall to collection height.

Tray Specs

Picture
Sensors: Tray has two photogate sensors to ascertain possession of a ball.

Gray and black plates on green surface are angled slightly, preventing tennis balls from getting trapped at the back of the tray.

Cutouts from side of tray allow casters to rotate freely without interference.

Black axle with gray collars serves as hard mechanical stop for roller arm.

Yellow and red vertical beams guard against tennis ball loss on sides.

Roller Arm and Tray Mount

Picture
Bound three-gear system used to attach carriage to chain.

Black axle in center allows for rotation of roller arm.

Roller arm is currently in position, resting on hard-stop.

Continuous servo motor drives chain on 1:1 ratio.

(Notes: Despite various mounting methods and gear ratios, the regular motor was unable to raise the lift.  The continuous servo provides the necessary torque, but requires additional programming, as the stop value tends to drift.)

Rollers

Picture
Because the rollers span the front of the robot, relatively little precision is needed to collect tennis balls, simplifying programming.

(Notes: The Roller Arm was orignally mounted lower, such that golf balls would also be taken in.  Theoretically, the Roller Arm would pivot up when encountering a tennis ball to accommodate its larger size.  This generally worked, but sometimes the torque required to bring in a tennis ball at the low height was too great for the motor.  In the current iteration, the Roller Arm sits at a height that is incompatible with golf balls, but optimal for tennis balls.)

Roller Gearbox

Picture
Gear ratio is 125:1.  Motors are very fast, and torque is needed more than speed to intake tennis balls.
 (Notes:  When the rollers contacted a wall, they would start to roll the entire lift arm up the wall, releasing tennis balls.  After the failure of various front guards, the motor speed of the roller was reduced to correct this issue.)



Tray Height Control

Picture
Sensors: 2 Limit switches to bound the maximum height the tray can go and the minimum height it should go.
Limit switch at top of lift’s travel allows lift to be held at rift height.
Another limit switch at the bottom of the lift’s travel allows the tray to be stopped at ground level.

Tank Drive

Picture
Two independently driven wheels, gear ratio 125:1, large wheels. A higher drive gear ratio provides more than enough torque to move the robot. To compensate for RPM lost in the motor, the size of the wheel was maximized to give the greatest possible speed for a given torque.




Caster

Picture
Two casters support front of robot.

(Notes: Casters have a relatively large footprint, but the two in combination gave the support needed for a heavy front.)

Electronics

Picture
Happy Board and Battery provide weight in back of robot to counteract heavy Roller Arm.

Lower Limit Switch and gyro are also visible.

Encoder

Picture
The encoder is mounted on the bottom of the robot at the center of rotation to measure the forward distance traveled by the robot.

Programming

Picture
The robot was programmed under C with built in joyos libraries to give compatibility with the Happy Board microprocessors.
Overview of Code Structure:
    The code runs on 3 main threads: umain,  navigation_loop, articulation_loop
     umain: Sent high-level commands such as MoveToPoint(x, y, speed), TurnToPoint(x, y, tolerance), MoveStraight(x,y, speed), and DeliverBalls(). Each function takes in the given arguments, and simply passes the values to the other threads using global variable assignment. For example, TurnToPoint(x, y, tolerance) takes in the arguments x and y, calculates the theta and puts this value in a global variable called desired_theta. The global variable can then be accessed by other threads such as the navigation_loop or the articulation_loop, and each separate threads can act accordingly.
    navigation_loop: This thread runs in the background and simply acts on any value passed by umain. Going back from the previous example, once desired_theta gets a new value from the inputs in umain, the navigation_loop gets updated and will move accordingly until the desired state is achieved. (In this case, turning to a point). Once the state is achieved, the navigation_loop will stay put doing nothing until umain tells it to do something else. The advantage of tjis multi-threading programming is that while the navigation_loop acts on the background, umain can freely do other things such as planning the next moves, tracking the movement of the targets, etc.
 articulation_loop: Like the navigation_loop, this thread acts on the background and waits for any command from umain. For example, if umain calls a function StartIntakeRollers(), the articulation_loop will change its state and run the intake rollers until umain tells it otherwise.  Likewise, if umain calls LiftTray(), this thread will lift the tray until it reaches a desired state usually indicated by a sensor a timer, or umain. In the same way, placing the articulation_loop in a different thread gives umain more flexibility.
Navigating the Playing Field:
    PID controllers: Since the robot uses a 2 wheel tank drive system, the robot doesn't necessarily drive straight even if they get provided the same output. For example, setting both motors at a value of 150 will cause the robot to drift at an angle over time. This is usually caused by the slight differences between the two motors. To fix this problem, a Proportional, Integral, and Derivative (PID) controller is used. In this robot, a gyroscope is used to indicate the current heading of the robot. Using the gyroscope, we can make the robot go relatively straight at the correct heading. The PID controller provides the proper correction amount to each side of the motor and tries to minimize the error to 0 thereby retaining a constant heading. Since the motors get the proper correction amount, the robot moves relatively straight towards the desired heading.
   Localization: To get somewhere, you need to know where you are first. In previous years, navigation was done by dead-reckoning. In essence, if you know how far you've gone and in what angle, you know your x and y coordinates using simple trigonometry where x = cos(theta) and y = sin(theta). This year, we have found that the Vision Positioning System (VPS) overhead gives a precise location of our robot with little to negligible latency.
   Navigation: Now that the robot's position is localized, the robot can now move to specified points in the playing field. Our robot has one primary function for moving around and it's called MoveToPoint(x, y, speed, tolerance). MoveToPoint actually breaks down into TurnToPoint(x, y, tolerance) and MoveStraight(x, y, speed). For example, if the robot is currently localized at pt (0,0) and I want it to move to pt (2, 2), the robot will 1st: Calculate the heading using the given x and y points which is 45 degrees. 2nd: The robot will turn to the point (which is basically turning to the pointed heading). by rotating each wheel opposite of each other 3rd: The robot calculates its distance from the point, and finds out that it needs to travel 2*sqrt(2). 4th The robot will then MoveStraight(2, 2, speed). Using the encoders, the robot will know how far it needs to go. The encoders record how much the wheels have spun. Using a conversion factor, the encoders can tell the robot if it has gone a distance of 2*sqrt(2). If it has, then the robot will stop moving. If we localized the position again, the robot should be at pt (2,2) at a heading of 45 degrees.

Using a simple TurnToPoint then MoveStraight to point function, the robot gets to where it needs to be. Granted, this worked for this competition because collision between the opponent and your robot was impossible. Which means that so long as the robot is not hitting anything, it can move to a desired point without fail.

Finding Proper Ball Targets:
Before the robot moves to a certain target, it needs to know which are tennis balls and which are golf balls. In the beginning before making any commands, the robot has a SortBalls function. It takes all the objects in the field and figures out which are tennis balls and golf balls based on the radius of the ball. It then checks if it has the same sign as our y coordinate. If it has, then that ball is in our field and its ID is stored into a new array. A list of balls in our side of the field is then generated. The robot then runs a for loop program which figures out which is the closest ball using the distance formula. The ID of the closest ball is then given and it takes it back to the original list of objects in the field. It's x and y is calculated at that instantaneous moment, and the robot will move using the MoveToPoint function. 

The ball may move, but this is negligible. If the robot misses the point, the robot will repeat its SortBalls function and this entire process and go to the new point specified. In addition, tennis balls have more friction and take quite an effort to move. From mock-competitions, the tennis balls hardly moves at all unless its hit by your robot. So in essence, taking its instantaneous x and y point is a good approximation of its location.

Capturing the Balls:
To capture the balls, the robot has its intake motors always ON in a direction which forces any tennis ball to go in and not out. More often than not, tennis balls get in by luck and the robot gets a free tennis ball even without having to navigate to a certain point in the field.

Delivering the Balls:
Likewise, to deliver the balls, the intake motors have to spin the opposite way forcing the balls to go out.

Ball Detection:
There are two breakbeam sensors inside the tray. If either of them gets broken, the robot will realize it has a tennis ball and will immediately deliver the ball. We realize that this is an inefficient method, and a better way to have done this is to try to capture at least 2 balls before delivering the balls.

TimeOuts: 
One of the most important part of the robot's code is a timeout. This is a code which prevents your robot from doing the same exact thing over and over again without producing results. For example, if your robot wants to turn to a certain point, but is wedged in a corner, the robot will forever try to turn and will never get to its point. This causes motors to burn out and die. In our robot, we have 2 simple timeouts. Our robot's timeout occurs on either TurnToPoint or MoveToPoint.
    TurnToPoint timeout: For turning to point, we gave the robot 3 seconds to turn. If it doesn't turn within 3 seconds, then it has to move back.
    MoveStraight timeout: For moving straight to a point, we used our encoders as our timeout. In essence, if the robot's state is moving forward but its encoder value is still 0, an internal timer will start ticking. If the timer goes on for x miliseconds (in this case it was 700), the robot needs to back up.

Other Safety Timeout Prevention Features: 1. The robot will only lift the tray if it's a certain distance away from the wall. 2. After delivering the balls, the tray needs to lower. Lowering the tray can cause problems because if it lowers on top of a ball, then it will get stuck. To prevent a tray from lowering into a ball, after the robot delivers the balls, the robot backs up, turns a complete 180 degrees pushing all the balls away and then lowers the tray. 3. If a target x and y position is beyond a certain x or y value, the robot will go to a maximum value where it knows it can't get stuck. 

Picture

Game Strategy

A preprogrammed routine runs in the beginning: Using the VPS, we tell the robot to deliver the first 4 golf balls. Then, the robot  turns on its intake rollers. The robot proceeds to a specified point which automatically gathers 2 tennis balls. The robot checks if it has any tennis balls, and proceeds to deliver them. After this pre-programmed routine, our team has already scored 10pts in the first 20 seconds.
Programmed AI: Robot sorts all of the balls in its field and figures out which is a tennis ball. The robot turns on its intake rollers and moves to the x and y of the ball. The robot checks if it has anything on the tray. If it does, then proceed to deliver. If not, then repeat the programmed routine.
In the event that the there are no more tennis balls on the side of the field or the robot can't get to a certain tennis balls, the robot proceeds to sorting and targeting golf balls.
Since this doesn't really happen in the game as there are always tennis balls in the field, the robot usually focuses on the tennis balls. This is the integral part of the strategy. For the most part, the robot ignores all golf balls and concentrates on the tennis balls.

Doing a simple math, this makes sense. Each team starts with 4 tennis balls and 8 golf balls. Your opponent can only score a maximum of 8 golf balls equaling to 8pts. Which means that in order to win, you need at least to deliver 3 tennis balls which equals to 9pts. Delivering 3 tennis balls is the same thing as saying that there should only be 1 tennis ball in your side of the field at the end of the game. If there's only 1 tennis ball in the field, then your team automatically wins. For every 3 golf balls that you score, you can afford 1 extra tennis ball on your side of the field. 

In our case, we already score 4 golfballs in the beginning. We can then afford 2 tennis balls on our side. But since our preprogrammed routine scores 2 tennis balls in the first 20 seconds, we've already secured an advantage since we only have 2 tennis balls on our side. 

The strategy then boils down to this: At the end of the game: If you have 1 tennis ball in your field. You win. If you have 2 tennis balls and scored 3 golf balls, you win. If you have 3 tennis balls and scored 6 golf balls, you win.