Project in progress
Frontier Thrust Vector Controlled Hopper!

Frontier Thrust Vector Controlled Hopper! © GPL3+

A small rocket test vehicle that launches without the use of fins!

  • 2 views
  • 0 comments
  • 0 respects

Components and supplies

Apps and online services

About this project

Website: deltaspacesystems.com

Hey Everyone! This project is made up of seperate parts so check out:https://create.arduino.cc/projecthub/UniverseRobotics/advanced-rocket-flight-computer-ab9c5a! You will need a TVC mount to gimbal the motor, and a flight computer! Both can be purchased from the Delta Space Systems Website!

Patreon to help fund projects: https://patreon.com/deltaspacesystems

Etsy for TVC Mounts: https://www.etsy.com/listing/824079367/delta-thrust-vector-control-system?ref=shop_home_active_1

Video of the three launches so far!

Flight Computer

TVC Mount

Code

OmegaSoft-2.1.inoC/C++
/* Delta Space Systems
      Version 2.1
    May, 22th 2020 */

//Libraries
#include <SD.h>
#include <SPI.h>
#include <Servo.h>
#include <Wire.h>
#include <Adafruit_BNO055.h>
#include "Adafruit_BMP3XX.h"
#include <MPU6050_tockn.h>
#include <math.h>
#define SEALEVELPRESSURE_HPA (1013.25)


MPU6050 mpu6050(Wire);

Adafruit_BMP3XX bmp;
Adafruit_BNO055 bno = Adafruit_BNO055();


const int MPU=0x68; 
int16_t AcX,AcY,AcZ,Tmp,GyX,GyroY,GyroZ;
double PIDX, PIDY, errorX, errorY, previous_errorX, previous_errorY, pwmX, pwmY, previouslog, OutX, OutY, OutZ, OreX, OreY, OreZ;
double PreviousGyroX, PreviousGyroY, PreviousGyroZ, IntGyroX, IntGyroY, RADGyroX, RADGyroY, RADGyroZ, RawGyZ, DifferenceGyroX, DifferenceGyroY, DifferenceGyroZ, matrix1, matrix2, matrix3;
double matrix4, matrix5, matrix6, matrix7, matrix8, matrix9, PrevGyX, PrevGyY, PrevGyZ, RawGyX, RawGyY;

//Upright Angle of the Flight Computer
int desired_angleX = 0;//servoY
int desired_angleY = 0;//servoX

//Offsets for tuning 
int servoX_offset = -115;
int servoY_offset = 103;

//Position of servos through the startup function
int servoXstart = 120;
int servoYstart = 120;

//The amount the servo moves by in the startup function
int servo_start_offset = 20;

//Ratio between servo gear and tvc mount
float servo_gear_ratio = 5.8;

imu::Vector<3> Gyro;
imu::Vector<3> Accel;

double OrientationX = 0;
double OrientationY = 0;
double OrientationZ = 1;
double Ax;
double Ay;
double Az;
double accAngleX;
double accAngleY;
double yaw;
double GyroX;
double gyroAngleX;
double gyroAngleY;
double pitch;
int rollmax = 180;
int rollmin = -180;
int ledblu = 2;    // LED connected to digital pin 9
int ledgrn = 5;    // LED connected to digital pin 9
int ledred = 6;    // LED connected to digital pin 9
int mosfet = 25;
int teensyled = 13;

Servo servoX;
Servo servoY;

int pyro1 = 24;
int buzzer = 21;

double dt, currentTime, previousTime;

//SD CARD CS
const int chipSelect = BUILTIN_SDCARD;

//"P" Constants
float pidX_p = 0;
float pidY_p = 0;

//"I" Constants
float pidY_i = 0;
float pidX_i = 0;

//"D" Constants
float pidX_d = 0;
float pidY_d = 0;


int pos;

//PID Gains
double kp = 0.26;
double ki = 0.03;
double kd = 0.07;


/*System State: 
 * 0 = Go/No Go before launch
 * 1 = PID Controlled Ascent
 * 2 = Parachute Controlled Descent
 */
int state;
 const long flightint = 100;
 double prevdt = 0;

void setup(){
 
  Serial.begin(9600);
  Wire.begin();
  mpu6050.begin();
  
  servoX.attach(29);
  servoY.attach(30);
  
  pinMode(mosfet, OUTPUT);
  pinMode(ledblu, OUTPUT);
  pinMode(ledgrn, OUTPUT);
  pinMode(ledred, OUTPUT);
  pinMode(buzzer, OUTPUT);
  pinMode(pyro1, OUTPUT);
  pinMode(teensyled, OUTPUT);
  
  bmp.setTemperatureOversampling(BMP3_OVERSAMPLING_8X);
  bmp.setPressureOversampling(BMP3_OVERSAMPLING_4X);
  bmp.setIIRFilterCoeff(BMP3_IIR_FILTER_COEFF_3);
  
  startup();
  sdstart();
  launchpoll();
 
}
void loop() {
  mpu6050.update();
  //Defining Time Variables
  previousTime = currentTime;        
  currentTime = millis();            
  dt = (currentTime - previousTime) / 1000; 
  launchdetect();
  sdwrite();
  //recov();
  digitalWrite(mosfet, HIGH);

}

void IntGyro () {
  PrevGyX = RawGyX;
  PrevGyY = RawGyY;
  PrevGyZ = RawGyZ;
  
  RawGyX = Gyro.x() / 65.5;
  RawGyY = Gyro.y() / 65.5;
  RawGyZ = Gyro.z() / 65.5;
  
  IntGyroX += (((RawGyX + PrevGyX) / 2) * dt);
  IntGyroX += (((RawGyX + PrevGyX) / 2) * dt);
  

}
void rotationmatrices () {
  mpu6050.update();
  PreviousGyroX = RADGyroX;
  PreviousGyroY = RADGyroY;
  PreviousGyroZ = RADGyroZ;
  
  RADGyroX = mpu6050.getGyroAngleY() * (PI / 180);
  RADGyroY = mpu6050.getGyroAngleX() * (PI / 180);
  RADGyroZ = mpu6050.getGyroAngleZ() * (PI / 180);
  
  
  DifferenceGyroX = (RADGyroX - PreviousGyroX);
  DifferenceGyroY = (RADGyroY - PreviousGyroY);
  DifferenceGyroZ = (RADGyroZ - PreviousGyroZ);

  OreX = OrientationX;
  OreY = OrientationY;
  OreZ = OrientationZ;
  
mpu6050.update();
 //X Matrices
  matrix1 = (cos(DifferenceGyroZ) * cos(DifferenceGyroY));
  matrix2 = (((sin(DifferenceGyroZ) * -1) * cos(DifferenceGyroX) + (cos(DifferenceGyroZ)) * sin(DifferenceGyroY) * sin(DifferenceGyroX)));
  matrix3 = ((sin(DifferenceGyroZ) * sin(DifferenceGyroX) + (cos(DifferenceGyroZ)) * sin(DifferenceGyroY) * cos(DifferenceGyroX)));
 mpu6050.update();
 //Y Matrices
  matrix4 = sin(DifferenceGyroZ) * cos(DifferenceGyroY);
  matrix5 = ((cos(DifferenceGyroZ) * cos(DifferenceGyroX) + (sin(DifferenceGyroZ)) * sin(DifferenceGyroY) * sin(DifferenceGyroX)));
  matrix6 = (((cos(DifferenceGyroZ) * -1) * sin(DifferenceGyroX) + (sin(DifferenceGyroZ)) * sin(DifferenceGyroY) * cos(DifferenceGyroX)));
 mpu6050.update();
 //Z Matrices
  matrix7 = (sin(DifferenceGyroY)) * -1;
  matrix8 = cos(DifferenceGyroY) * sin(DifferenceGyroX);
  matrix9 = cos(DifferenceGyroY) * cos(DifferenceGyroX);

 
 OrientationX = ((OreX * matrix1)) + ((OreY * matrix2)) + ((OreZ * matrix3));
 OrientationY = ((OreX * matrix4)) + ((OreY * matrix5)) + ((OreZ * matrix6));
 OrientationZ = ((OreX * matrix7)) + ((OreY * matrix8)) + ((OreZ * matrix9));


 mpu6050.update();
OutX = OrientationX * 60;
OutY = OrientationY * -60;

Ax = asin(OrientationX) * (-180 / PI);
Ay = asin(OrientationY) * (180 / PI);
Az = asin(OrientationZ) * (180 / PI);
pidcompute();

}


void servowrite() {
 servoX.write(pwmX);
 servoY.write(pwmY); 

}
void pidcompute () {
mpu6050.update();
previous_errorX = errorX;
previous_errorY = errorY; 

errorX = Ax - desired_angleX;
errorY = Ay - desired_angleY;

//Defining "P" 
pidX_p = kp*errorX;
pidY_p = kp*errorY;

//Defining "D"
pidX_d = kd*((errorX - previous_errorX)/dt);
pidY_d = kd*((errorY - previous_errorY)/dt);

//Defining "I"
pidX_i = ki * (pidX_i + errorX * dt);
pidY_i = ki * (pidY_i + errorY * dt);

PIDX = pidX_p + pidX_i + pidX_d;
PIDY = pidY_p + pidY_i + pidY_d;


pwmX = -1*((PIDX * servo_gear_ratio) + servoX_offset);
pwmY = ((PIDY * servo_gear_ratio) + servoY_offset);
servowrite();

}
void startup () {
  digitalWrite(ledgrn, HIGH);
  servoX.write(servoXstart);
  servoY.write(servoYstart);
  delay(1000);
  digitalWrite(ledgrn, LOW);
  digitalWrite(buzzer, HIGH);
  digitalWrite(ledred, HIGH);
  servoX.write(servoXstart + servo_start_offset);
  delay(200);
  digitalWrite(buzzer, LOW);
  servoY.write(servoYstart + servo_start_offset);
  delay(200);
  digitalWrite(ledred, LOW);
  digitalWrite(buzzer, HIGH);
  digitalWrite(ledblu, HIGH);
  servoX.write(servoXstart);
  delay(200);
  digitalWrite(buzzer, LOW);
  servoY.write(servoYstart);
  delay(200);
  digitalWrite(ledblu, LOW);
  digitalWrite(buzzer, HIGH);
  digitalWrite(ledgrn, HIGH);
  digitalWrite(teensyled, HIGH);
  servoX.write(servoXstart - servo_start_offset);
  delay(200);
  digitalWrite(buzzer, LOW);
  
  servoY.write(servoYstart - servo_start_offset);
  delay(200);
  servoX.write(servoXstart);
  delay(200);
  servoY.write(servoYstart);
  delay(500);
 }
void launchdetect () {
  if (state == 0 && mpu6050.getAccZ() > 1.6) {
  state++;
 }
  if (state == 1) {
  rotationmatrices();
  datadump();
 }
}
void datadump () {
Serial.println(Ay);
}
void abortstart () {
 
  if (OrientationX > 40 || OrientationY > 40) {
  digitalWrite(ledgrn, LOW);
  digitalWrite(ledred, HIGH);
}
    else if (OrientationX < 40 || OrientationY < 40) {
    digitalWrite(ledgrn, LOW);
    digitalWrite(ledred, HIGH);
}
}


void sdstart () { 
if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");
  
}

void sdwrite () {
  if (dt - prevdt >= flightint) {
    prevdt = dt;
 
 String datastring = "";
      
 datastring += String(Ay);
 datastring += "\t";
 datastring += "yaw";
 
 datastring += String(Ax);
 datastring += "\t";
 datastring += "pitch";

 
  File dataFile = SD.open("FrontierF2.txt", FILE_WRITE);
  
  if (dataFile) {
    dataFile.println(datastring);
    dataFile.close();
   
   
  }
  }
}


void recov () {
  
if (state == 1 && mpu6050.getAccZ() < -1) {
  state++;
}

if (state == 2) {
  digitalWrite(ledgrn, LOW);
  digitalWrite(ledblu, HIGH);
  
}
}
void launchpoll () {
  state == 0;
  delay(750);
  Serial.println("Omega is Armed");
  mpu6050.calcGyroOffsets(true); 
  delay(500);
  Serial.println("Xenon has calibrated the Gyros, we are ready for launch");
  digitalWrite(ledgrn, LOW);
  digitalWrite(ledred, HIGH);
}

Custom parts and enclosures

Motor Tube
Outer Gimbal
Inner Gimbal
Airframe

Schematics

annotation_2020-05-13_103325_XCYWAjgtD5.png
Annotation 2020 05 13 103325 xcywajgtd5

Comments

Similar projects you might like

Xenon | Thrust Vector Controlled Rocket!!!

Project in progress by Cole Purtzer

  • 4,397 views
  • 1 comment
  • 10 respects

Delta Thrust Vector Control Rocket Guidance System

Project in progress by Cole Purtzer

  • 5,194 views
  • 8 comments
  • 31 respects

Delta Thrust Vector Control System v8

Project in progress by Cole Purtzer

  • 4,714 views
  • 4 comments
  • 19 respects

PC Controlled Robotic Arm

Project tutorial by AhmedAzouz

  • 19,535 views
  • 14 comments
  • 98 respects

Advanced Model Rocket!!!!!!

Project in progress by Cole Purtzer

  • 4,186 views
  • 3 comments
  • 28 respects

Advanced Rocket Flight Computer

Project in progress by Cole Purtzer

  • 4,663 views
  • 7 comments
  • 26 respects
Add projectSign up / Login