Sensorer som accelerometrar och liknande ger ju ut data i form av treaxliga värden, x, y och z.
Vill man beräkna en rotationsvinkel utifrån x och y data finns ju en färdig formel:
v = arctan(x/y)
eller kanske
v = arcsin (x / sqr(x^2 + y^2))
(med reservation för att jag kanske har förväxlat x och y)
Detta är ju jobbigt och kräver en massa datakraft, särskilt om det är en applikation i en litet rörlig sak som snabbt ska ha reda på var den är nånstans och vart den är på väg.
Därför har jag hittat på ett sätt att approximera vinkel utifrån x och y data som bara kräver några enstaka beräkningar med de fyra räknesätten.
Ska man snabbt ta reda på ungefärlig vinkel använder man formeln v = x / (x+y) * 90 vilket blir förvånansvärt nära.
Vill man justera detta för ett mer exakt resultat lägger man till följande ekvation:
(V är beräknad vinkel enligt formeln ovan)
Kod: Markera allt
if (V < 45)
{
int Vc = V-22,5;
v = V+(Vc*Vc/128-4);
}
else
{
int Vc = V - (22,5 + 45);
v = V-(Vc*Vc/128-4);
}
Nu vill jag hitta något lika enkelt sätt att beräkna amplituden (längden) på en tvådimensionell vektor utifrån data (x,y) eller en tredimensionell vektor utifrån data (x, y, z).
Formlerna är enkla : a = sqr(x^2 + y^2) och a = sqr(x^2 + y^2 + z~2), men hur kan man förenkla den och approximera roten ur?
Jag kom att tänka på att sqr(2^n) = 2^(n/2).
Då kan man förenkla genom att kolla på vilken position högsta biten har i talet.
T.ex. beräkna sqr(10000).
MSB = bit 13. Det är en ojämn bit, så vi tar närmaste mindre jämna bit, dvs. bit 12.
sqr(2^12) = 2^6 dvs. 64.
ta bort 12 bitar och vi får talet (10000/4096) = 2,4414
Genom denna förenkling behöver vi bara beräkna roten ur ett tal melan 1 och 4.
Här kan vi t.ex. använda en tabell med 16 värden och interpolera fram ett svar.
Kan gå ruskigt snabbt, tar relativt lite minne och blir nog tillräckligt bra för beräkningar i realtid för farkoster som snabbt måste få reda på acceleration eller liknande.
Jag älskar såna här numeriska metoder.
(EDIT: stavfel)