miércoles, 5 de enero de 2011

Vector control




English
As we have said many times, our short-term goal is to make a rocket capable of reaching space (minimum 100 km), but thinking long term, this rocket will not just be to reach space but also we want to control the path in order to accurately place in orbit the wiki-sats as well as we can, so Roberto is responsible for the future manufacture and test of the definitive vector control rocket. The vector control of our satellite is based on 4 small copper tubes with a very small diameter, with a valve controlled by a servo in turn controlled by a satellite that will go in the rocket, the theoretical performance is simple, our wiki-sats are fitted with accelerometers, they look at the attitude of the rocket and corrected according to a prescribed path, if necessary, by air pressure expulsion (generated by the combustion of rocket) for the tubes may change as well in all three axes (pitch , Roll and yaw). In practice it is not as simple as it is not only the production itself with the servo valves and tubes (and in itself complicated by the small scale) but also have to find the appropriate control algorithms (a followed by mathematical formulas for how much you have to open a valve or another to make a turn more or less closed or faster). What you can see in the video are the tests that have been made of the vector control system to see if the valves closed withstand the pressure and also see if the system works.


Castellano
Como ya hemos repetido numerosas veces, nuestro objetivo a corto plazo es hacer un cohete capaz de llegar al espació (mínimo 100 km), pero pensando en largo plazo, este cohete no solo tendrá que llegar al espacio sino que además querremos controlar la trayectoria de este a fin de colocar con la mayor precisión los wiki-satélites en sus óptimas órbitas, por eso Roberto es el encargado de fabricar y probar el futuro control vectorial del cohete definitivo. El control vectorial de nuestro satélite se basa en 4 pequeños tubitos de cobre de un diámetro muy pequeño, con unas válvulas controladas por unos servos a su vez controladas por uno de los satélites que irá en el cohete, el funcionamiento teórico es simple, nuestros wiki-sats estan dotados de acelerómetros, estos miran la actitud del cohete y la corrigen según una trayectoria estipulada si es necesario mediante la expusión de aire a presión (generado por la combustión del cohete) por los tubitos pudiendo cambiar así en los tres ejes (cabeceo, alabeo y guiñada). En la práctica no es tan simple pues no es solo la fabricación en si de los servos con las válvulas y los tubitos (ya de por si complicado debido a su reducida escala) sinó que también se tienen que encontrar los algoritmos de control idoneos (un seguido de formulas matemáticas para saber cuanto se tiene que abrir una válvula o otra para hacer un giro más o menos cerrado o rápido). Lo que podeis ver en el vídeo son las pruebas que se le han practicado al sistema de control vectorial para ver si las válvulas aguantan cerradas la presión y para ver también si el sistema funciona.

lunes, 3 de enero de 2011

Launch campaign, first launch

English
In our wiki-space campaign we have decided the first launch date, this is the next January 28th. For this launch the following objectives:

    1. Launch a stratospheric balloon with our launch ramp and the system arrives at least 30 km.
    2. At 30 km high, launch a rocket stage with a monitoring system.
    3. At 2 km to open a parachute.
    4. See the results, analyze and report.

Then you can see the code that we will introduce the AWIP to the igniter is turned on at 30 km and the parachute at 2 km. This has been done by Juan Martínez and Joshua Tristancho and reviewed by Victor Kravchenko.



Castellano
En nuestra wiki-campaña espacial nos hemos propuesto la primera fecha de lanzamiento, esta es el 28 de enero. Para este lanzamiento los objetivos son los siguientes:
  1. Lanzar nuestro globo estratosferico con nuestra rampa le lanzamiento y que llegue a un mínimo de 30 km.
  2. A 30 km lanzar la etapa del cohete con un sistema de seguimiento.
  3. A 2 km que se abra un paracaídas.
  4. Ver los resultados, analizarlos y reportarlos.
Seguidamente podes ver el código que le vamos a introducir a la AWIP para que que el igniter se encienda a 30 km y el paracaídas a 2 km. Este ha sido hecho por Juan Martínez y Joshua Tristancho y revisado por Victor Kravchenko.


Code (codigo):


#include <Wire.h>
#include <SoftwareSerial.h>
#include <EEPROM.h>
#include <math.h>
#define IGNITION_ALTITUDE 30000 // Above this altitude in meters the igniter is activated
#define PARACHUTE_ALTITUDE 2000 // Below this altitude in meters the parachute is deployed
#define SAFETY_ALTITUDE 3000 // Safety altitude above wich the parachute can be deployed
#define APOGEE_ADDR 0 // Apogee EEPROM Address
#define IGNITION_PIN 12 // Ouput pin number to activate the igniter 5V
#define PARACHUTE_PIN 10 // Ouput pin number to activate the parachute 5V
#define GPSRX_PIN 11 // Input pin for GPS Rx serial port
#define GPSTX_PIN 13 // Output pin for GPS Tx serial port
//#include "itg3200.h" // GYRO ITG-3200
#define GyroID B1101001
//Register 22 - FS_SEL, DLPF_CFG
#define R22 0x16
#define R22INIT B00011011
//Register 62 - Power Management
#define R62 0x3e
#define R62INIT B00000001
//Registers 27 to 34 - Sensor Registers
#define TempH 0x1b
#define TempL 0x1c
#define GyroXH 0x1d
#define GyroXL 0x1e
#define GyroYH 0x1f
#define GyroYL 0x20
#define GyroZH 0x21
#define GyroZL 0x22
//#include "lis331hh.h" Accelerometer LIS331HH
#define AccID 0x18
//Register CTRL_REG0 - Power management and conf
#define RCTR0 0x20
#define RCTR0INIT B00100111
//Sensor Registers
#define AccXH 0x29
#define AccXL 0x28
#define AccYH 0x2B
#define AccYL 0x2A
#define AccZH 0x2D
#define AccZL 0x2C
#define AccStat 0x27
void i2cSetRegister(int device, int address, int value)
{
  Wire.beginTransmission(device);
  Wire.send(address);
  Wire.send(value);
  Wire.endTransmission();
}
byte i2cGetRegister(int device, int address)
{
  Wire.beginTransmission(device);
  Wire.send(address);
  Wire.endTransmission();
  Wire.requestFrom(device, 1);
  if(Wire.available())
  return Wire.receive();
  return B00000000;
}
int i2cGetValue(int device, int addressH, int addressL)
{
  return i2cGetRegister(device, addressH) * 256 + i2cGetRegister(device, addressL);
}
// Globals
SoftwareSerial GPS = SoftwareSerial(GPSRX_PIN,GPSTX_PIN);
int addr;
int val; // Last byte read from GPS
float alt; // Last altitude read from GPS
float apogee; // Highest altitude read from GPS. This variable is mirrored in EEPROM.
byte k[]={0,0,0,0,0,0,0,0,0,0,0,0,0}; // Read buffer for GPS input
float EEPROMGetFloat(int addr)
{
  float num;
  ((byte*)&num)[0]=EEPROM.read(addr++);
  ((byte*)&num)[1]=EEPROM.read(addr++);
  ((byte*)&num)[2]=EEPROM.read(addr++);
  ((byte*)&num)[3]=EEPROM.read(addr++);
  return num;
}
void EEPROMSetFloat(int addr, float num)
{
  EEPROM.write(addr++,((byte*)&num)[0]);
  EEPROM.write(addr++,((byte*)&num)[1]);
  EEPROM.write(addr++,((byte*)&num)[2]);
  EEPROM.write(addr++,((byte*)&num)[3]);
}
byte Next()
{
  // BYTE, BIN, OCT, HEX, 1 = number of decimals
  val=byte(GPS.read());
  Serial.print(val,BYTE); // For debbuging purpose only
  return val;
}
int ReadParam(byte chr=',')
{
  int i=0;
  while(true)
    if(i>=sizeof(k))
      return -1; // Buffer overrun
    else if((k[i]=Next())==chr)
      return i; // Read 'i' bytes
    else
      i++;
}
void setup ()
{
  pinMode(IGNITION_PIN,OUTPUT);
  digitalWrite(IGNITION_PIN,LOW);
  pinMode(PARACHUTE_PIN,OUTPUT);
  digitalWrite(PARACHUTE_PIN,LOW);
  GPS.begin(4800);
  Serial.begin(4800);
 
  // EEPROM dumping
  /*
  for(addr=0;addr<512;addr++)
  {
    if (!(addr%16)){Serial.println();Serial.print(addr/1000.0f,3);Serial.print(": ");}
    Serial.print(EEPROM.read(addr)/1000.0f,3);Serial.print(" ");
    //EEPROM.write(addr,0); // WARNING: This line will erase all the EEPROM memory
  }
  Serial.println();
  */
 
  addr=0;
  val=0;
  alt=0;
  apogee=EEPROMGetFloat(APOGEE_ADDR);
  Wire.begin();
  // Hyperterminal at 57600 and Arduino at 115200 bauds
  //Serial.begin(115200);
  // Accelerometer LIS331HH setup
  i2cSetRegister(AccID, RCTR0, RCTR0INIT);
  // Gyro ITG-3200 setup
  i2cSetRegister(GyroID, R62, R62INIT);
  i2cSetRegister(GyroID, R22, R22INIT);
  // Hardware-on-the-loop config
  //i=0;
}
void loop()
{
  int i;
  if(Next()=='$')if(Next()=='G')if(Next()=='P')if(Next()=='G')if(Next()=='G')if(Next()=='A')if(Next()==',')
  {
    if(ReadParam()>=0)      // Time in UTC of position
    if(ReadParam()>=0)      // Latitude of position
    if(ReadParam()>=0)      // Latitude N or S
    if(ReadParam()>=0)      // Longitude of position
    if(ReadParam()>=0)      // Longitude E or W
    if(ReadParam()>=0)      // GPS quality                            (0=fix not available, 1=Non-differential GPS fix available, 2=Differential GPS (WAAS) fix available, 6=Estimated)
    if(ReadParam()>=0)      // Number of satellites                   (00 to 12)
    if(ReadParam()>=0)      // Horizontal dilution of precision       (0.5 to 99.9)
    if(ReadParam()>0)       // Antenna altitude above mean sea level  (-9999.9 to 99999.9)
    {
      alt=atof((char*)&k[0]);
      if(ReadParam()>=0)    // Units of antenna altitude, meters      M
      if(ReadParam()>=0)    // Height of geoid above ellipsoid        (-999.9 to 9999.9)
      if(ReadParam()>=0)    // Units of geoid height, meters          M
      if(ReadParam()>=0)    // Age of differential GPS data, seconds  Null
      if(ReadParam('*')>=0) // Differential reference station ID      Null
      if(ReadParam(10)>0)   // Checksum                               *HH
      {
        if(alt>apogee)
        {
          apogee=alt;
          EEPROMSetFloat(APOGEE_ADDR,alt);
        }
        if(alt>IGNITION_ALTITUDE)digitalWrite(IGNITION_PIN,HIGH);
        if(alt<PARACHUTE_ALTITUDE)if(apogee>SAFETY_ALTITUDE)digitalWrite(PARACHUTE_PIN,HIGH);
      }
    }
  }
}