Docstoc

Santa Clara University - Download Now DOC

Document Sample
Santa Clara University - Download Now DOC Powered By Docstoc
					                      Santa Clara University
          DEPARTMENT of COMPUTER ENGINEERING

                          Date: July 17, 2011


  WE HEREBY RECOMMEND THAT THE THESIS PREPARED UNDER OUR
                     SUPERVISION BY



              Ryan Becker, Chris Borowski, Ognjen Petrovic

                              ENTITLED

          Formation Flight of Autonomous Aerial Vehicles


BE ACCEPTED IN PARTIAL FULFILLMENT OF THE REQUIREMENTS FOR THE

                              DEGREE OF


     BACHELOR OF SCIENCE IN COMPUTER ENGINEERING




                                                     ______________________
                                                         THESIS ADVISOR



                                                     ______________________
                                                         THESIS ADVISOR



                                                     ______________________
                                                        DEPARTMENTCHAIR




               Santa Clara University Aerial Robotics Team                    1
Formation Flight of Autonomous Aerial Vehicles


                           by



   Ryan Becker, Chris Borowski, and Ognjen Petrovic




        SENIOR DESIGN PROJECT REPORT




   Submitted in partial fulfillment of the requirements
                    for the degree of
     Bachelor of Science in Computer Engineering
                 School of Engineering
                 Santa Clara University




                 Santa Clara, California

                      July 17, 2011




     Santa Clara University Aerial Robotics Team          2
Abstract
       Santa Clara University‟s Aerial Robotics Team developed an autonomous fleet of
Uninhabited Aerial Vehicles (UAVs) capable of performing aerial reconnaissance and
demonstrating basic formation flying capabilities. In a single plane configuration, the
team exploited the capabilities of a commercial autopilot in order to automatically fly
through a pre-determined set of navigational waypoints and using real-time video feed in
order to image and provide open-loop tracking of specific targets. This capability will be
showcased in the international Association for Unmanned Vehicle Systems International
(AUVSI) UAV competition in June 2004.                 In a two-plane follow-the-leader
configuration, a human pilot flys a lead plane, and a chase plane automatically follows
the lead plane‟s trajectory. This is accomplished through the use of Ground Control
Station software, written by the team, that collects trajectory information from both
planes and controls the follow-the-leader formation. In performing this project, the team
has accomplished three significant objectives. First, it has successfully developed a flight
system that will prove to be competitive in the AUVSI competition. Second, it has
demonstrated an impressive multi-UAV flight capability that demonstrates the power of
multi-UAV formations for enhancing the ability of UAVs to perform scientific, civil,
humanitarian, and national defense missions. Finally, it has established a viable and
impressive multi-UAV test bed for future SCU robotics education and research projects.




                      Santa Clara University Aerial Robotics Team                              3
Acknowledgements
       The authors are grateful to the following community mentors. Mike Luvara of
RCATS Systems furnished a telemetry sensor package for the lead aircraft. NASA Ames
Research Center provided the opportunity to become certified in a Flight Readiness
Review in preparation to fly in Class D airspace. TJ Forsyth was of great assistance in
this process. Thanks are also extended to Steve Morris of MLB Company and Phil
Carlson of Lockheed for sitting in on a design review and the professors for all their
support and dedication. The Robotics Systems Laboratory and the Senior Design
Scholarship Fund funded the acquisition of the aircraft and flight electronics used for this
project. The team is also appreciative of the School of Engineering and Dean Daniel Pitt
for supporting the team in travel to and from the competition. [Appendix D] The Arruppe
Center was also very generous in their use of vehicles for outreach projects.
       In addition, portions of this project were supported by the National Science
Foundation under Grant No. EIA0079815 and EIA0082041; any opinions, findings, and
conclusions or recommendations expressed in this material are those of the authors and
do not necessarily reflect the views of the National Science Foundation.




                      Santa Clara University Aerial Robotics Team                              4
Table of Contents
ABSTRACT .................................................................................................................................................. 3
ACKNOWLEDGEMENTS ......................................................................................................................... 4
TABLE OF CONTENTS ............................................................................................................................. 5
CHAPTER 1- INTRODUCTION ............................................................................................................... 7
    1.1 SYSTEM OVERVIEW .............................................................................................................................. 7
    1.2 PROJECT OBJECTIVES ........................................................................................................................... 9
CHAPTER 2- AIRCRAFT DESIGN .........................................................................................................11
    2.1 AIRFRAME SELECTION .........................................................................................................................11
    2.2 ENGINE CHOICE ...................................................................................................................................13
    2.3 POWER SYSTEMS .................................................................................................................................14
    2.4 COMMUNICATION LINKS .....................................................................................................................14
    2.5 VIDEO RECONNAISSANCE PACKAGE ....................................................................................................15
CHAPTER 3- AERIAL VEHICLES .........................................................................................................17
    3.1 CHASE PLANE PAYLOAD .....................................................................................................................17
    3.2 LEAD PLANE PAYLOAD .......................................................................................................................21
CHAPTER 4- SOFTWARE .......................................................................................................................25
    4.1 FORMATION FLIGHT DESIGN OVERVIEW .............................................................................................25
    4.2 FORMATION FLIGHT SOFTWARE ARCHITECTURE.................................................................................26
    4.3 LIMITATIONS OF SCU GROUND CONTROL SOFTWARE ........................................................................30
CHAPTER 5- TEST RESULTS .................................................................................................................31
CHAPTER 6- SAFETY ..............................................................................................................................33
CHAPTER 7- FLIGHT OPERATIONS ...................................................................................................35
    7.1 COMPETITION STRATEGIES ..................................................................................................................35
    7.2 FORMATION FLYING ............................................................................................................................36
CHAPTER 8- SOCIETAL ISSUES ...........................................................................................................39
CHAPTER 9- COMMUNITY OUTREACH ............................................................................................42
CHAPTER 10- CONCLUSIONS ...............................................................................................................43
    10.1 SUMMARY .........................................................................................................................................43
    10.2 FUTURE WORK ..................................................................................................................................43
APPENDICES .............................................................................................................................................46
    APPENDIX A: ABBREVIATIONS ..................................................................................................................46
    APPENDIX B: SCU GROUND CONTROL SOFTWARE AUTOPILOT INTERFACE .............................................47
    APPENDIX C: RICOCHET MODEM TEST......................................................................................................49
    APPENDIX D: FUNDING REQUEST LETTERS ...............................................................................................50
    APPENDIX E: AUTOPILOT GRAPHS ............................................................................................................55
    APPENDIX F: HARDWARE FLOW DIAGRAMS .............................................................................................56
    APPENDIX G: SAFETY CHECK LIST ............................................................................................................59
    APPENDIX H: ENGINE STARTUP PROCEDURE ............................................................................................60
    APPENDIX I: LEAD PLANE BASIC STAMP CODE .........................................................................................61
    APPENDIX J: GROUND CONTROL STATION SOFTWARE CODE ....................................................................63




                                      Santa Clara University Aerial Robotics Team                                                                               5
List of Figures
Figure 1- Aircraft taxiing to the pit area after a successful flight. ...................................... 8
Figure 2- Piper Cub ........................................................................................................... 11
Figure 3- Lancair............................................................................................................... 12
Figure 4- Super Stunt .60 .................................................................................................. 13
Figure 5- Chase Plane Flowchart ...................................................................................... 18
Figure 6- Event driven aerial reconnaissance technique................................................... 19
Figure 7- Video Flow Chart .............................................................................................. 20
Figure 8- Basic Stamp Chip 2sx ....................................................................................... 22
Figure 9- Inside the Lead Plane ........................................................................................ 22
Figure 10- Garmin GPS 16 ............................................................................................... 22
Figure 11- RCATS Flight Computer ................................................................................ 22
Figure 12- Lead Plane Flow Diagram ............................................................................... 23
Figure 13- Basic Formation Flight Overview ................................................................... 26
Figure 14- Software Architecture Chart ........................................................................... 27
Figure 15- Successful Formation Flight ........................................................................... 31
Figure 16- Limitations of the Autopilot System ............................................................... 32
Figure 17- Emergency Engine Kill Switch ....................................................................... 33
Figure 18- Illustration of aircraft flight path ..................................................................... 35
Figure 19- Waypoint navigation using Micropilot‟s software .......................................... 36
Figure 20- Image of Ground Control Station Software .................................................... 37
Figure 21- Aircraft in „Follow the Leader‟ Formation ..................................................... 38


List of Tables
Table 1- Chase Plane Power Break Down ........................................................................ 21
Table 2- Lead Plane Sentence Example............................................................................ 23




                                Santa Clara University Aerial Robotics Team                                                           6
Chapter 1- Introduction
       The Santa Clara University (SCU) Robotic Systems Laboratory (RSL) conducts
an aggressive, integrative research and education program in intelligent robotic systems.
The centerpiece of this program is a set of yearly undergraduate design projects in which
teams of senior students completely design, fabricate, test, and operate high quality
robotic systems [1]. This project involved the development of automated flight capability
for UAV aircraft, a class of robotic systems previously unexplored within the RSL
program.


1.1 System Overview
       This particular project explores two uses for an off-the-shelf autopilot system
from Micropilot. SCU‟s aerial robotics team received the MP2028g autopilot system
from Micropilot through their entry into the AUVSI competition. The donation and free
use of this sophisticated autopilot made it an ideal platform for the Unmanned Aerial
Vehicle (UAV) project. For a complete list of abbreviations see appendix A. The
utilization and experimentation of the Micropilot autopilot system required the extended
configuration of environment variables and control system gains. After successful testing
of autopilot‟s primary functionality, the added applications could be implemented. The
first use is to create an autonomous UAV reconnaissance system that can monitor
designated targets and provide real-time video imaging to ground operators.             This
objective will be applied in an international student competition in June 2004. The
second use is to support the operation of a two-UAV fleet using an automated follow-the-
leader formation flying strategy in order to ultimately provide enhanced reconnaissance
capabilities. The lead aircraft will be pilot controlled and the chase aircraft will be
completely autonomous.       An additional aircraft is used as a training platform and
replacement airframe.
       To help facilitate the ease-of-use of this system, new ground station control
software was written that includes a graphical user interface along with real-time three-
dimensional plotting and telemetry. In support of these two objectives, the aerial robotics
team developed a fleet of three aircraft for SCU to use as a basis for its experimental
work in aerial robotics. Beyond the work reported here, the fleet will be used by future


                        Santa Clara University Aerial Robotics Team                            7
undergraduates, graduate students and professional researchers as a low-cost test bed to
perform compelling scientific investigations and technical demonstrations.




                Figure 1- Aircraft taxiing to the pit area after a successful flight.


       There are many applications and benefits to UAVs. The use of UAVs can
accomplish many of the same objectives as manned missions, at a lower cost and risk.
Some of the many applications include terrain mapping, search and rescue,
environmental monitoring and collaboration of aircraft. Government agencies currently
utilize the abilities of UAVs. Such aircraft include Predator, Global Hawk, Outrider and
Shadow. [2] The project objectives associated with this project involve implementing a
UAV observation platform and are consistent with these concepts.
       Given the aforementioned advantages of UAVs it is natural to consider the
potential benefits of using multiple robotic systems for the same applications. In general,
multi-robot systems offer potential benefits such as increased coverage and availability,
graceful constitution and degradation, and flexible reconfiguration for mission-specific
purposes. The use of multiple UAVs for a single mission, however, also poses significant
engineering challenges such as vehicle coordination, communication and integration. The
second objective of this project was to explore some of these issues with a simple two
UAV prototype system that implemented a follow-the-leader flight strategy.
       The development and use of this robotic system and opportunity to work on
multi-year robotics projects has served as the keystone for an integrated education within
the SCU program. Overall, the mixing of students, engineers and scientists across a


                       Santa Clara University Aerial Robotics Team                            8
variety of educational levels and from a multitude of organizations creates a particularly
stimulating environment for technical education, engineering innovation, and scientific
discovery. [3]
       This paper discusses the objectives of this project and describes some of the
engineering decisions that went into the design features of this system. Safety aspects of
the aircraft are also explored in detail. Some of the strategies that will be used for the
competition are explained including the approach taken to most accurately determine the
composition of the targets. The last section of the paper discusses the formation flight
aspect and the methods used to enable the two aircraft to fly in formation.


1.2 Project Objectives
       As previously stated, our two general areas of interest were to implement first, a
single UAV observation system, and secondly a simple two-UAV follow-the-leader
system.
       In order to achieve the first goal, our specific technical objectives required us to
integrate the Micropilot autopilot into our flight system in order to achieve automated
take-off, landing and navigation. For the AUVSI competition, the plane is designed to
pilot itself through a series of waypoints. During the course of the flight, it will perform
aerial observation. At the designated first waypoint, the aircraft will survey a 10 x 10
cement target with painted lines of various orientations and sizes. Aerial video will be
broadcasted back to the operators for analysis. The orientation, size and number of lines
will then be determined. After flying over the first target several times to ensure an
accurate reading, the aircraft flies toward the second target. At the second target, the
airplane will observe several vehicles and buildings. Analysis of video at this target will
consist of a count on the number of objects, position in relation to the designated GPS
coordinate and directional orientation of each object. After completing these tasks, the
aircraft will then proceed home for landing.
       To accomplish our second project objective, we had to do several things. First, a
follow-the-leader formation-flying algorithm needed to be designed. Secondly, it was
necessary to create a ground control station that could coordinate the two aircraft,




                      Santa Clara University Aerial Robotics Team                              9
calculate ground trajectory information and handle communication between the two
planes.




                   Santa Clara University Aerial Robotics Team                     10
Chapter 2- Aircraft Design
       Many engineering decisions went into the design of this project. The architecture
of all aspects had to be taken into account for successful integration of components. It
was important to consider all the systems, as many are interdependent on one another.


2.1 Airframe Selection
       Forming the foundation for the entire project, it was essential have a stable
airframe. In order to save on building time, it was decided that an almost-ready-to-fly
(ARF) aircraft would be chosen. This approach was taken because the aerial robotics
team is composed of three computer engineers, none of which have an aerospace
background or experience designing airframes. An ARF was also important for
compatibility reasons. If spare parts were required, it would be easy to obtain them from
the local hobby shop. During the aircraft selection process several different airframes
were tested. The investigation explored a high wing “Piper Cub” tail dragger, a low wing,
fast and scale “Lancair” and a .60 size trainer. It was determined that the first two
selections were poor choices.




                                    Figure 2- Piper Cub


       Our first experimentation was with the Piper Cub. The field in which many of the
flight operations are conducted is rather windy making it difficult to taxi the aircraft and
maintain a straight takeoff roll down the runway. Additionally, the characteristics of the
tail dragger type of landing gear on the Piper Cub made it non-conducive for this



                      Santa Clara University Aerial Robotics Team                              11
experiment. When the plane was equipped with sensors, the added weight resulted in a
longer time for the tail to rise off the ground. The wing spars also posed another
challenge as their attachment mechanism prevented easy access to the fuselage. This
attributed to making internal modifications difficult. Furthermore, the Cub proved to
handle poorly in high wind conditions because the wings would easily get caught in a
gust and the plane was susceptible to blowing over. In one instance, similar to a kite, the
aircraft was actually blown backwards when it was idling on the runway.




                                     Figure 3- Lancair



       To try and help solve some of the issues that plagued the Cub, the next aircraft
tested was a sleeker, low wing scale aircraft; a Lancair. However, the Lancair provided a
similar plethora of challenges that the Cub did. The building time on the aircraft, due to
its scale attributes was approximately 50 hours, not the anticipated 10 hours an ARF
usually requires. The wing profile and surface area on this particular aircraft are also
small resulting in a high stall speed. These factors contributed to a high takeoff, approach
and landing speed. The accurate scale and realism of this aircraft also limited the carrying
capacity making it less suitable for a UAV equipped with an array of sensors. For
example, it is much more stable to hang the weight from the plane than to set the weight
on top of the wing. An aircraft is more stable in a high wing configuration than the low
wing design. Furthermore, both the Piper Cub and Lancair were more expensive than the
.60 sized trainers that were finally selected for the project. While the Lancair and Piper
Cub were inappropriate for the UAV project, they assisted the team in several ways.


                      Santa Clara University Aerial Robotics Team                              12
Through the challenges and obstacles that the two aircraft provided, the team was able to
identify the traits of good UAV airframe.




                                   Figure 4- Super Stunt .60


       The .60 size trainer was chosen because it provided an adequate payload and
internal volume to carry the required sensor equipment. In addition, the aircraft wasn‟t
physically too large to work with, transport and store. The chosen aircraft, a Super Stunt
.60 is available as an ARF (Almost Ready to Fly) and was quick in assembly time. The
tricycle landing gear configuration allows for easy ground handling, even with a modest
amount of wind. The symmetrical airfoil helps the plane track straight through the air and
the large wing area permits it to fly stably through the entire speed envelope. Operational
flaps contribute to smooth handling and a higher payload at slower speeds. Overall, the
stability and dependability of the Super Stunt .60 allows the focus to be on more
important tasks such as learning and utilizing the full potential of the autopilot system.


2.2 Engine Choice
       With an airframe selected, the next engineering decision was to choose an engine
to power the aircraft. As SCU‟s Aerial Robotics Team had previous experience with OS
Engines, a .61 FX was selected to fulfill this need. While it has proven to be quite a
workhorse, it has left a few things to be desired. As a two-stroke glow-fuel engine, the
exhaust is very oily and a considerable amount of time is put into cleaning the planes and
equipment after every day of flying. The weight of the equipment inside the plane in


                       Santa Clara University Aerial Robotics Team                            13
addition to the drag of the belly mounted camera is enough to require nearly full throttle
during a fully loaded flight. While this engine gets the job done, a larger, more powerful
4-stroke engine is desirable. An engine of this type would create an almost non-existent
exhaust residue and have enough reserve power to quickly climb to higher altitudes.
       For the AUVSI competition, the team decided to continue working with the
original .61 FX to limit the fuel consumption rate. As fuel economy is one of the judging
categories, it‟s important to limit the consumption rate and consequently, a smaller
engine is more economical.


2.3 Power Systems
       With a suitable aircraft and engine selected, the power distribution system for the
plane servos and payload needed consideration. The aircraft utilizes four separate power
systems for redundancy and safety purposes. Upon consideration of a single high energy
Lithium Ion battery, it was declined for several reasons. First, since different components
have special voltage requirements, simplicity dictated avoiding the hassle of integrating
custom designed regulators to power all the on board equipment. Secondly, while
payload weight was a concern, evaluation of the aircraft‟s capacity indicated that using a
redundant four-battery system was an acceptable tradeoff. In other words, the benefits of
additional batteries outweighed the more efficient single battery power system.


2.4 Communication Links
       For physical control of the plane, the aircraft supports two primary means of
communication. These include a wireless radio modem made by Maxstream and the
traditional RC link.
       Two modems were considered for serial communication with the aircraft. The
first, a modem by Richochet, cost only ten dollars making them very attractive initially.
Upon testing however, there were several concerns. See appendix C for initial modem
test results. The modems, while able to maintain a connection over a long distance, were
very difficult to connect initially. It was necessary to dial up a particular modem followed
by a 30 second wait time while „hand-shaking‟ occurred. Even when connected, the




                       Santa Clara University Aerial Robotics Team                             14
modems had many dropouts making data transfer unreliable. The modems were also
much heavier and took up too much valuable cargo space.
          The second choice purchased from Maxstream greatly simplified the wireless
connection process to the autopilot. The initialization process simply involved turning on
each modem. Even more encouraging was the lack of dropouts and range capability.
After testing over a 2 mile range, the Maxstreams were determined more than acceptable
and they were integrated into the system. On the lead plane a different radio link was
used. The RCATS system utilizes a prebundled modem to implement its one way
communication to the ground.
          The RC link was selected because it provides a standard interface for the plane. It
is also well tested, approved by the FCC and safe when operating around other aircraft.
The aircraft are also not operated outside line of sight so it was not necessary to explore
other, longer range means of aircraft control.


2.5 Video Reconnaissance Package
          The video reconnaissance system consists of a package that mounts to the bottom
of the aircraft. Rubber bands are used to attach the camera box as in the event of a crash,
the box can break away from the plane thus limiting damage to the equipment housed
within.
          The camera and transmitter system, made by wirelessvideocameras.com, were
selected due to their ability to transmit long range (currently 10 miles with a directional
antenna). It took experimentation with several other less expensive camera solutions to
finally settle on this particular product. Other systems were disappointing due to their
limited range capabilities. The maximum range of the other systems peaked out around
150 yards before the signal became fuzzy. For this project it was important to have a
solution that could work effectively at least one mile away because of our flight range.
          The system selected consists of a CCD camera, transmitter and servo to control
tilt. This provides the ability to look anywhere between the forward position and twenty
degrees aft. The camera system was designed with this ability to solve several problems.
First, it eliminates the need to carry several stationary cameras looking in different
directions, thus reducing the weight. Additionally, a video camera is more effective than


                        Santa Clara University Aerial Robotics Team                             15
a still camera because operators can receive a continuous stream of images in which to
analyze. It also eliminates the need to „time‟ the moment in which to take a photo when
passing over a target.




                         Santa Clara University Aerial Robotics Team                      16
Chapter 3- Aerial Vehicles
3.1 Chase Plane Payload
       The chase plane is a completely autonomous UAV capable of maintaining
controlled flight, collecting video data, and receiving new commands in flight. This
functionality is made possible by the integration of electronics into a standard radio-
controlled (RC) model airplane. The central component onboard the aircraft is the
Micropilot MP2028g Autopilot System. In conjunction with a standard RC receiver and
servos, it utilizes an arsenal of sensors and microcontrollers to maintain controlled flight.
These sensors include GPS, static pressure, dynamic pressure, three-dimensional gyro,
and an ultrasonic altimeter. The GPS sensor is used to identify the exact location of the
aircraft in longitude and latitude. The static and dynamic pressure sensors are used in
combination with one another and provide two pieces of information; the aircraft‟s
airspeed and altitude above ground. The three-dimensional gyro is used to sense the yaw,
bank, and pitch of the aircraft. Finally, the ultrasonic sensor is used to take a more
accurate measurement of altitude above the ground using an ultrasonic signal bounced off
the ground. This sensor works only from zero to twenty feet above the ground and
therefore is used solely for autonomous takeoffs and landings. The RC 72 MHz receiver
link allows for the pilot to fly the aircraft manually. This is considered pilot in control
mode (PIC). Through a switch on the transmitter, the pilot has the ability to switch
between computer in control (CIC) mode and pilot in control. When in PIC mode,
information from the RC receiver passes directly into the autopilot. The autopilot then
sends the information to the aircraft servos that control movement of the control surfaces.
In CIC mode, all information from the RC receiver, aside from the CIC to PIC switch, is
ignored and the autopilot commands the servos based off of sensor information. Another
component of the system is the radio modem. The chase plane uses a Maxstream
9XStream radio modem that sends and receives across 900 MHz frequencies. The radio
modem provides a real-time link to the plane and a method to interface with the autopilot
system in-flight which permits the upload of flight-paths and commands. Real-time
information is also received from the aircraft such as airspeed, altitude, and positional
location through the radio modems.




                       Santa Clara University Aerial Robotics Team                              17
                              Figure 5- Chase Plane Flowchart



       In addition to an autopilot system, the chase plane carries an aerial reconnaissance
package. This helps fulfill one of the primary objectives of providing real-time video to
the ground station. Mounted to the bottom of the aircraft are a camera, servo, and
wireless video transmitter. The wireless video transmitter is an AAR05 Long Range
Airplane System from www.WirelessVideoCameras.com and can transmit color video
imagery over five miles. A CCD camera provides the imagery for this system. The
camera is attached to a servo providing for the ability to tilt the camera in flight. Thus,
the camera can be pointed any where between straight forward and twenty degrees aft
providing for a 120-degree viewing angle.




                      Santa Clara University Aerial Robotics Team                             18
Figure 6- Event driven aerial reconnaissance technique




 Santa Clara University Aerial Robotics Team             19
        Coupling the autopilot to the camera servo, the ability to track a target as the
aircraft flies over it was added, providing the most amount of viewing time possible. This
is accomplished by using events to drive the position of the camera. An illustration of this
appears in Figure 6. The camera tracking process is as follows. When creating a flight
plan for the aircraft and there is a designated location to observe in mind, a series of
waypoints are created at specified distances leading up to a target. As the plane crosses
the path leading up to the target, it gradually shifts the camera to a downward position so
that when the aircraft crosses the target, the camera is looking straight down. With the
ability to stream the video live to the ground, an operator has an advantage in that they
can analyze the data in real time as opposed to reviewing still photos after the flight.




                                  Figure 7- Video Flow Chart



        The chase plane also carries a redundant engine kill switch. In accordance with
Moffett Field and NASA Ames Research Center, this switch was added to reduce
possible range of the aircraft in the event of power, primary RC receiver, or autopilot
failure. The kill switch consists of a second 72 MHz RC receiver, servo, and spring-
loaded fuel valve. At any time, the operator can send a signal to the receiver that will tell
the servo to trip the spring-loaded fuel valve. This will close the fuel line and therefore
kill the engine.


                       Santa Clara University Aerial Robotics Team                              20
       Finally the chase plane payload must contain power for all its electrical systems.
The autopilot and flight servos were placed on a separate battery in the event of a high
current draw by one of the servos. This helps to ensure that the autopilot voltage will not
drop too low, resetting the flight computer mid-flight. A high capacity servo battery was
also selected to support the 7 operational servos and to reduce the risk of running out of
power. The selection of a 12-volt battery for the video package and modem was simple
due to their voltage requirements. This power system is considered a secondary system as
the aircraft could still function normally should this battery fail. The aircraft also has a
separate battery, receiver, antenna and servo to control a redundant engine kill switch.
The use of this emergency switch provides the ability to limit the range of the aircraft by
stopping the engine in the event of an autopilot or main servo battery failure. Table 1
shows the breakdown of all batteries on the chase plane.

                           Table 1- Chase Plane Power Break Down
            Purpose                              Battery Size
            Autopilot System                     4.8V 1800 mAh NiCd
            Flight Servos                        4.8V 2700 mAh NiMH
            Radio Modem, Video                   12V 1100 mAh NiMH
            Reconnaissance Package
            Redundant Engine Kill Switch         4.8V 600 mAh NiCd

3.2 Lead Plane Payload
       The lead plane‟s robotics hardware includes: one on-board computer,
communication equipment, and sensor equipment for navigation, flight, and health
feedback.
       The lead plane carries a package of sensors from RCATS Corporation. RCATS
provides information about altitude, airspeed, engine temperature, exhaust temperature,
engine RPM, battery voltage levels, and barometric pressure. A separate Garmin GPS-16
WAAS unit reports the plane‟s current location accurately (within ~3 meters). Garmin‟s
output is in the standard NMEA 0183 sentence form. A Basic Stamp 2 microcontroller is
the data processing and integration unit. RCATS radio modem transmits the data at 9600
b/s „through-air‟ rate. Redundant Engine Kill Switch adds extra safety to the lead plane.




                      Santa Clara University Aerial Robotics Team                              21
Figure 8- Basic Stamp Chip 2sx




Figure 10- Garmin GPS 16




                                          Figure 9- Inside the Lead Plane




Figure 11- RCATS Flight Computer




                       Santa Clara University Aerial Robotics Team          22
                             Figure 12- Lead Plane Flow Diagram



       GPS and RCATS sensors generate current navigation, flight, and health status of
the lead plane. This information is pushed to the Basic Stamp 2 microcontroller. The GPS
communicates with the Stamp at 19200 b/s serial port rate. RCATS sensors communicate
with the Stamp at 9600 b/s serial port rate. See appendix I for Basic Stamp Code. The
Basic stamp puts the data in the standardized format that GCS can understand. Standard
format is:

Table 2- Lead Plane Sentence Example
General GPS sentence    Comma RCATS        carriage return symbol: \n
Format                          sentence
Example $GPRMC,183354,A,3725.2494,N,12203.3319,W,043.7,315.4,050604,015.0,E*6E
        ,RCATS,P9642,A217.7,B119.6,C7827,D97,E51.3,F4.92,G26.69,H0.81,I1.56,J1.4
        6,K-66,L93.0,M-3

The basic stamp pushes integrated sensor data to the wireless RCATS modem at 9600 b/s
serial port rate. The modem, finally, transmits the information down to the ground.
RCATS modems do not support reliable data transfer mode.
   There are faster, more capable, better microcontrollers on the market that can replace
the Basic Stamp 2. We chose the Basic Stamp 2 for the following reasons:
   -   Familiarity with PBasic programming language
   -   Quick learning curve


                       Santa Clara University Aerial Robotics Team                          23
   -   Simple serial port interface
   -   Sufficient processing power and bandwidth
However, more than 2 additional sensors would probably reach the limits of BS2‟s
processing power. An Atmel board type would be a suitable replacement for BS2.




                      Santa Clara University Aerial Robotics Team                  24
Chapter 4- Software
        In writing the ground control station software, several things were apparent.
Functionally, the software was the heart of the algorithm in that its responsibilities
included the key aspects. The software handled communications with the aircraft,
analyzed data from both planes, ran the formation-flying algorithm and coordinated the
aircraft‟s flight path. It was also responsible for sending updates to the autopilot, warning
the operator about flight failures, logging sensor data and issuing commands and finally,
creating a real-time 3d plot of aircraft flight paths.
        To accomplish these tasks, the software had to fulfill a certain set of requirements.
To make the software easy to use, a graphical user interface was needed. This helped
present the operator with a manageable application where flight maneuvers could be
coordinated. The software also had to be a real-time, multi threaded application in order
to handle all the distinct operations. Finally, it had to synchronize communications
between the various devices.
        The software was written in the Visual Studio.NET programming environment as
it allowed for multiple components to easily be integrated together. The primary
programming language was C++ and made use of Micropilot‟s SDK as well as an open
source Serial Port Interface.


4.1 Formation Flight Design Overview
        Formation flying project has three main computer systems: lead plane, chase
plane, and ground control station. They all communicate via wireless links. There is no
direct communication between the planes. Ground control station serves as an indirect
hub between the planes. The overview of data and control flow is depicted below. The
hardware flow diagrams are available in appendix F.




                       Santa Clara University Aerial Robotics Team                              25
                         Figure 13- Basic Formation Flight Overview



       The link between the lead plane and GCS is unidirectional, while the link between
the chase plane and GCS is bi-directional. Link from the lead plane is unidirectional since
the lead plane has no autonomous capability and does not receive commands from the
GCS.

Planes achieve the formation through the following process:
   1. GCS gathers information from the lead plane
   2. GCS gathers information from the chase plane
   3. GCS makes the decision how to achieve formation flight for the chase plane
   4. Chase plane executes GCS flight plan


4.2 Formation Flight Software Architecture
       Start formation event triggers the start of formation flying mechanism. In default
configuration, GCS Graphical User Interface application issues the start formation event.
Start formation command is successful if all relevant flight parameters are satisfied. Both
lead and chase plane have to be „online‟ and in the air. Once started, the mechanism is
totally decoupled from GUI and video application. The user can stop formation flying by
issuing stop formation event signal at any moment of execution.
       There are two main inputs to the formation flying mechanism: sensor information
from the lead plane and from the chase plane. The output, in a form of flight schedule


                      Santa Clara University Aerial Robotics Team                             26
file, is sent to the chase plane. The whole process is asynchronous, based on sensor
events mainly from the lead plane.




                          Figure 14- Software Architecture Chart


       The lead plane data collector accepts the data from the lead plane. The collector
works as a stand-alone thread. Its implementation is based on the TserialEvent class.
TserialEvent is an open source serial interface. TserialEvent is the parent class of all
other serial port sensor classes. In the formation flying project, GenericSensor and
RCATSSensor class are children of TserialEvent class. For purposes of formation flying
TserialEvent has two modifications. First, it is optimized to work with maximum lead
plane sensor sentence length (170 characters). Second, its windows operating system
thread priority has been raised to TIME_CRITICAL. The collector generates an event


                     Santa Clara University Aerial Robotics Team                           27
whenever new data appears on the serial port. See appendix J for Ground Station
software code.
        The data extraction unit picks up events sent by the lead plane data collector. As
the name suggests, it parses the lead plane sensor sentence into more useful c++
parameters. RCATSSensor class implements all data extraction unit functions. We used
an open source string parser that is located in StringParser class. RCATSSensor object
keeps the most current sensor information as well as a queue of all previous sensor
information from the lead plane. More sophisticated formation algorithms can make
trajectory predictions and averaging using the history queue from the RCATSSensor
storage area. A copy of the parsed data is logged for debugging and simulation purposes
into a file.
        After the sensor‟s sentence parsing stage, flight parameters go to the filtering and
analysis stage. MaxStream wireless modems use non-reliable data transfer protocol. To
ensure proper calculations, the filtering unit checks data validity. If any validity test fails,
the current sensor reading is discarded. Filtering unit tests are embedded in RCATSensor
class. The following tests are performed:
    -   Parameter format check: e.g. an integer should be a number not a string.
    -   Number of parameters check: e.g. incomplete sentences should be discarded
    -   Sentence length check: e.g. length should be between 155 and 170 characters long

        The Formation flying mechanism will not upload an orbit pattern schedule to the
chase plane if data filtering unit returns a negative response. We changed our initial
design to incorporate this. If the chase plane runs out of target waypoints during the
formation flight, it will behave according to a list of „recovery‟ actions. Recovery actions
are stored in the chase plane‟s autopilot. The list of recovery actions has a default „go
home‟ procedure, and it can be modified in flight as needed. The recovery list feature
also covers the chain of events if the wireless link gets obstructed. The plane will
eventually go home when it runs out of waypoints.
        When sensor information passes the filtering stage it arrives at the main formation
flying algorithm stage. At the beginning of the algorithm stage, the program retrieves the
most current sensor information from the chase plane. With all data pieces, the algorithm
executes. Our formation-flying algorithm is simple, yet effective. The problem of



                       Santa Clara University Aerial Robotics Team                                 28
calculating a realistic formation trajectory path for the chase plane is definitely not a
linear problem. Our project demonstrated an approximation of formation flying, leaving
the software and hardware infrastructure ready for more sophisticated formation flying
algorithms.
        In our algorithm, every 5th trajectory waypoint is taken as a waypoint for the
chase plane. For visual demonstration purposes this approach was sufficient. We
understand the weaknesses of this approach:
    -   The airspeed is not taken into account
    -   Chase plane turns are inaccurate
    -   Long command issuing delays makes formation harder to control
    -   Sensor inaccuracy (mainly from GPS) can lead to full loss of formation

The benefits for our simple formation capabilities are:
    -   Simple to implement
    -   Easy to learn and improve
    -   Visually convincing

        The software implementation of the algorithm is in TestMicropilot class. See
appendix B for the autopilot interface.      Three command buffers hold current flight
schedule of the chase plane. First, beginCommands buffer contains necessary initial
commands for the autopilot. Second, waypointBuffer contains the most current list of
target waypoints. Third, endCommands contains the commands that are supposed to
execute if the plane passes all scheduled waypoints. When combined together, these three
buffers compose the full flight schedule file for the autopilot. For example:

//beginCommands content starts here
imperial
takeoff
climb 400
waitclimb 1

//wayointBuffer content starts here
flyTo ( 121:40.8176999999996W,37:10.30549999999994N)
flyTo ( 121:40.84759999999915W,37:10.34690000000001N)
flyTo ( 121:40.88349999999991W,37:10.39499999999998N)
flyTo ( 121:40.92849999999999W,37:10.4351999999999N)
flyTo ( 121:40.95180000000073W,37:10.47260000000006N)

//endCommands content starts here
fixed
circuit




                         Santa Clara University Aerial Robotics Team                        29
Formation flying algorithm has five main steps:
   1. Clear old waypoints from the buffer – the autopilot is incapable of removing old
      waypoints, so the GCS needs to continuously monitor the chase plane waypoint
      progress in the air.
   2. Append new waypoint to the buffer (in GPS longitude, latitude format).
   3. Optionally altitude can be added to the command buffer.
   4. Construction of the flight schedule for the autopilot. When ready, flight schedule
      is stored in test.fly file of the GCS home directory.
   5. Send new flight schedule to the autopilot using Micropilot‟s SDK.


4.3 Limitations of SCU Ground Control Software
       We built the ground control station out of the awkward Micropilot's SDK, open
source code, and our own work. Realistically speaking, SCU ground control station is a
software prototype. We learned autopilot‟s many quirks as we progressed with the
project. We had to make changes against the original design. The main value of the
current SCU ground control station lies in its components design. Several components
need better, and more efficient implementation.


The following known problems exist:
   -   Uploading a file to the autopilot takes too long. During uploading, the plane is not
       flying autonomously. It goes into pilot assisted mode. In practical terms, it usually
       keeps its original heading during the upload time. If the chase plane was flying
       straight it continued flying straight, or if the chase plane was turning it continued
       turning.
   -   More accurate error checking of the sensor data from the lead plane is needed. An
       upgrade of radio modems might solve this hardware problem.
   -   GPSSensor class should not be a subset of the RCATSSensor
   -   Serial interface (TserialEvent) is complex
   -   String parser (StringParser) is complex and buggy

Future improvements to the GCS:
   -   Remove RCATS data tracking from the general TserialEvent class to its children
       (RCATSSensor or GPSSensor). The function affected is SerialEventManager.
   -   Add GPS averaging function
   -   Add path prediction for the chase plane
   -   Create faster, and more reliable autopilots flight schedule construction using
       mpModifyWaypoint function from Micropilot‟s SDK




                      Santa Clara University Aerial Robotics Team                              30
Chapter 5- Test Results
       We conducted formation-flying tests at the Tomcats RC Model Airfield. During
all tests the weather conditions were normal (no rain, no strong wind). Both lead and
chase were pilot controlled at the take off. When both planes were airborne, the pilot of
the chase plane started the formation-flying algorithm.

                                                       325



                                                       225



                                                       125




                                                                                                   Latitude, meters
                                                                         END

                                                       25

300             200             100                0              -100         -200 START   -300
                                                       -75



          Lead Plane                                   -175
          Chase Plane


                                                     -275
                                           Longitude, meters


                             Figure 15- Successful Formation Flight



The chase plane followed the lead plane on one loop of approximately 0.8 miles. The
data was taken over 2 minutes of flying.




                        Santa Clara University Aerial Robotics Team                         31
                                                      325



                                                      225



                                                      125




                                                                                                   Latitude, meters
                                                              END
                                                      25

 300            200              100              0             -100         -200           -300

                                                      -75
                                                                                    START


               Lead Plane                             -175
               Chase Plane

                                                   -275
                                         Longitude, meters



                            Figure 16- Limitations of the Autopilot System


Figure 16 displays some of the Micropilot’s autopilot limitations. In sharp turns the autopilot
was unable to follow the lead plane and took a much wider route before it got in formation
sync.




                       Santa Clara University Aerial Robotics Team                                                    32
Chapter 6- Safety
       As one of the goals of this project was to establish a new aerial fleet at Santa
Clara‟s Robotics Systems Laboratory, the institution of safety procedures was very
important to implement from the start. Several fail-safe features have been implemented
through measures built directly into the plane as well as detailed checklists that are
followed prior to flight. See appendix G for the safety Checklists and appendix H for
engine startup procedures. A brain storming session enabled the generation of some of
the safety features that could help prevent some of the worst-case scenarios that could
happen with the aircraft. Battery failures, loss of one or both RC receivers, autopilot
malfunction, and structural failure were considered. By taking these ideas to mind, the
systems were isolated so that in the event of one failure, it would be possible to minimize
damage to the aircraft and equipment and even possibly recover from the fault.




                           Figure 17- Emergency Engine Kill Switch


       Additionally, in order to fly at one of our testing facilities, Moffett Field, located
at NASA Ames Research Center, it was necessary to present the project to a NASA
Flight Readiness Review board. Through demonstration of safety checklists, the
redundant engine kill switches and their experience, the aerial robotics team
demonstrated the ability to fly safely in Class D Airspace and was certified by the board
to fly on their military airfield. With the larger flight line provided by Moffett field, it



                      Santa Clara University Aerial Robotics Team                               33
gave the team the chance to “stretch their legs” testing the effectiveness of the video
system and their skill at aerial observation.




                       Santa Clara University Aerial Robotics Team                        34
Chapter 7- Flight Operations
7.1 Competition Strategies
       The effectiveness and efficiency in a flight plan plays a large role in determining
who wins the AUVSI competition. This path directly reflects the time needed in the air,
fuel consumed and accuracy of aerial images. Since this is such an important part of the
competition, there are several strategies we follow during the flight plan creation process.
       In any flight plan that‟s created, a combination of manipulating the waypoints in
the GCS Graphical User Interface and manually editing the .fly files is utilized. This
allows for the visual placement of desired waypoints and then provides the opportunity to
fine tune the path of the aircraft by editing and adding specific commands.




                          Figure 18- Illustration of aircraft flight path




                      Santa Clara University Aerial Robotics Team                              35
        When the purpose of the flight is aerial reconnaissance, the targets must be
approached in a particular way. A series of waypoints before and after the target are laid out
in a straight line. The design of the camera mount requires this attachment method as the
plane must be flying straight and level to accurately capture the designated target. If the
plane is banked, it would visually miss the target.




                   Figure 19- Waypoint navigation using Micropilot’s software



        To date, practice sessions have been very successful in the observation of objects
aerially. The SCU team has confidence in their ability to take the plane off, fly a series of
designated waypoints and land under manual control. Currently, autonomous takeoffs and
landings are being practiced and that ability may be utilized for the competition.


7.2 Formation Flying
        One of this project‟s goals was to explore other possible uses of the autopilot
system. Therefore, a project was also undertaken to develop multiple, autonomous aerial


                        Santa Clara University Aerial Robotics Team                              36
robots that fly in formation to achieve coordinated visual reconnaissance. This proves to
be a challenging engineering feat; however the contributions to the aerospace industry
outweigh the risks and difficulties involved in this design process.
       The formation flight system consists of a human-piloted lead plane and an
autonomously flown chase plane that follows the lead plane's flight path. As the lead
plane is flown, its trajectory is determined through an on-board GPS receiver, and this
data is transmitted to the ground control station. Software at the ground control station
filters this trajectory in order to generate suitable waypoints for the chase plane. These
waypoints are used to continuously update the chase plane's flight plan which is then
uploaded to the Micropilot unit on the chase plane. The flowchart in
         Execution of this ground control station processing is implemented by a real-
time event driven software application developed by the project team. The program's
graphical user interface, displays GPS location, airspeed, and altitude telemetry for both
planes; the interface can also plot the paths of the planes in real-time in both two and
three dimensions.




                     Figure 20- Image of Ground Control Station Software
       In limited testing to date, this system has been used to successfully demonstrate
follow-the-leader behavior. Our graphs show that the chase plane faithfully followed the



                      Santa Clara University Aerial Robotics Team                            37
human-piloted lead plane through a simple maneuver with an average accuracy of
approximately +/- 50 meters over the duration of the maneuver; this accuracy is
consistent with the rated accuracy of the GPS receivers used for this demonstration. In
early June, more extensive testing and evaluation of this capability will be performed at
Moffett Field.




                      Figure 21- Aircraft in ‘Follow the Leader’ Formation



       Overall, these results are quite positive for an initial implementation of UAV
formation flying. As a result, the team has entered into discussions with several external
collaborators in order to determine specific requirements for using multi-UAV formations
in real applications. Specific applications under consideration include estuary analysis
with photos from multiple UAVs being incorporated into a regional mosaic, fire
monitoring with UAVs tracking assets and monitoring hotspots in a coordinated manner,
and object visualization using two UAVs in a real-time formation to provide stereo
imaging capability.




                       Santa Clara University Aerial Robotics Team                           38
Chapter 8- Societal Issues
          As the aerial reconnaissance portion of the project became more successful,
questions were raised about the possible applications of such a UAV.            One ethical
question that persisted was the use of a reconnaissance UAV to gather intelligence for
military operations. Although the application of this project can be used for military
goals, the team has tried to stay focused on the more ethically sound uses of UAVs.
These specific goals can not be questioned as unethical. These applications include
coordinated search and rescue, environmental monitoring, and traffic surveillance. The
continued development of UAVs should and will continue because of these positive goals
that work towards the betterment of the entire world. The goods of reconnaissance UAV
research outweigh the possibly negative aspects.
          Social issues also present themselves when making a product of this type. Most
of these social issues align themselves with the ethical issues. One question is, do we
want to make a vehicle that can lead to more destruction in times of war? Once again,
the applications of UAVs are varied and not all applications have military purposes. A
fleet of coordinated search and rescue UAVs can find survivors in an ocean disaster.
Other UAVs can protect forests by watching for fires and consequently can protect the
surrounding homes and residents. Traffic UAVs can increase knowledge about traffic
flow for future civil engineers so that solutions can be made to ease everyone‟s commute.
There are many positive impacts to society with this product if the implementers choose
wisely.
          Politics always come into these types of projects because of the resulting products
they can create. Most products would be government projects and will have significant
impacts on issues such as Homeland Security.
          Once again the products derived from this project would have government
applications. Although expensive, the National Park and Wildlife Services, US Coast
Guard, and transportation departments would all want to fund continued research in this
field. Economically products like this are sound investments because of what they can
safe. Disaster relief funds could be put elsewhere when a forest fire is stopped early and
infrastructure is not damaged. Countless search boats and helicopters would not have to
be deployed if a safer and cheaper solution was available.            Traffic accidents and


                        Santa Clara University Aerial Robotics Team                             39
congestion could be found quickly to reduce delays and therefore people would get to
work on time. Products with such uses will be paid for especially when the government
has so much to gain.
        Health and Safety are also important things when engineering new technology.
Because of the nature of this project, safety was a constant concern. Redundancy was
built into the product in order to minimize the possibility of damage to human or material
resources. Not only does the project consider health and safety, major applications of the
project ensure goal. In the future, hurricanes will no longer be a barrier to rescue
attempts. The use of UAVs will substitute humans from endangering their lives in
unfortunate circumstances. This will protect the people that need rescuing as well as the
men and women that patrol our seas during disaster relief.
        A high degree of manufacturability exists for UAVs. The airframe, built from an
all-inclusive kit, can be produced in twenty-five hours. Installation of the engine and
flight electronics is also rapid due to their availability and ease of set up. The sensors and
flight computer that make this system autonomous must be installed, configured and
tested for each aircraft. This requires a certain expertise which can add cost to each
aircraft and the most time consuming aspect of assembly. The timeline in developing the
model aircraft, while about 80 hours, is far less than that of a full size aircraft making it a
very feasible alternative. This permits a rapid time-to-market and deployment of this
product.
        UAVs are very sustainable. They can be developed and can continue to be viable
and useful for a reasonable amount of time. They are adaptable to changing needs and
can easily be retrofitted for special applications. Updates can easily be applied and
materials for repair and additions are readily available. In a broader sense, the aircraft can
have a limited life due to their fragile nature. Additionally, a high degree of maintenance
is required to sustain the planes as there is almost a 1:1 ratio of flying time to preparation
time. However, this ratio is better than full-size aircraft.
        Environmentally, a miniature UAV is very friendly compared to their larger, full
size counterparts. They consume less fuel, pollute the air less and require fewer resources
to get the same job done that a piloted aircraft requires.




                       Santa Clara University Aerial Robotics Team                                40
       There are limitations on the usability of our project. It requires someone skilled in
model aviation to properly and safely handle the aircraft. However someone with basic
knowledge in this area could easily pick up our project and utilize its autonomous and
formation flight capabilities. Since the target audience is not the general public, the
UAVs are very usable for specific applications and marketable.
       As lifelong learning is important in the engineering profession, this project
provided the opportunity to explore material outside the ordinary curriculum and utilize
cutting-edge technology. This project provided the chance for students to learn new and
interesting techniques and study new material such as aerial robotics, artificial
intelligence, and formation flight.
       This project helped sow compassion in several ways. The outreach opportunities
with young students, senior citizens and the general public enriched everyone. This
project also presented the realization that there were non-military applications to the
UAVs that could benefit society. This was important because part of the project was
sponsored by the military.




                       Santa Clara University Aerial Robotics Team                             41
Chapter 9- Community Outreach
         Throughout the duration of the project, the SCU Aerial Robotics team has taken
part in many outreach events and activities. One company the team has continually
interacted with was Micropilot. Through use of their autopilot system, communication
was made to better the company‟s product because of both testing and suggestions by the
team. Additionally, constant interaction with the RCATS president helped him develop
new technology following the design of SCU‟s applications. MLB Corporation and SCU
also conversed to create a better design with the use of MLB‟s experience. During the
course of testing, SCU students had weekly interaction with members of Tomcats Santa
Clara Country Model Aircraft Sky park. These students became a constant fixture at the
flying field and showed the region what kind of research Santa Clara University is
involved in. Another aspect of outreach in the community has been with elementary
students. The SCU Aerial Robotics team helped foster learning by showing first and
second graders their exciting project. Through this outreach, these children may go on to
become engineers of the next generation. The SCU team is also proud to be connected to
the NASA Ames Research Center and its Space Technology Center. This will strengthen
bonds to other schools in the region such as San Jose State University, Stanford
University, and Utah State University as well as NASA.           In harmony with this
relationship, the SCU Aerial Robotics Team was able to participate in the NASA Ames
Research Center Air & Space Show 2004 at Moffett Field. Additionally, SCU conducts
some of its UAV research from Moffett Field and class D airspace. To accomplish this,
the Team had to pass a Moffett Field Safety Review Board inquiry. Finally, SCU
students will be competing in the international Association for Unmanned Vehicle
Systems International (AUVSI) Student UAV Competition in June 2004. Through the
competition, SCU hopes to become a more influential member in the robotics education
field.




                      Santa Clara University Aerial Robotics Team                           42
Chapter 10- Conclusions
10.1 Summary
       This project has successfully demonstrated several things including an

autonomous „follow the leader‟ formation flight algorithm and an inexpensive UAV

reconnaissance system. The team has established a fleet of aerial vehicles for Santa Clara

University to become a research platform for future projects. Through out this project, the

students conformed to the ethical standards established by Santa Clara University. Many

of the design choices in this project were determined by cost, compatibility with other

components and ease of integration. Safety was an extremely important factor for this

project as a precedent was established for precautions, rules and guidelines in working

with SCU‟s aerial fleet. This team will succeed in AUVSI‟s student UAV competition by

effectively utilizing an aerial observation system that provides more accurate real-time

information to operators. In addition, the autopilot system provided by Micropilot

coupled with our techniques will guide the aircraft to a successful finish.


10.2 Future Work
       Formation flying project opened a whole array of exciting opportunities for
further research and technology applications. Here are some project ideas:
      Creation of larger formation aircraft fleet. Currently, the formation of only two
       aircrafts is possible.
      Enhance formation flying algorithm. This is a great topic for all control systems
       enthusiasts. Right now the formation is controlled by unsophisticated control
       system. In addition, the first plane is manually controlled.
      Environmental observation. Putting scientific sensors in the planes can lead to
       all sorts of interesting scientific experiments.
      Further enhancement of autonomous navigation. For example, Micropilot‟s
       autopilot is far from perfect.
      Video and image processing. Homeland security and terrain mapping are hot
       topics today.
       Controlling the aircraft over the Internet.




                       Santa Clara University Aerial Robotics Team                            43
       This way of controlling the formation eliminates the problem of operator‟s
physical distance. One can control the formation from any point on the globe with an
Internet connection.




                       Santa Clara University Aerial Robotics Team                     44
       References
[1] Kitts, C., "Surf, Turf, and Above the Earth: An Aggressive Robotics Development
Program for Integrative Undergraduate Education," In Robotics and Automation
Magazine, IEEE Robotics and Automation Society, September 2003.


[2] Air Force Technology http://www.airforce-technology.com/projects/predator/


[3] Dougherty, R., Ochoa, V., Randles, Z., Kitts, C., “A Behavioral Control Approach to
Formation- Keeping through an Obstacle Field” Robotics Systems Laboratory, 2003.




                     Santa Clara University Aerial Robotics Team                          45
Appendices
Appendix A: Abbreviations

AUVSI -Association Unmanned Vehicle Systems International
BS2   - Basic Stamp 2
DGPS - Differential GPS
GCS    - Ground Control Software
GPS    - Global Positioning System
GUI   - Graphical User Interface
SCCMAS - Santa Clara County Model Aircraft Sky park
UAV -Uninhabited Aerial Vehicle
WAAS - Wide Area Augmentation Systems




                    Santa Clara University Aerial Robotics Team   46
Appendix B: SCU Ground Control Software Autopilot Interface
(from TestMicropilot.h)

The table below contains the list of public functions that control Micropilot‟s autopilot. These functions are built on top of
Micropilot‟s SDK. All the functions are part of the TestMicropilot C++ class.

Function                                                Input                    Output and Actions
TestMicropilot()                                                                 Constructor
                                                        Unique plane ID, com     Initializes communication with the chase plane.
void initializePlane(long scuPlaneId, char * comport)   port(e.g. “COM1).
void InitCommandBuffer()                                                         Initializes the all waypoint buffers.
                                                        Latitude, “N” or “S”,    Appends 3D coordinate to waypoint buffer.
void appendCoordinate(double lat, string latH,          longitude, “E” or “W”,
double lon, string lonH, int altitude)                  altitude
                                                        Name of the file to      Sends the .fly file to the autopilot. Needs established
void sendFileToAutopilot(string filename)               transmit                 connection with the autopilot.
                                                        Variable ID from         Reads Micropilot‟s variables from the autopilot.
long readMpVariable(long index)                         Micropilot‟s manual
void flushFlightBuffers()                                                        Empties waypoint buffers.
void shutDownPlane()                                                             Tears down existing connection with the autopilot
                                                                                 Prints on the screen all flight commands in command
void printCurrentCommands()                                                      buffers.




                          Santa Clara University Aerial Robotics Team                                         47
Appendix C: Ricochet Modem Test

                                        Distance Test: Longitude vs Latitude


                                                                300

        Jack in the Box
                                                                200
                                                        El Camino
                                                                100




                                                                                                           Latitude(Meters)
                                                                0
  600        500      400       300    200       100        0          -100    -200   -300   -400   -500

                                                                -100


                                                                -200


                                                                -300


                                                                -400                  RSL


                                                                -500
                                               Longitude(Meters)




                            Santa Clara University Aerial Robotics Team                                49
Appendix D: Funding Request Letters

D.1       Letter for Dean’s Fund


Formation Flight of Autonomous Aerial Vehicles
Team Members                    Major
Ryan Becker*                    Computer Engineering
Chris Borowski                  Computer Engineering
Ognjen Petrovic                 Computer Engineering

*Primary Contact

Advisors                        Department
Dr. Neil Quinn                  Computer Engineering
Dr. Christopher Kitts           Mechanical Engineering


External Sponsors
         MicroPilot has supplied an expensive and sophisticated autopilot system that
          includes most of the supporting electronic sensors. Our partnership with
          MicroPilot requires us to demonstrate the project at the AUVSI competition in
          Maryland this June, 2004.

         AUVSI (Association for Unmanned Vehicle System International) hosts the
          autonomous airplane student competition. They also organize the student event
          and coordinate all the sponsors of the week long competition.

         A possible third sponsor is NASA which will allow us to use their facilities at
          Moffett field for test flights.

Project Description
        The goal of our Senior Design Project is to create autonomous model airplanes
flying in formation. An essential part of our project is participation in AUVSI
(Association for Unmanned Vehicle System International) Student UAV (Unmanned
Aerial Vehicle) competition. One of the major sponsors of the competition is MicroPilot.
We will use the autopilot system provided by them to complete most of our tasks.
        Creating a control system for model airplanes to fly in autonomous formation is
an engineering challenge and an exciting area of research. This project is
multidisciplinary in that to achieve the goal of formation flight, we need to master
computer, electrical, and mechanical engineering techniques and practices. Applications
of robots operating in formations are numerous: from site-clearance and construction on
the Earth to automated missions in outer space. Prominent educational institutions like

                         Santa Clara University Aerial Robotics Team                        50
MIT and other organizations like NASA are actively exploring this field of robotics. We
believe that our participation in the AUVSI competition will start an on-going, multi-year
project at Santa Clara University in aerial robotics.
        Our project will have a strong impact on our community in several ways. With
our advisors we are creating an aerial robotics program which will benefit future Santa
Clara students. Interested students even in their freshmen year, will have an opportunity
to enroll in piloting sessions on a trainer aircraft along with the necessary safety training.
This program is capable of opening up new ideas for future senior design projects. Aerial
robotics is an intellectual gold mine for technological ideas. The applications are
numerous and important to society.
        As contributing members of our community, we want to make a difference in the
real world while at the same time excelling academically. While testing and
demonstrating the capabilities of our planes, we will participate in community outreach
programs involving neighborhood schools. This will spawn new interest in technology,
learning and continuing education for these younger students. We will also introduce our
work to people in industry who are interested in the development of UAVs. The belief in
success comes from the passion of exploring creative engineering ideas. This passion will
be shared with the rest of our community as we will be a recognized group at the local
flying fields.
        Santa Clara University would benefit from having a winning team in the AUVSI
competition. First, the SCU engineering program would have a recognized aerial robotics
program that would attract prospective high school students. Second, a good formation
robotics program would attract resources from the industry and the government. Third,
exciting research would promote collaboration with other universities.

Budget
Funds allocated or pending from MicroPilot and Santa Clara University:

- MicroPilot (Autopilot and flight electronics)                               $5750
- SCU Robotic Systems Lab (competition fees)                                  $500
- SCU Robotic Systems Lab (RC Planes)                                         $1000
- SCU Robotic Systems Lab (2 transmitters and other parts)                    $1500
- Student Leadership Fund Scholarship* (travel expenses                       $2500
  for AUVSI competition)

   *Approval Pending

SCU Senior Design Fund, please consider this requested budget:

- Wireless camera video system (camera, transmitter, receiver)                $700
- Radio Modems                                                                $300
- Microcontrollers                                                            $200
- Model Airplane                                                              $500
- Airplane fuel                                                               $50

Amount Requested                                                              $1750


                       Santa Clara University Aerial Robotics Team                               51
D.2       Maryland Travel Request

Formation Flight of Autonomous Aerial Vehicles
Maryland Travel Budget Proposal

Team Members                    Major
Ryan Becker*                    Computer Engineering
Chris Borowski                  Computer Engineering
Ognjen Petrovic                 Computer Engineering

*Primary Contact

Advisors                        Department
Dr. Neil Quinn                  Computer Engineering
Dr. Christopher Kitts           Mechanical Engineering

External Sponsors

         MicroPilot has supplied an expensive and sophisticated autopilot system that
          includes most of the supporting electronic sensors. Our partnership with
          Micropilot requires us to demonstrate the project at the AUVSI competition in
          Maryland this June, 2004.
         AUVSI (Association for Unmanned Vehicle System International) hosts the
          autonomous airplane student competition. They also organize the student event
          and coordinate all the sponsors of the week long competition.
         NASA will allow us to use their facilities at Moffett field for test flights.
         Robotics System Laboratory (RSL) has provided funding for Flying Field costs
          and other Fees
         Arrupe Center has provided us with a vehicle to assist with transportation to and
          from the flying field
         National Science Foundation has helped purchase much of our electronic
          equipment including our RC transmitters and receivers
         RCAT Systems has provided us with a real time telemetry system for use with
          our lead aircraft.

Project Description

        The goal of our Senior Design Project is to create autonomous model airplanes
flying in formation. An essential part of our project is participation in AUVSI
(Association for Unmanned Vehicle System International) Student UAV (Unmanned
Aerial Vehicle) competition. One of the major sponsors of the competition is MicroPilot.
We will use the autopilot system provided by them to complete most of our tasks.
        Creating a control system for model airplanes to fly in autonomous formation is
an engineering challenge and an exciting area of research. This project is
multidisciplinary in that to achieve the goal of formation flight, we need to master
computer, electrical, and mechanical engineering techniques and practices. Applications
of robots operating in formations are numerous: from site-clearance and construction on

                        Santa Clara University Aerial Robotics Team                           52
the Earth to automated missions in outer space. Prominent educational institutions like
MIT and other organizations like NASA are actively exploring this field of robotics. We
believe that our participation in the International AUVSI competition will start an on-
going, multi-year project at Santa Clara University in aerial robotics.
        Our project will have a strong impact on our community in several ways. With
our advisors we are creating an aerial robotics program which will benefit future Santa
Clara students. Interested students even in their freshmen year, will have an opportunity
to enroll in piloting sessions on a trainer aircraft along with the necessary safety training.
This program is capable of opening up new ideas for future senior design projects. Aerial
robotics is an intellectual gold mine for technological ideas. The applications are
numerous and important to society. One specific application would be environmental monitoring,
and future versions of our formation flying aircraft will complement current efforts within the
Environmental Studies Institute to develop an interdisciplinary academic program in this area.
As contributing members of our community, we want to make a difference in the real
world while at the same time excelling academically. While testing and demonstrating
the capabilities of our planes, we have participated in community outreach programs
involving neighborhood schools. This has helped spawn new interest in technology,
learning and continuing education for these younger students. We have already
introduced our work to people in industry and will continue to work with those who are
interested in the development of UAVs. Several researchers from NASA Ames and
Lockheed have already expressed interest in seeing the results of our work and in funding
future SCU efforts in this and other formation robot research. The belief in success comes
from the passion of exploring creative engineering ideas. This passion is being shared
with the rest of our community as we are already a recognized group at the local flying
field.
        Santa Clara University would benefit from having a winning team in the AUVSI
competition. First, the SCU engineering program would have a recognized aerial robotics
program that would attract prospective high school students. Second, a good formation
robotics program would attract resources from the industry and the government. Third,
exciting research would promote collaboration with other universities. Fourth, this is a
prestigious international competition as only 8 teams were selected to compete. It will be
recognized at the global level not only by companies like Lockheed, Northup Grumman
and NASA who are sponsors but by foreign companies as well.
        As part of this project, we also plan on producing a peer-reviewed conference
paper about our work and our participation in the competition. We will be submitting this
paper for publishing in several magazines including AUVSI‟s own publication and a
publication by Micropilot.
        Additionally, we can already perform more functionality than any team that
competed last year. As such, we feel that we have the potential to win this event. Below
please find a summary of other funding sources we have already secured and the budget
we are applying for to enable us to travel to this competition.

Sincerely,
Formation Flying Team

Ryan Becker
Chris Borowski
Ogjen Petrovic


                           Santa Clara University Aerial Robotics Team                            53
BUDGET

Funds already allocated from Sponsors:

- Micropilot (Autopilot and flight electronics)                            $5750
- SCU Robotic Systems Lab (Competition Participation fees)                 $500
- SCU Robotic Systems Lab (RC Planes)                                      $1000
- National Science Foundation (2 transmitters and other parts)             $1500
- SCU Robotic Systems Lab (Tomcats membership fees)                        $120
- RCAT Systems (Telemetry System)                                          $800
- Senior Design Fund (Wireless cameras, radio modems,                      $1750
       micro controllers, Ground Station Support Equipment)



We are applying for funding for the following activities:

- Five roundtrip plane tickets to Maryland                       5 X $400 = $2000
   and ground transportation fees
- 5 nights accommodation                                         5 X $200 = $1000
- Shipping of fragile planes, maintenance tools                             $500
  and electronics to Maryland
- 2 Rental Vehicles (for 5 people and 3 large aircraft)                    $600
-Entry Fee                                                                 $500
-Crates to ship large, fragile equipment                                   $400
TOTAL                                                                      $5000




                       Santa Clara University Aerial Robotics Team                  54
Appendix E: Autopilot Graphs
                                                                       Velocity Correlation


                              160


                              140


                              120
Pitot Tub e velocity (ft/s)




                              100


                              80                                                                                                     Series1

                              60


                              40


                              20


                               0
                                    0       20         40         60             80         100        120        140          160
                                                                      GPS velocity (ft/s)



                                                                              Takeoff


                              350


                              300


                              250
 Altitu de (ft)




                              200
                                                                                                                                     Series1
                              150


                              100


                               50


                                0
                                    1

                                        8

                                            15

                                                 22

                                                      29

                                                            36

                                                                 43

                                                                       50

                                                                            57

                                                                                  64

                                                                                       71

                                                                                             78

                                                                                                  85

                                                                                                       92

                                                                                                             99

                                                                                                                  106

                                                                                                                        113

                                                                                                                              120




                                                                            tim e (0.2s)




                                                      Santa Clara University Aerial Robotics Team                                              55
Appendix F: Hardware Flow Diagrams




                Santa Clara University Aerial Robotics Team   56
Santa Clara University Aerial Robotics Team   57
Santa Clara University Aerial Robotics Team   58
Appendix G: Safety Check List

Procedural and Safety Checklist
Night before Flying:
Charge the following:
12V Starter Battery
3V Glow Starter Battery
4.8V 2700mAh NiMH Servo Battery
4.8V 1800mAh NiCd Micropilot Battery
4.8V 600mAh NiCd Backup Receiver Battery
12V 1100mAh NiMH Radio Modem/Video System Battery
9.6V Transmitter Battery
120V Ground Station Battery

Flying Day:
Place AMA card in frequency lockbox, verifying that no one is on your frequency (Channel 35
and 38 for us)
Check that all electronics are secured inside aircraft and wires are clear of servo functions.
Check voltage of all four batteries on-board.
Attach wing and verify the secure connection of 2 flap wires, 2 aileron wires, Ultrasonic lead,
and Pitot tube.
Attach and fasten video reconnaissance package.
Perform visual check of aircraft for damage.
Perform balance check.
Fill tank with glow fuel.
Perform visual and tactile check to verify fuel is not leaking.
Set engine kill switch spring to loaded position.
Turn on video, radio modem, servos, emergency cutoff, and autopilot switches.
Make sure that plane is communicating a valid GPS signal to ground station.
Perform range test with antenna collapsed.
Verify the transition from PIC to CIC and back.
Engage CIC mode and examine proper deflection as a result of yaw, pitch, and roll.
Engage PIC mode and examine proper deflection due to transmitter inputs.
Load and verify the transmittal of mission .fly file.
Clear the area around the plane of loose equipment and persons.
Check RC PIC throttle control and idle.
Perform test triggering of engine secondary kill-switch.
Reset kill-switch spring.
Start engine. (See Appendix K: Engine Startup Procedure)
Perform range test with antenna collapsed.
Perform engine run-up.
Get clearance for takeoff.




                      Santa Clara University Aerial Robotics Team                            59
Appendix H: Engine Startup Procedure

To Start the Plane:
          1. Turn on aircraft and verify that there is little or not flutter after remaining
              on for a second. This will test to see if anyone else is on your frequency.
          2. Turn on the transmitter keeping the antenna retracted. If there was any
              flutter previously, it should immediately go away. If not, stop and see if
              someone else is on your channel.
          3. Check to make sure that all the control throws are in the correct direction
              when the corresponding stick on the transmitter is moved.           Test flap
              deflection and make sure that they are in the up position.
          4. Perform a range check by walking 50 paces away and with the antenna
              still retracted, make sure that the correct control movement occurs based
              on the corresponding stick input. Your partner may be needed if the
              control surfaces can not be seen clearly.*
          5. Set the throttle trim on the transmitter to the idle position.
          6. Turn the prop over carefully with your hand to make sure it is not already
              in compression.
          7. With your partner standing over the rear of the plane, keeping it from
              going forward, attach the glow lighter to the glow plug.
          8. Holding the plane with one hand (making sure your arm is out of the prop
              arc) firmly hold the starter cone to the nose cone of the plane. Once firmly
              pressed against the cone, squeeze the trigger, turning over the engine.
          9. Once engine starts, pull the starter cone away from the front of the plane.
          10. Stand up and walk to the middle of the plane and carefully remove the
              glow starter from the engine while standing behind the prop arc.




                      Santa Clara University Aerial Robotics Team                              60
Appendix I: Lead Plane Basic Stamp Code
                     '{$STAMP BS2p}
' -----[ Title ]-------------------------------------------------------
----
'
' Original Comm Program for the leading plane.
'
' RSL Santa Clara University
' Author:
         Ognjen Petrovic       opetrovic@scu.edu
'        Chris Borowski        cborowski@scu.edu
'        Ryan Becker           rbecker@scu.edu
' -----[ Program Description ]-----------------------------------------
----
'
' Forwards the sensor data from the leading plane to the ground. There
is a
' problem with varialble length of GPS string. GPS sentences can be
lost due
' to the fixed number of bytes to transmit.
'
'
' -----[ Constants ]---------------------------------------------------
----
'
'COM bandwidth
N115200 CON 16386
N19200 CON 16494
'N9600 CON 16624
N9600 CON 240
N38400 CON 16429

'number of bytes to transmit

Scratch1   CON    70
Scratch2   CON    100

'--{ Pinouts defined }-------------------------------------------------
------

GPS    CON 2
'COMM    CON 16         'Use this one when you don't want to use the
modems
COMM    CON 4           'Use this one when you want the modems to be in
the picture
RCATS   CON 15
MODEM   CON 4

' -----[ Variables ]---------------------------------------------------
----
'
character   VAR Byte
counter VAR Byte

' -----[ MAIN PROGRAM ]------------------------------------------------
--

main:

                   Santa Clara University Aerial Robotics Team            61
GPS_send:

'get data
SERIN GPS,N19200,[WAIT("RMC"),SPSTR Scratch1]        'reads data into
scratch1

'transmit data
SEROUT COMM,N9600,["$GPRMC"]

'The following code block reads in each character from the scratch ram
and checks
'if it is a carriage return (ascii 13). If it is, then it would be
time to go
'to the RCATS reader

FOR counter = 0 TO 90                          '90 is just a number larger
then the largest GPS RMC string length
  GET counter, character                       'read from scratch into
character
  IF character=13 THEN RCAT_send            'checks if carriage return
  SEROUT COMM,N9600,[character]             'writes character to modem
NEXT

RCAT_send:

SERIN RCATS,N9600,[WAIT("RCATS"),SPSTR Scratch2]       'reads data into
scratch2
SEROUT COMM,N9600,[",RCATS"]

'The following code block reads in each character from the scratch ram
and checks
'if it is a carriage return (ascii 13). If it is, then it would be
time to go
'to the GPS reader

FOR counter = 0 TO 130                         '130 is bigger than largest
RCAT string
  GET counter, character
  IF character=13 THEN GPS_send             '13 is carriage return
  SEROUT COMM,N9600,[character]
NEXT

GOTO GPS_send          'just in case it never finds the CR, it will
start again with GPS




                 Santa Clara University Aerial Robotics Team                 62
Appendix J: Ground Control Station Software Code
FORM1.H

#define _USE_MATH_DEFINES
#include <string>
#include <conio.h>
#include <math.h>
#include "RCATSensor.h"
#include "TestMicropilot.h"

#define MPFID_GPS_LONGITUDE 1095 //Micropilot's GPS Longitude variable
index
#define MPFID_GPS_LATITUDE 1096 //Micropilot's GPS Latitude variable
index

#pragma once

namespace GUI
{
   using namespace    System;
   using namespace    System::ComponentModel;
   using namespace    System::Collections;
   using namespace    System::Windows::Forms;
   using namespace    System::Data;
   using namespace    System::Drawing;
   using namespace    System::Threading;
   using namespace    std;
   using namespace    GraphicsServer::GSNet::Charting;
   using namespace    GraphicsServer::GSNet::SeriesData;

   #undef GetObject

   /// <summary>
   /// Summary for Form1
   ///
   /// WARNING: If you change the name of this class, you will need to
change the
   ///           'Resource File Name' property for the managed resource
compiler tool
   ///           associated with all .resx files this class depends on.
Otherwise,
   ///           the designers will not be able to interact properly
with localized
   ///           resources associated with this form.
   /// </summary>
   public __gc class Form1 : public System::Windows::Forms::Form
   {

   private: TestMicropilot * micro; //formation flying control
   private: bool * runFormation; // controls the formation thread
   private: bool * extracterConnected; //controls the lead plane
extracter thread
   private: bool * mpTelemetry; // controls the autopilot's telemetry
thread
   private: RCATSensor * rcats; //lead plane data collector
   private: long * scuPlaneId; //current plane ID



                  Santa Clara University Aerial Robotics Team             63
   private: Mutex * mpLock; //Control lock for autopilot's telemetry
thread
                     //and formation thread. These two thread CANNOT
access
                     // the autopilot in the same time

  public:

     //Constructor. Draws the GUI.
     Form1(void)
     {
        mpLock=new Mutex();
        scuPlaneId=new long;
        *scuPlaneId=0;
        InitializeComponent();
        updateStatus("Disconnected");

     }

  protected:
     void Dispose(Boolean disposing)
     {
        if (disposing && components)
        {
           components->Dispose();
        }
        __super::Dispose(disposing);
     }
  private: System::Windows::Forms::TabControl * tabControl1;
  private: System::Windows::Forms::TabPage * AircraftInfo;
  private: System::Windows::Forms::TabPage * Graphs;
  private: System::Windows::Forms::PictureBox * pictureBox6;
  private: System::Windows::Forms::PictureBox * pictureBox2;
  private: System::Windows::Forms::PictureBox * pictureBox1;
  private: System::Windows::Forms::GroupBox * ControlCenter;
  private: System::Windows::Forms::Button * Home;
  private: System::Windows::Forms::Button * Disconnect;
  private: System::Windows::Forms::Button * Pattern;
  private: System::Windows::Forms::Button * Follow;
  private: System::Windows::Forms::Button * Connect;
  private: System::Windows::Forms::GroupBox * ChasePlaneInfo;
  private: System::Windows::Forms::Label * Airspeed2;
  private: System::Windows::Forms::TextBox * showHeading2;
  private: System::Windows::Forms::TextBox * showWaypoint;
  private: System::Windows::Forms::Label * Longitude2;
  private: System::Windows::Forms::Label * Latitude2;
  private: System::Windows::Forms::TextBox * showLatitude2;
  private: System::Windows::Forms::Label * Altitude2;
  private: System::Windows::Forms::Label * Heading2;
  private: System::Windows::Forms::Label * CurrentWaypoint;
  private: System::Windows::Forms::TextBox * showLongitude2;
  private: System::Windows::Forms::TextBox * showAirspeed2;
  private: System::Windows::Forms::TextBox * showAltitude2;
  private: System::Windows::Forms::PictureBox * pictureBox3;
  private: System::Windows::Forms::GroupBox * LeadPlaneInfo;
  private: System::Windows::Forms::Label * Voltage;
  private: System::Windows::Forms::TextBox * showVoltage;
  private: System::Windows::Forms::TextBox * showAirspeed;
  private: System::Windows::Forms::TextBox * showAltitude;

                 Santa Clara University Aerial Robotics Team           64
  private:   System::Windows::Forms::Label * HeadTemperature;
  private:   System::Windows::Forms::Label * Airspeed;
  private:   System::Windows::Forms::Label * Altitude;
  private:   System::Windows::Forms::Label * RPM;
  private:   System::Windows::Forms::Label * MufflerTemp;
  private:   System::Windows::Forms::TextBox * showRPM;
  private:   System::Windows::Forms::TextBox * showMuffler;
  private:   System::Windows::Forms::TextBox * showHead;
  private:   System::Windows::Forms::Label * Heading;
  private:   System::Windows::Forms::Label * Longitude;
  private:   System::Windows::Forms::Label * Lattitude;
  private:   System::Windows::Forms::TextBox * showHeading;
  private:   System::Windows::Forms::TextBox * showLattitude;
  private:   System::Windows::Forms::TextBox * showLongitude;
  private:   System::Windows::Forms::PictureBox * pictureBox4;
  private:   System::Windows::Forms::TextBox * textBox1;
  private:   System::Windows::Forms::TextBox * textBox2;
  private:   System::Windows::Forms::TextBox * textBox3;
  private:   System::Windows::Forms::Label * label1;
  private:   System::Windows::Forms::Label * label2;
  private:   System::Windows::Forms::Label * label3;
  private:   System::Windows::Forms::TextBox * textBox4;
  private:   System::Windows::Forms::Label * label4;
  private:   System::Windows::Forms::GroupBox * StatusInfo;
  private:   System::Windows::Forms::TextBox * showAmbient;
  private:   System::Windows::Forms::Label * AmbientTemp;
  private:   System::Windows::Forms::Label * Time;
  private:   System::Windows::Forms::TextBox * showTime;
  private:   System::Windows::Forms::TextBox * showStatus;
  private:   System::Windows::Forms::Label * Status;
  private:   System::Windows::Forms::PictureBox * pictureBox5;
  private:   GraphicsServer::GSNet::Charting::GSNetWinChart * chart3d;
  private:   System::Windows::Forms::Button * StopFollow;
  private:   System::Windows::Forms::Button * connectLead;

  private:
     /// <summary>
     /// Required designer variable.
     /// </summary>
     System::ComponentModel::Container * components;

      /// <summary>
      /// Required method for Designer support - do not modify
      /// the contents of this method with the code editor.
      /// </summary>
      void InitializeComponent(void)
      {
         System::Resources::ResourceManager * resources = new
System::Resources::ResourceManager(__typeof(GUI::Form1));
         this->tabControl1 = new System::Windows::Forms::TabControl();
         this->AircraftInfo = new System::Windows::Forms::TabPage();
         this->pictureBox6 = new System::Windows::Forms::PictureBox();
         this->pictureBox2 = new System::Windows::Forms::PictureBox();
         this->pictureBox1 = new System::Windows::Forms::PictureBox();
         this->ControlCenter = new System::Windows::Forms::GroupBox();
         this->connectLead = new System::Windows::Forms::Button();
         this->StopFollow = new System::Windows::Forms::Button();
         this->Home = new System::Windows::Forms::Button();
         this->Disconnect = new System::Windows::Forms::Button();

                  Santa Clara University Aerial Robotics Team            65
         this->Pattern = new System::Windows::Forms::Button();
         this->Follow = new System::Windows::Forms::Button();
         this->Connect = new System::Windows::Forms::Button();
         this->ChasePlaneInfo = new System::Windows::Forms::GroupBox();
         this->Airspeed2 = new System::Windows::Forms::Label();
         this->showHeading2 = new System::Windows::Forms::TextBox();
         this->showWaypoint = new System::Windows::Forms::TextBox();
         this->Longitude2 = new System::Windows::Forms::Label();
         this->Latitude2 = new System::Windows::Forms::Label();
         this->showLatitude2 = new System::Windows::Forms::TextBox();
         this->Altitude2 = new System::Windows::Forms::Label();
         this->Heading2 = new System::Windows::Forms::Label();
         this->CurrentWaypoint = new System::Windows::Forms::Label();
         this->showLongitude2 = new System::Windows::Forms::TextBox();
         this->showAirspeed2 = new System::Windows::Forms::TextBox();
         this->showAltitude2 = new System::Windows::Forms::TextBox();
         this->pictureBox3 = new System::Windows::Forms::PictureBox();
         this->LeadPlaneInfo = new System::Windows::Forms::GroupBox();
         this->Voltage = new System::Windows::Forms::Label();
         this->showVoltage = new System::Windows::Forms::TextBox();
         this->showAirspeed = new System::Windows::Forms::TextBox();
         this->showAltitude = new System::Windows::Forms::TextBox();
         this->HeadTemperature = new System::Windows::Forms::Label();
         this->Airspeed = new System::Windows::Forms::Label();
         this->Altitude = new System::Windows::Forms::Label();
         this->RPM = new System::Windows::Forms::Label();
         this->MufflerTemp = new System::Windows::Forms::Label();
         this->showRPM = new System::Windows::Forms::TextBox();
         this->showMuffler = new System::Windows::Forms::TextBox();
         this->showHead = new System::Windows::Forms::TextBox();
         this->Heading = new System::Windows::Forms::Label();
         this->Longitude = new System::Windows::Forms::Label();
         this->Lattitude = new System::Windows::Forms::Label();
         this->showHeading = new System::Windows::Forms::TextBox();
         this->showLattitude = new System::Windows::Forms::TextBox();
         this->showLongitude = new System::Windows::Forms::TextBox();
         this->pictureBox4 = new System::Windows::Forms::PictureBox();
         this->textBox1 = new System::Windows::Forms::TextBox();
         this->textBox2 = new System::Windows::Forms::TextBox();
         this->textBox3 = new System::Windows::Forms::TextBox();
         this->label1 = new System::Windows::Forms::Label();
         this->label2 = new System::Windows::Forms::Label();
         this->label3 = new System::Windows::Forms::Label();
         this->textBox4 = new System::Windows::Forms::TextBox();
         this->label4 = new System::Windows::Forms::Label();
         this->StatusInfo = new System::Windows::Forms::GroupBox();
         this->showAmbient = new System::Windows::Forms::TextBox();
         this->AmbientTemp = new System::Windows::Forms::Label();
         this->Time = new System::Windows::Forms::Label();
         this->showTime = new System::Windows::Forms::TextBox();
         this->showStatus = new System::Windows::Forms::TextBox();
         this->Status = new System::Windows::Forms::Label();
         this->pictureBox5 = new System::Windows::Forms::PictureBox();
         this->Graphs = new System::Windows::Forms::TabPage();
         this->chart3d = new
GraphicsServer::GSNet::Charting::GSNetWinChart();
         this->tabControl1->SuspendLayout();
         this->AircraftInfo->SuspendLayout();
         this->ControlCenter->SuspendLayout();

                 Santa Clara University Aerial Robotics Team              66
         this->ChasePlaneInfo->SuspendLayout();
         this->LeadPlaneInfo->SuspendLayout();
         this->StatusInfo->SuspendLayout();
         this->Graphs->SuspendLayout();
         this->SuspendLayout();
         //
         // tabControl1
         //
         this->tabControl1->Controls->Add(this->AircraftInfo);
         this->tabControl1->Controls->Add(this->Graphs);
         this->tabControl1->Dock =
System::Windows::Forms::DockStyle::Fill;
         this->tabControl1->Location = System::Drawing::Point(0, 0);
         this->tabControl1->Name = S"tabControl1";
         this->tabControl1->SelectedIndex = 0;
         this->tabControl1->ShowToolTips = true;
         this->tabControl1->Size = System::Drawing::Size(976, 678);
         this->tabControl1->SizeMode =
System::Windows::Forms::TabSizeMode::FillToRight;
         this->tabControl1->TabIndex = 0;
         //
         // AircraftInfo
         //
         this->AircraftInfo->AccessibleDescription = S"Flight
Information";
         this->AircraftInfo->BackColor =
System::Drawing::SystemColors::AppWorkspace;
         this->AircraftInfo->Controls->Add(this->pictureBox6);
         this->AircraftInfo->Controls->Add(this->pictureBox2);
         this->AircraftInfo->Controls->Add(this->pictureBox1);
         this->AircraftInfo->Controls->Add(this->ControlCenter);
         this->AircraftInfo->Controls->Add(this->ChasePlaneInfo);
         this->AircraftInfo->Controls->Add(this->LeadPlaneInfo);
         this->AircraftInfo->Controls->Add(this->StatusInfo);
         this->AircraftInfo->Location = System::Drawing::Point(4, 24);
         this->AircraftInfo->Name = S"AircraftInfo";
         this->AircraftInfo->Size = System::Drawing::Size(968, 650);
         this->AircraftInfo->TabIndex = 0;
         this->AircraftInfo->Text = S"Aircraft Information";
         this->AircraftInfo->ToolTipText = S"This page displays
realtime aircraft information from both the lead and chase pla"
            S"ne.";
         //
         // pictureBox6
         //
         this->pictureBox6->Image = (__try_cast<System::Drawing::Image
* >(resources->GetObject(S"pictureBox6.Image")));
         this->pictureBox6->Location = System::Drawing::Point(787, 54);
         this->pictureBox6->Name = S"pictureBox6";
         this->pictureBox6->Size = System::Drawing::Size(165, 95);
         this->pictureBox6->TabIndex = 43;
         this->pictureBox6->TabStop = false;
         //
         // pictureBox2
         //
         this->pictureBox2->Image = (__try_cast<System::Drawing::Image
* >(resources->GetObject(S"pictureBox2.Image")));
         this->pictureBox2->Location = System::Drawing::Point(27, 6);
         this->pictureBox2->Name = S"pictureBox2";

                 Santa Clara University Aerial Robotics Team              67
         this->pictureBox2->Size = System::Drawing::Size(378, 32);
         this->pictureBox2->TabIndex = 42;
         this->pictureBox2->TabStop = false;
         //
         // pictureBox1
         //
         this->pictureBox1->Image = (__try_cast<System::Drawing::Image
* >(resources->GetObject(S"pictureBox1.Image")));
         this->pictureBox1->Location = System::Drawing::Point(411, 6);
         this->pictureBox1->Name = S"pictureBox1";
         this->pictureBox1->Size = System::Drawing::Size(339, 32);
         this->pictureBox1->TabIndex = 41;
         this->pictureBox1->TabStop = false;
         //
         // ControlCenter
         //
         this->ControlCenter->Controls->Add(this->connectLead);
         this->ControlCenter->Controls->Add(this->StopFollow);
         this->ControlCenter->Controls->Add(this->Home);
         this->ControlCenter->Controls->Add(this->Disconnect);
         this->ControlCenter->Controls->Add(this->Pattern);
         this->ControlCenter->Controls->Add(this->Follow);
         this->ControlCenter->Controls->Add(this->Connect);
         this->ControlCenter->Font = new
System::Drawing::Font(S"Microsoft Sans Serif", 9.75F,
System::Drawing::FontStyle::Regular,
System::Drawing::GraphicsUnit::Point, (System::Byte)0);
         this->ControlCenter->ForeColor =
System::Drawing::Color::White;
         this->ControlCenter->Location = System::Drawing::Point(811,
182);
         this->ControlCenter->Name = S"ControlCenter";
         this->ControlCenter->Size = System::Drawing::Size(144, 456);
         this->ControlCenter->TabIndex = 40;
         this->ControlCenter->TabStop = false;
         this->ControlCenter->Text = S"Control Center";
         //
         // connectLead
         //
         this->connectLead->BackColor =
System::Drawing::Color::ForestGreen;
         this->connectLead->Location = System::Drawing::Point(16, 96);
         this->connectLead->Name = S"connectLead";
         this->connectLead->Size = System::Drawing::Size(112, 32);
         this->connectLead->TabIndex = 6;
         this->connectLead->Text = S"Connect Lead";
         this->connectLead->Click += new System::EventHandler(this,
button1_Click);
         //
         // StopFollow
         //
         this->StopFollow->Enabled = false;
         this->StopFollow->Location = System::Drawing::Point(16, 264);
         this->StopFollow->Name = S"StopFollow";
         this->StopFollow->Size = System::Drawing::Size(112, 32);
         this->StopFollow->TabIndex = 5;
         this->StopFollow->Text = S"Stop Following";
         this->StopFollow->Click += new System::EventHandler(this,
StopFollow_Click);

                 Santa Clara University Aerial Robotics Team             68
         //
         // Home
         //
         this->Home->Enabled = false;
         this->Home->Location = System::Drawing::Point(16, 376);
         this->Home->Name = S"Home";
         this->Home->Size = System::Drawing::Size(112, 32);
         this->Home->TabIndex = 4;
         this->Home->Text = S"Return Home";
         this->Home->Click += new System::EventHandler(this,
Home_Click);
         //
         // Disconnect
         //
         this->Disconnect->BackColor =
System::Drawing::Color::Firebrick;
         this->Disconnect->Enabled = false;
         this->Disconnect->Location = System::Drawing::Point(16, 152);
         this->Disconnect->Name = S"Disconnect";
         this->Disconnect->Size = System::Drawing::Size(115, 32);
         this->Disconnect->TabIndex = 3;
         this->Disconnect->Text = S"Disconnect";
         this->Disconnect->Click += new System::EventHandler(this,
Disconnect_Click);
         //
         // Pattern
         //
         this->Pattern->Enabled = false;
         this->Pattern->Location = System::Drawing::Point(16, 320);
         this->Pattern->Name = S"Pattern";
         this->Pattern->Size = System::Drawing::Size(112, 32);
         this->Pattern->TabIndex = 1;
         this->Pattern->Text = S"Holding Pattern";
         this->Pattern->Click += new System::EventHandler(this,
Pattern_Click);
         //
         // Follow
         //
         this->Follow->Enabled = false;
         this->Follow->Location = System::Drawing::Point(16, 208);
         this->Follow->Name = S"Follow";
         this->Follow->Size = System::Drawing::Size(112, 32);
         this->Follow->TabIndex = 0;
         this->Follow->Text = S"Follow Lead";
         this->Follow->Click += new System::EventHandler(this,
Follow_Click);
         //
         // Connect
         //
         this->Connect->BackColor =
System::Drawing::Color::ForestGreen;
         this->Connect->Location = System::Drawing::Point(16, 48);
         this->Connect->Name = S"Connect";
         this->Connect->Size = System::Drawing::Size(115, 32);
         this->Connect->TabIndex = 2;
         this->Connect->Text = S"Connect Chase";
         this->Connect->Click += new System::EventHandler(this,
Connect_Click);
         //

                 Santa Clara University Aerial Robotics Team             69
         // ChasePlaneInfo
         //
         this->ChasePlaneInfo->BackColor =
System::Drawing::Color::Transparent;
         this->ChasePlaneInfo->Controls->Add(this->Airspeed2);
         this->ChasePlaneInfo->Controls->Add(this->showHeading2);
         this->ChasePlaneInfo->Controls->Add(this->showWaypoint);
         this->ChasePlaneInfo->Controls->Add(this->Longitude2);
         this->ChasePlaneInfo->Controls->Add(this->Latitude2);
         this->ChasePlaneInfo->Controls->Add(this->showLatitude2);
         this->ChasePlaneInfo->Controls->Add(this->Altitude2);
         this->ChasePlaneInfo->Controls->Add(this->Heading2);
         this->ChasePlaneInfo->Controls->Add(this->CurrentWaypoint);
         this->ChasePlaneInfo->Controls->Add(this->showLongitude2);
         this->ChasePlaneInfo->Controls->Add(this->showAirspeed2);
         this->ChasePlaneInfo->Controls->Add(this->showAltitude2);
         this->ChasePlaneInfo->Controls->Add(this->pictureBox3);
         this->ChasePlaneInfo->Font = new
System::Drawing::Font(S"Microsoft Sans Serif", 9.75F,
System::Drawing::FontStyle::Regular,
System::Drawing::GraphicsUnit::Point, (System::Byte)0);
         this->ChasePlaneInfo->ForeColor =
System::Drawing::Color::White;
         this->ChasePlaneInfo->Location = System::Drawing::Point(419,
190);
         this->ChasePlaneInfo->Name = S"ChasePlaneInfo";
         this->ChasePlaneInfo->Size = System::Drawing::Size(373, 456);
         this->ChasePlaneInfo->TabIndex = 38;
         this->ChasePlaneInfo->TabStop = false;
         this->ChasePlaneInfo->Text = S"Chase Plane Information";
         //
         // Airspeed2
         //
         this->Airspeed2->BackColor = System::Drawing::Color::DimGray;
         this->Airspeed2->Font = new System::Drawing::Font(S"Microsoft
Sans Serif", 9.75F, System::Drawing::FontStyle::Regular,
System::Drawing::GraphicsUnit::Point, (System::Byte)0);
         this->Airspeed2->ForeColor =
System::Drawing::Color::FromArgb((System::Byte)255, (System::Byte)192,
(System::Byte)128);
         this->Airspeed2->Location = System::Drawing::Point(29, 32);
         this->Airspeed2->Name = S"Airspeed2";
         this->Airspeed2->Size = System::Drawing::Size(59, 16);
         this->Airspeed2->TabIndex = 21;
         this->Airspeed2->Text = S"Airspeed";
         //
         // showHeading2
         //
         this->showHeading2->BackColor =
System::Drawing::SystemColors::ScrollBar;
         this->showHeading2->Location = System::Drawing::Point(29,
320);
         this->showHeading2->MaxLength = 10;
         this->showHeading2->Name = S"showHeading2";
         this->showHeading2->ReadOnly = true;
         this->showHeading2->Size = System::Drawing::Size(120, 22);
         this->showHeading2->TabIndex = 26;
         this->showHeading2->Text = S"";
         //

                 Santa Clara University Aerial Robotics Team             70
         // showWaypoint
         //
         this->showWaypoint->BackColor =
System::Drawing::SystemColors::ScrollBar;
         this->showWaypoint->Location = System::Drawing::Point(208,
56);
         this->showWaypoint->MaxLength = 20;
         this->showWaypoint->Name = S"showWaypoint";
         this->showWaypoint->ReadOnly = true;
         this->showWaypoint->Size = System::Drawing::Size(120, 22);
         this->showWaypoint->TabIndex = 25;
         this->showWaypoint->Text = S"";
         //
         // Longitude2
         //
         this->Longitude2->BackColor = System::Drawing::Color::DimGray;
         this->Longitude2->Font = new System::Drawing::Font(S"Microsoft
Sans Serif", 9.75F, System::Drawing::FontStyle::Regular,
System::Drawing::GraphicsUnit::Point, (System::Byte)0);
         this->Longitude2->ForeColor =
System::Drawing::Color::FromArgb((System::Byte)255, (System::Byte)192,
(System::Byte)128);
         this->Longitude2->Location = System::Drawing::Point(29, 200);
         this->Longitude2->Name = S"Longitude2";
         this->Longitude2->Size = System::Drawing::Size(67, 16);
         this->Longitude2->TabIndex = 32;
         this->Longitude2->Text = S"Longitude";
         //
         // Latitude2
         //
         this->Latitude2->BackColor = System::Drawing::Color::DimGray;
         this->Latitude2->Font = new System::Drawing::Font(S"Microsoft
Sans Serif", 9.75F, System::Drawing::FontStyle::Regular,
System::Drawing::GraphicsUnit::Point, (System::Byte)0);
         this->Latitude2->ForeColor =
System::Drawing::Color::FromArgb((System::Byte)255, (System::Byte)192,
(System::Byte)128);
         this->Latitude2->Location = System::Drawing::Point(208, 200);
         this->Latitude2->Name = S"Latitude2";
         this->Latitude2->Size = System::Drawing::Size(54, 16);
         this->Latitude2->TabIndex = 30;
         this->Latitude2->Text = S"Latitude";
         //
         // showLatitude2
         //
         this->showLatitude2->BackColor =
System::Drawing::SystemColors::ScrollBar;
         this->showLatitude2->Location = System::Drawing::Point(208,
224);
         this->showLatitude2->MaxLength = 20;
         this->showLatitude2->Name = S"showLatitude2";
         this->showLatitude2->ReadOnly = true;
         this->showLatitude2->Size = System::Drawing::Size(120, 22);
         this->showLatitude2->TabIndex = 22;
         this->showLatitude2->Text = S"";
         //
         // Altitude2
         //
         this->Altitude2->BackColor = System::Drawing::Color::DimGray;

                 Santa Clara University Aerial Robotics Team              71
         this->Altitude2->Font = new System::Drawing::Font(S"Microsoft
Sans Serif", 9.75F, System::Drawing::FontStyle::Regular,
System::Drawing::GraphicsUnit::Point, (System::Byte)0);
         this->Altitude2->ForeColor =
System::Drawing::Color::FromArgb((System::Byte)255, (System::Byte)192,
(System::Byte)128);
         this->Altitude2->Location = System::Drawing::Point(29, 112);
         this->Altitude2->Name = S"Altitude2";
         this->Altitude2->Size = System::Drawing::Size(51, 16);
         this->Altitude2->TabIndex = 27;
         this->Altitude2->Text = S"Altitude";
         //
         // Heading2
         //
         this->Heading2->BackColor = System::Drawing::Color::DimGray;
         this->Heading2->Font = new System::Drawing::Font(S"Microsoft
Sans Serif", 9.75F, System::Drawing::FontStyle::Regular,
System::Drawing::GraphicsUnit::Point, (System::Byte)0);
         this->Heading2->ForeColor =
System::Drawing::Color::FromArgb((System::Byte)255, (System::Byte)192,
(System::Byte)128);
         this->Heading2->Location = System::Drawing::Point(29, 296);
         this->Heading2->Name = S"Heading2";
         this->Heading2->Size = System::Drawing::Size(59, 16);
         this->Heading2->TabIndex = 29;
         this->Heading2->Text = S"Heading";
         //
         // CurrentWaypoint
         //
         this->CurrentWaypoint->BackColor =
System::Drawing::Color::DimGray;
         this->CurrentWaypoint->Font = new
System::Drawing::Font(S"Microsoft Sans Serif", 9.75F,
System::Drawing::FontStyle::Regular,
System::Drawing::GraphicsUnit::Point, (System::Byte)0);
         this->CurrentWaypoint->ForeColor =
System::Drawing::Color::FromArgb((System::Byte)255, (System::Byte)192,
(System::Byte)128);
         this->CurrentWaypoint->Location = System::Drawing::Point(208,
32);
         this->CurrentWaypoint->Name = S"CurrentWaypoint";
         this->CurrentWaypoint->Size = System::Drawing::Size(110, 16);
         this->CurrentWaypoint->TabIndex = 31;
         this->CurrentWaypoint->Text = S"Current Waypoint";
         //
         // showLongitude2
         //
         this->showLongitude2->BackColor =
System::Drawing::SystemColors::ScrollBar;
         this->showLongitude2->Location = System::Drawing::Point(29,
224);
         this->showLongitude2->MaxLength = 20;
         this->showLongitude2->Name = S"showLongitude2";
         this->showLongitude2->ReadOnly = true;
         this->showLongitude2->Size = System::Drawing::Size(120, 22);
         this->showLongitude2->TabIndex = 23;
         this->showLongitude2->Text = S"";
         //
         // showAirspeed2

                 Santa Clara University Aerial Robotics Team             72
         //
         this->showAirspeed2->BackColor =
System::Drawing::SystemColors::ScrollBar;
         this->showAirspeed2->Location = System::Drawing::Point(29,
56);
         this->showAirspeed2->MaxLength = 10;
         this->showAirspeed2->Name = S"showAirspeed2";
         this->showAirspeed2->ReadOnly = true;
         this->showAirspeed2->Size = System::Drawing::Size(120, 22);
         this->showAirspeed2->TabIndex = 19;
         this->showAirspeed2->Text = S"";
         //
         // showAltitude2
         //
         this->showAltitude2->BackColor =
System::Drawing::SystemColors::ScrollBar;
         this->showAltitude2->Location = System::Drawing::Point(29,
136);
         this->showAltitude2->MaxLength = 10;
         this->showAltitude2->Name = S"showAltitude2";
         this->showAltitude2->ReadOnly = true;
         this->showAltitude2->Size = System::Drawing::Size(120, 22);
         this->showAltitude2->TabIndex = 20;
         this->showAltitude2->Text = S"";
         //
         // pictureBox3
         //
         this->pictureBox3->BackColor =
System::Drawing::Color::Transparent;
         this->pictureBox3->BackgroundImage =
(__try_cast<System::Drawing::Image * >(resources-
>GetObject(S"pictureBox3.BackgroundImage")));
         this->pictureBox3->Location = System::Drawing::Point(8, 24);
         this->pictureBox3->Name = S"pictureBox3";
         this->pictureBox3->Size = System::Drawing::Size(360, 432);
         this->pictureBox3->TabIndex = 25;
         this->pictureBox3->TabStop = false;
         //
         // LeadPlaneInfo
         //
         this->LeadPlaneInfo->BackColor =
System::Drawing::Color::Transparent;
         this->LeadPlaneInfo->Controls->Add(this->Voltage);
         this->LeadPlaneInfo->Controls->Add(this->showVoltage);
         this->LeadPlaneInfo->Controls->Add(this->showAirspeed);
         this->LeadPlaneInfo->Controls->Add(this->showAltitude);
         this->LeadPlaneInfo->Controls->Add(this->HeadTemperature);
         this->LeadPlaneInfo->Controls->Add(this->Airspeed);
         this->LeadPlaneInfo->Controls->Add(this->Altitude);
         this->LeadPlaneInfo->Controls->Add(this->RPM);
         this->LeadPlaneInfo->Controls->Add(this->MufflerTemp);
         this->LeadPlaneInfo->Controls->Add(this->showRPM);
         this->LeadPlaneInfo->Controls->Add(this->showMuffler);
         this->LeadPlaneInfo->Controls->Add(this->showHead);
         this->LeadPlaneInfo->Controls->Add(this->Heading);
         this->LeadPlaneInfo->Controls->Add(this->Longitude);
         this->LeadPlaneInfo->Controls->Add(this->Lattitude);
         this->LeadPlaneInfo->Controls->Add(this->showHeading);
         this->LeadPlaneInfo->Controls->Add(this->showLattitude);

                 Santa Clara University Aerial Robotics Team            73
         this->LeadPlaneInfo->Controls->Add(this->showLongitude);
         this->LeadPlaneInfo->Controls->Add(this->pictureBox4);
         this->LeadPlaneInfo->Controls->Add(this->textBox1);
         this->LeadPlaneInfo->Controls->Add(this->textBox2);
         this->LeadPlaneInfo->Controls->Add(this->textBox3);
         this->LeadPlaneInfo->Controls->Add(this->label1);
         this->LeadPlaneInfo->Controls->Add(this->label2);
         this->LeadPlaneInfo->Controls->Add(this->label3);
         this->LeadPlaneInfo->Controls->Add(this->textBox4);
         this->LeadPlaneInfo->Controls->Add(this->label4);
         this->LeadPlaneInfo->Font = new
System::Drawing::Font(S"Microsoft Sans Serif", 9.75F,
System::Drawing::FontStyle::Regular,
System::Drawing::GraphicsUnit::Point, (System::Byte)0);
         this->LeadPlaneInfo->ForeColor =
System::Drawing::Color::White;
         this->LeadPlaneInfo->Location = System::Drawing::Point(14,
190);
         this->LeadPlaneInfo->Name = S"LeadPlaneInfo";
         this->LeadPlaneInfo->Size = System::Drawing::Size(381, 456);
         this->LeadPlaneInfo->TabIndex = 37;
         this->LeadPlaneInfo->TabStop = false;
         this->LeadPlaneInfo->Text = S"Lead Plane Information";
         //
         // Voltage
         //
         this->Voltage->BackColor = System::Drawing::Color::DimGray;
         this->Voltage->Font = new System::Drawing::Font(S"Microsoft
Sans Serif", 9.75F, System::Drawing::FontStyle::Regular,
System::Drawing::GraphicsUnit::Point, (System::Byte)0);
         this->Voltage->ForeColor =
System::Drawing::Color::FromArgb((System::Byte)255, (System::Byte)192,
(System::Byte)128);
         this->Voltage->Location = System::Drawing::Point(208, 200);
         this->Voltage->Name = S"Voltage";
         this->Voltage->Size = System::Drawing::Size(56, 16);
         this->Voltage->TabIndex = 21;
         this->Voltage->Text = S"Voltage";
         //
         // showVoltage
         //
         this->showVoltage->BackColor =
System::Drawing::SystemColors::ScrollBar;
         this->showVoltage->Location = System::Drawing::Point(208,
224);
         this->showVoltage->MaxLength = 10;
         this->showVoltage->Name = S"showVoltage";
         this->showVoltage->ReadOnly = true;
         this->showVoltage->Size = System::Drawing::Size(120, 22);
         this->showVoltage->TabIndex = 20;
         this->showVoltage->Text = S"";
         //
         // showAirspeed
         //
         this->showAirspeed->BackColor =
System::Drawing::SystemColors::ScrollBar;
         this->showAirspeed->Location = System::Drawing::Point(29, 56);
         this->showAirspeed->MaxLength = 20;
         this->showAirspeed->Name = S"showAirspeed";

                 Santa Clara University Aerial Robotics Team              74
         this->showAirspeed->ReadOnly = true;
         this->showAirspeed->Size = System::Drawing::Size(120, 22);
         this->showAirspeed->TabIndex = 0;
         this->showAirspeed->Text = S"";
         //
         // showAltitude
         //
         this->showAltitude->BackColor =
System::Drawing::SystemColors::ScrollBar;
         this->showAltitude->Location = System::Drawing::Point(29,
136);
         this->showAltitude->MaxLength = 10;
         this->showAltitude->Name = S"showAltitude";
         this->showAltitude->ReadOnly = true;
         this->showAltitude->Size = System::Drawing::Size(120, 22);
         this->showAltitude->TabIndex = 1;
         this->showAltitude->Text = S"";
         //
         // HeadTemperature
         //
         this->HeadTemperature->BackColor =
System::Drawing::Color::DimGray;
         this->HeadTemperature->Font = new
System::Drawing::Font(S"Microsoft Sans Serif", 9.75F,
System::Drawing::FontStyle::Regular,
System::Drawing::GraphicsUnit::Point, (System::Byte)0);
         this->HeadTemperature->ForeColor =
System::Drawing::Color::FromArgb((System::Byte)255, (System::Byte)192,
(System::Byte)128);
         this->HeadTemperature->Location = System::Drawing::Point(208,
32);
         this->HeadTemperature->Name = S"HeadTemperature";
         this->HeadTemperature->Size = System::Drawing::Size(120, 16);
         this->HeadTemperature->TabIndex = 16;
         this->HeadTemperature->Text = S"Head Temperature";
         //
         // Airspeed
         //
         this->Airspeed->BackColor = System::Drawing::Color::DimGray;
         this->Airspeed->Font = new System::Drawing::Font(S"Microsoft
Sans Serif", 9.75F, System::Drawing::FontStyle::Regular,
System::Drawing::GraphicsUnit::Point, (System::Byte)0);
         this->Airspeed->ForeColor =
System::Drawing::Color::FromArgb((System::Byte)255, (System::Byte)192,
(System::Byte)128);
         this->Airspeed->Location = System::Drawing::Point(29, 32);
         this->Airspeed->Name = S"Airspeed";
         this->Airspeed->Size = System::Drawing::Size(59, 16);
         this->Airspeed->TabIndex = 2;
         this->Airspeed->Text = S"Airspeed";
         //
         // Altitude
         //
         this->Altitude->BackColor = System::Drawing::Color::DimGray;
         this->Altitude->Font = new System::Drawing::Font(S"Microsoft
Sans Serif", 9.75F, System::Drawing::FontStyle::Regular,
System::Drawing::GraphicsUnit::Point, (System::Byte)0);




                 Santa Clara University Aerial Robotics Team             75
         this->Altitude->ForeColor =
System::Drawing::Color::FromArgb((System::Byte)255, (System::Byte)192,
(System::Byte)128);
         this->Altitude->Location = System::Drawing::Point(29, 112);
         this->Altitude->Name = S"Altitude";
         this->Altitude->Size = System::Drawing::Size(51, 16);
         this->Altitude->TabIndex = 12;
         this->Altitude->Text = S"Altitude";
         //
         // RPM
         //
         this->RPM->BackColor = System::Drawing::Color::DimGray;
         this->RPM->Font = new System::Drawing::Font(S"Microsoft Sans
Serif", 9.75F, System::Drawing::FontStyle::Regular,
System::Drawing::GraphicsUnit::Point, (System::Byte)0);
         this->RPM->ForeColor =
System::Drawing::Color::FromArgb((System::Byte)255, (System::Byte)192,
(System::Byte)128);
         this->RPM->Location = System::Drawing::Point(29, 200);
         this->RPM->Name = S"RPM";
         this->RPM->Size = System::Drawing::Size(35, 16);
         this->RPM->TabIndex = 14;
         this->RPM->Text = S"RPM";
         //
         // MufflerTemp
         //
         this->MufflerTemp->BackColor =
System::Drawing::Color::DimGray;
         this->MufflerTemp->Font = new
System::Drawing::Font(S"Microsoft Sans Serif", 9.75F,
System::Drawing::FontStyle::Regular,
System::Drawing::GraphicsUnit::Point, (System::Byte)0);
         this->MufflerTemp->ForeColor =
System::Drawing::Color::FromArgb((System::Byte)255, (System::Byte)192,
(System::Byte)128);
         this->MufflerTemp->Location = System::Drawing::Point(208,
112);
         this->MufflerTemp->Name = S"MufflerTemp";
         this->MufflerTemp->Size = System::Drawing::Size(128, 16);
         this->MufflerTemp->TabIndex = 13;
         this->MufflerTemp->Text = S"Muffler Temperature";
         //
         // showRPM
         //
         this->showRPM->BackColor =
System::Drawing::SystemColors::ScrollBar;
         this->showRPM->Location = System::Drawing::Point(29, 224);
         this->showRPM->MaxLength = 10;
         this->showRPM->Name = S"showRPM";
         this->showRPM->ReadOnly = true;
         this->showRPM->Size = System::Drawing::Size(120, 22);
         this->showRPM->TabIndex = 10;
         this->showRPM->Text = S"";
         //
         // showMuffler
         //
         this->showMuffler->BackColor =
System::Drawing::SystemColors::ScrollBar;



                 Santa Clara University Aerial Robotics Team             76
        this->showMuffler->Location = System::Drawing::Point(208,
136);
         this->showMuffler->MaxLength = 10;
         this->showMuffler->Name = S"showMuffler";
         this->showMuffler->ReadOnly = true;
         this->showMuffler->Size = System::Drawing::Size(120, 22);
         this->showMuffler->TabIndex = 6;
         this->showMuffler->Text = S"";
         //
         // showHead
         //
         this->showHead->BackColor =
System::Drawing::SystemColors::ScrollBar;
         this->showHead->Location = System::Drawing::Point(208, 56);
         this->showHead->MaxLength = 10;
         this->showHead->Name = S"showHead";
         this->showHead->ReadOnly = true;
         this->showHead->Size = System::Drawing::Size(120, 22);
         this->showHead->TabIndex = 7;
         this->showHead->Text = S"";
         //
         // Heading
         //
         this->Heading->BackColor = System::Drawing::Color::DimGray;
         this->Heading->Font = new System::Drawing::Font(S"Microsoft
Sans Serif", 9.75F, System::Drawing::FontStyle::Regular,
System::Drawing::GraphicsUnit::Point, (System::Byte)0);
         this->Heading->ForeColor =
System::Drawing::Color::FromArgb((System::Byte)255, (System::Byte)192,
(System::Byte)128);
         this->Heading->Location = System::Drawing::Point(29, 384);
         this->Heading->Name = S"Heading";
         this->Heading->Size = System::Drawing::Size(59, 16);
         this->Heading->TabIndex = 18;
         this->Heading->Text = S"Heading";
         //
         // Longitude
         //
         this->Longitude->BackColor = System::Drawing::Color::DimGray;
         this->Longitude->Font = new System::Drawing::Font(S"Microsoft
Sans Serif", 9.75F, System::Drawing::FontStyle::Regular,
System::Drawing::GraphicsUnit::Point, (System::Byte)0);
         this->Longitude->ForeColor =
System::Drawing::Color::FromArgb((System::Byte)255, (System::Byte)192,
(System::Byte)128);
         this->Longitude->Location = System::Drawing::Point(29, 296);
         this->Longitude->Name = S"Longitude";
         this->Longitude->Size = System::Drawing::Size(67, 16);
         this->Longitude->TabIndex = 17;
         this->Longitude->Text = S"Longitude";
         //
         // Lattitude
         //
         this->Lattitude->BackColor = System::Drawing::Color::DimGray;
         this->Lattitude->Font = new System::Drawing::Font(S"Microsoft
Sans Serif", 9.75F, System::Drawing::FontStyle::Regular,
System::Drawing::GraphicsUnit::Point, (System::Byte)0);




                 Santa Clara University Aerial Robotics Team             77
         this->Lattitude->ForeColor =
System::Drawing::Color::FromArgb((System::Byte)255, (System::Byte)192,
(System::Byte)128);
         this->Lattitude->Location = System::Drawing::Point(208, 296);
         this->Lattitude->Name = S"Lattitude";
         this->Lattitude->Size = System::Drawing::Size(56, 16);
         this->Lattitude->TabIndex = 15;
         this->Lattitude->Text = S"Lattitude";
         //
         // showHeading
         //
         this->showHeading->BackColor =
System::Drawing::SystemColors::ScrollBar;
         this->showHeading->Location = System::Drawing::Point(29, 408);
         this->showHeading->MaxLength = 10;
         this->showHeading->Name = S"showHeading";
         this->showHeading->ReadOnly = true;
         this->showHeading->Size = System::Drawing::Size(120, 22);
         this->showHeading->TabIndex = 3;
         this->showHeading->Text = S"";
         //
         // showLattitude
         //
         this->showLattitude->BackColor =
System::Drawing::SystemColors::ScrollBar;
         this->showLattitude->Location = System::Drawing::Point(208,
320);
         this->showLattitude->MaxLength = 20;
         this->showLattitude->Name = S"showLattitude";
         this->showLattitude->ReadOnly = true;
         this->showLattitude->Size = System::Drawing::Size(120, 22);
         this->showLattitude->TabIndex = 4;
         this->showLattitude->Text = S"";
         //
         // showLongitude
         //
         this->showLongitude->BackColor =
System::Drawing::SystemColors::ScrollBar;
         this->showLongitude->Location = System::Drawing::Point(29,
320);
         this->showLongitude->MaxLength = 20;
         this->showLongitude->Name = S"showLongitude";
         this->showLongitude->ReadOnly = true;
         this->showLongitude->Size = System::Drawing::Size(120, 22);
         this->showLongitude->TabIndex = 5;
         this->showLongitude->Text = S"";
         //
         // pictureBox4
         //
         this->pictureBox4->Image = (__try_cast<System::Drawing::Image
* >(resources->GetObject(S"pictureBox4.Image")));
         this->pictureBox4->Location = System::Drawing::Point(10, 24);
         this->pictureBox4->Name = S"pictureBox4";
         this->pictureBox4->Size = System::Drawing::Size(460, 432);
         this->pictureBox4->TabIndex = 19;
         this->pictureBox4->TabStop = false;
         //
         // textBox1
         //

                 Santa Clara University Aerial Robotics Team              78
         this->textBox1->BackColor =
System::Drawing::SystemColors::Desktop;
         this->textBox1->Location = System::Drawing::Point(29, 328);
         this->textBox1->Name = S"textBox1";
         this->textBox1->ReadOnly = true;
         this->textBox1->Size = System::Drawing::Size(120, 22);
         this->textBox1->TabIndex = 5;
         this->textBox1->Text = S"";
         //
         // textBox2
         //
         this->textBox2->BackColor =
System::Drawing::SystemColors::Desktop;
         this->textBox2->Location = System::Drawing::Point(29, 80);
         this->textBox2->Name = S"textBox2";
         this->textBox2->ReadOnly = true;
         this->textBox2->Size = System::Drawing::Size(120, 22);
         this->textBox2->TabIndex = 0;
         this->textBox2->Text = S"";
         //
         // textBox3
         //
         this->textBox3->BackColor =
System::Drawing::SystemColors::Desktop;
         this->textBox3->Location = System::Drawing::Point(29, 160);
         this->textBox3->Name = S"textBox3";
         this->textBox3->ReadOnly = true;
         this->textBox3->Size = System::Drawing::Size(120, 22);
         this->textBox3->TabIndex = 1;
         this->textBox3->Text = S"";
         //
         // label1
         //
         this->label1->BackColor = System::Drawing::Color::DimGray;
         this->label1->Font = new System::Drawing::Font(S"Microsoft
Sans Serif", 9.75F, System::Drawing::FontStyle::Regular,
System::Drawing::GraphicsUnit::Point, (System::Byte)0);
         this->label1->ForeColor =
System::Drawing::Color::FromArgb((System::Byte)255, (System::Byte)192,
(System::Byte)128);
         this->label1->Location = System::Drawing::Point(29, 40);
         this->label1->Name = S"label1";
         this->label1->Size = System::Drawing::Size(67, 16);
         this->label1->TabIndex = 2;
         this->label1->Text = S"Airspeed";
         //
         // label2
         //
         this->label2->BackColor = System::Drawing::Color::DimGray;
         this->label2->Font = new System::Drawing::Font(S"Microsoft
Sans Serif", 9.75F, System::Drawing::FontStyle::Regular,
System::Drawing::GraphicsUnit::Point, (System::Byte)0);
         this->label2->ForeColor =
System::Drawing::Color::FromArgb((System::Byte)255, (System::Byte)192,
(System::Byte)128);
         this->label2->Location = System::Drawing::Point(29, 120);
         this->label2->Name = S"label2";
         this->label2->Size = System::Drawing::Size(67, 16);
         this->label2->TabIndex = 12;

                 Santa Clara University Aerial Robotics Team             79
         this->label2->Text = S"Altitude";
         //
         // label3
         //
         this->label3->BackColor = System::Drawing::Color::DimGray;
         this->label3->Font = new System::Drawing::Font(S"Microsoft
Sans Serif", 9.75F, System::Drawing::FontStyle::Regular,
System::Drawing::GraphicsUnit::Point, (System::Byte)0);
         this->label3->ForeColor =
System::Drawing::Color::FromArgb((System::Byte)255, (System::Byte)192,
(System::Byte)128);
         this->label3->Location = System::Drawing::Point(29, 208);
         this->label3->Name = S"label3";
         this->label3->Size = System::Drawing::Size(67, 16);
         this->label3->TabIndex = 14;
         this->label3->Text = S"RPM";
         //
         // textBox4
         //
         this->textBox4->BackColor =
System::Drawing::SystemColors::Desktop;
         this->textBox4->Location = System::Drawing::Point(29, 248);
         this->textBox4->Name = S"textBox4";
         this->textBox4->ReadOnly = true;
         this->textBox4->Size = System::Drawing::Size(120, 22);
         this->textBox4->TabIndex = 10;
         this->textBox4->Text = S"";
         //
         // label4
         //
         this->label4->BackColor = System::Drawing::Color::DimGray;
         this->label4->Font = new System::Drawing::Font(S"Microsoft
Sans Serif", 9.75F, System::Drawing::FontStyle::Regular,
System::Drawing::GraphicsUnit::Point, (System::Byte)0);
         this->label4->ForeColor =
System::Drawing::Color::FromArgb((System::Byte)255, (System::Byte)192,
(System::Byte)128);
         this->label4->Location = System::Drawing::Point(29, 288);
         this->label4->Name = S"label4";
         this->label4->Size = System::Drawing::Size(77, 16);
         this->label4->TabIndex = 17;
         this->label4->Text = S"Longitude";
         //
         // StatusInfo
         //
         this->StatusInfo->BackColor =
System::Drawing::Color::Transparent;
         this->StatusInfo->Controls->Add(this->showAmbient);
         this->StatusInfo->Controls->Add(this->AmbientTemp);
         this->StatusInfo->Controls->Add(this->Time);
         this->StatusInfo->Controls->Add(this->showTime);
         this->StatusInfo->Controls->Add(this->showStatus);
         this->StatusInfo->Controls->Add(this->Status);
         this->StatusInfo->Controls->Add(this->pictureBox5);
         this->StatusInfo->Font = new System::Drawing::Font(S"Microsoft
Sans Serif", 9.75F, System::Drawing::FontStyle::Regular,
System::Drawing::GraphicsUnit::Point, (System::Byte)0);
         this->StatusInfo->ForeColor =
System::Drawing::SystemColors::ControlLightLight;

                 Santa Clara University Aerial Robotics Team              80
         this->StatusInfo->Location = System::Drawing::Point(35, 54);
         this->StatusInfo->Name = S"StatusInfo";
         this->StatusInfo->Size = System::Drawing::Size(736, 120);
         this->StatusInfo->TabIndex = 39;
         this->StatusInfo->TabStop = false;
         this->StatusInfo->Text = S"Status Information";
         //
         // showAmbient
         //
         this->showAmbient->BackColor =
System::Drawing::SystemColors::ScrollBar;
         this->showAmbient->Location = System::Drawing::Point(552, 88);
         this->showAmbient->MaxLength = 10;
         this->showAmbient->Name = S"showAmbient";
         this->showAmbient->ReadOnly = true;
         this->showAmbient->Size = System::Drawing::Size(120, 22);
         this->showAmbient->TabIndex = 9;
         this->showAmbient->Text = S"";
         //
         // AmbientTemp
         //
         this->AmbientTemp->BackColor =
System::Drawing::Color::DimGray;
         this->AmbientTemp->Font = new
System::Drawing::Font(S"Microsoft Sans Serif", 9.75F,
System::Drawing::FontStyle::Regular,
System::Drawing::GraphicsUnit::Point, (System::Byte)0);
         this->AmbientTemp->ForeColor =
System::Drawing::Color::FromArgb((System::Byte)255, (System::Byte)192,
(System::Byte)128);
         this->AmbientTemp->Location = System::Drawing::Point(544, 64);
         this->AmbientTemp->Name = S"AmbientTemp";
         this->AmbientTemp->Size = System::Drawing::Size(136, 16);
         this->AmbientTemp->TabIndex = 18;
         this->AmbientTemp->Text = S"Ambient Temperature";
         //
         // Time
         //
         this->Time->BackColor = System::Drawing::Color::DimGray;
         this->Time->Font = new System::Drawing::Font(S"Microsoft Sans
Serif", 9.75F, System::Drawing::FontStyle::Regular,
System::Drawing::GraphicsUnit::Point, (System::Byte)0);
         this->Time->ForeColor =
System::Drawing::Color::FromArgb((System::Byte)255, (System::Byte)192,
(System::Byte)128);
         this->Time->Location = System::Drawing::Point(40, 64);
         this->Time->Name = S"Time";
         this->Time->Size = System::Drawing::Size(88, 16);
         this->Time->TabIndex = 19;
         this->Time->Text = S"Current Time";
         //
         // showTime
         //
         this->showTime->BackColor =
System::Drawing::SystemColors::ScrollBar;
         this->showTime->Location = System::Drawing::Point(32, 88);
         this->showTime->MaxLength = 20;
         this->showTime->Name = S"showTime";
         this->showTime->ReadOnly = true;

                 Santa Clara University Aerial Robotics Team              81
         this->showTime->Size = System::Drawing::Size(120, 22);
         this->showTime->TabIndex = 8;
         this->showTime->Text = S"";
         //
         // showStatus
         //
         this->showStatus->BackColor =
System::Drawing::SystemColors::ScrollBar;
         this->showStatus->Location = System::Drawing::Point(216, 88);
         this->showStatus->MaxLength = 50;
         this->showStatus->Name = S"showStatus";
         this->showStatus->ReadOnly = true;
         this->showStatus->Size = System::Drawing::Size(278, 22);
         this->showStatus->TabIndex = 23;
         this->showStatus->Text = S"";
         //
         // Status
         //
         this->Status->BackColor = System::Drawing::Color::DimGray;
         this->Status->Font = new System::Drawing::Font(S"Microsoft
Sans Serif", 9.75F, System::Drawing::FontStyle::Regular,
System::Drawing::GraphicsUnit::Point, (System::Byte)0);
         this->Status->ForeColor =
System::Drawing::Color::FromArgb((System::Byte)255, (System::Byte)192,
(System::Byte)128);
         this->Status->Location = System::Drawing::Point(312, 64);
         this->Status->Name = S"Status";
         this->Status->Size = System::Drawing::Size(72, 16);
         this->Status->TabIndex = 24;
         this->Status->Text = S"Link Status";
         //
         // pictureBox5
         //
         this->pictureBox5->BackColor =
System::Drawing::SystemColors::Window;
         this->pictureBox5->BackgroundImage =
(__try_cast<System::Drawing::Image * >(resources-
>GetObject(S"pictureBox5.BackgroundImage")));
         this->pictureBox5->Location = System::Drawing::Point(10, 16);
         this->pictureBox5->Name = S"pictureBox5";
         this->pictureBox5->Size = System::Drawing::Size(718, 128);
         this->pictureBox5->TabIndex = 25;
         this->pictureBox5->TabStop = false;
         //
         // Graphs
         //
         this->Graphs->BackColor =
System::Drawing::SystemColors::ControlDark;
         this->Graphs->Controls->Add(this->chart3d);
         this->Graphs->Location = System::Drawing::Point(4, 24);
         this->Graphs->Name = S"Graphs";
         this->Graphs->Size = System::Drawing::Size(968, 650);
         this->Graphs->TabIndex = 1;
         this->Graphs->Text = S"Graphs";
         this->Graphs->ToolTipText = S"This page displays various
graphs of flight information.";
         //
         // chart3d
         //

                 Santa Clara University Aerial Robotics Team             82
         this->chart3d->AlternateContextMenu = 0;
         this->chart3d->Chart->ChartTitle->IsVisible = true;
         this->chart3d->Chart->ChartTitle->Location =
System::Drawing::Point(323, 19);
         this->chart3d->Chart->ChartTitle->Size =
System::Drawing::Size(322, 22);
         this->chart3d->Chart->ChartTitle->Text = S"3D Plot";
         this->chart3d->Chart->ChartTitle->TextFormat->Font = new
System::Drawing::Font(S"Arial", 22,
System::Drawing::FontStyle::Regular,
System::Drawing::GraphicsUnit::Pixel);
         this->chart3d->Chart->ChartTitle->TextFormat-
>HorizontalAlignment = System::Drawing::StringAlignment::Center;
         this->chart3d->Chart->ChartTitle->TextFormat-
>VerticalAlignment = System::Drawing::StringAlignment::Center;
         this->chart3d->Chart->ChartType =
GraphicsServer::GSNet::Charting::ChartType::Scatter3D;
         this->chart3d->Chart->Grid->Axis3DX->AxisMode =
GraphicsServer::GSNet::Charting::AxisMode::ValueLinear;
         this->chart3d->Chart->Grid->Axis3DX->LabelProperties->Font =
new System::Drawing::Font(S"Arial", 10);
         this->chart3d->Chart->Grid->Axis3DX->MajorTickCount = 5;
         this->chart3d->Chart->Grid->Axis3DY->AxisMode =
GraphicsServer::GSNet::Charting::AxisMode::ValueLinear;
         this->chart3d->Chart->Grid->Axis3DY->LabelFormatMask = S"#0.";
         this->chart3d->Chart->Grid->Axis3DY->LabelProperties->Font =
new System::Drawing::Font(S"Arial", 10);
         this->chart3d->Chart->Grid->Axis3DY->MajorTickCount = 5;
         this->chart3d->Chart->Grid->Axis3DZ->AxisMode =
GraphicsServer::GSNet::Charting::AxisMode::ValueLinear;
         this->chart3d->Chart->Grid->Axis3DZ->LabelProperties->Font =
new System::Drawing::Font(S"Arial", 10);
         this->chart3d->Chart->Grid->Axis3DZ->MajorTickCount = 5;
         this->chart3d->Chart->Grid->AxisAngular->AxisMode =
GraphicsServer::GSNet::Charting::AxisMode::ValueLinear;
         this->chart3d->Chart->Grid->AxisAngular->LabelProperties->Font
= new System::Drawing::Font(S"Arial", 10);
         this->chart3d->Chart->Grid->AxisPie->AxisMode =
GraphicsServer::GSNet::Charting::AxisMode::Category;
         this->chart3d->Chart->Grid->AxisPie->LabelProperties->Font =
new System::Drawing::Font(S"Arial", 10);
         this->chart3d->Chart->Grid->AxisRadial->AxisMode =
GraphicsServer::GSNet::Charting::AxisMode::ValueLinear;
         this->chart3d->Chart->Grid->AxisRadial->LabelProperties->Font
= new System::Drawing::Font(S"Arial", 10);
         this->chart3d->Chart->Grid->AxisX->AxisMode =
GraphicsServer::GSNet::Charting::AxisMode::ValueLinear;
         this->chart3d->Chart->Grid->AxisX->AxisPosition =
GraphicsServer::GSNet::Charting::AxisPositionType::Variable;
         this->chart3d->Chart->Grid->AxisX->LabelProperties->Font = new
System::Drawing::Font(S"Arial", 10);
         this->chart3d->Chart->Grid->AxisX->MajorTickInterval = 1;
         this->chart3d->Chart->Grid->AxisXPrime->AxisMode =
GraphicsServer::GSNet::Charting::AxisMode::Category;
         this->chart3d->Chart->Grid->AxisXPrime->LabelProperties->Font
= new System::Drawing::Font(S"Arial", 10);
         this->chart3d->Chart->Grid->AxisY->AxisMode =
GraphicsServer::GSNet::Charting::AxisMode::ValueLinear;



                 Santa Clara University Aerial Robotics Team              83
         this->chart3d->Chart->Grid->AxisY->AxisPosition =
GraphicsServer::GSNet::Charting::AxisPositionType::Variable;
         this->chart3d->Chart->Grid->AxisY->LabelFormatMask = S"#0.";
         this->chart3d->Chart->Grid->AxisY->LabelProperties->Font = new
System::Drawing::Font(S"Arial", 10);
         this->chart3d->Chart->Grid->AxisY->MajorTickCount = 5;
         this->chart3d->Chart->Grid->AxisYPrime->AxisMode =
GraphicsServer::GSNet::Charting::AxisMode::ValueLinear;
         this->chart3d->Chart->Grid->AxisYPrime->LabelProperties->Font
= new System::Drawing::Font(S"Arial", 10);
         this->chart3d->Chart->Grid->Cage->Outline->Color =
System::Drawing::Color::FromArgb((System::Byte)228, (System::Byte)228,
(System::Byte)228);
         this->chart3d->Chart->Grid->Cage->Rotation->XAxisRotation =
15;
         this->chart3d->Chart->Grid->Cage->Rotation->YAxisRotation =
16;
         this->chart3d->Chart->Grid->Cage->WallBack-
>ExteriorBackground->Color = System::Drawing::Color::LightGray;
         this->chart3d->Chart->Grid->Cage->WallBack-
>ExteriorBackground->Transparency = 65;
         this->chart3d->Chart->Grid->Cage->WallBack->IsVisible = true;
         this->chart3d->Chart->Grid->Cage->WallBottom-
>ExteriorBackground->Color = System::Drawing::Color::LightGray;
         this->chart3d->Chart->Grid->Cage->WallBottom-
>ExteriorBackground->Transparency = 65;
         this->chart3d->Chart->Grid->Cage->WallBottom->IsVisible =
true;
         this->chart3d->Chart->Grid->Cage->WallFront-
>ExteriorBackground->Color = System::Drawing::Color::LightGray;
         this->chart3d->Chart->Grid->Cage->WallFront-
>ExteriorBackground->Transparency = 65;
         this->chart3d->Chart->Grid->Cage->WallFront->IsVisible =
false;
         this->chart3d->Chart->Grid->Cage->WallLeft-
>ExteriorBackground->Color = System::Drawing::Color::LightGray;
         this->chart3d->Chart->Grid->Cage->WallLeft-
>ExteriorBackground->Transparency = 65;
         this->chart3d->Chart->Grid->Cage->WallLeft->IsVisible = true;
         this->chart3d->Chart->Grid->Cage->WallRight-
>ExteriorBackground->Color = System::Drawing::Color::LightGray;
         this->chart3d->Chart->Grid->Cage->WallRight-
>ExteriorBackground->Transparency = 65;
         this->chart3d->Chart->Grid->Cage->WallRight->IsVisible =
false;
         this->chart3d->Chart->Grid->Cage->WallThickness = 8;
         this->chart3d->Chart->Grid->Cage->WallTop->ExteriorBackground-
>Color = System::Drawing::Color::LightGray;
         this->chart3d->Chart->Grid->Cage->WallTop->ExteriorBackground-
>Transparency = 65;
         this->chart3d->Chart->Grid->Cage->WallTop->IsVisible = false;
         this->chart3d->Chart->Grid->IsVisible = true;
         this->chart3d->Chart->Grid->Location =
System::Drawing::Point(29, 97);
         this->chart3d->Chart->Grid->Size = System::Drawing::Size(677,
520);
         this->chart3d->Chart->Grid->SurfaceChart->SideWallsFill->Color
= System::Drawing::Color::PaleGoldenrod;
         this->chart3d->Chart->Legend->AutoTextColor = false;

                 Santa Clara University Aerial Robotics Team              84
         this->chart3d->Chart->Legend->Border->BorderType =
GraphicsServer::GSNet::Charting::BorderType::Simple;
         this->chart3d->Chart->Legend->BoxAlignment =
GraphicsServer::GSNet::Charting::LegendBoxAlignment::LeftCenter;
         this->chart3d->Chart->Legend->BoxSize =
System::Drawing::Size(27, 20);
         this->chart3d->Chart->Legend->DisplayHorizontal = false;
         this->chart3d->Chart->Legend->IsVisible = true;
         this->chart3d->Chart->Legend->Location =
System::Drawing::Point(745, 162);
         this->chart3d->Chart->Legend->NumberOfColumns = 1;
         this->chart3d->Chart->Legend->Size =
System::Drawing::Size(193, 344);
         this->chart3d->Chart->Legend->TextFormat->Font = new
System::Drawing::Font(S"Arial", 10);
         this->chart3d->Chart->Legend->TextFormat->HorizontalAlignment
= System::Drawing::StringAlignment::Center;
         this->chart3d->Chart->Legend->TextFormat->VerticalAlignment =
System::Drawing::StringAlignment::Center;
         this->chart3d->Chart->Size = System::Drawing::Size(968, 650);
         this->chart3d->Dock = System::Windows::Forms::DockStyle::Fill;
         this->chart3d->Location = System::Drawing::Point(0, 0);
         this->chart3d->Name = S"chart3d";
         this->chart3d->Size = System::Drawing::Size(968, 650);
         this->chart3d->TabIndex = 0;
         this->chart3d->Load += new System::EventHandler(this,
gsNetWinChart1_Load);
         this->chart3d->Chart->ReconcileDataAndRecalcForCodeGen();
         //
         // Form1
         //
         this->AutoScaleBaseSize = System::Drawing::Size(6, 14);
         this->BackColor = System::Drawing::Color::Gray;
         this->ClientSize = System::Drawing::Size(976, 678);
         this->Controls->Add(this->tabControl1);
         this->Font = new System::Drawing::Font(S"Microsoft Sans
Serif", 9, System::Drawing::FontStyle::Regular,
System::Drawing::GraphicsUnit::Point, (System::Byte)0);
         this->ForeColor =
System::Drawing::Color::FromArgb((System::Byte)255, (System::Byte)224,
(System::Byte)192);
         this->Name = S"Form1";
         this->Text = S"Formation Flight Ground Station";
         this->tabControl1->ResumeLayout(false);
         this->AircraftInfo->ResumeLayout(false);
         this->ControlCenter->ResumeLayout(false);
         this->ChasePlaneInfo->ResumeLayout(false);
         this->LeadPlaneInfo->ResumeLayout(false);
         this->StatusInfo->ResumeLayout(false);
         this->Graphs->ResumeLayout(false);
         this->ResumeLayout(false);

      }
   public:
      void updateLeadInfo(string status, string alt, string speed,
string lat, string Long, string time,
                string head, string muff, string ambient,string
rpm,string heading, string volt)
            {

                 Santa Clara University Aerial Robotics Team              85
                this->showStatus->set_Text(status.c_str());
                this->showAltitude->set_Text(alt.c_str());
                this->showAirspeed->set_Text(speed.c_str());
                this->showLattitude->set_Text(lat.c_str());
                this->showLongitude->set_Text(Long.c_str());
                this->showTime->set_Text(time.c_str());
                this->showHead->set_Text(head.c_str());
                this->showMuffler->set_Text(muff.c_str());
                this->showAmbient->set_Text(ambient.c_str());
                this->showRPM->set_Text(rpm.c_str());
                this->showHeading->set_Text(heading.c_str());
                this->showVoltage->set_Text(volt.c_str());
            }
   public:
      void updateChaseInfo(string alt,string lonString, string
latString, string heading, string airSpeed)
      {
         this->showAltitude2->set_Text(alt.c_str());
         this->showLatitude2->set_Text(latString.c_str());
         this->showLongitude2->set_Text(lonString.c_str());
         this->showAirspeed2->set_Text(airSpeed.c_str());
         this->showHeading2->set_Text(heading.c_str());
      }

        //Updates status box
     public:
        void updateStatus(string s)
              {
                 this->showStatus->set_Text(s.c_str());
              }

// Starts the lead plane data collector and passes parsed data to the
GUI. Updates 3D graph.
   public:
      void Extracter()
      {
         RCATSensor rcat = RCATSensor();

          //this->updateStatus("Starting");

          rcats = &rcat;
          RCATSVec* rcatV = rcats->getRCATSVector();
          GPSVec* gpsV = rcats->getGPSSensor()->getGPSVector();

         string status, alt, speed, lat, Long, time, head, muff,
ambient, rpm, heading, volt;
         int Size1;
         int Size2;
         int index = 0;
         Series* leadseries = new Series();

          leadseries->set_SeriesName("Lead Plane");
          this->chart3d->Chart->AddSeries(leadseries);
          try{
             this->chart3d->Chart->GetSeriesDrawing(0)->LinesOn = true;
             this->chart3d->Chart->GetSeriesDrawing(1)->LinesOn = true;
             this->chart3d->Chart->GetSeriesDrawing(1)->Symbol->Size =
3;

                   Santa Clara University Aerial Robotics Team            86
              this->chart3d->Chart->GetSeriesDrawing(0)->Symbol->Size =
3;
         }
         catch(NullReferenceException * e) {}
         //leadseries->Symbol->Size = 3;

         this->Disconnect->Enabled = true;

         while(*extracterConnected)
         {
            Size1 = rcatV->size();
            Size2 = gpsV->size();

              Size1--;
              Size2--;

              if (Size1 == Size2) ;//printf("same, %d\n", Size1);
              else updateStatus("Vector Mismatch");

              if (Size1   > 0)
              {
                 double   Voltage = rcatV->at(Size1).voltage;
                 double   Rpm = rcatV->at(Size1).rpm;
                 double   Temp1 = (int)rcatV->at(Size1).temp1;
                 double   Temp2 = (int)rcatV->at(Size1).temp2;
                 double   Ambient = (int)rcatV->at(Size1).ambient;
                 double   Speed = rcatV->at(Size1).ias;
                 double   Alt = rcatV->at(Size1).alt;
                 double   Packet = rcatV->at(Size1).packet;

                double LongD = gpsV->at(Size2).longitude;
                LongD=MinToDec(LongD); //convert to decimal
                string LongH = gpsV->at(Size2).lonHemisphere;
                double Lat = gpsV->at(Size2).latitude;
                Lat=MinToDec(Lat); //convert to decimal
                string LatH = gpsV->at(Size2).latHemisphere;
                string Time = gpsV->at(Size2).time;
                double Heading = gpsV->at(Size2).courseOverGround;

                status = "Running";
                alt = boost::lexical_cast<string>(Alt);
                speed = boost::lexical_cast<string>(Speed);
                lat = boost::lexical_cast<string>(Lat);
                Long = boost::lexical_cast<string>(LongD);
                time = boost::lexical_cast<string>(Time);
                head = boost::lexical_cast<string>(Temp1);
                muff = boost::lexical_cast<string>(Temp2);
                ambient = boost::lexical_cast<string>(Ambient);
                rpm = boost::lexical_cast<string>(Rpm);
                heading = boost::lexical_cast<string>(Heading);
                volt = boost::lexical_cast<string>(Voltage);

                lat += LatH;
                Long += LongH;

                updateLeadInfo(status, alt, speed, lat, Long, time,
head, muff,
                   ambient, rpm, heading, volt);
                AddPoint3d(leadseries, Lat, LongD, Alt,index);

                   Santa Clara University Aerial Robotics Team            87
                if(index==2){ //only sets this when data is in there
                this->chart3d->Chart->Grid->Axis3DX->AxisScale =
GraphicsServer::GSNet::Charting::AxisScaleType::BestFit;
                this->chart3d->Chart->Grid->Axis3DZ->AxisScale =
GraphicsServer::GSNet::Charting::AxisScaleType::BestFit;
                }
                index++;
             }
             else updateStatus("Filling Vector");
         Sleep(1000);
         }
      }
   private: System::Void gsNetWinChart1_Load(System::Object * sender,
System::EventArgs * e)
           {
           }
      public:
         void AddPoint3d(Series* s, double Lat, double Long, double
Alt, int index)
         {
             s->SetValue(SeriesComponent::X,index,__box(Lat));
             s->SetValue(SeriesComponent::Y,index,__box(Alt));
             s->SetValue(SeriesComponent::Z,index,__box(Long));
             this->chart3d->Chart->ReconcileDataAndRecalcForCodeGen();
         }

      //Autopilot's connection thread. Updates the gui and creates
connection with
      //with the autopilot.
      private:
         void MPConnect()
         {
            micro = new TestMicropilot();
            *scuPlaneId=*scuPlaneId + 1;
            micro->initializePlane(*scuPlaneId,"COM1");
            micro->initCommandBuffer();
            this->Disconnect->Enabled = true;
            this->Follow->Enabled = true;
            this->Pattern->Enabled=true;
            this->Home->Enabled=true;
         }

     //Sends hold pattern command to the autopilot
     private:
        void holdPattern()
        {
           micro->sendFileToAutopilot("hold.fly");
           this->Pattern->Enabled=true;
        }

     //Sends go home command to the autopilot
     private:
        void goHome()
        {
           micro->sendFileToAutopilot("flyhome.fly");
           this->Home->Enabled=true;
        }




                 Santa Clara University Aerial Robotics Team             88
      //Disconnect thread. Distroys connections to lead and chase
planes.
      private:
         void MPDisconnect()
         {

              try {
              if(extracterConnected!=NULL) *extracterConnected=false;
              Thread::Sleep(1100);
              if(rcats!=NULL) rcats->dumpIntoFile("leadPlane.txt");
              if(rcats!=NULL) rcats->disconnect();
              Thread::Sleep(200);

              //Checks are neccessary, otherwise free might fail
              if(extracterConnected!=NULL) free(extracterConnected);
              if(rcats!=NULL) free(rcats);
              }
              catch(NullReferenceException * e) {}

              //Shut down chase plane if connected
              try {
                 if(mpTelemetry!=NULL) *mpTelemetry=false;
                 if(runFormation!=NULL) *runFormation=false;
                 Thread::Sleep(1500);
                 if(micro!=NULL) micro->shutDownPlane();
                 if(runFormation!=NULL) free(micro);
                 cprintf("Disconnect from Micropilot\n");
                 if(runFormation!=NULL) free(runFormation);
              }
              catch(NullReferenceException * e) {}


              this->connectLead->Enabled=true;
              this->Connect->Enabled = true;
              this->Follow->Enabled = false;
              this->Pattern->Enabled=false;
              this->Home->Enabled=false;
              this->StopFollow->Enabled=false;
              this->updateStatus("Disconnected");
          }

       //Stop formation thread. Stops the formation flying and updates
GUI.
       private:
          void stopFormation()
          {
          *runFormation=false;
            Thread::Sleep(3000);
            this->Follow->Enabled=true;
          }

      //Formation flying thread.
      private:
         void Formation()
         {
            unsigned int flightCounter=rcats->getGPSSensor()-
>getGPSVector()->size();

              while(*runFormation)

                   Santa Clara University Aerial Robotics Team           89
              {
               if(rcats->getRCATSVector()->size()>flightCounter)
               {
               //gets the location of the lead plane
               double lat=rcats->getGPSSensor()->getGPSVector()-
>at(flightCounter).latitude;
               string latH=rcats->getGPSSensor()->getGPSVector()-
>at(flightCounter).latHemisphere;
               double lon=rcats->getGPSSensor()->getGPSVector()-
>at(flightCounter).longitude;
               string lonH=rcats->getGPSSensor()->getGPSVector()-
>at(flightCounter).lonHemisphere;

                  //test in progress
                  latH="N";
                  lonH="W";


                  mpLock->WaitOne();
                  micro->printCurrentCommands();
                  micro->appendCoordinate(lon,lonH,lat,latH,400);
                  mpLock->ReleaseMutex();

                 //use every 5th lead plane position
                 flightCounter+=5;
                 }
        Thread::Sleep(200); //test sleep
    }

    //flush buffers when formation flying ends
    micro->flushFlightBuffers();
    this->StopFollow->Enabled=false;

}
   public: double MinToDec(double gps)//this function converts Minutes
to Decminal GPS
          {
            gps /= 100;
            int real = (int)gps;
            gps -= real;
            gps = gps*100/60;
            gps += real;
            gps = Math::Round(gps,6);
            return gps;
          }
   public: double MPToDec(long gps)     // this function does
conversion from MP gps coords to normal decimal points
          {
            double doubleGPS = (double)gps;
            doubleGPS=((doubleGPS/500000000.0)*180)/M_PI; //MP formula
            doubleGPS=Math::Round(doubleGPS,6); //round to 6 digit
precision
            doubleGPS=Math::Abs(doubleGPS); //getting rid of negative
for western hemisphere
            return doubleGPS;
          }
   public: int leaderDrawing;
   public: int chaserDrawing;



                    Santa Clara University Aerial Robotics Team          90
   //autopilots telemetry thread. Displays temlemetry on the GUI .
Updates 3D graph.
   private: void MPTelemetry()
      {
         Series* chaseseries = new Series();
         chaseseries->set_SeriesName("Chase Plane");

           this->chart3d->Chart->AddSeries(chaseseries);
try{
               this->chart3d->Chart->GetSeriesDrawing(0)->LinesOn = true;
               this->chart3d->Chart->GetSeriesDrawing(1)->LinesOn = true;
           }
           catch(NullReferenceException * e) {}

         int index = 0;
         while(*mpTelemetry)
         {
            mpLock->WaitOne();
            double Alt = Math::Round((micro-
>readMpVariable(MPFID_CURRENT_ALTITUDE)/(-8)));
            string alt=boost::lexical_cast<string>(Alt);

               long lat = micro->readMpVariable(MPFID_GPS_LATITUDE);
               double latD = MPToDec(lat);
               string latString=boost::lexical_cast<string>(latD);

               long lon = micro->readMpVariable(MPFID_GPS_LONGITUDE);
               double lonD = MPToDec(lon);
               string lonString=boost::lexical_cast<string>(lonD);

            //converted into mph
            string
airSpeed=boost::lexical_cast<string>(Math::Round((micro-
>readMpVariable(MPFID_CURRENT_SPEED)*0.6818182)));

            string heading=boost::lexical_cast<string>(micro-
>readMpVariable(MPFID_CURRENT_HEADING));

               mpLock->ReleaseMutex();

               //update GUI fields
               updateChaseInfo(alt, lonString, latString, heading,
airSpeed);

            //Plot it!
            AddPoint3d(chaseseries, latD, lonD, Alt,index);
            if(index==2)
            {
               this->chart3d->Chart->Grid->Axis3DX->AxisScale =
GraphicsServer::GSNet::Charting::AxisScaleType::BestFit;
               this->chart3d->Chart->Grid->Axis3DZ->AxisScale =
GraphicsServer::GSNet::Charting::AxisScaleType::BestFit;
            }
            index++;

               Thread::Sleep(1000);

           }
       }

                    Santa Clara University Aerial Robotics Team             91
   private: System::Void Connect_Click(System::Object *        sender,
System::EventArgs * e)
       {
         this->Connect->Enabled = false;

         Thread* ConnectThread = new Thread(new
ThreadStart(this,&Form1::MPConnect));
         ConnectThread->ApartmentState= ApartmentState::MTA;
         ConnectThread->IsBackground = true ;
         ConnectThread->Start();

         //wait for initialization
         Thread::Sleep(2000);
         //start telemetry polling
         //mpTelemetry=new bool;
         //*mpTelemetry=true;
         //Thread* MPTelemetryThread = new Thread(new
ThreadStart(this,&Form1::MPTelemetry));
         //MPTelemetryThread->ApartmentState= ApartmentState::MTA;
         //MPTelemetryThread->IsBackground = true ;
         //MPTelemetryThread->Start();
       }

private: System::Void Disconnect_Click(System::Object * sender,
System::EventArgs * e)
       {
         this->Disconnect->Enabled = false;
         Thread* DisconnectThread = new Thread(new
ThreadStart(this,&Form1::MPDisconnect));
         DisconnectThread->ApartmentState= ApartmentState::MTA;
         DisconnectThread->IsBackground = true ;
         DisconnectThread->Start();

      }

private: System::Void Follow_Click(System::Object * sender,
System::EventArgs * e)
       {
          this->Follow->Enabled=false;
          runFormation=new bool;
         *runFormation=true;
         Thread* FormationThread = new Thread(new
ThreadStart(this,&Form1::Formation));
         FormationThread->ApartmentState= ApartmentState::MTA;
         FormationThread->IsBackground = true ;
         FormationThread->Start();
         this->StopFollow->Enabled=true;
       }

private: System::Void StopFollow_Click(System::Object * sender,
System::EventArgs * e)
       {
         this->StopFollow->Enabled=false;
         Thread* StopFormationThread = new Thread(new
ThreadStart(this,&Form1::stopFormation));
         StopFormationThread->ApartmentState= ApartmentState::MTA;
         StopFormationThread->IsBackground = true ;
         StopFormationThread->Start();

                 Santa Clara University Aerial Robotics Team             92
       }

private: System::Void Home_Click(System::Object * sender,
System::EventArgs * e)
       {
         this->Home->Enabled=false;
         Thread* homeThread = new Thread(new
ThreadStart(this,&Form1::goHome));
         homeThread->ApartmentState= ApartmentState::MTA;
         homeThread->IsBackground = true ;
         homeThread->Start();
       }

private: System::Void button1_Click(System::Object * sender,
System::EventArgs * e)
       {
         this->connectLead->Enabled=false;
         extracterConnected=new bool;
         *extracterConnected=true;
         Thread* connectThread = new Thread(new
ThreadStart(this,&Form1::Extracter));
         connectThread->ApartmentState= ApartmentState::MTA;
         connectThread->IsBackground = true ;
         connectThread->Start();
         updateStatus("Initializing");

       }

private: System::Void Pattern_Click(System::Object * sender,
System::EventArgs * e)
       {
         this->Pattern->Enabled=false;
         Thread* patternThread = new Thread(new
ThreadStart(this,&Form1::holdPattern));
         patternThread->ApartmentState= ApartmentState::MTA;
         patternThread->IsBackground = true ;
         patternThread->Start();
       }

};
}


FORM1.CPP

#include "stdafx.h"
#include "Form1.h"
#include <windows.h>
#include "RCATSensor.h"
//#include <io.h>
//#include <fcntl.h>
//#include <iostream>

using namespace GUI;

int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine, int nCmdShow)
{

                 Santa Clara University Aerial Robotics Team   93
   AllocConsole();
   System::Threading::Thread::CurrentThread->ApartmentState =
System::Threading::ApartmentState::STA;
   Application::Run(new Form1());
   return 0;
}

// GenericSensor.h: interface for the GenericSensor class.
//
//////////////////////////////////////////////////////////////////////

#include "StringParser.h"
#include <string>

using namespace std;

/*********************************************************************
* class GenericSensor
*
* This is a generic sensor class describing what should our typical
sensor
* have. The class implementation is based on assumption that we are
* transmitting ASCII data.
*********************************************************************/

class GenericSensor
{
public:
   GenericSensor();
   virtual ~GenericSensor();

   //Set internal data structures with the string input and parsing
options
   virtual void setData(string input, CParseOptions option);



protected:

     //Use this function if this sensor is a separate thread.
     virtual void setData();

     //parsed data storage
     CStringParser parsedData;
};

// GenericSensor.cpp: implementation of the GenericSensor class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "GenericSensor.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

GenericSensor::GenericSensor()
{

                   Santa Clara University Aerial Robotics Team           94
}

GenericSensor::~GenericSensor()
{
}

void GenericSensor::setData()
{
}
void GenericSensor::setData(string input, CParseOptions option)
{
   parsedData.Parse(_T(input.c_str()),option);
}


// GPSSensor.h: interface for the GPSSensor class.
//
//////////////////////////////////////////////////////////////////////

//#include "GenericSensor.h"
//#include "Tserial_event.h"

#include "StringParser.h"
//#include <string>
#include <conio.h>
#include <vector>
#include <boost/lexical_cast.hpp>
using namespace std;
using namespace boost;

//Structure for gps data
struct gpsStorage_t {
   string time;
   double latitude;
   string latHemisphere;
   double longitude;
   string lonHemisphere;
   double speed;
   double courseOverGround;
   double magneticVariation;
   string mVariationDirection;
};

typedef vector<gpsStorage_t> GPSVec;

/*****************************************************
* class GPSSensor
*
* This class takes care of any GPS sensor. Currently it
* is only used to store GPS current and past information.
* Supported gps sentence is RMC.
*
* LIMITATIONS
* 1. The class cannot yet be a separate thread. The reason
*    for this is that we have inegrated rcats and gps
*    sentences together into one big sentence.
* 2. Speed and magnetic variation are not tested and need more
development!!!!!

                 Santa Clara University Aerial Robotics Team             95
*
* FUTURE PROGRESS
* 1. Make this class serial port compatible
* 2. Add support for more gps sentence types (like gga,vtg ...)
*****************************************************/
class GPSSensor
{
public:
   GPSSensor();
   virtual ~GPSSensor();

     void setData(string input, CParseOptions option);

     //Accessor methods for data from the GPS sensor
     string getTime();
     double getLatitude();
     string getLatHemisphere();
     double getLongitude();
     string getLonHemisphere();
     double getSpeed();
     double getCourseOverGround();
     double getMagneticVariation();
     string getMVariationDirection();

     //returns gps history information
     GPSVec * getGPSVector();

     //prints most current gps telemetry
     void printGPS();

protected:

     //current gps data is stored in this structure
     gpsStorage_t gpsStorage;

     //currently parsed values are stored here
     CStringParser parsedData;

     //gps history information
     GPSVec gpsVector;
};


// GPSSensor.cpp: implementation of the GPSSensor class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "GPSSensor.h"

#define STARTINDEX 1 //useful information in parsed data start from
this
                //index
#define SENTENCETYPE "RMC" //supported gps sentence type

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////



                   Santa Clara University Aerial Robotics Team           96
GPSSensor::GPSSensor()
{

}

GPSSensor::~GPSSensor()
{

}

void GPSSensor::setData(string input, CParseOptions option)
{
   int startPosition;
   string
time,latitude,longitude,speed,courseOverGround,magneticVariation;

    startPosition=input.find(SENTENCETYPE,1);

    input=input.substr(startPosition,input.length()-1-startPosition);

    parsedData.Parse(_T(input.c_str()),option);

    gpsStorage.time=parsedData.GetAt(STARTINDEX);
    latitude=parsedData.GetAt(STARTINDEX+2);
    gpsStorage.latHemisphere=parsedData.GetAt(STARTINDEX+3);
    longitude=parsedData.GetAt(STARTINDEX+4);
    gpsStorage.lonHemisphere=parsedData.GetAt(STARTINDEX+5);
    //speed=parsedData.GetAt(STARTINDEX+6);
    courseOverGround=parsedData.GetAt(STARTINDEX+7);
    //magneticVariation=parsedData.GetAt(STARTINDEX+9);
    //gpsStorage.mVariationDirection=parsedData.GetAt(STARTINDEX+10);

        try
         {
            gpsStorage.latitude=boost::lexical_cast<double>(latitude);
         }
         catch(bad_lexical_cast &)
         {
             gpsStorage.latitude=-1;
         }

       try
         {
            gpsStorage.longitude=boost::lexical_cast<double>(longitude);
         }
         catch(bad_lexical_cast &)
         {
             gpsStorage.longitude=-1;
         }

       try
         {

gpsStorage.courseOverGround=boost::lexical_cast<double>(courseOverGroun
d);
        }
        catch(bad_lexical_cast &)
        {
          gpsStorage.courseOverGround=-1;

                  Santa Clara University Aerial Robotics Team              97
         }


   //cprintf("Sizes are %d %d %d %d %d
!!!!\n",latitude.size(),longitude.size(),speed.size(),courseOverGround.
size(),magneticVariation.size());
   /*if(latitude.size()==0) gpsStorage.latitude=-1;
   else gpsStorage.latitude=boost::lexical_cast<double>(latitude);

    if(longitude.size()==0) gpsStorage.longitude=-1;
    else gpsStorage.longitude=boost::lexical_cast<double>(longitude);

    //if(speed.size()==0) gpsStorage.speed=-1;
    //else gpsStorage.speed=boost::lexical_cast<double>(speed);

    if(courseOverGround.size()==0) gpsStorage.courseOverGround=-1;
    else
gpsStorage.courseOverGround=boost::lexical_cast<double>(courseOverGroun
d);

   //if(magneticVariation.size()==0) gpsStorage.magneticVariation=-1;
   //else
gpsStorage.magneticVariation=boost::lexical_cast<double>(magneticVariat
ion);*/

    //save data in vector
    gpsVector.push_back(gpsStorage);
}

//ACCESSORS
string GPSSensor::getTime()
{
  return gpsStorage.time;
}

double GPSSensor::getLatitude()
{
   return gpsStorage.latitude;
   //if(gpsStorage.latitude.size()==0) return -1;
   //return boost::lexical_cast<double>(gpsStorage.latitude);
}

string GPSSensor::getLatHemisphere()
{
   return gpsStorage.latHemisphere;
}

double GPSSensor::getLongitude()
{
   return gpsStorage.longitude;
      //if(gpsStorage.longitude.size()==0) return -1;
   //return boost::lexical_cast<double>(gpsStorage.longitude);
}

string GPSSensor::getLonHemisphere()
{
  return gpsStorage.lonHemisphere;
}



                  Santa Clara University Aerial Robotics Team             98
double GPSSensor::getSpeed()
{
    return gpsStorage.speed;
  //if(gpsStorage.speed.size()==0) return -1;
  //return boost::lexical_cast<double>(gpsStorage.speed);
}

double GPSSensor::getCourseOverGround()
{
    return gpsStorage.courseOverGround;
  //if(gpsStorage.courseOverGround.size()==0) return -1;
  //return boost::lexical_cast<double>(gpsStorage.courseOverGround);
}

double GPSSensor::getMagneticVariation()
{
    return gpsStorage.magneticVariation;
  //if(gpsStorage.magneticVariation.size()==0) return -1;
  //return boost::lexical_cast<int>(gpsStorage.magneticVariation);
}

string GPSSensor::getMVariationDirection()
{
  return gpsStorage.mVariationDirection;
  }

void GPSSensor::printGPS()
{
  cprintf("%s %f %s %f %s %f %f %f %s\n",
  gpsStorage.time.c_str(),
  gpsStorage.latitude,
  gpsStorage.latHemisphere.c_str(),
  gpsStorage.longitude,
  gpsStorage.lonHemisphere.c_str(),
  gpsStorage.speed,
  gpsStorage.courseOverGround,
  gpsStorage.magneticVariation,
  gpsStorage.mVariationDirection.c_str());

}

GPSVec * GPSSensor::getGPSVector()
{
   return &gpsVector;
}

// RCATSensor.h: interface for the RCATSensor class.
//
//////////////////////////////////////////////////////////////////////

#ifndef RCATSENSOR_H
#define RCATSENSOR_H
#include "GenericSensor.h"
#include "GPSSensor.h"
#include "Tserial_event.h"

#include <vector>

using namespace std;

                    Santa Clara University Aerial Robotics Team          99
//The sensor data is saved in this type of structure
struct rcatsStorage_t
{
   double time;
   double packet;
   double temp1;
   double temp2;
   double rpm;
   double alt;
   double ias;
   double voltage;
   double gforce;
   double current;
   double iO1;
   double iO2;
   double alt_off;
   double ambient;
   double rtc;
};

typedef vector<rcatsStorage_t> RCATSVec;

/**********************************************************
* class RCATSensors
*
* This class is designed to handle serial communication with
* the rcats sensor unit. I added the GPS extension since we
* combined the GPS and RCATS sentences into one big sentence.
* Currently only GPS RMC sentence works. RCATSensor supports
* rcats sentence format as of 03/11/04. The class it self can
* serve 2 purposes:
* 1. Serial port listener. The data arrives to the RCATSensor
*     and it is stored in current storage space and in the history
*     vector. The data can be accessed from outside objects via
*     accessor functions
* 1. As a container for RCATS data with useful functions for
*     data processing. Note -currently there is no such function
*     but we can add something like voltageTooLow() or
convertMetersToinches
*
* KNOWN ISSUES:
* - gps info should not really be part of this class
* - it is too big and a bit messy. Lack of static functions to perform
*    operations on existing data (for example you already have the data
from
*    somewhere else and you want to use some processing functions
*    from this class. Well in reallity you do not really want to
*    create whole RCATSensor object and deal with turning off serial
*    listener. You just want to use the processing functions).
*
* POSSIBLE PROBLEMS
* - possible serial event problems in SerialEventaManager
* - shared resource (currently I assumed that only this class can
*    be a writer and everybody else are reading data from this class)
*
***********************************************************/

class RCATSensor : public Tserial_event, protected GenericSensor

                  Santa Clara University Aerial Robotics Team             100
{

public:

    //CONSTRUCTORS AND DESTRUCTORS

   //This constructor accepts serial com port name(eg. "COM1),
speed(eg. 9600)
   //and sentence maximum lenght. It STARTS automatically tries to
receive data
   //from the serial port. The default values are COM1, 9600b/s,
maximum sentence
   //length 170.
   RCATSSensor(char * comPort="COM1", int speed=9600);

   //This constructor does the same thing as the constructor described
above.
   //It has built in parameters comPort="COM1" and speed=9600.
   RCATSensor();

   //This Constructor accepts the telemetry data in a struct format. It
DOES NOT
   //try to automatically receive data from the serial port. Serial
port data
   //receiver feature can be later turned on with startSerialReceiver
function
   RCATSSensor(rcatsStorage_t storage);

    virtual ~RCATSensor();

   //RCATS FORMAT
   //PACKET TEMP1 TEMP2 RPM ALT IAS VOLTAGE GFORCE CURRENT I/O 1 I/O 2
ALT_OFF
   //AMBIENT RTC

    //Accessor methods for data from rcats sensor
    //double getTime();
    double getPacket();
    double getTemp1();
    double getTemp2();
    double getRpm();
    double getAlt();
    double getIas();
    double getVoltage();
    double getGforce();
    double getCurrent();
    double getIO1();
    double getIO2();
    double getAlt_off();
    double getAmbient();
    double getRtc();

    //dumps the RCATS and GPS history vectors into a file
    void dumpIntoFile(string fileName);

    //gets vector with sensor history
    RCATSVec * getRCATSVector();

    //get gps data

                     Santa Clara University Aerial Robotics Team          101
   GPSSensor * getGPSSensor();

   //Parses the input string into the internal data structure, using
   //parsing options described in CParseOptions class
   void setData(string input, CParseOptions option);

   //prints current rcats parameters
   void printRCATS();

   //updates the buffer when there is an event on the serial port
   //There is no need to call this method explicitly (or in other
   //words DO NOT WORRY about it). The method itself is passed as
   //a function pointer to T_serial_event event manager from connect
   //function.
   static void SerialEventManager(uint32 object, uint32 event);

   //Starts the serial port data collection thread.
   void startSerial(char * comPort, int speed);


protected:

   //current sensor values from rcats sensor
   rcatsStorage_t rcatsStorage;


   //current data
   GPSSensor gpsSensor;

   //history vector
   RCATSVec rcatsVector;

   //This function is internally called each time there is new data on
   //the serial port. It parses the raw string from the serial port,
puts
   //it into storage data structure and also in history vector.
   void setData();
};

#endif //RCATSENSOR_H


// RCATSensor.cpp: implementation of the RCATSensor class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "RCATSensor.h"
#include <fstream>

#define STARTINDEX 0 //Parsing beggining index

#define SENTENCETYPE "RCATS" //Supported RCATS sentence format

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

RCATSensor::RCATSSensor(char * comPort, int speed)

                 Santa Clara University Aerial Robotics Team             102
{
    startSerial(comPort,speed);
}

RCATSensor::RCATSSensor(struct rcatsStorage_t storage)
{
   rcatsStorage=storage;
}

RCATSensor::RCATSensor()
{
   startSerial("COM4",9600);
}

// Starts the serial data collection thread
void RCATSensor::startSerial(char * comPort, int speed)
{
   int erreur;
   Tserial_event();
   setManager(SerialEventManager);
   erreur = connect(comPort, speed, SERIAL_PARITY_NONE, 8, true);
}

RCATSensor::~RCATSensor()
{
   disconnect();
}

//ACCESSORS
//double RCATSensor::getTime()
//{
// return rcatsStorage.time;
    //return boost::lexical_cast<double>(rcatsStorage.time);
//}

double RCATSensor::getPacket()
{
   return rcatsStorage.packet;
   //return boost::lexical_cast<double>(rcatsStorage.packet);
}
double RCATSensor::getTemp1()
{
   return rcatsStorage.temp1;
   //return boost::lexical_cast<double>(rcatsStorage.temp1);
}
double RCATSensor::getTemp2()
{
   return rcatsStorage.temp2;
   //return boost::lexical_cast<double>(rcatsStorage.temp2);
}

double RCATSensor::getRpm()
{
   return rcatsStorage.rpm;
   //return boost::lexical_cast<int>(rcatsStorage.rpm);
}

double RCATSensor::getAlt()
{

                  Santa Clara University Aerial Robotics Team       103
    return rcatsStorage.alt;
    //return boost::lexical_cast<int>(rcatsStorage.alt);
}

double RCATSensor::getIas()
{
   return rcatsStorage.ias;
   //return boost::lexical_cast<double>(rcatsStorage.ias);
}

double RCATSensor::getVoltage()
{
   return rcatsStorage.voltage;
   //return boost::lexical_cast<double>(rcatsStorage.voltage);
}

double RCATSensor::getGforce()
{
   return rcatsStorage.gforce;
   //return boost::lexical_cast<double>(rcatsStorage.gforce);
}
double RCATSensor::getCurrent()
{
   return rcatsStorage.current;
   //return boost::lexical_cast<double>(rcatsStorage.current);
}
double RCATSensor::getIO1()
{
   return rcatsStorage.iO1;
   //return boost::lexical_cast<double>(rcatsStorage.iO1);
}
double RCATSensor::getIO2()
{
   return rcatsStorage.iO2;
   //return boost::lexical_cast<double>(rcatsStorage.iO2);
}
double RCATSensor::getAlt_off()
{
   return rcatsStorage.alt_off;
   //return boost::lexical_cast<double>(rcatsStorage.alt_off);
}
double RCATSensor::getAmbient()
{
   return rcatsStorage.ambient;
   //return boost::lexical_cast<double>(rcatsStorage.ambient);
}
double RCATSensor::getRtc()
{
   return rcatsStorage.rtc;
   //return boost::lexical_cast<int>(rcatsStorage.rtc);
}

RCATSVec * RCATSensor::getRCATSVector()
{

    return &rcatsVector;
}




                  Santa Clara University Aerial Robotics Team    104
//This function is internally called each time there is new data on
//the serial port. It parses the raw string from the serial port, puts
//it into storage data structure and also in history vector.
//
//IMPORTANT NOTE!!!!
//Pragma directive is necessary to disable run time stack checking
alert for this function. This
// is due to old c style function call back mechanism for handling
events from the
// serial ports. The directive affects only one function that is right
after pragma directive.
#pragma runtime_checks( "s", off )
void RCATSensor::setData()
{
   string temp;
   string temp1;
   //gets the most current sentence from the serial port.

// tokenizer<> tok(currentSentence);

// Enforces the size of the sentece

    temp=currentSentence;

    temp1=currentSentence;

    //cprintf("%s\n\n", temp.c_str());
    setData(temp,rcPlaneLine);
    //printRCATS();

// take care of the gps

    gpsSensor.setData(temp1,gpsLine);
    //gpsSensor.printGPS();
}

//Prints all sensor parameters in alphabetical order.
void RCATSensor::printRCATS()
{

       cprintf("%f %f %f %f %f %f %f %f %f %f %f %f %f %f\n",
       getAlt(),
       getAlt_off(),
       getAmbient(),
       getCurrent(),
       getGforce(),
       getIas(),
       getIO1(),
       getIO2(),
       getPacket(),
       getRpm(),
       getRtc(),
       getTemp1(),
       getTemp2(),
       getVoltage()
       );




                  Santa Clara University Aerial Robotics Team            105
}

/* ======================================================== */
/* =============== SerialEventManager      ================= */
/* This function is called on each serial data arival. It updates
   the current sensor info with the most recent sensor data */
/* ======================================================== */
void RCATSensor::SerialEventManager(uint32 object, uint32 event)
{
    //char *buffer;
    //int   size;
    Tserial_event *com;

        com = (Tserial_event *) object;

        if (com!=0)
    {
            switch(event)
            {
                case SERIAL_CONNECTED       :
                                                    cprintf("Connected ! \n");
                                                    break;
                case   SERIAL_DISCONNECTED      :
                                                    cprintf("Disonnected ! \n");
                                                    break;
                case   SERIAL_DATA_SENT     :
                                                    cprintf("Data sent ! \n");
                                                    break;
                case   SERIAL_RING          :
                                                    cprintf("DRING ! \n");
                                                    break;
                case   SERIAL_CD_ON         :
                                                    cprintf("Carrier Detected !
\n");
                                                    break;
                case   SERIAL_CD_OFF        :
                                                    cprintf("No more carrier !
\n");
                                             break;
                case   SERIAL_DATA_ARRIVAL :
                                   //NEEDS MORE TESTING

            if(com->currentSentence[com->currentSentence.size()-
1]=='\n' /*||
               com->nextSentence[com->currentSentence.size()-1]=='\r'
*/)
                              {
                                 if(com->currentSentence.size()>140)
                                 {
                                    //cprintf("%s\n\n",com-
>currentSentence.c_str());
                                    ((RCATSensor *)com)->setData();
                                 }
                                 com->currentSentence="";
                              }
                                        com->dataHasBeenRead();

                                                    break;
            }

                       Santa Clara University Aerial Robotics Team                 106
     }
}

void RCATSensor::setData(string input, CParseOptions option)
{
   int startPosition;

    startPosition=input.find(SENTENCETYPE,1);


    input=input.substr(startPosition,input.length()-1-startPosition);

    parsedData.Parse(_T(input.c_str()),option);


   //RCAT format
   //PACKET TEMP1 TEMP2 RPM ALT IAS VOLTAGE GFORCE CURRENT I/O 1 I/O 2
ALT_OFF
   //AMBIENT RTC

   string
packet,temp1,temp2,rpm,alt,ias,voltage,gforce,current,iO1,iO2,alt_off,a
mbient,rtc;

    //parsedData.Dump();

   //Adding one at the end to get rid of RCATS letter before the actual
value

    packet=parsedData.GetAt(STARTINDEX+1)+1;
    temp1=parsedData.GetAt(STARTINDEX+2)+1;
    temp2=parsedData.GetAt(STARTINDEX+3)+1;
    rpm=parsedData.GetAt(STARTINDEX+4)+1;
    alt=parsedData.GetAt(STARTINDEX+5)+1;
    ias=parsedData.GetAt(STARTINDEX+6)+1;
    voltage=parsedData.GetAt(STARTINDEX+7)+1;
    gforce=parsedData.GetAt(STARTINDEX+8)+1;
    current=parsedData.GetAt(STARTINDEX+9)+1;
    iO1=parsedData.GetAt(STARTINDEX+10)+1;
    iO2=parsedData.GetAt(STARTINDEX+11)+1;
    alt_off=parsedData.GetAt(STARTINDEX+12)+1;
    ambient=parsedData.GetAt(STARTINDEX+13)+1;


   //needs better implementation for the last one. This is end of line
problem
   rtc=parsedData.GetAt(STARTINDEX+14)+1;

    parsedData.Parse(_T(rtc.c_str()),endOfLine);

    rtc=parsedData.GetAt(0);
    rtc=rtc.substr(1,rtc.size());


    try { rcatsStorage.packet=boost::lexical_cast<double>(packet); }
    catch(bad_lexical_cast &) { rcatsStorage.packet=-1; }

    try { rcatsStorage.temp1=boost::lexical_cast<double>(temp1); }
    catch(bad_lexical_cast &) { rcatsStorage.temp1=-1; }

                  Santa Clara University Aerial Robotics Team             107
    try   { rcatsStorage.temp2=boost::lexical_cast<double>(temp2); }
    catch(bad_lexical_cast &){rcatsStorage.temp2=-1; }

    try   { rcatsStorage.rpm=boost::lexical_cast<double>(rpm); }
    catch(bad_lexical_cast &) {   rcatsStorage.rpm=-1;}

    try   {rcatsStorage.alt=boost::lexical_cast<double>(alt);
    catch(bad_lexical_cast &){ rcatsStorage.alt=-1;

    try   {rcatsStorage.ias=boost::lexical_cast<double>(ias);
    catch(bad_lexical_cast &) {   rcatsStorage.ias=-1; }

    try { rcatsStorage.voltage=boost::lexical_cast<double>(voltage); }
    catch(bad_lexical_cast &) {rcatsStorage.voltage=-1;

    try   { rcatsStorage.gforce=boost::lexical_cast<double>(gforce); }
    catch(bad_lexical_cast &) {   rcatsStorage.gforce=-1;

    try   { rcatsStorage.current=boost::lexical_cast<double>(current); }
    catch(bad_lexical_cast &) {   rcatsStorage.current=-1; }

    try   { rcatsStorage.iO1=boost::lexical_cast<double>(iO1); }
    catch(bad_lexical_cast &) {   rcatsStorage.iO1=-1; }

    try   { rcatsStorage.iO2=boost::lexical_cast<double>(iO2); }
    catch(bad_lexical_cast &) { rcatsStorage.iO2=-1; }

    try   { rcatsStorage.alt_off=boost::lexical_cast<double>(alt_off); }
    catch(bad_lexical_cast &) {   rcatsStorage.alt_off=-1; }

    try   { rcatsStorage.ambient=boost::lexical_cast<double>(ambient); }
    catch(bad_lexical_cast &) {   rcatsStorage.ambient=-1; }

    try { rcatsStorage.rtc=boost::lexical_cast<double>(rtc); }
    catch(bad_lexical_cast &) { rcatsStorage.rtc=-1; }

    //printRCATS();

    //save data in vector
    rcatsVector.push_back(rcatsStorage);
}

GPSSensor * RCATSensor::getGPSSensor()
{
   return & gpsSensor;
}

//dumps the RCATS and GPS history vectors into a file
void RCATSensor::dumpIntoFile(string fileName)
{
   ofstream fout;
   fout.open(fileName.c_str());
   if (fout.fail())
   {
      cprintf("rcats telemetry file opening failed\n");
      exit(1);
   }



                  Santa Clara University Aerial Robotics Team              108
    fout.clear();

    rcatsStorage_t tempRCATS;
    gpsStorage_t tempGPS;
    for(unsigned int i=0;i<rcatsVector.size();i++)
    {
       tempRCATS=rcatsVector.at(i);

      tempGPS=getGPSSensor()->getGPSVector()->at(i);
      fout<<tempGPS.time<<" "<<tempRCATS.alt<<" "<<tempGPS.latitude<<"
"<<tempGPS.longitude<<endl;
   }

    fout.close();
}


// StringParser.h: interface for the CStringParser class.
//
//////////////////////////////////////////////////////////////////////

#if
!defined(AFX_STRINGPARSER_H__E3708777_30A5_11D5_A483_00105ADBB436__INCL
UDED_)
#define
AFX_STRINGPARSER_H__E3708777_30A5_11D5_A483_00105ADBB436__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#ifndef assert
#define assert ASSERT
#endif

#include   <windows.h>
#include   <stdio.h>
#include   <tchar.h>
#include   <assert.h>
#include   <malloc.h>

namespace Char
{
   const TCHAR           NUL          = _T('\0');
   const TCHAR           TAB          = _T('\t');
   const TCHAR           QUOTE     = _T('\"');
   const TCHAR           SPACE     = _T(' ');
   const TCHAR           SEMICOL      = _T(';');
   const TCHAR           COMMA     = _T(',');
   const TCHAR           RETURN       = _T('\n');
};

class CParseOptions
{
public:
   CParseOptions( TCHAR chDelimiter,
               TCHAR chQuoter = Char::QUOTE,
               TCHAR chEscape = Char::NUL,
               bool bGather      = false,
               bool bRTrim    = true,

                    Santa Clara University Aerial Robotics Team           109
                   bool bKeepQuote   = false )
        :   m_chDelimiter( chDelimiter )
        ,   m_chQuoter( chQuoter )
        ,   m_chEscape( chEscape )
        ,   m_bGather( bGather )
        ,   m_bRTrim( bRTrim )
        ,   m_bKeepQuote( bKeepQuote )
   {}

   inline void SetDelimiter( TCHAR chDelimiter )
   inline void SetQuoter( TCHAR chQuoter )
   inline void SetEscape( TCHAR chEscape )

   inline TCHAR GetDelimiter() const
   inline TCHAR GetQuoter() const
   inline TCHAR GetEscape() const

   inline void NoDelimiter()
   inline void NoQuoter()
   inline void NoEscape()

   inline bool IsDelimiter( TCHAR ch ) const
   inline bool IsQuoter( TCHAR ch ) const
   inline bool IsEscape( TCHAR ch ) const

   inline void SetGather( bool bGather )
   inline bool IsGather() const

   inline void SetRTrim( bool bRTrim )
   inline bool IsRTrim() const

   inline void SetKeepQuote( bool bKeepQuote )
   inline bool IsKeepQuote() const

protected:

   TCHAR       m_chDelimiter;   //   to   separate each string
   TCHAR       m_chQuoter;      //   to   introduce a quoted string
   TCHAR       m_chEscape;      //   to   escape to next character
   bool        m_bGather;       //   to   treat adjacent delimiters as one
delimiter
   bool        m_bRTrim;        // to ignore empty trailing argument
   bool        m_bKeepQuote;    // to keep the quote of a quoted argument
};

//const CParseOptions     poCmdLine          ( Char::SPACE, Char::QUOTE,
Char::NUL, true );
//const CParseOptions     poCsvLine          ( Char::SEMICOL, Char::QUOTE,
Char::NUL, false );
//const CParseOptions    poTabbedCsvLine
  const CParseOptions    rcPlaneLine   ( Char::COMMA, Char::QUOTE,
Char::NUL );
  const CParseOptions    gpsLine ( Char::COMMA, Char::QUOTE, Char::NUL );
  const CParseOptions    endOfLine ( Char::RETURN, Char::QUOTE, Char::NUL
) ;

class CStringParser
{
public:

                     Santa Clara University Aerial Robotics Team             110
     CStringParser();
     virtual ~CStringParser();

     void Empty();
     int Parse( LPCTSTR pszStr, const CParseOptions& po );
     int GetCount() const;
     LPCTSTR GetAt(int nIndex) const;

     #ifndef NDEBUG
     void Dump() const;
     #endif // #ifndef NDEBUG

protected:

     BYTE*     m_pAlloc;
     TCHAR**      m_argv;
     int          m_argc;

   void Parse( LPCTSTR pszStr, const CParseOptions& po, int& numargs,
int& numchars, TCHAR** argv = NULL, TCHAR* args = NULL );

};

inline int CStringParser::GetCount() const
{
   return( m_argc );
}



#endif //
!defined(AFX_STRINGPARSER_H__E3708777_30A5_11D5_A483_00105ADBB436__INCL
UDED_)

// StringParser.cpp: implementation of the CStringParser class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "StringParser.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CStringParser::CStringParser()
{
   m_pAlloc    = NULL;
   m_argv         = NULL;
   m_argc         = 0;
}

CStringParser::~CStringParser()
{
   Empty();
}

void CStringParser::Empty()
{

                    Santa Clara University Aerial Robotics Team           111
    if ( m_pAlloc )
    {
       free( m_pAlloc );
       m_pAlloc     = NULL;
       m_argv          = NULL;
       m_argc          = 0;
    }
}

int CStringParser::Parse( LPCTSTR pszCmd, const CParseOptions& po )
{
   Empty();

    if ( pszCmd )
    {
       int            numargs;
       int            numchars;
       TCHAR*         pBuf;

          Parse( pszCmd, po, numargs, numchars );

          #ifndef NDEBUG
          assert( numargs > 0 );
          assert( numchars >= 0 );
          //_tprintf( _T("Count of args needed = %d\n"), numargs );
          //_tprintf( _T("Count of chars needed = %d\n"), numchars );
          #endif // #ifndef NDEBUG

      m_pAlloc = (BYTE*)malloc( sizeof(TCHAR) * numchars +
sizeof(TCHAR*) * numargs );
      if (!m_pAlloc) {
         ::SetLastError(ERROR_OUTOFMEMORY);
         return( 0 );
      }

          m_argv   = (TCHAR**)m_pAlloc;
          pBuf = (TCHAR*)( m_pAlloc + ( sizeof(TCHAR*) * numargs ) );
          Parse( pszCmd, po, numargs, numchars, m_argv, pBuf );
          m_argc   = numargs - 1;

          #ifndef NDEBUG
          assert( numargs > 0 );
          //_tprintf( _T("Count of args returned = %d\n"), numargs );
          //_tprintf( _T("Count of chars returned = %d\n"), numchars );
          #endif // #ifndef NDEBUG
    }
        return( m_argc );
}

void CStringParser::Parse( LPCTSTR pszStr, const CParseOptions& po,
int& numargs, int& numchars, TCHAR** argv, TCHAR* args )
{
    numchars   = 0;
    numargs    = 1;

   assert( (argv == NULL && args == NULL) || (argv != NULL && args !=
NULL) );

        if ( NULL == pszStr || *pszStr == _T('\0') )

                     Santa Clara University Aerial Robotics Team          112
     {
                 if ( argv ) argv[0] = NULL;
                 return;
         }

         LPCTSTR             p         = pszStr;
         bool                bInQuote = false;        /* true = inside quotes */
         bool                bCopyChar = true;        /* true = copy char to *args
*/
   bool                 bNeedArg = false; /* true = found delimiter and not
gathering */
    unsigned                 numslash     = 0;

     assert( *p != _T('\0') );

     if ( po.IsQuoter( *p ) && p[1] != _T('\0') )
     {
        bInQuote = true;
        p++;
     }

         /* loop on each argument */
         for (;;)
     {
                 if (*p == _T('\0'))
             {
                  if ( bNeedArg && !po.IsRTrim() )
                  {
                     /* scan an empty argument */
                     if (argv)
                         *argv++ = args;     /* store ptr to arg */
                     ++numargs;
                     /* add an empty argument */
                     if (args)
                         *args++ = _T('\0'); /* terminate string */
                     ++numchars;
                  }
                  break;               /* end of args */
             }

                 /* scan an argument */
                 if (argv)
                     *argv++ = args;       /* store ptr to arg */
                 ++numargs;

                 /* loop through scanning one argument */
                 for (;;)
             {
                  bCopyChar = true;
                  numslash = 0;

         if ( po.IsEscape( *p ) )
         {
            /*
            ** Rules:    2N backslashes + " ==> N backslashes and
begin/end quote
            **        2N+1 backslashes + " ==> N backslashes + literal "
                **          N backslashes ==> N backslashes
            */

                          Santa Clara University Aerial Robotics Team                113
               /* count number of backslashes for use below */
               do { ++p; ++numslash; } while (*p == po.GetEscape());
           }

           if ( po.IsQuoter( *p ) )
           {
              /*
              ** if 2N backslashes before, start/end quote, otherwise
              ** copy literally
              */
              if (numslash % 2 == 0)
              {
                 if (bInQuote)
                 {
                    if (p[1] == po.GetQuoter())
                       p++;     /* Double quote inside quoted string */
                    else         /* skip first quote char and copy second
*/
                         bCopyChar = po.IsKeepQuote();
                  } else
                     bCopyChar = po.IsKeepQuote();               /* don't copy
quote */
                  bInQuote = !bInQuote;
               }
               numslash /= 2;           /* divide numslash by two */
           }

           /* copy slashes */
           while (numslash--)
           {
              if (args)
                 *args++ = po.GetEscape();
              ++numchars;
           }

               /* if at end of arg, break loop */
               if ( *p == _T('\0') )
           {
                      break;
           }

           if ( !bInQuote && *p == po.GetDelimiter() )
           {
              do
              {
                 p++;
              } while ( po.IsGather() && *p == po.GetDelimiter() );
              bNeedArg = true;
              break;
           }

               /* copy character into argument */
               if (bCopyChar)
           {
                      if (args)
                          *args++ = *p;
                      ++numchars;
               }
               ++p;

                       Santa Clara University Aerial Robotics Team               114
            bNeedArg = false;
        }

        /* null-terminate the argument */
        if (args)
            *args++ = _T('\0');           /* terminate string */
        ++numchars;
    }

    /* We put one last argument in -- a null ptr */
    if (argv)
        *argv++ = NULL;
}

#ifndef NDEBUG
void CStringParser::Dump() const
{
   _tprintf( _T("Count of args = %d\n"), GetCount() );
   for ( int i = 0; i < GetCount(); i++ )
      _tprintf( _T("Arg[%d] = <%s>\n"), i, GetAt(i) );
}

LPCTSTR CStringParser::GetAt(int nIndex) const
{
   //not the quick and dirty fix of returning -1
   //assert( m_argv != NULL && nIndex >= 0 && nIndex < m_argc );
   if(!(m_argv != NULL && nIndex >= 0 && nIndex < m_argc ))
      return "-1";
   else
      return( m_argv[nIndex] );
}

#endif // #ifndef NDEBUG

// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
#pragma once


#define WIN32_LEAN_AND_MEAN          // Exclude rarely-used stuff from
Windows headers
// C RunTime Header Files
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>

// TODO: reference additional headers your program requires here

// stdafx.cpp : source file that includes just the standard includes
// GUI.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information

#include "stdafx.h"




                    Santa Clara University Aerial Robotics Team          115
// TestMicropilot.h: interface for the TestMicropilot class.
//
//////////////////////////////////////////////////////////////////////

#if
!defined(AFX_TESTMICROPILOT_H__B41C5AE0_8188_403A_9F0E_4D15FBE0D9C2__IN
CLUDED_)
#define
AFX_TESTMICROPILOT_H__B41C5AE0_8188_403A_9F0E_4D15FBE0D9C2__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#define VC_EXTRALEAN
#define WIN32_LEAN_AND_MEAN

#include <conio.h>
#include <windows.h>
#include <math.h>

// Micropilot's SDK stuff
#include <simdll.h>
#include <c-multi.h>
#include <mpconsts.h>
#include <mperrors.h>
#include <mpfields.h>
#include <mptypes.h>

#include <vector>
#include <iostream>
#include <fstream>

using namespace std;

#define START_UPLOAD_NUMBER 4 //When autopilot have multiple flyto
waypoints it won't get
                       //new waypoints from GCS until it passes
START_UPLOAD_NUMBER
                       //of waypoints
#define MAX_UPLOAD_NUMBER ((START_UPLOAD_NUMBER)+2) //Maximum number of
flyto waypoints for



typedef vector<string> StringVec;
typedef vector<StringVec *> VectorOfStringVectors;

const short MAXREADATTEMPT = 20; //maximum number of retries when
reading data from the autopilot


/**********************************************************************
************************
* TestMicropilot Class
*
* This is a wrapper interface class for Micropilot's autopilot SDK.
Proper communication with the
* autopilot has 3 main steps:

                 Santa Clara University Aerial Robotics Team              116
* 1. Initialize link to the autopilot
* 2. Use the autopilot
* 3. Shutdown connection with the autopilot

IMPORTANT: Currently altitude is not taken into account for formation
flying. Some important parts
of the code were commented out! For details contact opetrovic@scu.edu

Three command buffers hold current flight schedule of the chase plane.
First, beginCommands buffer
contains necessary initial commands for the autopilot. Second,
waypointBuffer contains the most current
list of target waypoints. Third, endCommandBuffer contains the commands
that are supposed to execute
if the plane passes all scheduled waypoints. When combined together,
these three buffers compose the
full flight schedule file for the autopilot. For example:

//beginCommands content starts here
imperial
takeoff
climb 400
waitclimb 1

//wayointBuffer content starts here
flyTo ( 121:40.8176999999996W,37:10.30549999999994N)
flyTo ( 121:40.84759999999915W,37:10.34690000000001N)
flyTo ( 121:40.88349999999991W,37:10.39499999999998N)
flyTo ( 121:40.92849999999999W,37:10.4351999999999N)
flyTo ( 121:40.95180000000073W,37:10.47260000000006N)

//endCommands content starts here
fixed
circuit
***********************************************************************
************************/
class TestMicropilot
{
public:
   //Constructor
   TestMicropilot();

  // destructor
  virtual ~TestMicropilot();

   /*******************************************************************
****************
   * appendCoordinate
   *
   * Appends 3D location to the inflight command buffers.
   ********************************************************************
***************/
   void appendCoordinate(double lat, string latH, double lon, string
lonH, int altitude);

   /*******************************************************************
****************
   * initializePlane
   *

                 Santa Clara University Aerial Robotics Team              117
   * Takes unique plane ID and communication commport(e.g. "COM1") Sets
up a connection
   * with the autopilot. A call to this function is neccessarry in
order to use the
   * autopilot.
   *
   * NOTE:When the connection is established uavXXX.dll is created by
the SDK. It can
   * not be erased while the app is executing. So if you make another
connection to
   * the plane use a different ID number.
   ********************************************************************
***************/
   void initializePlane(long scuPlaneId, char * comport);

   /*******************************************************************
****************
   * initCommandBuffer
   *
   * Initializes all the command buffers used to create formation .fly
file.
   ********************************************************************
***************/
   void initCommandBuffer(void);

   /*******************************************************************
****************
   * shutDownPlane
   *
   * Tears down the connection with the autopilot.
   ********************************************************************
***************/
   void shutDownPlane();

   /*******************************************************************
****************
   * printCurrentCommands
   *
   * Utility function that prints the whole current content of the
flight command buffer.
   ********************************************************************
***************/
   void printCurrentCommands();

   /*******************************************************************
****************
   * sendFileToAutopilot
   *
   * Sends .fly file(specify path in fileName) and sends it to the
autopilot
   ********************************************************************
***************/
   void sendFileToAutopilot(string fileName);

   /*******************************************************************
****************
   * readMpVariable
   *



                 Santa Clara University Aerial Robotics Team              118
   * Accepts the index of a Micropilot's autopilot variable (see
Micropilots manual for
   * variable indecies). Returns the value of a specific variable.
   ********************************************************************
***************/
   long readMpVariable(long index);

   /*******************************************************************
****************
   * flushFlightBuffers
   *
   * Flushes the in-flight command buffers.
   ********************************************************************
***************/
   void flushFlightBuffers();

private:

   long scuPlaneId; //current chase plane id
   int uploadedFlyTos; //number of uploaded flyto commands

   //the following vectors compose together formation .fly file
   StringVec beginCommands; //list of commands for .fly begining
   StringVec waypointBuffer;//list of "flyto" commands
   StringVec climbBuffer; //list of "climb" commands
   StringVec waitclimbBuffer;//list of "waitclimb" commands
   StringVec endCommands;//list of commands that go to end of .fly file
   VectorOfStringVectors commandBuffer; //big list that contains all
previous formation lists

   /*******************************************************************
****************
   * printStringVector
   *
   * Utility function that can print contents of the StringVec type of
vector to desired
   * output form.
   ********************************************************************
***************/
   static void printStringVector(StringVec vec, string
name="Vec",ostream& outs=cout);

   /*******************************************************************
****************
   * MinToDec
   *
   * Converts dddmm.nnn (d -degrees, m - minutes, n - decimal minutes)
into ddd.mmm
   * (d -degrees, m -decimal degrees) format.
   ********************************************************************
***************/
   double MinToDec(double gps);

   /*******************************************************************
****************
   * mpError
   *
   * Utility function that takes Micropilot's error code and displays
user's error message.

                 Santa Clara University Aerial Robotics Team              119
   * If errorCode is ok (errorCode!=MP_OK) nothing happens.
   ********************************************************************
***************/
   void mpError(long errorCode, char * message);

   /*******************************************************************
****************
   * checkInitialize
   *
   * Loops until the initialization step is successfuly accomplished.
   ********************************************************************
***************/
   void checkInitialize();

   /*******************************************************************
****************
   * modifyWaypoint
   *
   * Stub!!!!!!
   ********************************************************************
***************/
   void modifyWaypoint(double lat, string latH, double lon, string
lonH);

   /*******************************************************************
****************
   * appendWaypoint
   *
   * Appends gps location to the waypointBuffer.
   ********************************************************************
***************/
   void appendWaypoint(double lat, string latH, double lon, string
lonH);

   /*******************************************************************
****************
   * constructFlyFile
   *
   * Constructs a .fly file from the flight command buffers. Path of
the .fly file is
   * specified in fileName
   ********************************************************************
***************/
   void constructFlyFile(string fileName);

   /*******************************************************************
****************
   * appendAltitude
   *
   * Appends given altitude to the flight command buffers.
   ********************************************************************
***************/
   void appendAltitude(int alt);

   /*******************************************************************
****************
   * clearOldCoordinates
   *



                 Santa Clara University Aerial Robotics Team              120
   * Clears waypointBuffer coordinates that chase plane have already
passed.
   ********************************************************************
***************/
   long clearOldCoordinates(void);

   /*******************************************************************
****************
   * readyToUpload
   *
   * Returns true: If the autopilot is ready for the new upload
           false: If the autopilot can not handle new uploads at the
current moment
   ********************************************************************
***************/
   bool readyToUpload(long flyToIndex);

};

#endif //
!defined(AFX_TESTMICROPILOT_H__B41C5AE0_8188_403A_9F0E_4D15FBE0D9C2__IN
CLUDED_)

// TestMicropilot.cpp: implementation of the TestMicropilot class.
//
//////////////////////////////////////////////////////////////////////
#include <conio.h>
#include "stdafx.h"
#include "TestMicropilot.h"
#include ".\testmicropilot.h"
#include <boost\lexical_cast.hpp>

using namespace boost;

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
TestMicropilot::TestMicropilot()
{
long retVal=0;
long value=0;
scuPlaneId=0;
uploadedFlyTos=0;
}

TestMicropilot::~TestMicropilot()
{
}

/**********************************************************************
*************
* initializePlane
*
* Takes unique plane ID and communication commport(e.g. "COM1") Sets up
a connection
* with the autopilot. A call to this function is neccessarry in order
to use the
* autopilot. The take off command should be eventually taken out from
this command

                 Santa Clara University Aerial Robotics Team              121
*
* NOTE:When the connection is established uavXXX.dll is created by the
SDK. It can
* not be erased while the app is executing. So if you make another
connection to
* the plane use a different ID number.
***********************************************************************
************/
void TestMicropilot::initializePlane(long scuPlaneId, char * comport)
{
    long retVal = 0;
   this->scuPlaneId=scuPlaneId;

   /* This Funtion will create the uav#.dll */
    cprintf("\nCreateing UAV %d\n", scuPlaneId);
    retVal = mpCreate(scuPlaneId);
    mpError(retVal,"failed to create plane");

    /* This function will Initialize the comport to the planeId */
   cprintf("COM is %s \n",comport);
   retVal = mpInitLink(scuPlaneId, comport) ;
    mpError(retVal,"failed to initialize link to plane\n");

   // Neccessary initialization of simulator
   retVal=mpInitFly(scuPlaneId,"default.fly");
   mpError(retVal,"failed while initializing the simulator");

    //waits for the initialization success
   checkInitialize();

    /* Check the take off state, if it is equl to 1 then we are ready
to take off, set it to 2 */
    long value=0;
   retVal = mpReadVar(scuPlaneId, MPFID_TAKEOFF_STATE, &value,
AUTO_MODE, NORMAL_MODE);
    mpError(retVal,"Failed on reading\n");

   if (value ==1)
       {
             /* set takeoff state to "2" to initiate takeoff */
             retVal = mpWriteVar(scuPlaneId , MPFID_TAKEOFF_STATE , 2,
AUTO_MODE, NORMAL_MODE);
             mpError(retVal,"Failed on forcing a takeoff\n");
             cprintf(".......TakeOff Initiated!\n");
         }
     else
         {
           if(value==2)
           {
               cprintf("Already in the air \n");
           }
           else
           {
               //Do nothing for now!!!!!!!!!! NEEDS FIXING
               //cprintf(".......TakeOff Failed! VALUE=%d\n",value);
           }
         }
}



                  Santa Clara University Aerial Robotics Team             122
/**********************************************************************
*************
* mpError
*
* Utility function that takes Micropilot's error code and displays
user's error message.
* If errorCode is ok (errorCode!=MP_OK) nothing happens.
***********************************************************************
************/
void TestMicropilot::mpError(long errorCode,char * message)
{
    if ( errorCode != MP_OK )
         {
            cprintf("\nMP ERROR %d - %s \n", errorCode, message);
       }
}

/**********************************************************************
*************
* checkInitialize
*
* Loops until the initialization step is successfuly accomplished.
***********************************************************************
************/
void TestMicropilot::checkInitialize()
{
    long retVal = MP_MORE;
    long value = 0;
    long readCount = 0;

    while ((readCount < MAXREADATTEMPT) && (retVal != MP_OK))
    {
        ++readCount;
        cprintf("\n%d. Checking To See if Board Is Initialized",
readCount);
        retVal = mpReadVar(scuPlaneId, MPFID_KOUNTER, &value,
AUTO_MODE, QUICK_MODE);
        if (retVal != MP_OK)
        {
             cprintf(".......failed\n");
        }
        else
        {
             cprintf(".......passed\n");
        }
    }

   if (retVal != MP_OK)
   {
        cprintf("\nFailed, Board is Not Initialized\n");
        //exit(1);
   }
   else
   {
        cprintf("\nSuccess, Board is Initialized\n");
   }
}
/**********************************************************************
*************

                 Santa Clara University Aerial Robotics Team              123
* modifyWaypoint
*
* Stub!!!!!!
***********************************************************************
************/
void TestMicropilot::modifyWaypoint(double lat, string latH, double
lon, string lonH)
{
}

/**********************************************************************
*************
* MinToDec
*
* Converts dddmm.nnn (d -degrees, m - minutes, n - decimal minutes)
into ddd.mmm
* (d -degrees, m -decimal degrees) format.
***********************************************************************
************/
double TestMicropilot::MinToDec(double gps)//this function converts
Minutes to Decminal GPS
{
   gps /= 100;
   int real = (int)gps;
   gps -= real;
   gps = gps*100/60;
   gps += real;
   gps = System::Math::Round(gps,10);
   return gps;
}

/**********************************************************************
*************
* appendWaypoint
*
* Appends gps location to the waypointBuffer.
***********************************************************************
************/
void TestMicropilot::appendWaypoint(double lat, string latH, double
lon, string lonH)
{
   string insertString;

   /* Commented part is Micropilot's old style for GPS input
coordinates
   int latDegrees=(int)lat/100;
   int lonDegrees=(int)lon/100;


  double restLat=lat-latDegrees*100;
  double restLon=lon-lonDegrees*100;
  insertString="flyTo ( "+boost::lexical_cast<string>(lonDegrees)+":"
           + boost::lexical_cast<string>(restLon)+lonH+","
           + boost::lexical_cast<string>(latDegrees)+":"
           + boost::lexical_cast<string>(restLat)+latH+")"; */

   double restLat=MinToDec(lat);
  double restLon=MinToDec(lon);



                 Santa Clara University Aerial Robotics Team              124
   insertString="flyTo ( "+
boost::lexical_cast<string>(restLon)+lonH+","
            + boost::lexical_cast<string>(restLat)+latH+")";

    //put flyto command into waypointBuffer
    waypointBuffer.push_back(insertString);
}

/**********************************************************************
*************
* appendAltitude
*
* Appends given altitude to the command buffers. Micropilot's autopilot
needs 2
* commands in the .fly file to support altitude control. First is
"climb" command,
* second is "waitclimb" command. For details consult Micropilot's
manual.
***********************************************************************
************/
void TestMicropilot::appendAltitude(int alt)
{
   string altitudeString;
   altitudeString="climb "+boost::lexical_cast<string>(alt);
   climbBuffer.push_back(altitudeString);
}

/**********************************************************************
*************
* appendCoordinate
*
* Takes GPS coordinates(latitude, "N" or "S", longitude, "E" or "W",
altitude) and goes
* through the following process:
* 1. Clear old waypoints from the buffer – the autopilot is incapable
of removing
* old waypoints, so the GCS needs to continuously monitor the chase
plane waypoint progress
* in the air.
* 2. Append new waypoint to the buffer (in GPS longitude, latitude
format).
* 3. Optionally altitude can be added to the command buffer (CURRENTLY
COMMENTED OUT)
* 4. Construction of the flight schedule for the autopilot. When
ready, flight schedule is
* stored in test.fly file of the GCS home directory.
* 5. Send new flight schedule to the autopilot using Micropilot’s SDK.
   ********************************************************************
***************/
void TestMicropilot::appendCoordinate(double lon, string lonH, double
lat,
                              string latH, int alt)
{
   //parameter error checking
   if(lon<0.0 || lat<0.0 || alt<0 || lonH=="-1" || latH=="-1")
   {
      cprintf("%f,%s,%f,%s,%d
\n",lon,lonH.c_str(),lat,latH.c_str(),alt);
      cprintf("Invallid sensor info, skiping upload...\n");

                  Santa Clara University Aerial Robotics Team             125
        return;
    }

    //temporary file for formation schedule
    string fileName="test.fly";

    long clearNumber; //autopilot's currently executed command index
                  //calculated with respect to the flyto command
                  //buffer
    clearNumber=clearOldCoordinates();

    appendWaypoint(lat,latH,lon,lonH);

    //ALTITUDE IS CURRENTLY DISABLED
    //appendAltitude(alt);
    //waitclimbBuffer.push_back("waitclimb 0");

    if(!readyToUpload(clearNumber))
    {
       cprintf("NO UPLOAD\n");
       return;
    }

   //experimental
   int tempAltitude =
System::Math::Round((readMpVariable(MPFID_CURRENT_ALTITUDE)/(-8)));
   if(tempAltitude<375)
      beginCommands.at(2)="climb
"+boost::lexical_cast<string>(tempAltitude+5);
   else if(tempAltitude>425)
      beginCommands.at(2)="climb
"+boost::lexical_cast<string>(tempAltitude-5);
   else
      beginCommands.at(2)="climb
"+boost::lexical_cast<string>(tempAltitude);

   //cprintf("Target altitude is
%s!!!!!!\n",beginCommands.at(2).c_str());

    //constructing the fly file
    constructFlyFile(fileName);

    cprintf("Sending file...\n");
    sendFileToAutopilot(fileName);
    cprintf("Done Sending\n");

    ::Sleep(1000); //sleep is necessary
    cprintf("CURRENT COMMAND1 IS: %d\n",readMpVariable(1121));

    //skips initial commands, and goes straight to the flyto commands
    long retVal=0;
     retVal=mpThreadGoto(scuPlaneId,4,0,AUTO_MODE,NORMAL_MODE);
     mpError(retVal,"Goto Failed");
}

/**********************************************************************
*************
* clearOldCoordinates
*

                  Santa Clara University Aerial Robotics Team             126
* Clears waypointBuffer coordinates that chase plane have already
passed. Returns
* the index number of the currently executed command on the autopilot
minus the number
* of commands in the beginBuffer. Still in experimental stage.
***********************************************************************
************/
long TestMicropilot::clearOldCoordinates(void)
{
   long value=0;
   long retVal=0;

   //reading autopilot's current execution command index
   retVal = mpReadVar(scuPlaneId, MPFID_STEP, &value, AUTO_MODE,
NORMAL_MODE);
   mpError(retVal,"Error while reading the command buffer index\n");

    //debugging
    cprintf("First Value is %d\n",value);

   //calculates current execution command with respect to flyto command
buffer.
   //Can be negative when the autopilot is working on initial non-flyto
commands!
   //Can be out of range if the autopilot passed all waypoints!!
   value=value-beginCommands.size();

    if(!readyToUpload(value))
    {
       return value;
    }

   //if the autopilot finished flyto commands and executed commands
from endBuffer
   //delete total number of flyto waypoints from the last update
   if(value>(long)waypointBuffer.size())
   {
      value=uploadedFlyTos;
   }
   //value/=3;

    //debbugging
    cprintf("Real Value is %d\n",value);

    for(long i=0;i<value;i++)
    {
       for(unsigned int j=0;j<commandBuffer.size();j++)
       {
          if(commandBuffer.at(j)->size()>0)
          {
          commandBuffer.at(j)->erase(commandBuffer.at(j)->begin());
          }
       }
    }

    return value;
}




                    Santa Clara University Aerial Robotics Team           127
/**********************************************************************
*************
* readyToUpload
*
* Accepts: Current execution command index of the autopilot
* Returns true: If the autopilot is ready for the new upload
        false: If the autopilot can not handle new uploads at the
current moment
* This function is still experimental .
***********************************************************************
************/
bool TestMicropilot::readyToUpload(long flyToIndex)
{
   if(flyToIndex<START_UPLOAD_NUMBER &&
waypointBuffer.size()>=MAX_UPLOAD_NUMBER)
      return false;
   else
      return true;
}

/**********************************************************************
*************
* initCommandBuffer
*
* Initializes all the command buffers used to create formation .fly
file.
***********************************************************************
************/
void TestMicropilot::initCommandBuffer(void)
{
    //init command buffer
   //commandBuffer.push_back(&climbBuffer);
   //commandBuffer.push_back(&waitclimbBuffer);
   commandBuffer.push_back(&waypointBuffer);

    //init beginCommands
    beginCommands.push_back("imperial");
    beginCommands.push_back("takeoff");
    beginCommands.push_back("climb 400");
    beginCommands.push_back("waitclimb 1");

    //init endCommands
    //endCommands.push_back("");
     endCommands.push_back("fixed");
    endCommands.push_back("circuit");
    //endCommands.push_back("");
}

/**********************************************************************
*************
* printStringVector
*
* Utility function that can print contents of the StringVec type of
vector to desired
* output form.
***********************************************************************
************/
void TestMicropilot::printStringVector(StringVec vec, string
name,ostream& outs)

                  Santa Clara University Aerial Robotics Team             128
{
    for(unsigned int i=0;i<vec.size();i++)
       outs<<name.c_str()<<" ["<<i<<"] : "<<vec.at(i).c_str()<<endl;
}

/**********************************************************************
*************
* constructFlyFile
*
* Constructs a .fly file from the flight command buffers. Path of the
.fly file is
* specified in fileName. Remembers in uploadedFlyTo variable number of
uploaded
* flyTo commands
***********************************************************************
************/
void TestMicropilot::constructFlyFile(string fileName)
{
   ofstream fout;
   fout.open(fileName.c_str());
   if (fout.fail())
   {
      cprintf("inFlight.dat file opening failed\n");
      exit(1);
   }

    fout.clear();
    for(unsigned int i=0;i<beginCommands.size();i++)
    fout<<beginCommands.at(i).c_str()<<endl;

    uploadedFlyTos=0;

   for(unsigned int
i=0;i<waypointBuffer.size()&&i<=MAX_UPLOAD_NUMBER;i++)
   {
      for(unsigned int j=0;j<commandBuffer.size();j++)
      {
         if(commandBuffer.at(j)->size()>0)
         {
         uploadedFlyTos++;
         fout<<commandBuffer.at(j)->at(i)<<endl;
         }
      }
   }

    for(unsigned int i=0;i<endCommands.size();i++)
    fout<<endCommands.at(i).c_str()<<endl;

    fout.close();
}

/**********************************************************************
*************
* readMpVariable
*
* Accepts the index of a Micropilot's autopilot variable (see
Micropilots manual for
* variable indecies). Returns the value of a specific variable.



                    Santa Clara University Aerial Robotics Team           129
***********************************************************************
************/
long TestMicropilot::readMpVariable(long index)
{
   long value=0;
   long retVal=0;
   retVal = mpReadVar(scuPlaneId, index, &value, AUTO_MODE,
NORMAL_MODE);
    mpError(retVal,"Failed on reading\n");
   return value;
}

/**********************************************************************
*************
* printCurrentCommands
*
* Utility function that prints the whole current content of the flight
command buffer.
* Also prints the current command executed by the autopilot. It clears
the screen before
* printing.
***********************************************************************
************/
void TestMicropilot::printCurrentCommands()
{
   long stepCount=0;

  ::system("cls");
  cprintf("CURRENT COMMAND IS: %d\n",readMpVariable(1121));

   //MIGHT BE USEFUL LATER
   //System::Console::WriteLine("Longitude: "+readMpVariable(1095)+"
Latitude: "
   //+readMpVariable(1096)+"    Altitude: "+readMpVariable(1054));
   //System::Console::WriteLine("GPS OK: "+readMpVariable(1139)+
   //"   Satelites: "+readMpVariable(1148));
   //System::Console::WriteLine("Inflight Reset:
"+readMpVariable(1136)+
   //"   Inflight FAILURE: "+readMpVariable(1262));

  for(unsigned int i=0;i<beginCommands.size();i++)
  cprintf("[%d] %s\n",i+stepCount,beginCommands.at(i).c_str());

   stepCount=i-1;
   for(unsigned int i=0;i<waypointBuffer.size();i++)
   {
      for(unsigned int j=0;j<commandBuffer.size();j++)
      {
         if(commandBuffer.at(j)->size()>0)
         {
         stepCount++;
         cprintf("[%d] %s\n",stepCount,commandBuffer.at(j)-
>at(i).c_str());
         }
      }
   }

  stepCount++;
  for(unsigned int i=0;i<endCommands.size();i++)

                 Santa Clara University Aerial Robotics Team              130
    cprintf("[%d] %s\n",i+stepCount,endCommands.at(i).c_str());
}

/**********************************************************************
*************
* sendFileToAutopilot
*
* Sends .fly file(specify path in fileName) and sends it to the
autopilot
***********************************************************************
************/
void TestMicropilot::sendFileToAutopilot(string fileName)
{
   int x=0;
   long retVal=0;

  do {
   //cprintf("Sending new .fly \n");
   retVal=mpProgramInFlight(scuPlaneId,&x,(char
*)fileName.c_str(),AUTO_MODE);
  }while (retVal==MP_MORE);
  mpError(retVal,"Failed to upload .fly file\n");
}

/**********************************************************************
*************
* flushFlightBuffers
*
* Flushes the in-flight command buffers.
***********************************************************************
************/
void TestMicropilot::flushFlightBuffers()
{
   waypointBuffer.clear();
   climbBuffer.clear();
   waitclimbBuffer.clear();
}

/**********************************************************************
*************
* shutDownPlane
*
* Tears down the connection with the autopilot. CANNOT delete the
temporary uavXXX.dll
* file created by Micropilot's SDK
***********************************************************************
************/
void TestMicropilot::shutDownPlane()
{
    long retVal = 0;

    flushFlightBuffers();

   /* This function will Close the Simulator, if it fails will still
have other thing to do, so dont break */
    cprintf("Closing Simulator %d\n", scuPlaneId);
    retVal = mpCloseFly(scuPlaneId);
    mpError(retVal,"Could not close simulator");



                  Santa Clara University Aerial Robotics Team             131
    /* This function will Close the Link to the MP Autopilot, if it
fails we still have to attempt to delete plane
       so dont break */
    cprintf("Closing Link to Plane: %d\n", scuPlaneId);
    retVal = mpCloseLink(scuPlaneId);
    mpError(retVal,"Could Not Close the Link to the MP Autopilot");

     /* This function will delete the uav */
     cprintf("Deleting Plane: %d\n", scuPlaneId);
     retVal = mpDelete(scuPlaneId);
    mpError(retVal,"Could Not Delete Plane: %d");
}



/* --------------------------------------------------------------------
---- --
--
--
--                        PC serial port connection object
--
--                           for event-driven programs
--
--
--
--
--
--
--
-- Copyright @ 2001-2002      Thierry Schneider
--
--                            thierry@tetraedre.com
--
--
--
--
--
--
--
-- --------------------------------------------------------------------
---- --
--
--
-- Filename : Tserial_event.cpp
--
-- Author    : Thierry Schneider
--
-- Created : April 4th 2000
--
-- Modified : June 22nd 2002
--
-- Plateform: Windows 95, 98, NT, 2000, XP (Win32)
--
-- --------------------------------------------------------------------
---- --
--
--
-- This software is given without any warranty. It can be distributed
--

                  Santa Clara University Aerial Robotics Team             132
-- free of charge as long as this header remains, unchanged.
--
--
--
-- --------------------------------------------------------------------
---- --
--
--
-- 01.04.24      Comments added
--
-- 01.04.28      Bug 010427 corrected. OnDisconnectedManager was not
--
--                initialized
--
-- 01.04.28      connect() function prototype modified to handle 7-bit
--
--                communication
--
-- 01.04.29      "ready" field added to remove a bug that occured
during      --
--                 reconnect (event manager pointers cleared)
--
--                 I removed the "delete" in Tserial_event_thread_start
--
--                 because it was destroying the object even if we
would      --
--                 use it again
--
--
--
-- 02.01.30      Version 2.0 of the serial event object
--
--
--
--
--
-- 02.06.22      - wait for the thread termination before
--
--                 quiting or restarting
--
--               - "owner" field added to be able to call C++ object
from    --
--                  the event manager routine
--
--               - Correction of a bug that occured when receiving data
--
--                 (setting twice the SIG_READ_DONE event)
--
--
--
--
--
--
--
-- --------------------------------------------------------------------
---- --
--
--



                 Santa Clara University Aerial Robotics Team              133
--    Note to Visual C++ users: Don't forget to compile with the
--
--      "Multithreaded" option in your project settings
--
--
--
--          See   Project settings
--
--                    |
--
--                    *--- C/C++
--
--                           |
--
--                           *--- Code generation
--
--                                        |
--
--                                        *---- Use run-time library
--
--                                                      |
--
--                                                      *----
Multithreaded --
--
--
--
--
--
--
-- --------------------------------------------------------------------
---- */


#ifndef TSERIAL_EVENT_H
#define TSERIAL_EVENT_H

#include <windows.h>

#include <string>

using namespace std;


#define SERIAL_PARITY_NONE 0
#define SERIAL_PARITY_ODD 1
#define SERIAL_PARITY_EVEN 2

#define   SERIAL_CONNECTED           0
#define   SERIAL_DISCONNECTED        1
#define   SERIAL_DATA_SENT           2
#define   SERIAL_DATA_ARRIVAL        3
#define   SERIAL_RING                4
#define   SERIAL_CD_ON               5
#define   SERIAL_CD_OFF              6

typedef unsigned long uint32;
typedef void (*type_myCallBack) (uint32 object, uint32 event);



                    Santa Clara University Aerial Robotics Team           134
#ifndef   __BORLANDC__
#define   bool BOOL
#define   true TRUE
#define   false FALSE
#endif


#define SERIAL_SIGNAL_NBR 7             // number of events in the thread
#define SERIAL_MAX_RX     256           // Input buffer max size
#define SERIAL_MAX_TX     256           // output buffer max size


/* --------------------------------------------------------------------
*/
/* ----------------------------- Tserial ----------------------------
*/
/* --------------------------------------------------------------------
*/
class Tserial_event
{
    // -------------------------------------------------------- //
protected:



    bool            ready;
    bool            check_modem;
    char            port[10];                               // port name
"com1",...
    int             rate;                                   // baudrate
    int             parityMode;

     HANDLE         serial_events[SERIAL_SIGNAL_NBR];       // events to wait
on
    unsigned int threadid;                                  //   ...
    HANDLE        serial_handle;                            //   ...
    HANDLE        thread_handle;                            //   ...
    OVERLAPPED    ovReader;                                 //   Overlapped
structure for ReadFile
    OVERLAPPED    ovWriter;                                 // Overlapped
structure for WriteFile
    OVERLAPPED    ovWaitEvent;                              // Overlapped
structure for WaitCommEvent
    char          tx_in_progress;                           // BOOL indicating
if a WriteFile is
                                                            // in progress
    char            rx_in_progress;                         // BOOL indicating
if a ReadFile is
                                                            // in progress
    char           WaitCommEventInProgress;
    char           rxBuffer[SERIAL_MAX_RX];
    int            max_rx_size;
    int            received_size;
    char           txBuffer[SERIAL_MAX_TX];
    int            tx_size;
    DWORD          dwCommEvent;                             // to store the
result of the wait

     type_myCallBack manager;

                   Santa Clara University Aerial Robotics Team                   135
    // ............................................................
    void          OnCharArrival    (char c);
    void          OnEvent          (unsigned long events);


    // ++++++++++++++++++++++++++++++++++++++++++++++
    // .................. EXTERNAL VIEW .............
    // ++++++++++++++++++++++++++++++++++++++++++++++
public:
   void setData();
    void         *owner;                // do what you want with this



    void            run          (void);
                    Tserial_event();
                   ~Tserial_event();

  int      connect (char *port_arg, int rate_arg, int parity_arg,
                                char ByteSize , bool modem_events);

    void            setManager          (type_myCallBack manager);
    void            setRxSize           (int size);
    void            sendData            (char *buffer, int size);
    int             getNbrOfBytes       (void);
    int             getDataInSize       (void);
    char *          getDataInBuffer     (void);
    void            dataHasBeenRead     (void);
    void            disconnect          (void);

  string currentSentence;
  string nextSentence;
};
/* --------------------------------------------------------------------
*/

#endif TSERIAL_EVENT_H




/* --------------------------------------------------------------------
---- --
--
--
--                        PC serial port connection object
--
--                           for event-driven programs
--
--
--
--
--

                    Santa Clara University Aerial Robotics Team           136
--
--
-- Copyright @ 2001-2002      Thierry Schneider
--
--                            thierry@tetraedre.com
--
--
--
--
--
--
--
-- --------------------------------------------------------------------
---- --
--
--
-- Filename : Tserial_event.cpp
--
-- Author    : Thierry Schneider
--
-- Created : April 4th 2000
--
-- Modified : June 22nd 2002
--
-- Plateform: Windows 95, 98, NT, 2000, XP (Win32)
--
-- --------------------------------------------------------------------
---- --
--
--
-- This software is given without any warranty. It can be distributed
--
-- free of charge as long as this header remains, unchanged.
--
--
--
-- --------------------------------------------------------------------
---- --
--
--
-- 01.04.24      Comments added
--
-- 01.04.28      Bug 010427 corrected. OnDisconnectedManager was not
--
--                initialized
--
-- 01.04.28      connect() function prototype modified to handle 7-bit
--
--                communication
--
-- 01.04.29      "ready" field added to remove a bug that occured
during    --
--                 reconnect (event manager pointers cleared)
--
--                 I removed the "delete" in Tserial_event_thread_start
--
--                 because it was destroying the object even if we
would    --



                 Santa Clara University Aerial Robotics Team              137
--                  use it again
--
--
--
-- 02.01.30       Version 2.0 of the serial event object
--
--
--
--
--
-- 02.06.22       - wait for the thread termination before
--
--                  quiting or restarting
--
--                - "owner" field added to be able to call C++ object
from    --
--                   the event manager routine
--
--                - Correction of a bug that occured when receiving data
--
--                  (setting twice the SIG_READ_DONE event)
--
--
--
--
--
--
--
-- --------------------------------------------------------------------
---- --
--
--
--    Note to Visual C++ users: Don't forget to compile with the
--
--      "Multithreaded" option in your project settings
--
--
--
--          See   Project settings
--
--                    |
--
--                    *--- C/C++
--
--                           |
--
--                           *--- Code generation
--
--                                        |
--
--                                        *---- Use run-time library
--
--                                                       |
--
--                                                       *----
Multithreaded --
--
--



                  Santa Clara University Aerial Robotics Team              138
--
--
--
--
-- --------------------------------------------------------------------
---- */




/* --------------------------------------------------------------------
-- */

#define STRICT
#include "stdafx.h"
//#include <stdio.h>
//#include <stdlib.h>
//#include <string.h>
#include <process.h>
//#include <conio.h>
//#include <windows.h>


#include "Tserial_event.h"
#include ".\tserial_event.h"

#define   SIG_POWER_DOWN      0
#define   SIG_READER          1
#define   SIG_READ_DONE       2    // data received has been read
#define   SIG_WRITER          3
#define   SIG_DATA_TO_TX      4    // data waiting to be sent
#define   SIG_MODEM_EVENTS    5
#define   SIG_MODEM_CHECKED   6

void Tserial_event_thread_start(void *arg);

typedef unsigned (WINAPI *PBEGINTHREADEX_THREADFUNC) (LPVOID
lpThreadParameter);
typedef unsigned *PBEGINTHREADEX_THREADID;

/* --------------------------------------------------------------------
-- */
/* --------------------- Tserial_event_thread_start -----------------
-- */
/* --------------------------------------------------------------------
-- */
/**
     This function is not part of the Tserial_event object. It is simply
used
     to start the thread from an external point of the object.
*/
void Tserial_event_thread_start(void *arg)
{
     class Tserial_event *serial_unit;

    serial_unit = (Tserial_event *) arg;

    if (serial_unit!=0)
        serial_unit->run();

                   Santa Clara University Aerial Robotics Team             139
}

/* --------------------------------------------------------------------
*/
/* -------------------------    Tserial_event -------------------------
*/
/* --------------------------------------------------------------------
*/
Tserial_event::Tserial_event()
{
    int i;

     currentSentence="";
     nextSentence="";

      ready            =   false;
      parityMode       =   SERIAL_PARITY_NONE;
      port[0]          =   0;
      rate             =   0;
      threadid         =   0;
      serial_handle    =   INVALID_HANDLE_VALUE;
      thread_handle    =   0;
      owner            =   0;
      tx_in_progress   =   0;
      rx_in_progress   =   0;
      max_rx_size      =   1;
      tx_size          =   0;
      received_size    =   0;
      check_modem      =   false;

      manager          = 0;

      /* --------------------------------------------------------------
*/
    // creating Events for the different sources
    for (i=0; i<SERIAL_SIGNAL_NBR; i++)
    {
        if ((i==SIG_READER) || (i==SIG_WRITER) ||
(i==SIG_MODEM_EVENTS))
             serial_events[i] = CreateEvent(NULL, TRUE, FALSE, NULL);
// Manual Reset
        else
             serial_events[i] = CreateEvent(NULL, FALSE, FALSE, NULL);
// Auto reset
    }
}

/* --------------------------------------------------------------------
*/
/* --------------------------    ~Tserial_event -----------------------
*/
/* --------------------------------------------------------------------
*/
Tserial_event::~Tserial_event()
{
    int i;

      if (thread_handle!=0)
          WaitForSingleObject(thread_handle, 2000);

                   Santa Clara University Aerial Robotics Team            140
    thread_handle = 0;

    /* -------------------------------------------------------- */
    for (i=0; i<SERIAL_SIGNAL_NBR; i++)          // deleting the events
    {
        if (serial_events[i]!=INVALID_HANDLE_VALUE)
            CloseHandle(serial_events[i]);
        serial_events[i] = INVALID_HANDLE_VALUE;
    }

    if (serial_handle!=INVALID_HANDLE_VALUE)
        CloseHandle(serial_handle);
    serial_handle = INVALID_HANDLE_VALUE;
}
/* --------------------------------------------------------------------
*/
/* --------------------------    disconnect   -------------------------
*/
/* --------------------------------------------------------------------
*/
void Tserial_event::disconnect(void)
{
    ready = false;
    SetEvent(serial_events[SIG_POWER_DOWN]);

    if (thread_handle!=0)
        WaitForSingleObject(thread_handle, 2000);
    thread_handle = 0;
}
/* --------------------------------------------------------------------
*/
/* --------------------------     connect      -------------------------
*/
/* --------------------------------------------------------------------
*/
/**
     Serial port, file and overlapped structures initialization
*/
int Tserial_event::connect (char *port_arg, int rate_arg, int
parity_arg,
                              char ByteSize , bool modem_events)
{
    int erreur;
    DCB dcb;
    int i;
    COMMTIMEOUTS cto = { 0, 0, 0, 0, 0 };

    /* --------------------------------------------- */
    if (serial_handle!=INVALID_HANDLE_VALUE)
        CloseHandle(serial_handle);
    serial_handle = INVALID_HANDLE_VALUE;

    if (port_arg!=0)
    {
        strncpy(port,    port_arg, 10);
        rate         =   rate_arg;
        parityMode =     parity_arg;
        check_modem =    modem_events;



                  Santa Clara University Aerial Robotics Team              141
        erreur      = 0;
        ZeroMemory(&ovReader   ,sizeof(ovReader)   );          // clearing the
overlapped
        ZeroMemory(&ovWriter   ,sizeof(ovWriter)   );
        ZeroMemory(&ovWaitEvent,sizeof(ovWaitEvent));
        memset(&dcb,0,sizeof(dcb));

        /* ------------------------------------------------------------
-------- */
        // set DCB to configure the serial port
        dcb.DCBlength       = sizeof(dcb);

        /* ---------- Serial Port Config ------- */
        dcb.BaudRate        = rate;

        switch(parityMode)
        {
            case SERIAL_PARITY_NONE:
                            dcb.Parity          = NOPARITY;
                            dcb.fParity         = 0;
                            break;
            case SERIAL_PARITY_EVEN:
                            dcb.Parity          = EVENPARITY;
                            dcb.fParity         = 1;
                            break;
            case SERIAL_PARITY_ODD:
                            dcb.Parity          = ODDPARITY;
                            dcb.fParity         = 1;
                            break;
        }


        dcb.StopBits          = ONESTOPBIT;
        dcb.ByteSize          = (BYTE) ByteSize;

        dcb.fOutxCtsFlow      =   0;
        dcb.fOutxDsrFlow      =   0;
        dcb.fDtrControl       =   DTR_CONTROL_DISABLE;
        dcb.fDsrSensitivity   =   0;
        dcb.fRtsControl       =   RTS_CONTROL_DISABLE;
        dcb.fOutX             =   0;
        dcb.fInX              =   0;

        /* ----------------- misc parameters ----- */
        dcb.fErrorChar      = 0;
        dcb.fBinary         = 1;
        dcb.fNull           = 0;
        dcb.fAbortOnError   = 0;
        dcb.wReserved       = 0;
        dcb.XonLim          = 2;
        dcb.XoffLim         = 4;
        dcb.XonChar         = 0x13;
        dcb.XoffChar        = 0x19;
        dcb.EvtChar         = 0;

        /* ------------------------------------------------------------
-------- */
        serial_handle    = CreateFile(port, GENERIC_READ |
GENERIC_WRITE,

                 Santa Clara University Aerial Robotics Team                     142
                        0, NULL, OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
                        // opening serial port

          ovReader.hEvent    = serial_events[SIG_READER];
          ovWriter.hEvent    = serial_events[SIG_WRITER];
          ovWaitEvent.hEvent = serial_events[SIG_MODEM_EVENTS];

          if (serial_handle     != INVALID_HANDLE_VALUE)
          {
              if (check_modem)
              {
                   if(!SetCommMask(serial_handle, EV_RING | EV_RLSD))
                       erreur = 1;
              }
              else
              {
                   if(!SetCommMask(serial_handle, 0))
                       erreur = 1;
              }


                 // set timeouts
                 if(!SetCommTimeouts(serial_handle,&cto))
                     erreur = 2;

                 // set DCB
                 if(!SetCommState(serial_handle,&dcb))
                     erreur = 4;
          }
          else
                 erreur = 8;
   }
   else
          erreur = 16;


   /* --------------------------------------------- */
   for (i=0; i<SERIAL_SIGNAL_NBR; i++)
   {
       if (serial_events[i]==INVALID_HANDLE_VALUE)
           erreur = 32;
   }

    /* --------------------------------------------- */
    if (erreur!=0)
    {
         CloseHandle(serial_handle);
         serial_handle = INVALID_HANDLE_VALUE;
    }
    else
    {
         // start thread
      SetThreadPriority(thread_handle,THREAD_PRIORITY_TIME_CRITICAL);
         thread_handle = (HANDLE) _beginthreadex(NULL,0,
                   (PBEGINTHREADEX_THREADFUNC)
Tserial_event_thread_start,
                    this, 0, &threadid);

     SetThreadPriority(thread_handle,THREAD_PRIORITY_TIME_CRITICAL);

                      Santa Clara University Aerial Robotics Team            143
       /*if (thread_handle==-1)
           thread_handle=0;   */
   }

   /* --------------------------------------------- */
   return(erreur);
}
/* --------------------------------------------------------------------
*/
/* ---------------------            setManager    ---------------------
*/
/* --------------------------------------------------------------------
*/
void Tserial_event::setManager(type_myCallBack manager_arg)
{
         manager = manager_arg;
}
/* --------------------------------------------------------------------
*/
/* ---------------------            setRxSize     ---------------------
*/
/* --------------------------------------------------------------------
*/
void          Tserial_event::setRxSize(int size)
{
         max_rx_size = size;
         if (max_rx_size>SERIAL_MAX_RX)
             max_rx_size = SERIAL_MAX_RX;
}
/* --------------------------------------------------------------------
*/
/* ---------------------            setManager    ---------------------
*/
/* --------------------------------------------------------------------
*/
char *       Tserial_event::getDataInBuffer(void)
{
     return(rxBuffer);
}
/* --------------------------------------------------------------------
*/
/* ---------------------            getDataInSize    ------------------
--- */
/* --------------------------------------------------------------------
*/
int       Tserial_event::getDataInSize(void)
{
     return(received_size);
}
/* --------------------------------------------------------------------
*/
/* ---------------------            setManager    ---------------------
*/
/* --------------------------------------------------------------------
*/
void    Tserial_event::dataHasBeenRead(void)
{
     SetEvent(serial_events[SIG_READ_DONE]);
}

                 Santa Clara University Aerial Robotics Team              144
/* --------------------------------------------------------------------
*/
/* -----------------------   getNbrOfBytes ---------------------------
*/
/* --------------------------------------------------------------------
*/
int Tserial_event::getNbrOfBytes    (void)
{
    struct _COMSTAT status;
    int             n;
    unsigned long   etat;

   n = 0;

   if (serial_handle!=INVALID_HANDLE_VALUE)
   {
       ClearCommError(serial_handle, &etat, &status);
       n = status.cbInQue;
   }
   return(n);
}
/* --------------------------------------------------------------------
*/
/* --------------------------    sendData     -------------------------
*/
/* --------------------------------------------------------------------
*/
void Tserial_event::sendData (char *buffer, int size)
{
    if ((!tx_in_progress) && (size<SERIAL_MAX_TX) && (buffer!=0))
    {
        tx_in_progress = 1;
        memcpy(txBuffer, buffer, size);
        tx_size = size;
        SetEvent(serial_events[SIG_DATA_TO_TX]);
        // indicating data to be sent
    }
}
/* --------------------------------------------------------------------
*/
/* --------------------------    OnEvent      -------------------------
*/
/* --------------------------------------------------------------------
*/
void Tserial_event::OnEvent (unsigned long events)
{
    unsigned long ModemStat;

   GetCommModemStatus(serial_handle, &ModemStat);

   if ((events & EV_RING)!=0)
   {
       if ((ModemStat & MS_RING_ON)!= 0)
       {
           if (manager!=0)
               manager((uint32) this, SERIAL_RING);
       }
   }



                 Santa Clara University Aerial Robotics Team              145
    if ((events & EV_RLSD)!=0)
    {
        if ((ModemStat & MS_RLSD_ON)!= 0)
        {
             if (manager!=0)
                 manager((uint32) this, SERIAL_CD_ON);
        }
        else
        {
             if (manager!=0)
                 manager((uint32) this, SERIAL_CD_OFF);
        }
    }
}
/* --------------------------------------------------------------------
*/
/* --------------------------       run       -------------------------
*/
/* --------------------------------------------------------------------
*/

/**
 this function is the main loop of the Tserial object. There is a
 do while() loop executed until either an error or a PowerDown is
 received.
 this is not a busy wait since we use the WaitForMultipleObject
function
*/

/* * /
#define DEBUG_EVENTS
/* */

void Tserial_event::run(void)
{
    bool          done;
    long          status;
    unsigned long read_nbr, result_nbr;
    char          success;

    ready                     =   true;
    done                      =   false;
    tx_in_progress            =   0;
    rx_in_progress            =   0;
    WaitCommEventInProgress   =   0;

    if (manager!=0)
        manager((uint32) this, SERIAL_CONNECTED);

    GetLastError();               // just to clear any pending error
    SetEvent(serial_events[SIG_READ_DONE]);
    if (check_modem)
        SetEvent(serial_events[SIG_MODEM_CHECKED]);

    /* ----------------------------------------------------------- */
    while(!done)
    {
        /* ------------------------------------------------------------
------ */

                  Santa Clara University Aerial Robotics Team             146
        /*
*/
        /*
*/
        /*
*/
        /*                             Waiting    for signals
*/
        /*
*/
        /*
*/
        /*
*/
        /* ------------------------------------------------------------
------ */
        // Main wait function. Waiting for something to happen.
        // This may be either the completion of a Read or a Write or
        // the reception of modem events, Power Down, new Tx
        //
        status = WaitForMultipleObjects(SERIAL_SIGNAL_NBR,
serial_events,
                                        FALSE, INFINITE);

        // processing answer to filter other failures
        status = status - WAIT_OBJECT_0;
        if ((status<0) || (status>=SERIAL_SIGNAL_NBR))
             done=true;   // error
        else
        {
             /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
             /* ++++++++++++++++++++ EVENT DISPATCHER ++++++++++++++++++
*/
             /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
            switch(status)
            {
                /*
######################################################## */
                case SIG_POWER_DOWN:
                     // receiving a POWER down signal. Stopping the
thread
                     done = true;
                     break;
                /*
######################################################## */
                /* #
# */
                /* #
# */
                /* #                        RX
# */
                /* #
# */
                /* #
# */
                /*
######################################################## */

                  Santa Clara University Aerial Robotics Team              147
                case SIG_READ_DONE:
                    // previous reading is finished
                    // I start a new one here
                    if (!rx_in_progress)
                    {
                        // locking reading
                        rx_in_progress = 1;

                  // starting a new read


                  success = (char) ReadFile(serial_handle,&rxBuffer,

max_rx_size,&read_nbr,&ovReader);
                        if (!success)
                        {
                             // failure
                             if(GetLastError() != ERROR_IO_PENDING )
                             {
                                  // real failure => quiting
                                  done = true;
                                  #ifdef DEBUG_EVENTS
                                  printf("Readfile error (not
pending)\n");
                                  #endif DEBUG_EVENTS
                             }
                             #ifdef DEBUG_EVENTS
                             else
                                  printf("ReadFile pending\n");
                             #endif DEBUG_EVENTS
                        }
                        #ifdef DEBUG_EVENTS
                        else
                        {
                             // I make nothing here since the overlapped
                             // will be signaled anyway, so I'll make
                             // the processing there
                             printf("ReadFile immediate success\n");
                        }
                        #endif
                    }
                    break;
                /*
######################################################## */
                case SIG_READER:
                    // reading the result of the terminated read
                    //BOOL GetOverlappedResult(
                    //     HANDLE hFile,
                    //     LPOVERLAPPED lpOverlapped,
                    //     LPDWORD lpNumberOfBytesTransferred,
                    //     BOOL bWait
                    //    );
                    //

                    if (GetOverlappedResult(serial_handle, &ovReader,
                        &result_nbr, FALSE))
                    {
                        #ifdef DEBUG_EVENTS



                  Santa Clara University Aerial Robotics Team              148
                                 printf("ReadFile => GetOverlappedResult
done\n");
                             #endif DEBUG_EVENTS
                             // no error => OK




                             // Read operation completed successfully
                             ResetEvent(serial_events[SIG_READER]);
                             // Write operation completed successfully
                             received_size = result_nbr;
                             rx_in_progress = 0; // read has ended
                             // if incoming data, I process them
                             if ((result_nbr!=0) &&(manager!=0))
                  {
                  //OGI

                  nextSentence="";

                        nextSentence=getDataInBuffer();
                  nextSentence=nextSentence.substr(0,max_rx_size);
                  currentSentence=currentSentence+nextSentence;

//                printf("CURRENT2 is
%d.%s!!!!!!!!!!\n",currentSentence.size(),currentSentence.c_str());



                             manager((uint32) this, SERIAL_DATA_ARRIVAL);

                  }
                             // I automatically restart a new read once the
                             // previous is completed.
                             //SetEvent(serial_events[SIG_READ_DONE]);
                             // BUG CORRECTION 02.06.22
                      }
                      else
                      {
                             // GetOverlapped didn't succeed !
                             // What's the reason ?
                             if(GetLastError()!= ERROR_IO_PENDING )
                                 done = 1; // failure
                      }
                      break;
                /*
######################################################## */
                /* #
# */
                /* #
# */
                /* #                       TX
# */
                /* #
# */
                /* #
# */
                /*
######################################################## */

                 Santa Clara University Aerial Robotics Team                  149
                case SIG_DATA_TO_TX:
                    // Signal asserted that there is a new valid
message
                    // in the "txBuffer" variable
                    // sending data to the port
                    success = (char) WriteFile(serial_handle, txBuffer,
tx_size,
                                         &result_nbr, &ovWriter);
                         if (!success)
                         {
                             // ouups, failure
                             if(GetLastError() != ERROR_IO_PENDING )
                             {
                                 // real failure => quiting
                                 done = true;
                                 #ifdef DEBUG_EVENTS
                                 printf("WriteFile error (not
pending)\n");
                                   #endif DEBUG_EVENTS
                              }
                              #ifdef DEBUG_EVENTS
                              else
                                   printf("WriteFile pending\n");
                              #endif DEBUG_EVENTS
                        }
                        #ifdef DEBUG_EVENTS
                        else
                        {
                             // I make nothing here since the overlapped
                             // will be signaled anyway, so I'll make
                             // the processing there
                             printf("WriteFile immediate success\n");
                        }
                        #endif
                    break;
                /*
######################################################## */
                case SIG_WRITER:
                    // WriteFile has terminated
                    // checking the result of the operation
                    if (GetOverlappedResult(serial_handle, &ovWriter,
                         &result_nbr, FALSE))
                    {
                         // Write operation completed successfully
                         ResetEvent(serial_events[SIG_WRITER]);
                         // further write are now allowed
                         tx_in_progress = 0;
                         // telling it to the manager
                         if (manager!=0)
                             manager((uint32) this, SERIAL_DATA_SENT);
                    }
                    else
                    {
                         // GetOverlapped didn't succeed !
                         // What's the reason ?
                         if(GetLastError() != ERROR_IO_PENDING )
                             done = 1; // failure
                    }
                    break;

                  Santa Clara University Aerial Robotics Team              150
                /*
######################################################## */
                /* #
# */
                /* #
# */
                /* #                       MODEM_EVENTS EVENTS
# */
                /* #
# */
                /* #
# */
                /*
######################################################## */
                case SIG_MODEM_CHECKED:
                     if ((!WaitCommEventInProgress) && check_modem)
                     // if no wait is in progress I start a new one
                     {
                         WaitCommEventInProgress=1;
                         success = (char)
WaitCommEvent(serial_handle,&dwCommEvent,
                                                          &ovWaitEvent);
                         // reading one byte only to have immediate
answer on each byte
                         if (!success)
                         {
                              // ouups, failure
                              if(GetLastError() != ERROR_IO_PENDING )
                              {
                                   // real failure => quiting
                                   done = true;
                                   #ifdef DEBUG_EVENTS
                                   printf("WaitCommEvent error (not
pending)\n");
                                   #endif DEBUG_EVENTS
                              }
                              #ifdef DEBUG_EVENTS
                              else
                                   printf("WaitCommEvent pending\n");
                              #endif DEBUG_EVENTS
                         }
                         #ifdef DEBUG_EVENTS
                         else
                         {
                              // I make nothing here since the overlapped
                              // will be signaled anyway, so I'll make
                              // the processing there
                              printf("WaitCommEvent immediate
success\n");
                         }
                         #endif
                     }
                     break;
                /*
######################################################## */
                case SIG_MODEM_EVENTS:
                     // reading the result of the terminated wait
                     if (GetOverlappedResult(serial_handle,
&ovWaitEvent,

                  Santa Clara University Aerial Robotics Team               151
                           &result_nbr, FALSE))
                    {
                           // Wait operation completed successfully
                           ResetEvent(serial_events[SIG_MODEM_EVENTS]);
                           WaitCommEventInProgress = 0;
                           // if incoming data, I process them
                           OnEvent(dwCommEvent);
                           // automatically starting a new check
                           SetEvent(serial_events[SIG_MODEM_CHECKED]);
                    }
                    else
                    {
                           // GetOverlapped didn't succeed !
                           // What's the reason ?
                           if(GetLastError() != ERROR_IO_PENDING )
                               done = 1; // failure
                    }
                    break;
                /*
######################################################## */
            }
            /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
            /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
            /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
        }
    };

    // --------------------- Disconnecting ----------------
    ready = false;
    if (serial_handle!=INVALID_HANDLE_VALUE)
        CloseHandle(serial_handle);
    serial_handle = INVALID_HANDLE_VALUE;

    if (manager!=0)
        manager((uint32) this, SERIAL_DISCONNECTED);
}
/* --------------------------------------------------------------------
*/

void Tserial_event::setData()
{

}




                 Santa Clara University Aerial Robotics Team              152

				
DOCUMENT INFO