c't

c't-Projekte - Mailinglisten


[Voriger (Datum)] [Nächster (Datum)] [Voriger (Thread)] [Nächster (Thread)]
[Nach Datum][Nach Thread]

AW: AW: [ct-bot] MAP-Verhalten nur fuer Sim ? -> Patch fuer Verhalten

Absender: Frank Menzel
Datum: Mi, 27.08.2008 20:50:53
In-reply-to: <6B04F1F3-9EF5-45B6-A0ED-84BB88DF6D13@xxxxxxxxxxxxxxx>


Hallo Timo,
habe jetzt auf dem echten doch testen können, wobei mir noch einiges
aufgefallen ist:
Während der Geradeausfahrt hält er einfach an, weil wohl so viele
Mapdaten zu aktualisieren sind und nicht hinterherkommt (nehme ich
jedenfalls an). Und wenn er dann weiterfährt, fährt er nicht geradeaus
sondern schräg. Er hält damit jedenfalls beim Geradeausfahren bis zu
einem Hindernis nicht seine Spur obwohl die Motorregelung ein ist. Somit
ist die eigentliche Geradeausfahrt schon eckig und kurvig. Bringt hier
die Map die Regelung durcheinander ?

Dann ist hier auch manchmal, wie auch im sim, zu beobachten, dass er
sich plötzlich ein- bis mehrmals im Kreis dreht, um erst dann seinen
Zielpunkt anzusteuern. Ist da noch möglicherweise ein bug in
bot_goto_pos ?

Dann geht ja jetzt das Löschen der Map wahnsinnig schnell, wo es noch
vor kurzem ewig gedauert hat. Ein Knopfdruck, kurzes grünes Aufleuchten
und schon fertig. Ist dies wirklich so (wenn ja Lob !)?

Gruß, Frank


-----Ursprüngliche Nachricht-----
Von: ct-bot-entwickler-bounces@xxxxxxxxxxxxxxxxx
[mailto:ct-bot-entwickler-bounces@xxxxxxxxxxxxxxxxx] Im Auftrag von Timo
Sandmann
Gesendet: Mittwoch, 27. August 2008 18:52
An: Entwicklung rund um den c't-bot
Betreff: Re: AW: [ct-bot] MAP-Verhalten nur fuer Sim ? -> Patch fuer
Verhalten

Hallo Frank,

Am 27.08.2008 um 08:09 schrieb Menzel, Frank IT-OO4:
> Hallo Timo,
> es gibt für die linke und rechte Spur jeweils ein Beobachter- 
> Verhalten, welches diese Spur im Auge behält. Darin gibt es schon  
> einen Timer, um erst nach Ablauf einer bestimmten Zeit auf die Map  
> zuzugreifen, da es beim echten ja sonst zur Mapüberlastung kommen  
> würde.

ja das ist mir auch nicht so ganz klar geworden: Wenn nur alle 700 ms  
auf die Map zugegriffen wird, ist es aber ja trotzdem ein reines  
Lotteriespiel, ob die Map gerade frei ist oder nicht. Dafür gibt es  
eigentlich die Funktion map_locked(). Außerdem bringt es ja nichts,  
seltener in der Map nachzuschauen, wenn man dafür dann einen größeren  
Bereich seit dem letzten Check prüfen muss (dauert dann entsprechend  
länger). Am Sinnvollsten erscheint mir, nach X cm gefahrener Strecke  
die letzten X cm nebendran zu prüfen. Entscheidend ist eigentlich nur,  
ob das Überwachen der Nebenspuren zeitlich noch passt oder nicht, wie  
oft man die Abfrage dann macht (solange derselbe Bereich nicht  
mehrfach überprüft wird), sollte eigentlich egal sein.

> Ist die Map schon erforscht und es wird ein Hindernis auf der  
> Nebenbahn laut Map (nach Ablauf der Zeitspanne seit letztem Check)  
> erkannt, dann wird die bis zu dem Hindernis freie Strecke auf dem  
> Stack vermerkt. Es wird dann wieder nach dem nächsten gültigen  
> Startpunkt nach dem Hindernis gesucht und so geht es weiter. An  
> einem Hindernis voraus angekommen entscheidet er sich für eine  
> Richtung, vorzugsweise rechts, und fährt diesen rechts vom bot  
> berechneten Startpunkt der Nebenbahn an. Wäre links auch eine freie  
> Alternative gewesen, wird die linke Strecke (Start- und Endpunkt)  
> auf den Stack gespeichert. Geht es irgendwann einmal nicht mehr für  
> den Bot weiter, also rechts oder links von ihm Hindernis oder schon  
> befahren, wird eine Strecke aus dem Stack geholt (dieser enthält ja  
> nur unbefahrene Strecken) und angefahren. Beim Anfahren einer vom  
> Stack geholten Strecke liegt diese ja durchaus relativ weit weg vom  
> bot und der Weg dorthin kann auch von einem Hindernis verstellt  
> sein. Zum Anfahren müßte eigentlich ein Pfadplanungsverhalten her,  
> welches es aber noch nicht gibt. Der bot kann somit diese Strecke  
> nur direkt anfahren, d.h. einen der beiden Streckenpunkte,  
> vorzugsweise den nahesten. Ist dieser nicht erreichbar aber der Weg  
> zum anderen Punkt frei, wird dieser angefahren und versucht, von  
> dort aus die Strecke zu befahren. Ist diese auch nicht anfahrbar,  
> wird die Strecke verworfen und die nächste vom Stack geholt. Ohen  
> den Pfadplaner kann es somit auch zu unbefahrenen Stellen kommen.
> Nach dem Stackholen werden auch lange Strecken geradeaus gefahren,  
> um den neuen Weg zu erreichen. Und hier bin ich aber auf das Map- 
> Update voraus (der Hindernisse) angewiesen. Das Anfahren erfolgt  
> hier zweistufig, einmal bis 30cm vorher. Dann wird der Punkt auf  
> Mapwert geprüft und bei Hinderniswahrscheinlichkeit möglicherweise  
> der andere Punkt angefahren. Also einfach Abschalten des Map-Updates  
> bei Geradeausfahrt geht nicht, für die Freistrahlen schon (werden  
> nicht gebraucht).

Ja du kannst zwar mit set_scan_otf_distance(0) das Distanzsensorupdate  
ausschalten, bis voraus ein Hindernis erkannt wird und dann wieder  
einschalten, aber das ist natürlich ein bisschen umständlich.
Sollten wir das Distanzsensorupdate vielleicht feiner steuerbar  
machen? Also "ganz an" oder "ganz aus" oder "nur Hindernisse  
eintragen"? Das könnte sinnvoll sein, weil gerade das Update der  
Freistrahlen sehr lange dauert.
Vielleicht funktioniert das Verhalten aber auch mit Distanzsensoren  
immer an, müsste man mal ausprobieren, wie viel Zeit das Überwachen  
der Nebenspuren wirklich braucht und ob das in die "Lücken" des Map- 
Updates passt.

> Mit dem Bereitstellen einer allgemeinen "Auslese-Funktionalität"  
> habe ich nicht so recht verstanden.

Das Problem bei der Map auf einer SD-Karte / MMC ist, dass ein  
(Schreib-)Zugriff (512 Byte) unterschiedlich lange dauert, je nachdem,  
ob der gewünschte Block noch im selben Cache-Block des MMC-Controllers  
wie der letzte benutzte Block ist oder nicht (im ersten Fall dauert es  
1 ms und im Zweiten können es auch 50 ms werden, je nach Karte usw.).  
Daher kann man keine genaue Aussage treffen, wie lange ein Map-Update  
dauert und somit auch nicht exakt planen, ob es in Echtzeit während  
der Fahrt geht oder nicht. Darum läuft das Schreiben auf die Karte  
jetzt im Hintergrund, also letztlich immer dann, wenn der Bot alles  
für einen Zyklus bereits erledigt hat, aber seine Zykluszeit von 10 ms  
noch gar nicht aufgebraucht hat. Da ein Schreibzugriff deutlich länger  
als 10 ms dauern kann, muss man ihn folglich unterbrechen, um einen  
neuen Durchlauf der Bot-Main-Schleife ausführen zu können.
Genau das passiert seit dem Map-Umbau auch. Der Nachteil an der ganze  
Sache ist, dass man natürlich während ein Schreibzugriff pausiert ist,  
nicht lesend auf die MMC zugreifen kann. Da unbekannt ist, wie lange  
ein Schreibzugriff dauert (s.o.), kann man nicht voraussagen, wann man  
lesend auf die MMC (und somit auf die Map) zugreifen kann. Die  
Funktion map_locked() gibt Auskunft darüber, ob die Karte gerade  
gesperrt ist, oder man auf sie zugreifen kann.
Greift man (über eine der Funktionen aus map.h) auf eine gesperrte  
Karte zu, wird der Zugriff solange verzögert, bis die Karte wieder  
frei ist. Allerdings werden damit auch alle anderen Bot-Aktivitäten  
(Sensorupdates, Notfallverhalten usw.) blockiert, es wird alles  
angehalten und das Map-Update zu Ende geführt. Nicht besonders  
elegant, aber auf Grund der beschränkten Ressourcen des ATmegas ein  
Kompromiss.
Der Gedanke dabei ist, dass man die Karte eben nur dann ausliest, wenn  
entweder map_locked() == 0 oder wenn der Bot stillsteht, denn dann  
schadet es nicht, falls keine Sensorupdates und Notfallverhalten  
ausgeführt werden. Soviel erstmal zum allgemeinen Ablauf bei der Map  
(ich weiß es fehlt noch eine anständige Dokumentation...)

Was ich mit einer allgemeinen Funktionalität zum Auslesen der Map  
meinte: Dein neues Verhalten könnte jetzt entweder mit map_locked()  
usw. seine Zugriffe selbst koordinieren, oder wir machen genau wie für  
das Map-Update ein Gegenstück zum Auslesen der Map. Also dass man  
sagen kann, ich möchte gern die und die Auskunft von der Map  
(irgendeine der Funktionen, die es in map.h gibt), die eigentliche  
Abfrage wird dann auch im Hintergrund ausgeführt und wenn das Ergebnis  
zur Verfügung steht, kann es vom Verhalten, das es braucht,   
"abgeholt" werden.
Für ein Verhalten, das die Map benutzen will, lohnt sich das  
vielleicht nicht, aber wenn es mehrere Verhalten gibt, die ähnliches  
brauchen, macht es vielleicht Sinn, das Ganze zentral vom Map-Code aus  
bereitzustellen?

> Beim echten bot sollte es eigentlich auch funktionieren, habe mit  
> diesem aber momentan ein paar Problemchen und kann nicht testen...

Oh sorry, da im Betreff steht "nur für Sim", habe ich es auf dem  
echten Bot gar nicht erst ausprobiert, werde ich mal nachholen!

Was mir beim Testen im Sim aufgefallen ist: Wenn der Bot bis zur Wand  
rechts (oder links) vorgedrungen ist (die aber noch nicht als  
Hindernis in der Map steht), crasht er irgendwann seitlich in die Wand  
und hängt dort fest. Das ist eigentlich bei allen Welten im Sim so.  
Dadurch kommt es leider nie zu dem Fall, dass das Verhalten den Bot  
zur anderen Seite der schon abgefahrenen Fläche schickt, was aber ja  
eigentlich einer der interessantesten Fälle ist.

Grüße,
Timo


_______________________________________________
ct-bot-entwickler Mailingliste
ct-bot-entwickler@xxxxxxxxxxxxxxxxx
http://www.heise.de/bin/newsletter/listinfo/ct-bot-entwickler