Fixed some math bugs in the compass calcs, needle is now more accurate.
This commit is contained in:
parent
a77b3845e0
commit
26a1da2cb9
4 changed files with 38 additions and 22 deletions
|
@ -1,19 +1,22 @@
|
|||
use libm::{cosf, roundf, sinf};
|
||||
|
||||
use crate::line_drawing::{draw_line, FourQuadrantMatrix, Line, Point};
|
||||
use crate::tilt_compensation::Heading;
|
||||
|
||||
fn heading_to_line(heading: f32, square_size: usize) -> Line {
|
||||
fn heading_to_line(heading: Heading, square_size: usize) -> Line {
|
||||
Line(
|
||||
Point { x: 0, y: 0 },
|
||||
Point {
|
||||
x: roundf((square_size as f32) * sinf(heading)) as isize,
|
||||
y: roundf((square_size as f32) * cosf(heading)) as isize,
|
||||
x: roundf((square_size as f32) * sinf(heading.0)) as isize,
|
||||
y: roundf((square_size as f32) * cosf(heading.0)) as isize,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
pub fn draw_heading<const X: usize, const Y: usize>(
|
||||
heading: f32,
|
||||
// given the compass heading that the board '0' is facing,
|
||||
// draws a line always pointing towards heading 0
|
||||
pub fn draw_constant_heading<const X: usize, const Y: usize>(
|
||||
heading: Heading,
|
||||
matrix: &mut FourQuadrantMatrix<{ X }, { Y }, u8>,
|
||||
) {
|
||||
draw_line::<X, Y>(&heading_to_line(heading, X.min(Y)), matrix);
|
||||
|
|
|
@ -18,6 +18,7 @@ pub struct Heading(pub f32);
|
|||
|
||||
pub fn calc_attitude(measurement: &NedMeasurement) -> Attitude {
|
||||
//based off of: https://www.nxp.com/docs/en/application-note/AN4248.pdf
|
||||
//Gp{xyz} is the acellerometer measurements.
|
||||
let roll = atan2f(measurement.y, measurement.z);
|
||||
let pitch = atanf(-measurement.x / (measurement.y * sinf(roll) + measurement.z * cosf(roll)));
|
||||
Attitude { pitch, roll }
|
||||
|
@ -28,23 +29,30 @@ pub fn calc_tilt_calibrated_measurement(
|
|||
attitde: &Attitude,
|
||||
) -> NedMeasurement {
|
||||
//based off of: https://www.nxp.com/docs/en/application-note/AN4248.pdf
|
||||
|
||||
let corrected_mag_y =
|
||||
mag_measurement.z * sinf(attitde.roll) - mag_measurement.y * cosf(attitde.roll);
|
||||
// ø=roll,
|
||||
// θ=pitch,
|
||||
// Bp{xyz} is magnometer readings,
|
||||
// V{xyz} is the magnometers constant hard-iron compnent, (currently taken care by micro:bits
|
||||
// library)
|
||||
|
||||
let corrected_mag_x = mag_measurement.x * cosf(attitde.pitch)
|
||||
+ mag_measurement.y * sinf(attitde.pitch) * sinf(attitde.roll)
|
||||
+ mag_measurement.z * sinf(attitde.pitch) * cosf(attitde.roll);
|
||||
let corrected_mag_y =
|
||||
mag_measurement.y * cosf(attitde.roll) - mag_measurement.z * sinf(attitde.roll);
|
||||
let corrected_mag_z = -mag_measurement.x * sinf(attitde.pitch)
|
||||
+ mag_measurement.y * cosf(attitde.pitch) * sinf(attitde.roll)
|
||||
+ mag_measurement.z * cosf(attitde.pitch) * cosf(attitde.roll);
|
||||
|
||||
NedMeasurement {
|
||||
x: corrected_mag_x,
|
||||
y: corrected_mag_y,
|
||||
z: 0.0,
|
||||
z: corrected_mag_z,
|
||||
}
|
||||
}
|
||||
|
||||
//0 is the top sector and positive is clockwise, negative is counterclockwise.
|
||||
pub fn heading_from_measurement(measurement: NedMeasurement) -> Heading {
|
||||
pub fn heading_from_measurement(measurement: &NedMeasurement) -> Heading {
|
||||
Heading(atan2f(-measurement.y, measurement.x))
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue