PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Bestimmte Anzahl an Sekunden etwas ausführen



Pyrgo
29.07.2008, 15:23
Ich werde leicht verrückt. :D

Ich habe mich mit den Beispielprogrammen beschäftigt und bin gerade dabei eines nachzuschreiben, aber ohne zu schmuhen. :D

Er soll bei Berührung mit den Tastern oder bei Blickkontakt mit Gegenständen (ACS) rückwärts fahren und wenden.

Klappt alles prima, nur wie realisiere ich mit C eine Art Timer. Wenn er anfängt rückwärts zu fahren, hört er nicht mehr auf. Klar. Aber wie haben die das in den Beispielprogrammen gelöst, dass er nur 2 Sekunden rückwärts fährt, 1 Sekunde wartet, 2 Sekunden wendet und dann weiter geradeaus fährt?

Ich hab deren Code durchforstet aber ich schein echt zu blöd zu sein das zu finden. :D

SlyD
29.07.2008, 15:28
Hallo,

Stichwörter:
Stopwatches
und
mSleep

State Machines sind auch nützlich.
Such auch mal im Forum danach, ich hab irgendwann mal ne recht universelle Statemachine für Bewegungsabläufe gepostet (lange her).

MfG,
SlyD

PS:
Das reicht allerdings nur für einfache Sachen.
Für komplexere Verhalten musst Du Dir mal ansehen wie man einen verhaltensbasierten Roboter realisieren kann (Subsumptions Architektur)

Pyrgo
29.07.2008, 15:31
Hallo,

Stichwörter:
Stopwatches
und
mSleep

State Machines sind auch nützlich.
Such auch mal im Forum danach, ich hab irgendwann mal ne recht universelle Statemachine für Bewegungsabläufe gepostet (lange her).

MfG,
SlyD

Also meiner Erfahrung nach kann es mit mSleep nicht gehen, aber ich sag lieber nix dazu, ist ja kein Delphiforum hier. :D

Stopwatches ... ich könnte mich erhängen. Ich hielt das für irgendwas Unwichtiges und habe es gnadenlos ignoriert. :-#

SlyD
29.07.2008, 15:32
beachte auch oben mein PS: ;)

Pyrgo
29.07.2008, 16:20
beachte auch oben mein PS: ;)

Hm .. ich probier jetzt seit gut 2 Stunden rum. Es will einfach nicht. [-(

Er führt bei mehreren StopWatches immer nur meine erste Abfrage durch, manchmal auch gar nix. Liegt aber an mir. Ich komm damit noch nicht ganz zurecht.

Sollte ich in den nächsten 2 Stunden auch keinen Erfolg haben, werde ich hier nochmal posten. =P~

SlyD
29.07.2008, 16:23
Also Du kannst ja evtl. doch mal in eines der Beispielprogramme reinschauen wo die Stopwatches erklärt werden... und in der Anleitung steht auch was dazu.

;)

Pyrgo
29.07.2008, 16:27
Also Du kannst ja evtl. doch mal in eines der Beispielprogramme reinschauen wo die Stopwatches erklärt werden... und in der Anleitung steht auch was dazu.

;)

Ich weiß ... ich schreib die die ganze Zeit um. Aber irgendwann klappt dann gar nichts mehr. :D

Pyrgo
29.07.2008, 16:39
Ich habe eben mal zugeschaut ob alle meine Schleifen, etc. durchlaufen werden. (In dem Terminal). Habe bei jeder If-Abfrage einfach einen String ausgegeben.

Und siehe da, ich bin gar nicht so blöd. :D Er führt das alles im Sekundenrythmus aus, wie er es auch soll. Nur leider macht er nichts. Er hält weder an, noch dreht er sich. Er fährt einfach weiter. :(


#include "RP6RobotBaseLib.h"

void bumpersStateChanged(void)
{
if(bumper_left)
{
startStopwatch1();
uint8_t counter = 1;
while(true)
{
if(getStopwatch1() > 1000)
{
if(counter == 1)
{
moveAtSpeed(0,0);
writeString_P("#### 1");
}

if(counter == 2)
{
changeDirection(BWD);
moveAtSpeed(50,50);
writeString_P("#### 2");
}

if(counter == 3)
{
moveAtSpeed(0,0);
writeString_P("#### 3");
}

if(counter == 4)
{
changeDirection(FWD);
moveAtSpeed(80,30);
writeString_P("#### 4");
}

if(counter == 5)
{
moveAtSpeed(0,0);
writeString_P("#### 5");
}

if(counter == 6)
{
moveAtSpeed(50,50);
writeString_P("#### 6");
}
if(counter == 7)
{
stopStopwatch1();
exit;
writeString_P("#### 7");
}
counter++;
setStopwatch1(0);
}
}
}

if(bumper_right)
{

}
}


int16_t main(void)
{
initRobotBase();
setLEDs(0b111111);
mSleep(1000);
setLEDs(0b001001);

ACS_setStateChangedHandler(acsStateChanged);
BUMPERS_setStateChangedHandler(bumpersStateChanged );

powerON();

setACSPwrMed();
// setACSPwrLow(); // Low power
// setACSPwrHigh(); // High Power
// setACSPwrOff(); to turn it off completely!

changeDirection(FWD);
moveAtSpeed(50,50);
while(true)
{
task_RP6System();
}
return 0;
}


Ist das jetzt ein Problem mit den Stopwatches oder liegt das eher an einem anderen Problem in meinem Code? Sicherlich nicht sehr elegant gelöst, aber das war immerhin meine 8. Idee oder so das zu realisieren, nachdem die 7 davor auch nicht gingen. :D

SlyD
29.07.2008, 16:58
ne ne also in bumperstatechanged gehört KEINE Endlosschleife rein!
Nichtmal nen Delay mit mSleep oder sonstigen blockierenden Funktionen.
Für sowas besser einfach direkt bumper_left und right abfragen in ner Schleife und nicht die automatik Funktionen der Lib verwenden - dafür sind die nicht gedacht.

Die Funktion wird immer dann aufgerufen wenn sich der Bumperzustand ÄNDERT. Dann kann man da kurz z.B. den Programmzustand ändern, LEDs setzen, ne Debug Message ausgeben oder sowas in der Art, aber keine Endlosschleifen bitte ;)

Das sich nichts mehr ändert liegt einfach daran, dass dann task_RP6System nicht mehr aufgerufen wird (ist ja dann nicht mehr in der Main Loop drin).
Das ist aber auch ganz gut so - denn sonst würde jedesmal wenn die Bumper gedrückt würden bumpersStateChanged aufgerufen und wenn man das dann zu oft machen würde gäbe es irgendwann einen Stack Overflow ;)

MfG,
SlyD

Pyrgo
29.07.2008, 17:05
Hm, wenn ich dich recht verstehe, wäre das dann besser: (hatte ich vorher so, ging dann aber total schief :D):

Ich rufe setze eine globale Variable, z.B. "State" auf "BumpLeft". Und in der While-Schleife der Hauptprozedure frage ich nach task_RP6System ab:

Wenn State == BumpLeft, dann ...

Und da kommt dann die ganze Schose mit StopWatch rein. Oder habe ich dich falsch verstanden?

SlyD
29.07.2008, 17:10
Jap so ähnlich ist es in den Beispielen auch gelöst.

steveLB
30.07.2008, 12:11
void seltsame_fahrweise(void)
{
startStopwatch1(); //stopwach starten

if(getStopwatch1() >= 5000) // weiter gerade aus
{
changeDirection(FWD);
moveAtSpeed(50,50);
setStopwatch1(0); // stopwatch beenden
}
else if (getStopwatch1() >= 3000) //2sec wenden
{
changeDirection(FWD);
moveAtSpeed(80,30); //deine art zu wenden
}
else if (getStopwatch1() >= 2000) //1sec warten
{
moveAtSpeed(0,0);
}
else if (getStopwatch1() < 2000) //2 sec rueckwaerts
{
changeDirection(BWD);
moveAtSpeed(50,50);

}
}


// aufrufen mit-> seltsame_fahrweise();


und wenn eine bumper betaetigung das ausloesen soll kannst ja :
if (bumper_left)
{
seltsame_fahrweise();
}
benutzen

so wuerd ich das loesen