Files
flix/flix/estimate.ino
2025-12-24 05:43:55 +03:00

41 lines
1.0 KiB
C++

// Copyright (c) 2023 Oleg Kalachev <okalachev@gmail.com>
// Repository: https://github.com/okalachev/flix
// Attitude estimation from gyro and accelerometer
#include "quaternion.h"
#include "vector.h"
#include "lpf.h"
#include "util.h"
float accWeight = 0.003;
LowPassFilter<Vector> ratesFilter(0.2); // cutoff frequency ~ 40 Hz
void estimate() {
applyGyro();
applyAcc();
}
void applyGyro() {
// filter gyro to get angular rates
rates = ratesFilter.update(gyro);
// apply rates to attitude
attitude = Quaternion::rotate(attitude, Quaternion::fromRotationVector(rates * dt));
}
void applyAcc() {
// test should we apply accelerometer gravity correction
float accNorm = acc.norm();
landed = !motorsActive() && abs(accNorm - ONE_G) < ONE_G * 0.1f;
if (!landed) return;
// calculate accelerometer correction
Vector up = Quaternion::rotateVector(Vector(0, 0, 1), attitude);
Vector correction = Vector::rotationVectorBetween(acc, up) * accWeight;
// apply correction
attitude = Quaternion::rotate(attitude, Quaternion::fromRotationVector(correction));
}