If you are interested in completing this tutorial but have no experience building planes, please see the following tutorial on how to construct the Magpie AP. It should be noted that a 6 channel receiver and transmitter are recommended for this tutorial. This will allow the user to implement a manual override safety feature.
To complete this tutorial, you'll need the following items:
| PART DESCRIPTION | VENDOR | PART | PRICE (2006) | QTY | TOTAL |
| GPS Receiver | Garmin | GPS 18 5Hz | $199 | 1 | $199 |
| PIC Microcontroller (for storing GPS waypoints) | Microchip | PIC16F877A | $3.71 | 1 | $3.71 |
| PIC Microcontroller (for controlling rudder) | Microchip | PIC16F87 | $1.80 | 1 | $1.80 |
| Serial EEPROM (for logging lat/long data) | Microchip | 24FC515 | $2.99 | 1 | $2.99 |
| RS232 Converter Chip | Digikey | MAX235 | $16.38 | 1 | $16.38 |
| 5V Voltage Regulator | Digikey | LM7805CT-ND | $0.48 | 1 | $0.48 |
| 10 MHz Oscillator | Digikey | CTX163-ND | $2.78 | 2 | $5.56 |
| 4KOhm Resistor | Digikey | $0.20 | 2 | $0.40 | |
| 270 Ohm Resistor | Digikey | $0.20 | 1 | $0.20 | |
| 18-Pin IC Socket | Digikey | AE8918-ND | $0.22 | 1 | $0.22 |
| 24-Pin IC Socket | Digikey | AE8924-ND | $0.29 | 1 | $0.29 |
| 40-Pin IC Socket | Digikey | AE8940-ND | $0.49 | 1 | $0.49 |
| Single Row Pin Headers | Digikey | S1251E-36-ND | $3.85 | 4 | $15.40 |
| Hyperion Male Servo Connectors | All e RC | HP-SERCONM5L | $3.95 | 2 | $7.90 |
| Hyperion Servo Extension Wire | All e RC | HP-WR020 | $7.95 | 1 | $7.95 |
| Hyperion STD Extension Cable | All e RC | HP-WR004 | $2.45 | 1 | $2.45 |
To begin, let's first configure our GPS receiver. We have to change the device's baud rate to match that of the PIC16F877 microcontroller which will be receiving the data. To do this, go to the GPS 18 5Hz updates and downloads page and download the Unit Sofware. Use this software to change the baud rate of the receiver to 9600 and configure it to output the $GPRMC NMEA data string ONLY.
To verify that your GPS 18 5Hz is setup properly, use the supplied RS232 cable to connect it to your laptop's serial port. Open up hyperterminal and set the Bits per second to 9600 and the Flow control to None. Then power your GPS receiver using 5 volts and you should see something similar to the picture below (i.e. just the $GPRMC data string should be printed at 5 times per second). If not, you have incorrectly configured your GPS receiver in the above step. Please consult the GPS 18 5Hz manual.

The National Marine Electronics Association (NMEA, pronounced Nee-muh) has developed a standard for all GPS devices. From the previous section, it is obvious we will be using the $GPRMC data string which is the Recommended Minimum Specific GPS/TRANSIT Data. The $GPRMC data string contains 12 pieces of information separated by commas within the string:
For this tutorial, we will be concerned with latitude (3), longitude (5), and true course (8). The true course is the current heading of the aircraft (in degrees) and is measured clockwise from the North direction. If your plane is heading East, for example, then the true course would be equal to 90 degrees. This single value saves an enormous amount of computation. Otherwise, you would have to draw a vector from the previous latitude/longitude point to the current latitude/longitude point and then calculate the angle it forms with the North direction.
Unfortunately, the waypoint heading is not given to us and must be calculated. The technically correct way of calculating the heading to a waypoint is to use the bearing formula:

where d is the great circle distance. Unfortunately, trig functions (i.e. sines, cosines, tangents and their inverses) tend to eat up a lot of microcontroller memory. To minimize the use of these functions, we are going to use the pythagorean theorem to calculate our waypoint heading. This is not technically correct because it doesn't factor in the curvature of the Earth, but will work extremely well if remaining within your town's borders (won't work as well if you plan on flying your RC plane from Pennsylvania to New Jersey!). Looking at the following coordinate system

we can see that it's a bit unconventional as the x-axis is positive from right to left and not left to right (in the United States that is!). Furthermore, if we were to determine the heading using the inverse tan function with the N-S axis as the y-axis and the E-W axis as the x-axis, it would yield an angle about the East axis. However, we need the waypoint heading about the North axis since our aircraft heading is given to us with respect to this axis. Rotating this coordinate system by 90 degrees clockwise will yield solutions to both problems. The new coordinate system is shown below.

Now, taking the inverse tan in this coordinate frame will yield the angle about the North axis. One last problem remains, however, as the angle yielded will take the counter-clockwise direction as positive. To change the positive direction to clockwise in order to coincide with the true heading value (8), the following two lines of code are added to the algorithm.
// make clockwise direction positive (CCW is +ve as is)
if(sin(currentWayptLong - currentLong)>0.0) waypointHeading = 360.0 - waypointHeading*(180.0/Pi);
else waypointHeading = -waypointHeading*(180.0/Pi);
Now that the current heading of the airplane and the heading to the next waypoint are known, we can discern which way and how much the aircraft should turn in order to hit the next waypoint. For example, the figure below shows one scenario given the waypoint heading angle (measured from the North direction) and the true course angle (which is the current heading of the aircraft, also measured from the North direction). Intuitively, it is obvious the aircraft should turn right here to head towards the next waypoint. However, it is not as easy when coding this algorithm.

The easiest, but definitely least effective, way of coding this algorithm is to say that if the aircraft heading is less than the waypoint heading, turn right. Otherwise turn left. However, this can be very inefficient in certain instances. For example, if the waypoint is just to the left of the North direction and you are heading a little right of North, the plane should turn slightly left to hit the waypoint. However, with the above algorithm the plane will get to the waypoint, but not before flying in a complete circle (well almost). This scenario is demonstrated in the graphic below.

The algorithm used in this tutorial is based on proportional control of the error between the aircraft heading and the waypoint heading. The code is listed below:
error = (long)waypointHeading - trueHeading;
Kp = 1;
// keep error between -180 and 180
if(error>=180) error = error - 360;
if(error<=-180) error = 360 + error;
rud_pwm = 142 - Kp*error; // typical neutral position (127) is a little off on Magpie (142)
The purpose of keeping the error between -180 and 180 degrees is to force the aircraft to take the shortest turn (in terms of degrees) possible to the waypoint. That is, it will not make a 300 degree right turn when it can make a 60 left turn to head toward the next waypoint. Furthermore, the value of 142 is taken as the neutral position (no deflection in either direction) of the servo. This value will have to be tuned as it depends on the construction of the aircraft. Finally, the code ends by limiting the deflection in each direction. Typically a value of 0 is full deflection in one direction and 255 is full deflection in the other. However, deflecting the rudder fully in one direction will cause the aircraft to roll in addition to yawing. If it's deflected long enough, the plane will begin a downward spiral and you will lose stabilization. All you need is a small amount of deflection in each direction to turn the aircraft.
// no ailerons on Magpie; have to limit rudder deflection
if(rud_pwm<122) rud_pwm=122; // turn right (neutral-20)
if(rud_pwm>162) rud_pwm=162; // turn left (neutral+20)
Mount the GPS receiver on top of the Magpie's wing (like shown in the figure below) using a piece of velcro or double-sided foam tape. Determine how much of the 5 meter cable is needed to reach from the top of the wing to the camera bay (this is where your control circuit will be secured). Now strip the end of the cable at the determined length to expose the 7 wires inside the insulation. Two out of the three ground wires need to be connected for the GPS receiver to function properly. I took the thick ground (black) wire and soldered it to one of the thinner ground wires (you can leave the other thin ground wire unconnected). Next, feed the power, transmit, receive, and ground (the one you just soldered from above) wires into a 4-pin female header. This will fit over the 4-pin male header on your circuit board.
    
Construct your circuit board based on the schematic shown below (click on the image to enlarge):
The PIC16F877 performs the majority of the calculations for waypoint navigation. That is, it reads in the latitude and longitude data from the GPS receiver and then calculates the current aircraft heading and the heading to the next waypoint. Once the direction and amount of turn is known, the PIC16F877 communicates this information to the PIC16F87 which is used to deflect the rudder servo accordingly. The PIC16F87 is also used to perform manual override of the aircraft via the RC transmitter. In the event that the algorithm is not performing as expected (or if your plane is about to crash), a flick of the transmitter switch will allow a human pilot to take over and avoid the crash.
It should also be noted that the above schematic was designed so that no additional batteries are needed to power the control circuit board. The 12 volt lithium polymer battery that powers the airplane electronics should also be fed into the voltage regulator on this circuit board. The regulator will then power all the components on the board with 5V.
Once the circuit is constructed, the next step is to program each of the PICs for their respective functions. Download the following C files (gpsNavigationF877_multipleEeprom.c, interrupts.c, and rdaDefine.c.). Open up the F877 C file and you will notice three waypoints stored in the variable currentWaypoint. Change these values to three waypoints at a nearby flying field, otherwise, your plane will start heading to Philadelphia! Upon doing so, compile the F877 and F87 (the rdaDefine.c file is included with the F87 file so you do not need to compile it) C files in order to generate both HEX files. Finally, burn the HEX files to the PIC16F877A and PIC16F87 microcontrollers.
My original plan was to fly the plane manually over certain waypoints and every time I wanted to select a waypoint, I would quickly switch from manual to autonomous control and then back to manual. This would signal to the microcontroller that I wanted to store this point as a waypoint. This would eliminate the need to enter these in manually. However, I didn't have enough memory on the PIC16F877A microcontroller to create variables for these waypoints to be stored in.
Before hooking up the GPS receiver, you want to make sure that the two PICs were correctly programmed. First, using the servo extension wire and two of the male servo connectors, create a servo cable with a male connector on both ends. It will run from the airplane's receiver to the control circuit board so be sure that it is long enough before cutting the wire. Repeat this process so that you have two cables that look like the one below.

Take one end of the servo cable created in the previous step and connect it to channel 6 of your airplane's receiver. Take the other end and connect it to the 3-pin header on your circuit labeled CH6_IN. Now, complete the following steps to make sure everything is properly working.
Using the other cable created in the above step, hook one end to the rudder channel on the receiver (usually channel 4) and hook the other end to the control circuit board labeled RUD_IN. Then, using your servo extension cable (1 male end and 1 female end), connect the male end to the 3-pin header on your control circuit marked RUD_OUT and the female end to the rudder servo. Finally, secure the control circuit board in the cutout of the fuselage (this was originally spec'd out for a digital camera, but our control circuit should fit nicely here). Attach the control circuit using velcro, double-sided foam tape, or a zip tie.
The following is a video of the Magpie AP performing GPS waypoint navigation (note: this is footage with some old code...the code given on this web page performs much more efficiently!).

This tutorial was created by B. Green: home page