c't

c't-Projekte - Mailinglisten


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

RE: Fwd: Re[2]: [ct-bot] ct-Bot-Wettkämpfe

Absender: Timo Sandmann
Datum: Mi, 26.04.2006 03:19:08
In-reply-to: <444EA4CE.4020907@xxxxxxxxxx>


Hallo,

> Ich habe aber auch schon an funktional gegliederte 
> Bibliotheken gedacht. Die aktuellen Quellen sind viel zu 
> komplex, um Einsteigern das Leben einfach zu machen, 
> insbesondere schreckt das sicherlich gut gemeinte 
> Behaviour-System doch eher ab, da man eben doch dort nach- 
> schauen muß, warum der Bot gerade etwas bestimmtes macht.

Sorry, aber ich verstehe nicht so ganz, was noch so gegliederte Bibliotheken
am Behaviour-System ändern sollten. Soweit ich verstanden habe, was uns so
beigebracht wird, sollten weder Compiler- noch Linkeroptionen die Logik der
Algorithmen beeinflussen. Ob der Linker nun frisch übersetzten Quellcode
oder alte libs verwendet, sollte IMHO Einsteigern doch eigentlich ziemlich
egal sein.

> Wenn man z.B. die Licht/Wandfolger-Quellen aus dem anderen 
> Forum anschaut, wird das Problem sofort offensichtlich: dort 
> braucht es zehn bis zwanzig Zeilen Code, um eine absolut 
> simple Fahrstrategie umzusetzen. 

Es spricht meiner Meinung nach wirklich nichts gegen einfachen Code, aber
ist der Sinn eines Frameworks nicht eine umfassende Implementierung der von
der Hardware bereitgestellten Funktionalitäten? "Das Problem" scheint mir
hier eher ein etwas unpassender Vergleich zu sein, zum Addieren brauche ich
nur einen Taschenrechner, der selbstverständlich kein vom PC bekanntes
Betriebssystem benötigt und dementsprechend auch einfacher programmiert ist.
Deshalb kann ich aber doch nicht sagen, ein PC-Betriebssystem sei zu komplex
aufgebaut.

> Als anderes Beispiel mag das 
> Turtle-Konzept der Sprache Logo herhalten: zum Lernen auch 
> komplexerer Zusammenhänge und Problemstellungen war das 
> System hervorragend geeignet, obwohl oder eben weil das 
> Grundgerüst sehr einfach aufgebaut war.

Soweit ich weiß, wurde dieses einfache Grundgerüst vor allem durch den
Einsatz von Rekursion möglich. Das mag für einen abstrakten Lernprozess sehr
sinnvoll sein, ich weiß aber beim besten Willen nicht, was das hier zu
suchen hat. Wenn es doch darum geht, etwas zu vereinfachen, dann stellt sich
die Frage, inwieweit hierzu etwas undurchsichtige Beispiele hilfreich sein
könnten.
 
> Hätte ich die Zeit (momentan komme ich bzgl. der ct-Bots zu 
> garnix), würde ich wahrscheinlich versuchen, einige echte 
> Bibliotheken für die Sensoren/Aktorensteuerung vorzuschlagen 
> und mit zu entwickeln, die wirklich nur einfachste 
> Schnittstellen bieten:

Sind es denn nicht die Funktionen, die die Schnittstellen bilden? In welcher
Form diese als Maschinencode auf einem physischen Datenträger liegen
(lib-Files oder Object-Files) spielt doch keine Rolle für die in eigenen
Verhalten zu verwendenden Schnittstellen?!? 

>   - momentaner Wert Rad/Kante/Distanz/Linie rechts/links (keine
>     globalen Variablen, sondern Funktionsaufrufe),

Hierbei sollte man aber auch bedenken, was Funktionsaufrufe letztlich sind
und was sie auf der verwendeten Architektur kosten. Und macht man sie
inline, wird vermutlich bald der Flashspeicher knapp.

>   - Setzen der Motorengeschwindigkeit rechts/links,

Aber gerade hier sticht doch die Modularität des bisherigen Frameworks, wo
man die low-level-Motorfunktionen eben _nicht_ zu verwenden braucht. Ich
weiß leider wirklich nicht, was hier auf die dargestellte Weise zu
verbessern wäre.

>   - Setzen anderer Aktoren (LEDs etc.)
>   - momentane Werte anderer Sensoren (auch IR etc.).
> 
> Wenn dann das existierende Framework auf dieser simplen 
> Bibliothek basieren würde, könnte der bis jetzt eher 
> verwirrte Anfänger das Framework einfach wegwerfen (nicht 
> benutzen), die Bibliothek in das eigene, leere Projekt 
> einbinden, und Code ala

Ich verstehe nicht, wieso das existierende Framework eine (neue) Bibliothek
benutzen sollte, wo es doch selber höchst modular aufgebaut ist und die von
einer derartigen Bibliothek (bzw. deren Funktionen) gelieferten
Schnittstellen selbst schon mitbringt.
Auch frage ich mich, woher der Anfänger dann weiß, welche Funktionen der
Bibliothek er benutzen kann / soll? Durch die Bibliothek kann er das nicht
im Quellcode nachschlagen, es bleibt dem viel zitierten Anfänger also nur
das Nachschlagen in einer Dokumentation. Genau das kann er jetzt aber auch
tun und den folgenden Beispielcode genauso verwenden. 
Um genau dieses Problem zu verringern, hatte ich ja auch bereits eine
grafische Übersicht vorgeschlagen.

> int main()
> {
>     led(LEFT_BLUE,ON);
> 
>     while (1)
>     {
>        if (sensor(DISTANCE,LEFT) < 30)
>           motor(BACKWARD,10,30); // rechts etwas, links stärker zurück
>        else if (sensor(DISTANCE,RIGHT) < 30)
>           motor(BACKWARD,30,10); // rechts stärker, links etwas zurück
>        else
>           motor(FORWARD,30,30);  // gleichmässig nach vorn
> 
>        pause(10);                // zehn ms Pause
>     }
> }
> 
> schreiben. Im obigen Falle gäbe es keine Verarbeitung von 
> RC-Kommandos, keine echte Kollisions/Kantenvermeidung usw. 
> Perfekt um zu lernen, und einfach dazu. Zehn Zeilen, und der 
> Bot rennt los.

Nun ist nur die Frage, wer dabei was lernt. Um Programmieren zu lernen,
brauche ich keinen Bot programmieren. Und wenn ich lernen will einen Bot zu
steuern, dann erscheint mir ein Ansatz, der eben all das abdeckt, was der
Bot auch kann, sinnvoller. Wie implementiere ich nach obigem Schema denn
RC-Kommandos, echte Kollisions-/Kantenvermeidung usw.? Was habe ich
übersehen, dass der vorgeschlagene Ansatz nicht in eine Sackgasse führt?

> Zudem würde eine derartige Kapselung (nicht eben nur auf 
> Quelldatei- Basis, sondern direkt auf Projekt/Binärbasis) 
> erlauben, komplexe Änderungen ohne die momentanen 
> Abstimmungsprobleme zu beginnen.

Das kommt IMHO ganz darauf an, wo die Änderung liegt. Sobald sie die
Schnittstellengrenze berührt, wird man immer Probleme bekommen. Je weiter
ich diese Grenze "nach oben" verschiebe, desto mehr kann ich intern ändern,
ohne dass sich für den high-level-Programmierer etwas ändert, klar. Nur wird
der nutzbare Funktionsumfang damit doch immer kleiner. Treibt man das Ganze
auf die Spitze, dann stellt die Schnittstelle nur noch die Funktion go()
bereit und der Bot macht irgendwas, das in dieser Kapselung implementiert
ist. Intern kann ich hier ändern, wie ich lustig bin, der go()-Aufruf bleibt
immer gleich, aber sinnvoll scheint das nun nicht zu sein. 
Wir haben ja bereits jetzt entsprechende Schnittstellen an _sinnvollen_
Stellen. Nun mag man die ein oder andere Funktion als zu low oder zu high
angesiedelt finden, das hat aber meiner Meinung nach nichts mit dem
Grundsatz des Frameworks zu tun. 
Was aber sich ändern soll, wenn ich teile des Frameworks (eben die unterhalb
der angesprochenen Schnittstellengrenzen) vorkompiliert ausliefere und dann
erst beim Linken hinzufüge, will mir noch immer nicht einleuchten. 
Man könnte fast das Gefühl bekommen, als zielte der Vorschlag in Richtung
eines pseudo-objektorientierten Ansatzes (mit Klassen, die Funktionalitäten
kapseln und Schnittstellen nach außen bieten) unter dem Deckmantel des
Begriffs "Bibliothek". 

> Ich möchte mich z.B. irgendwann doch noch mal mit einem 
> Multithreading- Kern für den Bot befassen, dazu sollte aber 
> nirgends auf irgendwelche Variablen zugegriffen werden, die 
> eine Hardware-Nähe aufweisen, kein direkter Zugriff auf 
> irgendwelche I/O-Ports usw.usf.

Sondern? Jeden HW-Zugriff in Funktionen kapseln, am besten mit Mutex & Co.?
Der arme Atmega32... 
 
> So könnte obiges motor() im ersten Stadium direkt aus 
> bestehendem Code zusammengesetzt werden, später könnte das 
> eine Signalfunktion für einen Aktorenthread sein, die diesem 
> Thread die Werte übergibt, und ihn dann aufweckt. Den 
> Threading-Kern könnte ich sowohl obigem Miniprojekt als auch 
> dem aktuellen Behaviour-Projekt unterjubeln.
> 
> Eine Aufteilung in verschiedene Bibliotheken und einem 
> Hauptprogramm würde wahrscheinlich auch die CVS-Verwaltung 
> vereinfachen, da weitaus weniger Quelldateien pro Projekt zu 
> überschauen wären.

Ob das ein Vorteil wäre, sei mal dahingestellt, auf jeden Fall bekommt man
dann IMHO aber schnell ein (unüberschaubares) Versionschaos der vielleicht
überschaubaren Bibliotheken.
 
> Ist natürlich nur eine Idee von vielen, ob es wirklich 
> motor() heissen oder drei Parameter haben sollte, ist nicht 
> wirklich relevant. Die Schnittstellen müssten gut durchdacht 
> und letztlich so simpel wie nur möglich sein. 

Ich bitte die (zu?) deutlichen Worte zu entschuldigen, aber wenn man der
Meinung ist, das vorhandene Framework sei für Einsteiger zu komplex, dann
sollte man an den Ursachen, die es zurzeit unübersichtlich machen, etwas
ändern, nicht an der Form der Maschinen- oder Quellcodeablage auf der
Platte. 
Einerseits ging es um den Vorteil eines modularen Aufbaus, der zweifellos
bereits vorhanden ist und eben den großen Vorteil des Frameworks ausmacht,
andererseits um Bibliotheken (deren Sinn mir auch nach mehrmaligem Lesen der
eMail nicht zugedacht zu sein scheint), die aber die Module logisch nur zu
Paketen zusammenschnüren und implementierungstechnisch sowie
verständnismäßig keinen erkennbaren Unterschied bieten. 

Nach vergeblichem Suchen des roten Fadens wäre ich dankbar für Hinweise auf
diesen und natürlich andere Meinungen zum Thema!

Mit freundlichen Grüßen
Timo Sandmann