Welcome to the final part of our GPS Navigation article. In this last part, I have refined the original test platform to be able to not only navigate from one waypoint to another, but to handle input from sensors and also correct for errors in heading not adequately handled in the code from the last article. This code is a bit more complex and so the focus will be on how the individual sections work to complete the task of navigation.
Typically there is a style to my programming that involves a main loop and many subroutines to complete the tasks of the program. Usually the main loop is not much more than a series of subroutine calls. This usually makes it pretty easy to break the program up into manageable chunks. In this application we’ll be following a similar pattern although some of the subroutines will be handling tasks based on variables set in other subroutines. While not exactly unusual for BASIC programming, the logic may be quite different for controllers which pass parameters into or out of subroutines.
In order to handle the additional sensors, the original Super Carrier Board (Figure 1) was replaced with a new Super Carrier Board (Figure 2) with different connections for the various sensors used by the new code. There is also some facility for expansion, although with only 16 I/O pins we’re stretching things a bit now.
The new board supports the following interfaces:
- Parallax Serial LCD (#27977)
- Push Button ()
- IR Detector (#350-00014)
- Multi-Channel ADC
- HM55B Compass Module (#29123)
- Parallax GPS Receiver (#28146)
- (2) IR LEDs (#350-00017)
- (2) PING))) Sensors (#28015)
- (2) PING))) Mounting Bracket Kits (#570-28015)
- (2) HB-25 Motor Controllers (#29144)
Both the ADC and the HM55B use an SPI-type interface, meaning that the ADC only required 1 additional I/O pin. The IR Emitters are configured to use only one detector. The GPS Module is configured for raw output mode by tying the /RAW pin to VSS. The ultrasonic sensors are set up to detect a car in the path of the robot, which is why they are positioned on top of the robot. The HM55B Compass Module is moved up and away from the PCB, which sits directly over the two NiCd batteries and four motors.
Once the changes to the control board were completed, it was time to download the revised program code onto it. The revised program has a main loop that does the following tasks until the last waypoint has been reached:
- Check for obstacles (handle avoidance)
- Obtain target GPS coordinates
- Obtain current GPS coordinates
- Calculate desired heading based on target position vs current position
- Obtain current heading from compass module
- Adjust course based on desired heading vs current heading
- Handle heading change > 90 degrees
- Determine if waypoint has been reached (and is last)
- Adjust course and speed of motor drive as needed to reach goal
This loop will continue until the robot reaches its goal or the batteries die. Once the robot has reached its destination the LCD will display a confirmation message that the course is complete. In Figure 3 you can see the robot traversing a parking lot during testing.
The first task now is to check for obstacles. This adds a certain factor of complexity in that the sensor code is trying to adjust your course away from an obstacle while the navigation code is trying to keep you on your current heading. The solution is to override the navigation routines and move out of the way first. After moving some distance the code can then check to see if it can get to the desired coordinates from its new position.
Unfortunately with the current sensors coming in at the wrong angle can cause the robot not to see surfaces it is approaching from a low angle. As Figure 4 shows, some obstacles will require some fine tuning to the sensors. After obstacles have been checked for we obtain the coordinates of the current position. These coordinates are used along with the target coordinates to calculate the desired heading.
As before we can also get distance to target in this section. Next we want to obtain the current heading from the compass module and compare it to our desired heading and any course corrections are applied by the motion routines, which also handle ramping and speed changes. The skid-steering design is quite nice for this type of application however a tail-wheel robot with differential drive would be just as effective. The ability to turn in place has advantages in this type of application.
To really appreciate the project you really need to see it in action. As with many projects of this type development is ongoing until I am happy with the performance of the design given the available resources. Eventually this robot chassis will pave the way for the Stingray version of the code, which will of course run on a Propeller, but which will also add additional sensors including wheel encoders.
Having just obtained some Windows 7 compatible flowchart software, I should have a flowchart for the code up on the project page. The flowchart will be very detailed about what the code is doing. It is my hope that this will make it easier to port the routines over to your favorite microcontroller. Remember, the code is heavily commented to help as well. I hope you enjoy the information presented. This project was published in the May 2010 issue of Servo Magazine.
THIS IS A RESTORED ARCHIVE PROJECT AND AS SUCH MAY BE MISSING PHOTOS, PARTS LIST, SCHEMATIC, SOURCE CODE, ETC.