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