Sida 3 av 6

Re: Programeringsfrågor C++ radiostyrd båt

Postat: 13 juni 2018, 05:38:28
av Andax
Du har ju ungefär att:
X = A*cos(vinkel)+B
Y = C*sin(vinkel)+D
Där A, B, C och D är konstanter.
B och D är ju medelvärdet, och A och C är amplituden.

Räkna om X och Y så att de går mellan -1 och +1. Då kan du räkna ut vinkel som arctan(Y/X).
Titta på funktionen atan2 så slipper du problem med division med noll om X är nära noll.

Re: Programeringsfrågor C++ radiostyrd båt

Postat: 13 juni 2018, 12:06:31
av Glattnos
Tack för svaret :)

Från sensorn så är både X och Y koncentrerade runt 0, jag la på lite på varje värde för att göra alla positiva när jag gjorde kurvan(lite onödigt iofs). Om jag ska skala om så att X och Y går från -1 till 1 så måste jag alltså dividera med deras respektive max-värde?
Går det att göra något liknande detta:

Kod: Markera allt

Read_X();
if(X > X_max)X_max = X;
X /= X_max;

Read_Y();
if(Y > Y_max)Y_max = Y;
Y /= Y_max;

Angle = atan2(Y/X);
Detta borde kalibrera den om man kör runt ett varv och sedan kalibrera ytterligare under användning eller är det bättre att kalibrera en gång och sen låta det vara så för att undvika att den "över-kalibrerar"?
Jag är dock lite osäker eftersom det lästa värdet är i 2-komplementsform och jag måste ju även ta negativa max i beräkning. Är jag på rätt spår?

Re: Programeringsfrågor C++ radiostyrd båt

Postat: 13 juni 2018, 14:10:32
av Icecap
2-komplement är ju just heltal med förtecken så det är inte mycket att spekulera på.

Att göra om det till flyttal är enkelt.
Att räkna ut verkliga vinkeln baserat på X och Y ska väl inte heller vara ett problem, det finns formler för det.

Att "kalibrera" den på det vis du visar känns helt fel, det finns fasta värden som är ±max, använd dom.
Lite bra att veta 1
Lite bra att veta 2

Re: Programeringsfrågor C++ radiostyrd båt

Postat: 13 juni 2018, 17:54:46
av Andax
Funktionen atan2 tar två argument, just för att hantera fallet då X eller Y är noll och också de 4 kvadranterna korrekt.
Vinkel = atan2(Y, X)

Re: Programeringsfrågor C++ radiostyrd båt

Postat: 13 juni 2018, 19:23:05
av Glattnos
OMG it works! Tack så mycket!

Kod: Markera allt

//Variabler
int MagX;
int MagZ;
float DirectionX;
float DirectionY;

signed int Direction;
I2C1_Read(); //Läser in värdet från snesorn i MagX och MagY
	DirectionX = MagX;
	DirectionY = MagY;
	Direction = atan2(DirectionY, DirectionX) * 180 / 3.1416;
Men är det rätt att värdet från sensorn (som är i 16-bitars tvåkomplementsform) läses in i MagX(som är en int) och att den sedan kopieras in i DirectionX(som är en float)?
Sen är det lite konstigt även om det kvittar, men Direction 0 och Direction 180 ligger inte 180 grader ifrån varann utan snarare 90 grader ifrån varann. Spannet 0-180 ligger dock fint fördelat både på plus- och minus-sidan. Gör jag nått fel eller ska det vara så?

Re: Programeringsfrågor C++ radiostyrd båt

Postat: 14 juni 2018, 13:17:41
av Andax
Vad får du för värden på MagX och MagY för de fyra väderstrecken? Och vad får du för värde på Direction för dessa fyra fall?

Re: Programeringsfrågor C++ radiostyrd båt

Postat: 15 juni 2018, 22:04:28
av Glattnos
Om jag utgår ifrån att max-värdet på X motsvarar norr, vilket det verkar göra så blir det ungefär såhär:

X109 Y-26
X0 Y18
X-65 Y-91
X54 Y-137

Ser ju ganska mystiskt ut men det ligger i den regionen och är väldigt repeterbart när man återkommer till samma vinkel.

Re: Programeringsfrågor C++ radiostyrd båt

Postat: 15 juni 2018, 23:14:55
av Andax
Värdena du får ser ju skumma ut. I grafen du visade tidigare var ju Y kring mittvärdet då X var min eller max, och X kring mittvärdet då Y var min eller max, vilket är precis som det ska!
Men värdena du visar följer inte detta mönster nu!
Kan du samla in mätvärden på samma sätt som du gjorde då du plottade grafen?

Re: Programeringsfrågor C++ radiostyrd båt

Postat: 16 juni 2018, 00:43:43
av Glattnos
Det är värdena från grafen, det blir så om man drar ifrån dom 256 som jag la på där förut. Kurvorna blir likadana. Mycket skumt.
Men jag blir färdig med båten hårdvarumässigt imorgon så nästa vecka kommer det bli testning och försök att programmera den så jag kan ta nya mätvärden när båten faktiskt kör som det är tänkt med all övrig elektronik inkopplad.

Edit: Noterade nu att X pendlar kring ett värde högre än 0 och Y kring ett värde som är lägre än 0. Det är ju förmodligen det som gör skillnaden, är det måhända bara att "flytta" X neråt och Y uppåt för att det ska bli rätt? Frågan är ju varför det är så alls men det kanske inte är så bra sensor?
Det är en switch-regulator från 12V-batteriet --> 5 V och sen är det en linjär regulator från 5 --> 3.3V som driver sensorn.

Re: Programeringsfrågor C++ radiostyrd båt

Postat: 16 juni 2018, 02:06:04
av Andax
Justerar du dem så att de pendlar hyffsat symmetriskt kring noll så kommer det nog bli mycket bättre beräknade värden...

Re: Programeringsfrågor C++ radiostyrd båt

Postat: 17 juni 2018, 14:44:32
av Glattnos
Jag ska prova det så får vi se :)

En fråga till, varför ger detta varningen att jag jämför en signed med en unsigned integer:

Kod: Markera allt

#define SERVO_CENTER 3000
#define STEERING_OFFSET 0
#define SERVO_SPEED 2

#define STEERING OCR1A

int16_t Steering_Set = SERVO_CENTER + STEERING_OFFSET;

if(STEERING < (Steering_Set + STEERING_OFFSET)) STEERING += SERVO_SPEED;
Jag vill jämföra värdet i OCR1A med (Steering_Set + STEERING_OFFSET) och värdet i OCR1A kan ju inte vara signed, så vad jämför jag egentligen med i koden?

Edit: Hmmm...hjärnsläpp som vanligt. int16_t är ju signed

Re: Programeringsfrågor C++ radiostyrd båt

Postat: 18 juni 2018, 08:40:12
av Glattnos
Jag ämnar testa båten idag eller imorgon men har en liten fundering.
Är det möjligt att i ett interrupt sätta ett nytt ställe i programmet att fortsätta ifrån efter avbrottet?

Jag såg att det fanns en avbrotts-vector för watchdog-timern. Min tanke var om jag i det avbrottet skulle kunna tala om att den ska fortsätta på annat ställe efteråt samt eventuellt tända en LED som indikering att avbrott har inträffat. På så vis borde buggar som gör att programmet hänger sig inte göra att båten slutar fungera. Mitt manuella läge funkar, men det förutsätter att jag även kan växla till manuell från auto, och det går ju inte om programmet hängt sig i auto.
Det är mest för att minska risken för ”runaways” lite. Jag vill helst inte att den gör reset utan skulle bara vilja välja nytt ställe i min huvudloop att fortsätta ifrån.

Re: Programeringsfrågor C++ radiostyrd båt

Postat: 18 juni 2018, 15:11:17
av Icecap
Det ska gå att göra det - men det är extrem dålig programmeringsskick.

Det finns dock ett stort problem som är att du vill göra det i en interrupt. Då måste du rulla av returadressen från stacken, rulla in den "rätta" och sedan lämna interrupten. Det kan finnas andra värden på stacken som kan ge problem.

Men om du gör så usla program att de hänger sig är det mycket bättre att göra bättre program. Det är ju DU som styr om uträkningar kan riskera hänga sig så DU kan också avgöra när det finns risk för detta och då göra en "räddning".

Re: Programeringsfrågor C++ radiostyrd båt

Postat: 18 juni 2018, 19:25:41
av Glattnos
Problemet är att det är svårt att testa båten utan att släppa iväg den och då känns det bättre att använda en watchdog-timer om det går. Det är inte programmeringsfel jag vet om som jag ska rädda, utan fel jag inte vet om.
Men om det inte finns något "inbyggt" sätt att ändra retur-adress från avbrottet så får det bli en vanlig reset hellre än inget alls, då kan jag hur som helst få tillbaka manuell kontroll oavsett om programmet hänger sig :)

Re: Programeringsfrågor C++ radiostyrd båt

Postat: 18 juni 2018, 22:39:25
av Glattnos
Jungfruturen gick galant :) Manuellt läge funkar utmärkt men auto-läge kunde jag dock bara dutta lite på eftersom jag inte har programmerat den mer än att köra rakt med hjälp av GPS:en och kompassen.
Den gick väldigt rakt och stabilt på plattvatten men det återstår att se hur den klarar vågor.