Beräkna vinkel från x och y

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
Användarvisningsbild
jesse
Inlägg: 9233
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Beräkna vinkel från x och y

Inlägg av jesse »

Jag håller på med ett litet projekt där många vinklar ska beräknas från sensordata.
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);
}
Då kommer man väldigt nära korrekt värde.
vinkel_xy.png
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. :mrgreen:
(EDIT: stavfel)
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Senast redigerad av jesse 24 september 2017, 13:39:52, redigerad totalt 1 gång.
kodar-holger
EF Sponsor
Inlägg: 916
Blev medlem: 26 maj 2014, 12:54:35
Ort: Karlskoga

Re: Beräkna vinkel från x och y

Inlägg av kodar-holger »

Användarvisningsbild
lillahuset
Gått bort
Inlägg: 13969
Blev medlem: 3 juli 2008, 08:13:14
Ort: Norrköping

Re: Beräkna vinkel från x och y

Inlägg av lillahuset »

Vad har du tänkt att använda för processor?
Har du övervägt att skippa flyttal och använda heltal?
Användarvisningsbild
mankan
EF Sponsor
Inlägg: 905
Blev medlem: 18 juli 2015, 11:23:22
Ort: Linköping

Re: Beräkna vinkel från x och y

Inlägg av mankan »

Vad har du för CPU egentligen? Skippa roten ur på amplituden är det mest uppenbara.
Användarvisningsbild
baron3d
EF Sponsor
Inlägg: 1339
Blev medlem: 1 oktober 2005, 23:58:43
Ort: Torestorp

Re: Beräkna vinkel från x och y

Inlägg av baron3d »

För positiva tal, A > B
L = A + B*0.4

Lite korrigering på detta...
Användarvisningsbild
jesse
Inlägg: 9233
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: Beräkna vinkel från x och y

Inlägg av jesse »

lillahuset skrev:Vad har du tänkt att använda för processor?
Har du övervägt att skippa flyttal och använda heltal?
Jag tänker generellt, alla microcontrollers från 8-bit Attiny till 32 bit.
Jag använder aldrig flyttal. 16 eller 32 bit heltal brukar duga alldeles utmärkt.
Formlerna ovan är inte anpassade för heltal eftersom man i så fall först måste veta saker som max amplitud och upplösning, så det beror ju på applikationen.
(Jag ser nu att jag skrivit 'int' i kodexemplet. Det funkar kanske inte så bra ihop med tal som 22,5 (dessutom med kommatecken! ), men det är tanken som räknas :)
Användarvisningsbild
lillahuset
Gått bort
Inlägg: 13969
Blev medlem: 3 juli 2008, 08:13:14
Ort: Norrköping

Re: Beräkna vinkel från x och y

Inlägg av lillahuset »

Om du läser kodar-holgers länkar kanske du tänker lite mindre generellt:
But the packages unfortunately isolate us from these grimy computational details, which can lead to significant performance penalties. A fast desktop with built-in floating point hardware can return a cosine in a few tens of nanoseconds. But the same function often takes many milliseconds on embedded systems.

Or even longer. Everyone recognizes that to do a double-precision trig function (as required by the C standard) would take about a week on an 8051, so most of those compilers cheat and return shorter floats.
Användarvisningsbild
lillahuset
Gått bort
Inlägg: 13969
Blev medlem: 3 juli 2008, 08:13:14
Ort: Norrköping

Re: Beräkna vinkel från x och y

Inlägg av lillahuset »

Kom just att tänka på att jag någonstans har en artikel från BYTE från 70-talet (?) om CORDIC som var rätt intressant. Passar bra för processorer utan multiplikator.
På nätet finns det en del artiklar om det. En av de första applikationerna i "modern tid" verkar ha varit att förbättra precisionen när man genom bombning jävlas med folk på marken. :(

https://en.wikipedia.org/wiki/CORDIC
https://dspguru.com/dsp/faqs/cordic/
https://duckduckgo.com/?q=cordic+algorithm&t=lm&ia=web
Nerre
Inlägg: 26655
Blev medlem: 19 maj 2008, 07:51:04
Ort: Upplands väsby

Re: Beräkna vinkel från x och y

Inlägg av Nerre »

Har man klen datorkraft så är väl det normala att man använder tabeller för att få lämpliga approximationer. Man kan öka "upplösningen" genom att interpolera mellan två värden i tabellen med linjär interpolering.

Det bästa är antagligen att försöka eliminera steget att gå via vinkel. Vill man verkligen ha ut vinkeln så går det såklart inte, men om vinkeln ändå bara ska användas som ett mellansteg så kanske man kan förenkla bort den. Ta fram alla formler som behövs och förenkla dem algebraiskt bara.
Användarvisningsbild
4kTRB
Inlägg: 18289
Blev medlem: 16 augusti 2009, 19:04:48

Re: Beräkna vinkel från x och y

Inlägg av 4kTRB »

För arctan finns några tips för de som håller på med DSP.

dsp TIPS&TRICKS
http://www-labs.iro.umontreal.ca/~migno ... nction.pdf
Användarvisningsbild
lillahuset
Gått bort
Inlägg: 13969
Blev medlem: 3 juli 2008, 08:13:14
Ort: Norrköping

Re: Beräkna vinkel från x och y

Inlägg av lillahuset »

Dessa approximationer är nog ännu intressantare för användare av "vanliga" processorer. Biblioteken för DSP brukar vara ganska väl optimerade. Men det är ju alltid intressant att lära sig mer. :)
Skriv svar