Page 259 - The Definitive Guide to Building Java Robots
P. 259
Preston_5564C07.fm Page 240 Monday, September 26, 2005 5:38 AM
240 CHAPTER 7 ■ NAVIGATION
public DistanceVector(String h, String inches) throws Exception {
super(h, inches);
}
public String toString() {
return "Heading: " + heading + " Inches: " + magnitude;
}
}
The next thing I want to do is create the navigation class. The three instance fields in this
class are for the drive, the microcontroller, and the current surface type, since the surface could
change during a robot’s journey.
The first of the static constants are four enumerations to specify that when given a command
the robot should move in a specific direction for a specific time. The second set consists of relative
coordinate readings taken from the compass while the robot was facing a specific direction. In
this new coordinate system, north is to the front of the house, east is to the right side, south is
to the rear, and west is to the left side. The final static constant is the default speed, which I set
to 25.
■Note I modified the SpeedDiffDrive class from Chapter 3 to take timing from 1 to 10 to 1 to 100 for
greater precision.
The constructors for this class are the same: JSerialPort. With this JSerialPort, I create
an instance of the SpeedDiffDrive, NavStamp, and SonarServos. Right now, all I need is the
NavStamp and the SpeedDiffDrive. I also set the default speed to the constant value
DEFAULT_SPEED; this can be any value from 1 to 100.
The next method is changeHeading() with an input parameter of an int that will represent
the robot’s goal heading. The goal heading will be from 0 to 360, where 0 is north, 90 is east, 180
is south, and 270 is west. However, these numbers are ideal and do not match the relative
headings taken via experimentation. To get the robot’s goal heading to match the real-world
headings, I created a method called getRealAngle() to do the conversion.
Now, because of the robot’s speed I had to slow my robot down considerably during the
turn process. Otherwise, it will move too fast and take longer to find the correct heading because
of overshoot. An overshoot happens when the robot is trying to go from, say, 90 to 100 degrees
and it moves too far—perhaps 130 degrees. Overshoot happens because of the time of the turn
and the speed of the turn.
To prevent overshoot, I created a Boolean called toggle. When the method is in the toggle
state, it tells the method that it already overshot once and that it’s time to reduce the speed of
the turn size by 250 milliseconds.
I have found through experimentation that the robot works best with an accuracy of plus
or minus 2 degrees, a speed of 12, and a turn size of 1 second.
For the actual change heading part of the algorithm, I wanted to ensure that the robot took
readings and refined its position until it was within the accuracy defined ~4 degrees. For this,
I had it loop continuously via a while(true) conditional.