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.
   254   255   256   257   258   259   260   261   262   263   264