Project in progress

Autonomous High Altitude Glider © CC BY

A fully autonomous fixed-wing glider designed to safely return a payload after being deployed on near-space missions.

  • 44 respects

Components and supplies

Ardgen 101
Arduino 101 & Genuino 101
The Gyro and Accelerometer in the Curie IMU is the main reason we're using the 101
Servo (generic)
Used for glider flaps. We used metal gear 15g servos.
u-blox uBLOX MAX-M8Q GPS
We're specifically using this due to the fact that it does not have a GPS cutoff as long as you aren't moving 515 m/s. The module itself is rated at 50,000 meters.

Apps and online services

About this project

  • Update 3: Tarik uploaded Project Log 2, we'll be rebuilding the airframe this week. Feel free to ask us any questions and we'll do a video Q&A if we receive enough questions!


High Altitude Balloon missions are usually very risky, as there is a high chance of losing or damaging one’s payload during a mission. There are a lot of points of failure, and it is easy to lose track of your payload. Our Autonomous High Altitude Glider project aims to solve that issue. The glider deploys when it reaches a target altitude, detaches from the balloon, and navigates back to a predetermined location using GPS and Gyroscope/Accelerometer data.

This project originally began in 2015, but very little progress was made until it was put on the shelf until June 2017. We plan on finishing this project with at least one successful mission by the end of 2017.


The current plan is to deploy a fixed-wing glider at an altitude of 100,000 ft(approx. 30.5 km.), and navigate back to our launch site. Our flight path is as follows:

  • Deploy at 100,000 ft
  • Detach from balloon
  • Dive until the glider reaches an altitude of 30,000 ft(In order to avoid strong winds and jet streams)
  • Maneuver to predetermined location
  • Spiral down and stall to kill speed and land safely
  • Land

We are using Tarik’s “Sequioa” UAV design, a fixed-wing, plank-style glider. The glider is controlled via a receiver and an Arduino 101 linked with a Raspberry Pi. We are currently considering fiberglassing the glider to increase its durability and endurance.

To stabilize the aircraft and implement autonomous navigation algorithms, we used a PID algorithm to adjust the servos to react to the gliders position and orientation. This is used to counteract wind, as with a normal Proportional feedback loop, the glider would not be able to account for wind and counteract current. This would be undesirable, as we would lose control of the aircraft, and regaining control would be a very difficult task.

For our navigation algorithm, we plan on integrating weather patterns, GPS data, and accelerometer data to calculate the best route possible in real time. The glider is linked to our computers via a radio link, allowing us to monitor the glider, and the glider to receive weather data in real time. Route calculation is done on the fly (pun intended), and uses a set of maneuvers that we have modeled in simulations to prevent any errors with our PID algorithm.

For telemetry data and communications purposes, we will be connected to the glider via a radio link that provides us with sensor data, location data, status updates and errors, a live video feed, and a manual override option should any issues arise from our autonomous glider program.

We are currently working on pursuing sponsors, as we would like to add more cameras to our glider to obtain high altitude footage.

Goals & Deadlines

Our main goal is to develop an autonomous glider that can successfully return a payload from an altitude of 100,000 ft.


  • Temperatures in high altitudes can reach a chilly -40 degrees Celsius, which would prevent our batteries from working properly. We plan on insulating our electronics, and possibly incorporating a heater into our control hardware.
  • Wind – Wind blowing against the glider would prevent it from following its route. This is why we are working on incorporating weather data into our navigation algorithm in order to have our glider fly through the safest and most efficient zones possible. Our initial dive maneuver is mainly to fly to lower altitudes to fly in a zone that is less likely to have strong winds.
  • Code – A lot of things can go wrong with our program, so we are currently doing our best to eliminate glitches and bugs in our code.
  • GPS Cutoff – Most GPS modules shut off after reaching 20,000 meters as a safety measure, which would mean that the glider will have to navigate without knowing its location in its initial maneuvers. We plan on reducing the risks associated with navigating with no GPS by having the glider dive to lower altitudes and attempt to navigate using our flight estimations until it can receive GPS data.


We have developed the PID loop, and are adding our finishing touches to it. Our next step in the process is to develop a navigational algorithm that uses and tracks location data to interpret weather data, measure the speed of the glider, and determine the optimal route. Once that is done, we will then run a few tests, finalize our code, and launch our glider.

Update 1: PID Stabilizer code is finally finished, and Tarik is doing some finishing touches to the code. It corrects the glider's orientation by mixing two PID loops for the Roll and Pitch Axes, and controls two servos that will be attached to the flaps of the glider soon.

Video demonstrating the PID Code. Apologies for the vertical video.

Update 2: Getting GPS Data!

We recently got our GPS sensor working, and have finally been able to pull data from it! The following program shows how we got Speed, Heading, and Location Data from a Ublox Max-M8Q connected to our Arduino 101.

We’re going to be using this data along with an Input coordinate to plan a path for the glider, then use our previous PID Code so that our target direction will be determined by the difference between its current location and the target location/waypoint in 3D space.

#include <SoftwareSerial.h>
#include <TinyGPS.h>

long lat,lon; // create variable for latitude and longitude object
float heading;
float speed;

SoftwareSerial gpsSerial(7, 8); // create gps sensor connection
TinyGPS gps; // create gps object

void setup(){
 Serial.begin(9600); // connect serial
 gpsSerial.begin(9600); // connect gps sensor

void loop(){
 while(gpsSerial.available()){ // check for gps data
  if(gps.encode({ // encode gps data
   gps.get_position(&lat,&lon); // get latitude and longitude
   speed = gps.f_speed_mps(); //Speed in m/s
   heading = gps.f_course(); //Heading in degrees

   //Output Data:
   Serial.print("Heading: "); Serial.print(heading);
   Serial.print("Speed: "); Serial.print(speed);
   Serial.print("Position: ");Serial.print("lat: ");Serial.print(lat);Serial.print(" ");// print latitude
   Serial.print("lon: ");Serial.println(lon); // print longitude

Project Log 1 by Tarik Agcayazi:

Project Log 2 by Tarik Agcayazi:

Project Log 3 by Tarik Agcayazi:

Project Log 4 by Tarik Agcayazi:

Collaborizm Project Page:


PID Stabilizer CodeC/C++
This is the first iteration of our glider code; it makes the glider attempt to fly straight.
/*Arduino 101 Glider Stabilizer
*By: Kemal Ficici and Tarik Agcayazi
*Current code only sabilizes glider back to 0,0,0 degrees X,Y,Z.
*TO DO - Fix PID mixing(line 130,131)
*TO DO - Maneuvers(Initial Dive, Turns, Spiral)
*TO DO - Navigate to GPS Coordinate, Dive till set altitude, release mechanism

#include <CurieIMU.h>
#include <MadgwickAHRS.h>
#include <PID_v1.h>
#include <Servo.h>

///////////////////////////////IMU Stuff///////////////////////////////////
Madgwick filter;
unsigned long microsPerReading, microsPrevious;
float accelScale, gyroScale;
float roll, pitch, heading;
///////////////////////////////IMU Stuff///////////////////////////////////

/////////////////////////////////PID Stuff////////////////////////////////////////
double Kp=1, Ki=1, Kd=0.07;  //PID Tuning Parameters (NOTE: idk if I tuned it properly)
//     Roll PID stuff
double rollSetpoint, rollInput, rollOutput;
PID rollPID(&rollInput, &rollOutput, &rollSetpoint, Kp, Ki, Kd, DIRECT);

//   PitchPID Stuff
double pitchSetpoint, pitchInput, pitchOutput;
PID pitchPID(&pitchInput, &pitchOutput, &pitchSetpoint, Kp, Ki, Kd, DIRECT);

//Specify the links and initial tuning parameters
/////////////////////////////////PID Stuff////////////////////////////////////////

Servo leftServo, rightServo; //Servos for flaps
int leftOutput, rightOutput; //Output for flaps

void setup(){
    ///////////////PID Setup/////////////
      rollInput = roll; //Sets the PID inputs to the gyro's roll and pitch axes
      pitchInput = pitch;
      rollSetpoint = 0; 
      pitchSetpoint = 0;
      rollPID.SetOutputLimits(-90, 90); //limits the PID loop to output numbers in between -90 and 90. I used values from -90 to 90 in order to better visualize the glider position(when flaps are flat, the PID output is 0)
      rollPID.SetMode(AUTOMATIC);  //Turns PID on
    ///////////////PID Setup/////////////
    ///////////////IMU Setup/////////////
      // start the IMU and filter
      // Set the accelerometer range to 2G
      // Set the gyroscope range to 250 degrees/second
      // initialize variables to pace updates to correct rate
      microsPerReading = 1000000 / 25;
      microsPrevious = micros();
    ///////////////IMU Setup/////////////

void loop() {
  rollInput = roll; //sets PID inputs to Roll and Pitch
  pitchInput = pitch;
  rollPID.SetTunings(Kp, Ki, Kd); //PID Tunings
  pitchPID.SetTunings(Kp, Ki, Kd);

  int aix, aiy, aiz;  //IMU Stuff
  int gix, giy, giz;
  float ax, ay, az;
  float gx, gy, gz;

  unsigned long microsNow;

  // check if it's time to read data and update the filter
  microsNow = micros();
  if (microsNow - microsPrevious >= microsPerReading) {

    // read raw data from CurieIMU
    CurieIMU.readMotionSensor(aix, aiy, aiz, gix, giy, giz);

    // convert from raw data to gravity and degrees/second units
    ax = convertRawAcceleration(aix);
    ay = convertRawAcceleration(aiy);
    az = convertRawAcceleration(aiz);
    gx = convertRawGyro(gix);
    gy = convertRawGyro(giy);
    gz = convertRawGyro(giz);

    // update the filter, which computes orientation
    filter.updateIMU(gx, gy, gz, ax, ay, az);

    // print the heading, pitch and roll
    roll = filter.getRoll();
    pitch = filter.getPitch();
    heading = filter.getYaw();

    //Calculates PID

    //Combines the outputs and adds 90 to make it work with the servos
    leftOutput = ((rollOutput + pitchOutput) / 2) + 90;
    rightOutput = ((rollOutput - pitchOutput) / 2) + 90;

    /*  ^^^^^^^^^^NOTE TO TARIK: PLEASE FIX MIXING PIDS ^^^^^^^^^^^^^^^
     *  One issue with the code is that the way I mix the Roll and Pitch PID loops
     * is not the best way to mix PID loops. For instance, if the pitchPID was 90, and 
     * rollPID was 0, both flaps would not trim up, rather, rightServo would be at -45,
     * while leftServo trims at 135.  

    //writes to the servos
    // increment previous time, so we keep proper pace
    microsPrevious = microsPrevious + microsPerReading;
  } //if
} //loop()

float convertRawAcceleration(int aRaw) {
  // since we are using 2G range
  // -2g maps to a raw value of -32768
  // +2g maps to a raw value of 32767
  float a = (aRaw * 2.0) / 32768.0;
  return a;

float convertRawGyro(int gRaw) {
  // since we are using 250 degrees/seconds range
  // -250 maps to a raw value of -32768
  // +250 maps to a raw value of 32767
  float g = (gRaw * 250.0) / 32768.0;
  return g;


Similar projects you might like


Project in progress by Petoi

  • 1,234 respects

Arduino Controlled Pinball Machine

Project tutorial by Bob Blomquist

  • 74 respects

UAV Arduino

Project showcase by Gorceag Victor

  • 127 respects

OCS-2: A Digital, Semi Modular Synthesizer

Project showcase by chnry

  • 72 respects

Arduino UNO with 8 Times More Memory

Project showcase by T.F. Mc Temucin

  • 64 respects

Ultimate Kegerator

Project tutorial by Kevin D Wolf

  • 52 respects
Add projectSign up / Login