A quadcopter with Maple rev5 + 9 DOF - Razor IMU - AHRS.
A quadcopter with Maple
(8 posts) (6 voices)-
Posted 3 years ago #
-
xpomvid,
I am glad you took the effort to create a new topic to describe your maple-based quadcopter project. In your original post (part of the "Using Vin pin" topic) I did not understand the connection.
Any chance you can share your code, parts list (and supplier), and other details with other LeafLabs users?
Once again, congratulations and thanks!
Stephen from NYC (full disclosure: I am not a member of the LeafLabs staff)
Posted 3 years ago # -
Hi, here is the parts list and supplier. The code is not finished, it remains to debug and comments.
/******************************************************************************
* MAPLECOPTER *
* ----------------------------------------------------------------------------*
* SOFTWARE CUADRICOPTERO: MCoptero v1.0 por XPOMVID
* ----------------------------------------------------------------------------*
* Placa: Maple Rev5 (BricoGeek) *
* Procesador: 32-bit ARM Cortex M3 at 72MHz *
* Memory: 120 KB Flash and 20 KB SRAM *
* I/O Pins: 34 (of which 12 provide PWM output at 16-bit resolution) *
* ADCs: 9 (at 12-bit resolution) *
* Peripherals: 4 timers, 2 I2Cs, 2 SPI ports, 3 USARTs *
* ---------------------------------------------------------------------------*
* Sist. de medición inercial: 9DOF-Razor IMU-AHRS (BricoGeek) *
* Yaw Gyro: LY530AL - 300°/s single-axis gyro *
* Pitch and Roll Gyro: LPR530AL - 300°/s dual-axis gyro *
* Accelerometer: ADXL345 - 13-bit, ±16g, triple-axis accelerometer *
* Magnetometer: HMC5843 - triple-axis, digital magnetometer *
* Todas las salidas de los sensores son procesadas por un *
* ATmega328@3.3V w/ external 8MHz resonator y Firmware v1.0. *
* ---------------------------------------------------------------------------*
* Sensor de presión barométrica BMP085 (BricoGeek) *
* ---------------------------------------------------------------------------*
* Motor brushless 1000KV Outrunner (BricoGeek) *
* Hélices 8x4.5 *
* ---------------------------------------------------------------------------*
* ESC TURNIGY Plush 25amp Speed Controller (HobbyKing) *
* ---------------------------------------------------------------------------*
* Emisora Turnigy 9X 9Ch Transmitter (HobbyKing) *
*****************************************************************************/Posted 3 years ago # -
The PID control used:
//variables de trabajo
unsigned long lastTimePitch, lastTimeRoll, lastTimeYaw, lastTimeAlt;
float lastErrPitch, lastAngPitch, derivPitch, lastDerivPitch, integralPitch;
float lastErrRoll, lastAngRoll, derivRoll, lastDerivRoll, integralRoll;
float lastErrYaw, lastAngYaw, derivYaw, lastDerivYaw, integralYaw;
float lastErrAlt, derivAlt, lastDerivAlt, integralAlt;
float factorIn=0.80 ; //1.00; // factorIn amortigua el error. Rango 0.01-1.0 (0.01=suave, 1.0=fuerte)
uint8 outLimYaw=100, outLim=100, errMaxPitchRoll=25, errMaxYaw=60, errMaxAlt=2;
byte fcort=20; //frecuencia de corte del filtro de paso bajo
float RC=1/(2*PI*fcort);
// fcort = 10 Hz -> RC = 15.9155e-3
// fcort = 15 Hz -> RC = 10.6103e-3
// fcort = 20 Hz -> RC = 7.9577e-3
// fcort = 25 Hz -> RC = 6.3662e-3
// fcort = 30 Hz -> RC = 5.3052e-3void ComputePIDPitch(void)
{
unsigned long now = millis();
float DT = (float)(now - lastTimePitch)/1000.00;//Error pitch
errorPitch=(AngPitch-SetpointPitch)*factorIn;
errorPitch = constrain(errorPitch,-errMaxPitchRoll,errMaxPitchRoll); //Limita el valor max del error de pitch
//componente proporcional
OutputPitch = errorPitch * KpPitch;
//componente derivativa con filtro paso-bajo
derivPitch =(errorPitch - lastErrPitch) / DT;
derivPitch=lastDerivPitch+(DT/(RC+DT))*(derivPitch - lastDerivPitch);
//suma componenete derivativa
OutputPitch+=KdPitch*derivPitch;
//componente integral
integralPitch+=KiPitch*errorPitch*DT;
//limita integralPitch
integralPitch=constrain(integralPitch,-outLim,outLim);
//Salida y limitada
OutputPitch += integralPitch;
OutputPitch=constrain(OutputPitch,-outLim,outLim);
//renueva estado
lastErrPitch=errorPitch;
lastAngPitch=AngPitch;
lastDerivPitch=derivPitch;
lastTimePitch = now;
}//----------------------------------------------------
void ComputePIDRoll(void)
{
unsigned long now = millis();
float DT = (float)(now - lastTimeRoll)/1000.00;//Error roll
errorRoll=(AngRoll-SetpointRoll)*factorIn;
errorRoll = constrain(errorRoll,-errMaxPitchRoll,errMaxPitchRoll); //Limita el valor max del error de roll
//componente proporcional
OutputRoll = errorRoll * KpRoll;
//componente derivativa con filtro paso-bajo
derivRoll = (errorRoll - lastErrRoll) / DT;
derivRoll=lastDerivRoll+(DT/(RC+DT))*(derivRoll-lastDerivRoll);
//suma componenete derivativa
OutputRoll+=KdRoll*derivRoll;
//componente integral
integralRoll+=KiRoll*errorRoll*DT;
//limita integralRoll
integralRoll=constrain(integralRoll,-outLim,outLim);
//Salida y limitada
OutputRoll += integralRoll;
OutputRoll=constrain(OutputRoll,-outLim,outLim);
//renueva estado
lastErrRoll=errorRoll;
lastAngRoll=AngRoll;
lastDerivRoll=derivRoll;
lastTimeRoll = now;
}
//----------------------------------------------------
void ComputePIDYaw(void)
{
/*How long since we last calculated*/
unsigned long now = millis();
float DT = (float)(now - lastTimeYaw)/1000.00;//Error yaw
errorYaw=(AngYaw-SetpointYaw)*factorIn;
if (errorYaw > 180) errorYaw -= 360; // Normalizar a -180,180
else if(errorYaw < -180) errorYaw += 360;
errorYaw = constrain(errorYaw,-errMaxYaw,errMaxYaw); // Limita el valor max del error de yaw
//componente proporcional
OutputYaw = errorYaw * KpYaw;
//componente derivativa con filtro paso-bajo
derivYaw = (errorYaw - lastErrYaw) / DT;
derivYaw=lastDerivYaw+(DT/(RC+DT))*(derivYaw-lastDerivYaw);
//suma componenete derivativa
OutputYaw += KdYaw*derivYaw;
//componente integral
integralYaw+=KiYaw*errorYaw*DT;
//limita integralYaw
integralYaw=constrain(integralYaw,-outLimYaw, outLimYaw);
//Salida y limitada
OutputYaw+=integralYaw;
OutputYaw=(-1)*constrain(OutputYaw,-outLim,outLim);
//renueva estado
lastErrYaw=errorYaw;
lastAngYaw=AngYaw;
lastDerivYaw=derivYaw;
lastTimeYaw = now;
}
//----------------------------------------------------
void ComputePIDAlt(void)
{
unsigned long now = millis();
float DT = (float)(now - lastTimeAlt)/1000.00;//Error altura
errorAlt=(-1)*(h_filter-SetpointAlt)*10; //dm
errorAlt=constrain(errorAlt,-errMaxAlt,errMaxAlt);
//componente proporcional
OutputAlt = errorAlt * KpA;
//componente derivativa con filtro paso-bajo
derivAlt = (errorAlt - lastErrAlt) / DT;
derivAlt=lastDerivAlt+(DT/(RC+DT))*(derivAlt-lastDerivAlt);
//suma componenete derivativa
OutputAlt+=KdA*derivAlt;
//componente integral
integralAlt+=KiA*errorAlt*DT;
//limita integralPich
integralAlt=constrain(integralAlt,-outLim,outLim);
//Salida y filtro PID
OutputAlt+=integralAlt;
OutputAlt=constrain(OutputAlt,-outLim,outLim);
//renueva estado
lastErrAlt=errorAlt;
lastDerivAlt=derivAlt;
lastTimeAlt = now;
}Posted 3 years ago # -
Hello It is a good project. Can I download MCoptero v1.0 code?
Posted 3 years ago # -
Wow, nice project!
Posted 3 years ago # -
Looks great! I want to control ESC motors myslef! But having issues with Arming ESC, can you explain how to handle ESC ? IF you can share some code we would be really appreciated !
Posted 2 years ago #
Reply
You must log in to post.