mirror of
https://github.com/okalachev/flix.git
synced 2026-01-10 21:16:50 +00:00
42 lines
1.1 KiB
C++
42 lines
1.1 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"
|
|
|
|
#define WEIGHT_ACC 0.003
|
|
#define RATES_LFP_ALPHA 0.2 // cutoff frequency ~ 40 Hz
|
|
|
|
void estimate() {
|
|
applyGyro();
|
|
applyAcc();
|
|
}
|
|
|
|
void applyGyro() {
|
|
// filter gyro to get angular rates
|
|
static LowPassFilter<Vector> ratesFilter(RATES_LFP_ALPHA);
|
|
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) * WEIGHT_ACC;
|
|
|
|
// apply correction
|
|
attitude = Quaternion::rotate(attitude, Quaternion::fromRotationVector(correction));
|
|
}
|