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.

  • 8,132 views
  • 7 comments
  • 37 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
×1
Servo (generic)
Used for glider flaps. We used metal gear 15g servos.
×2
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.
×1

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!

Introduction

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.

Plan

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.

Risks

  • 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.

Progress

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.

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: https://www.collaborizm.com/project/Sk3JncxD-

Code

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 - TEST OUT PID WITH SERVOS ATTACHED TO GLIDER FLAPS
*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
*
*https://playground.arduino.cc/Code/PIDLibrary
*https://www.arduino.cc/en/Tutorial/Genuino101CurieIMUOrientationVisualiser
*/

#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(){
    Serial.begin(9600);
    ///////////////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)
      pitchPID.SetOutputLimits(-90,90);
    
      rollPID.SetMode(AUTOMATIC);  //Turns PID on
      pitchPID.SetMode(AUTOMATIC);
    ///////////////PID Setup/////////////
    
    
    ///////////////IMU Setup/////////////
      // start the IMU and filter
      CurieIMU.begin();
      CurieIMU.setGyroRate(25);
      CurieIMU.setAccelerometerRate(25);
      filter.begin(25);
    
      // Set the accelerometer range to 2G
      CurieIMU.setAccelerometerRange(2);
      // Set the gyroscope range to 250 degrees/second
      CurieIMU.setGyroRange(250);
    
      // initialize variables to pace updates to correct rate
      microsPerReading = 1000000 / 25;
      microsPrevious = micros();
    ///////////////IMU Setup/////////////
    
      leftServo.attach(9);
      rightServo.attach(10); 
}//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
    rollPID.Compute();
    pitchPID.Compute();

    //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.  
     * 
     * ^^^^^^^^^^^NOTE TO TARIK: TEST OUT CODE WITH SERVOS ATTACHED TO GLIDER FLAPS^^^^^^^^^^^^
     */

     
    //writes to the servos
    leftServo.write(leftOutput);
    rightServo.write(rightOutput);
    Serial.println(pitch);
    // 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;
}
  

Comments

Similar projects you might like

Pixel Blast

Project showcase by KIMbAB STUDIO

  • 3,567 views
  • 2 comments
  • 8 respects

How to create a website communicating Arduino by using PHP

Project tutorial by Kutluhan Aktar

  • 254 views
  • 0 comments
  • 0 respects

Intel Math Kernel Library on Arduino

Project tutorial by Arduino_Genuino

  • 240 views
  • 0 comments
  • 1 respect

Arduino Controlled Pinball Machine

Project tutorial by Bob Blomquist

  • 22,353 views
  • 27 comments
  • 61 respects

UAV Arduino

Project showcase by Gorceag Victor

  • 15,763 views
  • 20 comments
  • 86 respects

OCS-2 : a digital, semi modular synthesizer

Project showcase by chnry

  • 13,669 views
  • 20 comments
  • 45 respects
Add projectSign up / Login