Der "ct-Bot-Weihnachtskalender" - Programmieren lernen am Beispiel ohne Vorkenntnisse

Die Programmierung des c't-Bot
Antworten
anonybot
Friends of Sonny
Friends of Sonny
Beiträge: 118
Registriert: 07 Okt 2015, 00:14

Der "ct-Bot-Weihnachtskalender" - Programmieren lernen am Beispiel ohne Vorkenntnisse

Beitrag von anonybot » 09 Jun 2019, 23:29

Hallo zusammen,

wie im Chat heute kurz besprochen, folgende Idee: Ich habe einen ct-Bot funktionstüchtig aufgebaut, kann aber nicht prgrammieren, finde die entsprechendne heise-Artikel dazu nicht genügend aufschlussreich, um mir selbst zu helfen, will aber nun mit dem Bot auch etwas machen, was dem eigentlichen Sinn des ct-Bot-Projekts näher kommt.

Daher folgende Idee: Ich beschreibe hier sehr kleinteilig, was ich dem Bot "beibringen" will, hoffe auf Antworten, die mir sagen, wie ich die "Schrittchen" zum gewünschten Ziel erreichen kann. Dies selbstverständlich nicht in der Form, dass mir jemand etwas "vorprogrammiert", sondern dahingehend, dass ihr mir helft, punktuell am vorhanden Bot-Code zu verstehen, wie ich ein bestimmtes kleines Planziel umsetzen kann, ohne zwingend dafür das "große Ganze" verstehen zu müssen, also im Sinne kleinkindlichen Spracherwerbs von "einfach" zu "komplex", aber ohne dem "Kleinkind" eine "Grammatik" vorzulegen :wink: - ob das im Sinne des Erfinders ist, mag zweifelhaft sein, aber einen Programmierkurs besuchen werde ich auf absehbare Zeit nicht schaffen und das wird für min. zwei weitere Personen in meinem Freundeskreis auch ein "show stopper", daher dies auch als Experiment, ob wir den klassischen Code niedrigschwelliger einem breiteren Publikum erschließen können.

Aus den (wahrscheinlich sehr) vielen Fragen und Antworten werde ich nach Fertigstellung des Bot-Verhaltens ein Tutorial schreiben, das in die Doku fließt.

Also:

1. Ziele
  • Ein Bot-Verhalten, das einen (eigenwilligen) Adventskalender darstellt. Der Bot fährt dazu in der "Basisversion" auf einer schneckenförmigen schwarzen Linie, die auf ein Tablett, das als Untergrund dient, gezeichnet wird, von einer definierten Startposition aus so lange in eine Richtung, bis er eine von vierundzwanzig Foto-Dosen (die "Kalender-Türchen") eingefangen hat, dreht sich um und bringt die Dose zurück zum Startpunkt.
  • In einer zweiten Ausbaustufe könnte man dem Bot über eine Display-Abfrage sagen, wie oft er das Verhalten wiederholen soll, falls man mal einen Tag vergessen hat, eine Kalender-Tür zu öffnen, sodass er am nächsten Tag nacheinander 2 Foto-Dosen zum Ziel bringen soll.
  • In einer komplexeren Ausbaustufe könnte der Bot versuchen, auf die schwarze Leitlinie zu verzichten und die Dosen auf dem Tablett, das durch Wände begrenzt ist, mit Hilfe der Distanzsensoren suchen.
  • Das Verhalten sollte bis Ende November 2019 fertig sein, damit der Weihnachtskalender pünklich einsatzbereit ist. Klingt viel, ist aber wenig Zeit, da ich in den Abschlussprüfen bin und vielleicht auch mal ein paar Wochen nichts machen kann. Dies nur als Vorwarnung und Entschuldigung dafür, dass ich evtl. eine längere Zeit nicht antworte - ich verspreche aber dran zu bleiben. ;)
  • Um meinen guten Willen "dran zu bleiben" zu untermauern, habe ich für die Erstellung der virtuellen Testumgebung bereits (mit eax umfangreicher Hilfe) fehlende Kartenbauelemente ergänzt, die sich zusammen mit allen verfügbaren Elementen übersichtlich geordnet in einem Karten-Template im Develop-Code befindet.
2. Die virtuelle Testumgebung
advent-calendar.png

Code: Alles auswählen

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE collection SYSTEM "parcours.dtd">

<world>
	<description>
	Teststrecke fuer ctBot/bot-logic/behaviour_advent-calendar.c - ein Parcours, auf dem der Bot 24 Positionen entlang einer Linien-Schnecke abfahren und, stellvertretend fuer die Tuerchen eines Advents- bzw. Weihnachtskalenders, 24 Transportfach-Objekte einsammeln kann.
	</description>

<!-- Autor: anonybotATriseupDOTnet 2018-12-08 CC-BY-SA -->

	<parcours>
		<line>*===*</line>
		<line>#p_q#</line>
		<line>#(T(#</line>
		<line>#(((#</line>
		<line>#(((#</line>
		<line>#(((#</line>
		<line>#(((#</line>
		<line>#(((#</line>
		<line>#(bd#</line>
		<line>#(  #</line>
		<line>#$  #</line>
		<line>*]==*</line>
	</parcours>

<!-- Liste akt. verwendbarer Kartenbauelemente

Alle nachfolgenden Elemente, die mit der Beschreibung "Bodenplatte" beginnen, sind fuer den Bot (je nach eingestelltem Verhalten) passierbar.

ASCII-Zeichen | Beschreibung (Hex-Code des ASCII-Zeichens)
L | Abgrund (4c)
X | Wandblock (58)
= | Wand horizontal (3d)
# | Wand vertikal (23)
* | Saeule mit Lichtquelle (2a)
  | Bodenplatte normal (20)
. | Bodenplatte weisz; definiert, sofern direkt an "Bodenplatte Startfeld ..." angrenzend, die Blickrichtung eines auf die Karte gerufenen Bots (e3)
O | Bodenplatte Startpunkt Default; eigentlich sollte hier jeder aufgerufene Bot starten, sofern keine anderen Startpunkte verwendet werden, akt. jedoch startet hier, wahrscheinlich aufgrund eines Bugs, der dritte (und jeder weitere) aufgerufene Bot (30)
1 | Bodenplatte Startpunkt Bot1; wenn verwendet, startet der erste aufgerufene Bot hier (31)
2 | Bodenplatte Startpunkt Bot2; wenn verwendet, startet der zweite aufgerufene Bot (32)
Z | Bodenplatte Bot-Zielpunkt (5a)
o | Bodenplatte mit Transportfach-Objekt (6f)
l | Bodenplatte mit Bot Positioning System (BPS)-Landmarke (6c)
| | Bodenplatte mit Linie vertikal (7C)
$ | Bodenplatte mit Linie vertikal als Startpunkt Bot1; aktuell leider optisch nicht von "Linie vertikal" zu unterscheiden, weil andere Farb-Definitionen dazu führen, dass die Linie nicht mehr vom Bot erkannt wird (24)
! | Bodenplatte mit Linie vertikal unterbrochen (21)
- | Bodenplatte mit Linie horizontal (2d)
% | Bodenplatte mit Linie horizontal unterbrochen (25)
/ | Bodenplatte mit Linie Ecke NW (2f)
\ | Bodenplatte mit Linie Ecke NE (5c)
+ | Bodenplatte mit Linie Ecke SW (2b)
~ | Bodenplatte mit Linie Ecke SE (7e)
[ | Bodenplatte mit Linie Kreuzung +-Form (5b)
T | Bodenplatte mit Linie Kreuzung T-Form (54)
} | Bodenplatte mit Linie Kreuzung T-Form 90° gegen UZS (7d)
{ | Bodenplatte mit Linie Kreuzung T-Form 90° mit UZS (7b)
] | Bodenplatte mit Linie Kreuzung T-Form kopfstehend (5d)
( | Bodenplatte mit Linie vertikal und Transportfach-Objekt (28)
_ | Bodenplatte mit Linie horizontal und Transportfach-Objekt (5f)
p | Bodenplatte mit Linie Ecke NW und Transportfach-Objekt (70)
q | Bodenplatte mit Linie Ecke NE und Transportfach-Objekt (71)
b | Bodenplatte mit Linie Ecke SW und Transportfach-Objekt (62)
d | Bodenplatte mit Linie Ecke SE und Transportfach-Objekt (64)

ACHTUNG: Die Liste bei Änderungen/Erweiterung in ctSim/model/ParcoursLoader.java und ctSim/develop/documentation/map-parts.md bitte ebenfalls aktualisieren!

Die nachfolgenden optics-Definitionen der Kartenbauelemente folgen der Listen-Reihenfolge. 

Hinweise aus https://www.heise.de/ct/artikel/Genesis-290480.html zu den Farb-Angaben der optics-Definitionen:

Java3D unterscheidet 4 Typen von Farben, laut Artikel:
- type="ambient": Farbe eines indirekt beleuchteten Objekts
- type="diffuse": Farbe von gerichteten Lichtquellen
- type="specular": Farbe von glaenzenden Reflexionen
- type="emmissive": Farbe einer Lichtquelle, bspw. bei "Saeule mit Lichtquelle"

Definiert werden die Farben in HTML-Notation, also bspw. #FFFFFF fuer "weisz".

Wird keine Farbe definiert, verwendet der ParcoursLoader die Java3D-Standards:
- type="ambient": grau
- type="diffuse": weisz
- type="specular": weisz
- type="emmissive": schwarz

Bei bestimmten Kartenbauelementen wie den Bodenplatten mit Linien erzeugen diese Default-Werte ein Glaenzen und sollten daher angepasste Werte (wie unten angegeben) verwenden. -->

	<optics>
		<appearance type="L"> 
			<description>Abgrund</description>
			<color type="ambient">#000000</color>
			<color type="diffuse">#000000</color>
		</appearance>
		<appearance type="X">
			<description>Wandblock</description>
			<texture>textures/rock_wall.jpg</texture>
		</appearance>
		<appearance type="=">
			<description>Wand horizontal</description>
			<clone>X</clone>
		</appearance>
		<appearance type="#">
			<description>Wand vertikal</description>
			<clone>X</clone> 
		</appearance>
		<appearance type="*">
			<description>Saeule mit Lichtquelle</description>
			<color type="emmissive">#FFFF90</color>
		</appearance>
		<appearance type=" "> 
			<description>Bodenplatte normal</description>
			<color type="ambient">#606060</color>
			<color type="diffuse">#606060</color>
		</appearance>
		<appearance type="."> 
			<description>Bodenplatte weisz</description>
			<color type="ambient">#FFFFFF</color>
			<color type="diffuse">#FFFFFF</color>
		</appearance>
		<appearance type="0">
			<description>Startpunkt Default</description>
			<clone>.</clone>
		</appearance>
		<appearance type="1">
			<description>Bodenplatte Start Bot1</description>
			<color type="ambient">#993030</color>
			<color type="diffuse">#993030</color>
		</appearance>
		<appearance type="2">
			<description>Bodenplatte Start Bot2</description>
			<color type="ambient">#000099</color>
			<color type="diffuse">#000099</color>
		</appearance>
		<appearance type="Z"> 
			<description>Bodenplatte Bot-Zielpunkt</description>
			<color type="ambient">#66FF00</color>
			<color type="diffuse">#66FF00</color>
		</appearance>
		<appearance type="o">
			<description>Bodenplatte mit Transportfach-Objekt</description>
			<texture>textures/object.jpg</texture>
			<color>#999999</color>
		</appearance>
		<appearance type="l"> 
			<description>Bodenplatte mit Bot Positioning System (BPS)-Landmarke</description>
			<color type="emmissive">#990000</color>
		</appearance>
		<appearance type="|"> 
			<description>Bodenplatte mit Linie vertikal</description>
			<color type="ambient">#000000</color>
			<color type="diffuse">#000000</color>
			<color type="specular">#000000</color>
			<color type="emmissive">#000000</color>
		</appearance>
		<appearance type="$"> 
			<description>Bodenplatte mit Linie vertikal als Startpunkt Bot1</description>
			<clone>|</clone>
		</appearance>
		<appearance type="!"> 
			<description>Bodenplatte mit Linie vertikal unterbrochen</description>
			<clone>|</clone>
		</appearance>
		<appearance type="-">
			<description>Bodenplatte mit Linie horizontal</description>
			<clone>|</clone>
		</appearance>
		<appearance type="%"> 
			<description>Bodenplatte mit Linie horizontal unterbrochen</description>
			<clone>|</clone>
		</appearance>
		<appearance type="\"> 
			<description>Bodenplatte mit Linie Ecke NE</description>
			<clone>|</clone>
		</appearance>
		<appearance type="/"> 
			<description>Bodenplatte mit Linie Ecke NW</description>
			<clone>|</clone>
		</appearance>
		<appearance type="~"> 
			<description>Bodenplatte mit Linie Ecke SE</description>
			<clone>|</clone>
		</appearance>
		<appearance type="+"> 
			<description>Bodenplatte mit Linie Ecke SW</description>
			<clone>|</clone>
		</appearance>
		<appearance type="["> 
			<description>Bodenplatte mit Linie Kreuzung +-Form</description>
			<clone>|</clone>
		</appearance>
		<appearance type="T"> 
			<description>Bodenplatte mit Linie T-Form</description>
			<clone>|</clone>
		</appearance>
		<appearance type="}"> 
			<description>Bodenplatte mit Linie Kreuzung T-Form 90° gegen UZS</description>
			<clone>|</clone>
		</appearance>
		<appearance type="{"> 
			<description>Bodenplatte mit Linie Kreuzung T-Form 90° mit UZS</description>
			<clone>|</clone>
		</appearance>
		<appearance type="]"> 
			<description>Bodenplatte mit Linie Kreuzung T-Form kopfstehend</description>
			<clone>|</clone>
		</appearance>
		<appearance type="("> 
			<description>Bodenplatte mit Linie vertikal und Transportfach-Objekt</description>
			<clone>|</clone>
		</appearance>
		<appearance type="_"> 
			<description>Bodenplatte mit Linie horizontal und Transportfach-Objekt</description>
			<clone>|</clone>
		</appearance>
		<appearance type="q"> 
			<description>Bodenplatte mit Linie Ecke NE und Transportfach-Objekt</description>
			<clone>|</clone>
		</appearance>
		<appearance type="p"> 
			<description>Bodenplatte mit Linie Ecke NW und Transportfach-Objekt</description>
			<clone>|</clone>
		</appearance>
		<appearance type="d"> 
			<description>Bodenplatte mit Linie Ecke SW und Transportfach-Objekt</description>
			<clone>|</clone>
		</appearance>
		<appearance type="b"> 
			<description>Bodenplatte mit Linie Ecke SE und Transportfach-Objekt</description>
			<clone>|</clone>
		</appearance>
	</optics>
</world>
3. Gedankenskizze zum Code
  • Der Bot startet auf einen kopfstehenden "T", damit die Startposition über Kanten-Sensoren für den Bot erkennbar bleibt (Startposition erreicht = Bot stoppt). Ebenso wird das Ende der "Schnecke" durch ein "T" definiert (das er im Idealfall aber nie erreichen sollte). Mögliches Problem: Ausschließen, dass der Bot mit einem Kanten-Sensor auf dem T-Flügel und der schwarzen Linie gleichzeitig steht und dies fälschlich als Erreichen der Startposition erkennt.
  • Nach dem Aufrufen des Programms dreht der Bot sich um 180°.
  • Der Bot fährt nun so lange auf der schwarzen Linie entlang, bis das Transportfach ein Objekt registriert, woraufhin er stoppt und das Transportfach schließt.
  • Der Bot dreht sich mit der Foto-Dose abermals 180°.
  • Der Bot fährt entlang der schwarzen Linie, bis beide Kanten-Sensoren die Startposition anhand des kopfstehenden "T" erkennen, woraufhin der Bot stoppt und das Transportfach öffnet.
  • Ist beim Programm aufruf etwas im Transportfach, öffnet der Bot die Klappe, fährt ein Stück nach hinten, bis das Transportfach als "leer" erkannt wird, schließt die Klappe und fährt wieder bis zur Startposition vor. Ziel: Im Transportfach vergessene Foto-Dose wird aus dem Startbereich geschoben.
Danke im Voraus für eure Hilfe, nachfolgend formuliere ich separat die erste Fragen.
Zuletzt geändert von anonybot am 06 Okt 2019, 20:44, insgesamt 5-mal geändert.
Von mir selbst verfasste (daher nicht zitierte) Inhalte dieses Beitrags sind zur Weiternutzung unter CC-BY-SA freigegeben +++ ct-Bot -> Libre-Bot? - Diskussion zur Zukunft des ct-Bots +++ anonybot sagt hello!

anonybot
Friends of Sonny
Friends of Sonny
Beiträge: 118
Registriert: 07 Okt 2015, 00:14

Re: Der "ct-Bot-Weihnachtskalender" - Programmieren lernen am Beispiel ohne Vorkenntnisse

Beitrag von anonybot » 09 Jun 2019, 23:31

1. Übersehe ich in der "Gedankenskizze" etwas oder sollte der Ablauf so klappen?

2. Welches Verhalten sollte ich als Vorlage nehmen? Das "fahre im Viereck"-Verhalten (simple) scheint mir wenig Anknüpfungspunkte zu geben, da es, soweit ich verstanden habe, einer "Schleife" folgt. Das von mir geplante Verhalten ist aber in der Grundversion keine, sondern läuft einmal durch und fertig.
Von mir selbst verfasste (daher nicht zitierte) Inhalte dieses Beitrags sind zur Weiternutzung unter CC-BY-SA freigegeben +++ ct-Bot -> Libre-Bot? - Diskussion zur Zukunft des ct-Bots +++ anonybot sagt hello!

eax
Friends of Sonny
Friends of Sonny
Beiträge: 110
Registriert: 18 Jan 2006, 16:16
Wohnort: Karlsruhe

Re: Der "ct-Bot-Weihnachtskalender" - Programmieren lernen am Beispiel ohne Vorkenntnisse

Beitrag von eax » 15 Jun 2019, 00:59

Zur "Gedankenskizze": Nach dem Stopp und Öffnen des Fachs könnte der Bot noch ein Stück zurück fahren, um die Dose "freizugeben". Hierzu könnte das bot_unload_pillar() Verhalten verwendet werden.
Ansonsten passt das schon mal sehr gut so denke ich.

Zu 2.: Meinst du als "Vorlage" zum Verständnis, wie man ein Verhalten aufbaut, oder als "Template" für den Code des neuen Verhaltens? Für letzteres gibt es behaviour_prototype.c.
Inhaltlich ist das Simple-Verhalten schon geeignet (wenn auch extrem simpel...), die "Schleife" wird ja nur dadurch erzeugt, dass die Zustände alternieren.
Da ergibt sich doch gleich mal eine Einstiegsfrage zum Aufwärmen: was müsste man denn ändern, damit das Verhalten nicht ewig im Quadrat fährt, sondern die vier Seite des Quadrats nur jeweils einmal abfährt und dann abbricht? ;-)

Das was du bauen willst, ähnelt zumindest zum Teil dem Verhalten behaviour_follow_line_enhanced.c, insbesondere, weil dort auch andere Verhalten gestartet werden, bis eine Bedingung erfüllt ist (über den bot_cancel_behaviour() Mechanismus). Das ist sicher auch mal einen Blick wert.
Timo -- Meine Beiträge sind unter CC-BY-SA freigegeben

lenchen
Friends of Gort
Friends of Gort
Beiträge: 30
Registriert: 12 Apr 2011, 15:31

Re: Der "ct-Bot-Weihnachtskalender" - Programmieren lernen am Beispiel ohne Vorkenntnisse

Beitrag von lenchen » 06 Okt 2019, 19:26

Hi,

coole Idee :D

Ist das ganze hier noch aktuell? sorry war längere Zeit nicht hier und ist etwas unübersichtlich das Forum wenn man später was nachlesen will :roll: also falls ja:
anonybot hat geschrieben:
09 Jun 2019, 23:29
  • Ein Bot-Verhalten, das einen (eigenwilligen) Adventskalender darstellt. Der Bot fährt dazu in der "Basisversion" auf einer schneckenförmigen schwarzen Linie, die auf ein Tablett, das als Untergrund dient, gezeichnet wird, von einer definierten Startposition aus so lange in eine Richtung, bis er eine von vierundzwanzig Foto-Doses (die "Kalender-Türchen") eingefangen hat, dreht sich um und bringt die Dose zurück zum Startpunkt.
soll der Bot dann echt auf einem Tablet fahren? :shock:

Grüße
Lena

anonybot
Friends of Sonny
Friends of Sonny
Beiträge: 118
Registriert: 07 Okt 2015, 00:14

Re: Der "ct-Bot-Weihnachtskalender" - Programmieren lernen am Beispiel ohne Vorkenntnisse

Beitrag von anonybot » 06 Okt 2019, 20:44

lenchen hat geschrieben:
06 Okt 2019, 19:26
Hi,

coole Idee :D

Ist das ganze hier noch aktuell?
Danke und ja ist es. Wenn ich mein Jahresziel schaffen will, müsste ich nur bald mal loslegen (was aktuell an der Einrichtung einer ct-Sim-VM hängt, die erstmal ansteht).
lenchen hat geschrieben:
06 Okt 2019, 19:26
sorry war längere Zeit nicht hier und ist etwas unübersichtlich das Forum wenn man später was nachlesen will :roll:
Und dabei hat Nightwalker doch das Forum so gut aufgeräumt. Ich find es jetzt um ein Vielfaches übersichtlicher als vorher, allein schon aufgrund der sinnvollen Reduktion der zig Unterforen.
lenchen hat geschrieben:
06 Okt 2019, 19:26
also falls ja:
anonybot hat geschrieben:
09 Jun 2019, 23:29
  • Ein Bot-Verhalten, das einen (eigenwilligen) Adventskalender darstellt. Der Bot fährt dazu in der "Basisversion" auf einer schneckenförmigen schwarzen Linie, die auf ein Tablett, das als Untergrund dient, gezeichnet wird, von einer definierten Startposition aus so lange in eine Richtung, bis er eine von vierundzwanzig Foto-Dosen (die "Kalender-Türchen") eingefangen hat, dreht sich um und bringt die Dose zurück zum Startpunkt.
soll der Bot dann echt auf einem Tablet fahren? :shock:
Es kann natürlich auch ein entsprechend großer Karton mit offenem Deckel sein, aber am Anfang muss man ja sicher häufiger etwas nachjustieren und da ist eine Fläche ohne "Wände" sicher besser geeignet.
Toll wäre natürlich, wenn der Bot es irgendwann schafft, in einem geschlossenen Karton allein durch seine Abstandssensoren Dosen zu finden und zum Ausgang zu bringen. Aber erstmal scheint mir diese Variante die Debug-freundlichere zu sein. ;)
Zuletzt geändert von anonybot am 06 Okt 2019, 21:58, insgesamt 1-mal geändert.
Von mir selbst verfasste (daher nicht zitierte) Inhalte dieses Beitrags sind zur Weiternutzung unter CC-BY-SA freigegeben +++ ct-Bot -> Libre-Bot? - Diskussion zur Zukunft des ct-Bots +++ anonybot sagt hello!

lenchen
Friends of Gort
Friends of Gort
Beiträge: 30
Registriert: 12 Apr 2011, 15:31

Re: Der "ct-Bot-Weihnachtskalender" - Programmieren lernen am Beispiel ohne Vorkenntnisse

Beitrag von lenchen » 06 Okt 2019, 21:32

anonybot hat geschrieben:
06 Okt 2019, 20:44
lenchen hat geschrieben:
06 Okt 2019, 19:26
sorry war längere Zeit nicht hier und ist etwas unübersichtlich das Forum wenn man später was nachlesen will :roll:
Und dabei hat Nightwalker doch das Forum so gut aufgeräumt. Ich find es jetzt um ein Vielfaches übersichtlicher als vorher, allein schon aufgrund der sinnvollen Reduktion der zig Unterforen.
Sorry war nicht darauf bezogen oder negativ gemeint, ist bestimmt schon viel besser geworden!
anonybot hat geschrieben:
09 Jun 2019, 23:29
Es kann natürlich auch ein entsprechend großer Karton mit offenem Deckel sein, aber am Anfang muss man ja sicher häufiger etwas nachjustieren und da ist eine Fläche ohne "Wände" sicher besser geeignet.
Toll wäre natürlich, wenn der Bot es irgendwann schafft, in einem geschlossenen Karton allein durch seine Abstandssensoren Dosen zu finden und zum Ausgang zu bringen. Aber erstmal scheint mir diese Variante die Debug-freundlichere zu sein. ;)
Äh meinst du Tablet (Computer) oder Tablett (Tafel, zum Tragen von Geschirr oder so)? :D
Und ist beides nicht zu klein?

anonybot
Friends of Sonny
Friends of Sonny
Beiträge: 118
Registriert: 07 Okt 2015, 00:14

Re: Der "ct-Bot-Weihnachtskalender" - Programmieren lernen am Beispiel ohne Vorkenntnisse

Beitrag von anonybot » 06 Okt 2019, 22:02

lenchen hat geschrieben:
06 Okt 2019, 21:32
anonybot hat geschrieben:
06 Okt 2019, 20:44
lenchen hat geschrieben:
06 Okt 2019, 19:26
sorry war längere Zeit nicht hier und ist etwas unübersichtlich das Forum wenn man später was nachlesen will :roll:
Und dabei hat Nightwalker doch das Forum so gut aufgeräumt. Ich find es jetzt um ein Vielfaches übersichtlicher als vorher, allein schon aufgrund der sinnvollen Reduktion der zig Unterforen.
Sorry war nicht darauf bezogen oder negativ gemeint, ist bestimmt schon viel besser geworden!
"Besser" ist nicht "optimal", da bin ich bei Dir. Optimal wäre für mich Discourse.
lenchen hat geschrieben:
06 Okt 2019, 21:32
anonybot hat geschrieben:
09 Jun 2019, 23:29
Es kann natürlich auch ein entsprechend großer Karton mit offenem Deckel sein, aber am Anfang muss man ja sicher häufiger etwas nachjustieren und da ist eine Fläche ohne "Wände" sicher besser geeignet.
Toll wäre natürlich, wenn der Bot es irgendwann schafft, in einem geschlossenen Karton allein durch seine Abstandssensoren Dosen zu finden und zum Ausgang zu bringen. Aber erstmal scheint mir diese Variante die Debug-freundlichere zu sein. ;)
Äh meinst du Tablet (Computer) oder Tablett (Tafel, zum Tragen von Geschirr oder so)? :D
Und ist beides nicht zu klein?
Letzteres - mit Doppel-T. Dachte ich hatte mich verschrieben, aber habe überall "Tablett" geschrieben, wobei "Tafel" oder "Pinnwand" es natürlich konkretisiert hätte. :) Aber ja, von der Größe passt das. Ich hatte es grob mit einer alten Pinnwand getestet.
Von mir selbst verfasste (daher nicht zitierte) Inhalte dieses Beitrags sind zur Weiternutzung unter CC-BY-SA freigegeben +++ ct-Bot -> Libre-Bot? - Diskussion zur Zukunft des ct-Bots +++ anonybot sagt hello!

lenchen
Friends of Gort
Friends of Gort
Beiträge: 30
Registriert: 12 Apr 2011, 15:31

Re: Der "ct-Bot-Weihnachtskalender" - Programmieren lernen am Beispiel ohne Vorkenntnisse

Beitrag von lenchen » 07 Okt 2019, 19:04

ah okay :lol:
war mir erst unsicher was gemeint ist wegen dem "Linie, die ... gezeichnet wird". aber jetzt ist es klar :wink:
also coole Idee auf jeden Fall, bin ich mal gespannt :)

anonybot
Friends of Sonny
Friends of Sonny
Beiträge: 118
Registriert: 07 Okt 2015, 00:14

Re: Der "ct-Bot-Weihnachtskalender" - Programmieren lernen am Beispiel ohne Vorkenntnisse

Beitrag von anonybot » 23 Nov 2019, 19:50

eax hat geschrieben:
15 Jun 2019, 00:59
Da ergibt sich doch gleich mal eine Einstiegsfrage zum Aufwärmen: was müsste man denn ändern, damit das Verhalten nicht ewig im Quadrat fährt, sondern die vier Seite des Quadrats nur jeweils einmal abfährt und dann abbricht? ;-)
Fürs Protokoll: Eine mögliche Antwort wäre:

Code: Alles auswählen

...
static uint8_t simple_counter = 0;	/*!< Counter fuer das simple-Verhalten, um es opt. nicht unendlich lange wiederholen zu lassen*/
...
void bot_simple_behaviour(Behaviour_t * data) {
	switch (simple_state) {
	case 0:
		bot_drive_distance(data, 0, BOT_SPEED_MAX, 14);
		simple_state = 1;
		break;
	case 1:
		bot_turn(data, 90);
		simple_state = 0;
		simple_counter = simple_counter + 1;
		/*!< Bedingung, die den simple_counter nutzt, um den Bot genau ein einziges Qudrat fahren zu lassen */
		if(simple_counter == 4)
		{
			/*!< "simple_state = 2" führt dazu, dass die Schleife weder "case 0" noch "case 1" aufruft, sodass "return_from_behaviour(data);" wodurch das Verhalten auf "beendet" gesetzt wird */
			simple_state = 2;
		}
		break;
	default:
		return_from_behaviour(data);
		break;
	}

}
Von mir selbst verfasste (daher nicht zitierte) Inhalte dieses Beitrags sind zur Weiternutzung unter CC-BY-SA freigegeben +++ ct-Bot -> Libre-Bot? - Diskussion zur Zukunft des ct-Bots +++ anonybot sagt hello!

anonybot
Friends of Sonny
Friends of Sonny
Beiträge: 118
Registriert: 07 Okt 2015, 00:14

Re: Der "ct-Bot-Weihnachtskalender" - Programmieren lernen am Beispiel ohne Vorkenntnisse

Beitrag von anonybot » 24 Nov 2019, 15:12

Zunächst müssen die nötigen Dateien für das Verhalten für ein neues Verhalten vorbereitet werden. Hier dazu nur meine ursprünglich englischen Markdown-Notizen in angepasster Form für das "Adventskalender-Verhalten" (kurz "ADVENTCAL"):

Copy the template behaviour source and header file to create your new behaviour by renaming `prototype` in the following file names (avoid using `-` in the new name):

- `ctBot/bot-logic/behaviour_prototype.c`
- `ctBot/include/bot-logic/behaviour_prototype.h`

Example creating a bevahiour "hellobot" in develop branch:

1. Check out the "devel(op)" branch of "ct-bot_github-tsandmann":

Right click on ct-bot_github-tsandmann -> Team -> Switch To -> Other... -> Remote Tracking -> "origin/develop ..." -> Check Out... -> Check out as New Local Branch -> Finish

2. Copypaste the needed behaviour files:

- Right click on `ctBot/bot-logic/behaviour_prototype.c` -> Copy -> Right click on `ctBot/bot-logic/behaviour_prototype.c` again -> Paste -> `behaviour_hellobotworld.c` -> OK

- Right click on `ctBot/include/bot-logic/behaviour_prototype.h` -> Copy -> Right click on `ctBot/include/bot-logic/behaviour_prototype.h` again -> Paste -> `behaviour_hellobotworld.c` -> OK

3. Prepare behaviour files

3.1. Double click on `ctBot/include/bot-logic/behaviour_hellobotworld.h` -> Ctrl+F ->

- Find: `prototype`
- Replace with: `hellobotworld`
- Cas esensitive
- Wrap search

-> Replace All

3.2. Repeat this for:

- Find: `PROTOTYPE`
- Replace with: `HELLOBOTWORLD`

3.3. Repeat 3.1. for `ctBot/bot-logic/behaviour_hellobotworld.c`.

3.4. In `ctBot/include/bot-logic/available_behaviours.h` replace the line

```
//#define BEHAVIOUR_PROTOTYPE_AVAILABLE /**< Prototyp fuer neue Verhalten */
```

with:

```
//#define BEHAVIOUR_PROTOTYPE_AVAILABLE /**< Prototyp fuer neue Verhalten */
#define BEHAVIOUR_HELLOBOTWORLD_AVAILABLE /**< The Hello World example for ct-Bots */
```

and

```
#include "behaviour_prototype.h"
```

with

```
#include "behaviour_prototype.h"
#include "behaviour_hellobotworld.h"
```

3.5. Save all.

4. In `ctBot/bot-logic/bot-logic.c` under `bot_behave_init()` add a definition for your new behaviour:

```
#ifdef BEHAVIOUR_HELLOBOTWORLD_AVAILABLE
insert_behaviour_to_list(&behaviour, new_behaviour(101, bot_hellobotworld_behaviour, BEHAVIOUR_INACTIVE));
#endif
```

The priority of `101` is a good start value. The higher the number the higher is the priority of the behaviour (means: the highest priority will prioritized if multiple behaviours are active the same time so that the behaviour preventing the bot falling down from a table will always be executed before all other behaviours).

If the behaviour should start immediately when the bot is switched on change `BEHAVIOUR_INACTIVE` to `BEHAVIOUR_ACTIVE`.

5. If the behaviour shall be available in the remote call list of ct-Sim you have to note it under `bot-logic/behaviour_remotecall.c` by adding under `const remotecall_entry_t remotecall_beh_list[] PROGMEM = {`:

```
#ifdef BEHAVIOUR_HELLOBOTWORLD_AVAILABLE
PREPARE_REMOTE_CALL(bot_prototype, 0, "", 0),
// PREPARE_REMOTE_CALL(bot_prototype, 1, "int16 param", 2),
#endif
```
Zuletzt geändert von anonybot am 24 Nov 2019, 16:31, insgesamt 2-mal geändert.
Von mir selbst verfasste (daher nicht zitierte) Inhalte dieses Beitrags sind zur Weiternutzung unter CC-BY-SA freigegeben +++ ct-Bot -> Libre-Bot? - Diskussion zur Zukunft des ct-Bots +++ anonybot sagt hello!

anonybot
Friends of Sonny
Friends of Sonny
Beiträge: 118
Registriert: 07 Okt 2015, 00:14

Re: Der "ct-Bot-Weihnachtskalender" - Programmieren lernen am Beispiel ohne Vorkenntnisse

Beitrag von anonybot » 24 Nov 2019, 15:42

Nachdem die Dateien vorbereitet wurden, könnte die konkrete Umsetzung damit beginnen, entsprechend des Prototype-Verhaltens das, was der Bot tun soll, in verschiedenen Zuständen zu definieren. Ein erster Zustand wäre der "Startzustand", der verschiedene SItuationen haben könnte:

- Situation 1: Bot steht auf Linie, sodass er, wenn er weiterfährt, direkt zu einer Dose gelangt
- Situation 2: Bot steht auf Linie, jedoch falsch herum, sodass er, wenn er weiterfährt, auf dem umgedrehten T-Stück landet und dann dort drehen müsste, weil er noch keine Dose im Transportfach hat.
- Situation 3: Bot steht verkehrt herum so, dass die Kanten-Sensoren melden, er steht auf dem umgedrehten T-Stück, sodass er sofort 180 Grad wenden soll.
- Situation 4: Bot steht weder auf T-Stück noch auf der Linie -> hier sollte das Display am besten eine "stell mich vernünftig hin"-Warnung ausgeben, da ich nicht wüsste, wie der Bot nur mit Bodensensoren zurück auf die Linie finden könnte, ohne den Kalenderaufbau dabei zu demolieren.

Um es für den Anfang einfacher zu halten, wird davon ausgegangen, dass der Bot ideal steht, also so wie in Situation 1 beschrieben. Der schon vordefinierte case "STATE_ADVENTCAL_INIT" wird also für Situation 1 genommen:

Code: Alles auswählen

void bot_adventcal_behaviour(Behaviour_t * data) {
	switch (adventcal_state) {
	case STATE_ADVENTCAL_INIT:
		//Solange im Transportfach kein Objekt ist, der Transportfach-Sensor also "0" meldet...
		if (sensTrans == 0) {
			//...folgt der Bot einer schwarzen Linie so lange, bis... 
			bot_follow_line(data, 0);
		} else {
			//...das Gegenteil der if-Bedingung erfolgt, also der Transportfach-Sensor ein Objekt erkennt, woraufhin das "Folge der Linie"-Verhalten nicht mehr zutrifft, der Bot also stoppt und stattdessen die Transportfach-Klappe geschlossen wird
			bot_servo(data, SERVO1, DOOR_CLOSE);
		}
		break;
	default:
		//Das, was passiert, wenn kein "case" zutrifft, in diesem Fall gar nichts, der Bot bleibt also stehen
		return_from_behaviour(data);
		break;
	}
- Wie kommt man auf "sensTrans == 0"?

Man schaut sich vorhandene Verhalten an, die dem Namen nach wohl das Transportfach nutzen, also bspw. behaviour_catch_pillar.c und entdeckt (mit Hilfe von hilfsbereiten Usern wie EAX ;) ) Code wie

Code: Alles auswählen

	case CLOSE_DOOR:
		if (sensTrans == 1) {
			// Klappe schliessen falls Objekt eingefangen wurde
			bot_servo(data, SERVO1, DOOR_CLOSE);
		}
aus dem zu schließen ist, dass

Code: Alles auswählen

sensTrans == 1)
der Sensor für das Transportfach ist und auch, wie man dessen Zustand abfragt ("1" = Transportfach voll, "0" entsprechend wohl = Transportfach leer).
Außerdem erfährt man, dass der Befehl zum Schließen des Transportfaches

Code: Alles auswählen

bot_servo(data, SERVO1, DOOR_CLOSE)
lautet.

- Wie kommt man auf "bot_follow_line(data, 0);"?

Ohne Programmierkenntnisse bin ich nicht umhin bekommen, um Hilfe zu fragen, aber dennoch hier ein Ansatz, sich zunächst etwas selbst zu helfen:

Auch hier schaut man sich vorhandene Verhalten an, die dem Namen nach wohl die gewünschten Funktionen nutzen, bspw. behaviour_follow_line. Suche ich hier nach dem Begriff "folge", lande ich zuerst in einer Zeile

Code: Alles auswählen

#define FOLLOW_LINE					1	/* !< Folgen einer geraden oder leicht gekruemmten Linie */
die mir verrät, dass der User, der das Verhalten ursprünglich programmiert hat, das "Folge Linie-Verhalten" als "FOLLOW_LINE" benannt hat. Ich suche weiter nach dem Begriff "FOLLOW_LINE" vor dem Hintergrund, dass die Bezeichnung, mit der Verhalten adressiert wird, nach "void" steht (so auch in meinem Fall für das Adventskalender-Verhalten:

Code: Alles auswählen

void bot_adventcal_behaviour(Behaviour_t * data) {
.

Die Suche zeigt mir 28 Ergebnisse, die "FOLLOW_LINE" enthalten, wobei

- das neunte in (aktuell) Zeile 68 (

Code: Alles auswählen

void bot_follow_line_behaviour(Behaviour_t* data) {
) steht und
- das zehnte in (aktuell) Zeile 190 (

Code: Alles auswählen

void bot_follow_line(Behaviour_t* caller, uint8_t dummy) {
)

also einmal mit "_behaviour" am Ende und einmal ohne. Der Code-Kommentar vor beiden Zeilen sagt in beiden Fällen "Folgt einer Linie, sobald beide Liniensensoren ausloesen", hilft also nicht wirklich, zu entscheiden, welches der gesuchte Befehl ist. Auch hier hat mit User EAX geholfen:
Das, was ich suche ist

Code: Alles auswählen

bot_follow_line(data, 0);
.
Von mir selbst verfasste (daher nicht zitierte) Inhalte dieses Beitrags sind zur Weiternutzung unter CC-BY-SA freigegeben +++ ct-Bot -> Libre-Bot? - Diskussion zur Zukunft des ct-Bots +++ anonybot sagt hello!

anonybot
Friends of Sonny
Friends of Sonny
Beiträge: 118
Registriert: 07 Okt 2015, 00:14

Re: Der "ct-Bot-Weihnachtskalender" - Programmieren lernen am Beispiel ohne Vorkenntnisse

Beitrag von anonybot » 01 Dez 2019, 03:47

Obwohl ich es gerne früher veröffentlicht hätte, dennoch pünktlich zum 1. Dezember:

Code: Alles auswählen

/*
 * c't-Bot
 *
 * This program is free software; you can redistribute it
 * and/or modify it under the terms of the GNU General
 * Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your
 * option) any later version.
 * This program is distributed in the hope that it will be
 * useful, but WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 * PURPOSE. See the GNU General Public License for more details.
 * You should have received a copy of the GNU General Public
 * License along with this program; if not, write to the Free
 * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307, USA.
 *
 */



/*!
 * @file 	behaviour_adventcal.h
 * @brief 	Adventskalender-Verhalten
 * @author 	anonybot (anonybot@riseup.net), based on template "behaviour_prototype.h" by Benjamin Benz (bbe@heise.de), created with a lot of help by Timo Sandmann (mail@timosandmann.de)
 * @date 	2019-11-30
 */

//
#ifndef BEHAVIOUR_ADVENTCAL_H_
#define BEHAVIOUR_ADVENTCAL_H_

#ifdef BEHAVIOUR_ADVENTCAL_AVAILABLE
/*!
 * Verhalten für einen Adventskalender:
 * @param *data Der Verhaltensdatensatz
 *
 * Der Bot faehrt direkt nach dem Einschalten eine Linie ab, auf der 24 Fotodosen stehen.
 * Faengt er einen Behaelter ein, bringt er diesen zum Startpunkt zurueck und
 * gibt ihn frei.
 * Da der Bot noch kein Verdauungssystem besitzt, duerfen die Sueszigkeiten,
 * die zuvor in den Dosen platziert wurden, von der Person gegessen werden,
 * die den Bot angeschaltet hatte. ;)
 *
 * Zur Aktivierung muss in include/bot-logic/available_behaviours.h neben
 * - "BEHAVIOUR_ADVENTCAL_AVAILABLE"
 * auch
 * - "BEHAVIOUR_FOLLOW_LINE_AVAILABLE" aktiviert sein, damit das Verhalten funktioniert.
 * Achtung: Im Default wird davon ausgegangen, dass das Verhalten zunaechst im Sim ausprobiert wird,
 * sodass fuer reale Tests in bot-logic/behaviour_adventcal.c fuer die Abbruch-Funktion "cancel_follow_line_on_border"
 * die entsprechend kommentierte Zeile deaktiviert bzw. aktiviert werden muss, damit der Bot die Linie findet.
 *
 *
 * Als Test-Parcours im ct-Sim dient parcours/adventcal.xml - beim Nachbau fuer den realen Kalender sollte Folgendes beachtet werden:
 * - zwischen Start-Position des Bots und erster Fotodose muss ein gewisser Abstand sein, falls gewuenscht ist,
 * dass die Transportfach-Klappe nach dem Einfangen einer Fotodose ordentlich schliesst (zur Zeit
 * der Erstellung dieses Verhaltens waren das 15cm zwischen geschlossener Bot-Klappe und erster Fotodose).
 * Dies ist noetig, damit der Transportfach-Klappen-Servo wahrend der Fahrt unmittelbar nach dem Start genuegend Zeit hat,
 * seinen Arbeitsvorgang abschliessen zu koennen, da sonst das Verhalten zum Schliessen desselben aufgerufen wird,
 * waehrend der Klappen-Servo noch mit der Oeffnen-Aktion beschaeftig ist, wodurch das Schlieszen verhindert wird.
 *
 * Bei der realen "Kalenderflaeche" muss die Ziel-Linie eventuell in doppelter Breite angelegt werden, also bei Verwendung von
 * 1cm schwarzem Klebeband (fuer die Fahrtlinie wunderbar) ca. 2cm, damit der Oeffnungswinkel der Kanten-Sensoren genuegend
 * Flaeche hat, sie zu erkennen.
 *
 * Das Verhalten geht davon aus, dass der Bot bereits eine ideale Startposition hat,
 * bevor er angeschaltet wird, woraufhin sich das Verhalten automatisch startet.
 * Die ideale Startposition ist:
 * - linker Linien-Sensor steht auf der schwarzen Linke
 * - rechter Linien-Sensor steht nicht auf der schwarzen Linke
 * - die erste Dose findet sich in "Blickrichtung" des Bots
 * - im Sim findet der Bot durch die optimalen Bedingungen die Linie auch in Aufruf-Position,
 * falls doch nicht, muss im Sim nach Aufruf und vor Start des Bots
 * fuer "X [m]" der Wert "0.363" und fuer "Richtung" der Wert "0" eingestellt werden.
 * Dies bedeutet leider auch, dass der Bot nach dem Abliefern der Dose neu ideal positioniert werden muss,
 * falls er am Ende des Verhaltens mit beiden Linien-Sensoren links von der Linie zum Stehen gekommen ist.
 */
void bot_adventcal_behaviour(Behaviour_t * data);

/*!
 * Rufe das Adventskalender-Verhalten auf
 * @param *caller	Der obligatorische Verhaltensdatensatz des Aufrufers
 */
void bot_adventcal(Behaviour_t * caller);

#endif // BEHAVIOUR_ADVENTCAL_AVAILABLE
#endif // BEHAVIOUR_ADVENTCAL_H_

Code: Alles auswählen

/*
 * c't-Bot
 *
 * This program is free software; you can redistribute it
 * and/or modify it under the terms of the GNU General
 * Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your
 * option) any later version.
 * This program is distributed in the hope that it will be
 * useful, but WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 * PURPOSE. See the GNU General Public License for more details.
 * You should have received a copy of the GNU General Public
 * License along with this program; if not, write to the Free
 * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307, USA.
 *
 */

/*!
 * @file 	behaviour_adventcal.c
 * @brief 	Adventskalender-Verhalten
 * @author 	anonybot (anonybot@riseup.net), based on template "behaviour_prototype.h" by Benjamin Benz (bbe@heise.de), created with a lot of help by Timo Sandmann (mail@timosandmann.de)
 * @date 	2019-11-30
 */


#include "bot-logic/bot-logic.h"
#ifdef BEHAVIOUR_ADVENTCAL_AVAILABLE

//Log-Ausgaben, wenn in ct-bot.h aktiviert
#include "log.h"

// Status des Adventskalender-Verhaltens beim Start des Verhaltens
static uint8_t adventcal_state = 0;

#define STATE_ADVENTCAL_START 0
#define STATE_ADVENTCAL_FIND 1
#define STATE_ADVENTCAL_FLAPCLOSE 2
#define STATE_ADVENTCAL_TURNTODELIVER 3
#define STATE_ADVENTCAL_DELIVER 4
#define STATE_ADVENTCAL_FLAPOPEN 5
#define STATE_ADVENTCAL_MOVEBACK 6
#define STATE_ADVENTCAL_TURNTOSTARTPOS 7

//Abbruch-Funktion, die spaeter im Programm benoetigt wird, um zu pruefen, ob das Verhalten, einer Linie zu folgen, beendet werden kann...
static uint8_t cancel_follow_line_object_catched(void) {
	//...und zwar in Abhaengigkeit davon, ob der Sensor im Transportfach etwas sieht oder nicht
	if (sensTrans == 1) {
		//"1" bedeutet, dass ein Objekt im Transportfach ist und die Abbruch-Funktion mittels "return" meldet, dass die Abbruch-Bedingung erfuellt ist und das Verhalten, einer Linie zu folgen, abgebrochen werden soll
		return 1;

	} else {
		//ansonsten, also wenn sich nichts im Transportfach befindet, meldet die Abbruch-Funktion, dass die Abbruch-Bedingung nicht erfuellt ist und das Verhalten, einer Linie zu folgen, weiterlaufen muss
		return 0;
	}
}

//Abbruch-Funktion, die spaeter im Programm benoetigt wird, um zu pruefen, ob das Verhalten, einer Linie zu folgen, beendet werden kann...
static uint8_t cancel_follow_line_on_border(void) {
	//...und zwar in Abhaengigkeit davon, ob die Abgrund- bzw. Kanten-Sensoren eine schwarze Linie sehen oder nicht
	//fuer Sim-Tests nur folgende Zeile nutzen
	//if (sensBorderL>BORDER_DANGEROUS && sensBorderR>BORDER_DANGEROUS) {
	//fuer Real-Tests nur folgende Zeile nutzen und ggf. die Werte (0x2A0) an Schwarz-Werte des verwendeten Klebebandes anpassen, die der Bot uber die Linien-Sensoren meldet
	if (sensBorderL>0x2A0 && sensBorderR>0x2A0) {
		//wenn die Abbruch-Bedingung erfuellt ist, die beiden Kanten-Sensoren also eine schwarze Linie sehen, meldet die Abbruch-Funktion mittels "return", dass die Abbruch-Bedingung erfuellt ist und das Verhalten, einer Linie zu folgen, abgebrochen werden soll
		return 1;

	} else {
		//ansonsten, sofern also die Kanten-Sensoren keine schwarze Linie sehen, meldet die Abbruch-Funktion, dass die Bedingung nicht erfuellt ist und das Verhalten, einer Linie zu folgen, weiterlaufen muss
		return 0;
	}
}

void bot_adventcal_behaviour(Behaviour_t * data) {
	switch (adventcal_state) {
	//Sicherstellen, dass die Transportfach-Klappe geoeffnet ist, bevor die Suche nach dem "Tuerchen" beginnt
	case STATE_ADVENTCAL_START:
			LOG_DEBUG("STATE_ADVENTCAL_START_BEGIN");
			bot_servo(data, SERVO1, DOOR_OPEN);
			adventcal_state = STATE_ADVENTCAL_FIND;
			LOG_DEBUG("STATE_ADVENTCAL_START_END");
			break;
	//Suchen des Transportfach-Objekts
	case STATE_ADVENTCAL_FIND:
		LOG_DEBUG("STATE_ADVENTCAL_FIND_BEGIN");
		//Solange der Transportfach-Sensor nichts sieht...
		if (sensTrans == 0) {
			//...folgt der Bot der Linie...
			bot_follow_line(data, 0);
			//...und bricht ab, sobald der Transportfach-Senor ein Objekt im Transportfach registriert
			bot_cancel_behaviour(data, bot_follow_line_behaviour, cancel_follow_line_object_catched);
		}
		adventcal_state = STATE_ADVENTCAL_FLAPCLOSE;
		LOG_DEBUG("STATE_ADVENTCAL_FIND_END");
		break;
	//Schlieszen der Transportfach-Klappe
	case STATE_ADVENTCAL_FLAPCLOSE:
		LOG_DEBUG("STATE_ADVENTCAL_FLAPCLOSE_BEGIN");
		bot_servo(data, SERVO1, DOOR_CLOSE);
		adventcal_state = STATE_ADVENTCAL_TURNTODELIVER;
		LOG_DEBUG("STATE_ADVENTCAL_FLAPCLOSE_END");
		break;
	//Wende als Vorbereitung, um das Transportfach-Objekt zur Startposition zurueckzubringen
	case STATE_ADVENTCAL_TURNTODELIVER:
		LOG_DEBUG("STATE_ADVENTCAL_TURNTODELIVER_BEGIN");
		//nicht ganz 180 Grad, damit das Liniensuchverhalten nicht dazu tendiert, den Bot in die falsche Richtung zu drehen
		bot_turn(data, 170);
		LOG_DEBUG("STATE_ADVENTCAL_TURNTODELIVER_TURN_DONE");
		//bot_drive_distance(data, 0, BOT_SPEED_FOLLOW, 1);
		//LOG_DEBUG("STATE_ADVENTCAL_TURNTODELIVER_MOVE1CM_DONE");
		adventcal_state = STATE_ADVENTCAL_DELIVER;
		LOG_DEBUG("STATE_ADVENTCAL_TURNTODELIVER_END");
		break;
	//Transport des Transportfach-Objekts zur Startposition
	case STATE_ADVENTCAL_DELIVER:
		LOG_DEBUG("STATE_ADVENTCAL_DELIVER_BEGIN");
		//Soalange die Kanten-Sensoren keine Linie erkennen...
		if (sensBorderL<BORDER_DANGEROUS && sensBorderR<BORDER_DANGEROUS) {
			//...folgt der Bot der Linie...
			bot_follow_line(data, 0);
			//...und bricht ab, sobald beide Kanten-Sensoren eine Linie erkennen.
			bot_cancel_behaviour(data, bot_follow_line_behaviour, cancel_follow_line_on_border);
		}
		adventcal_state = STATE_ADVENTCAL_FLAPOPEN;
		LOG_DEBUG("STATE_ADVENTCAL_DELIVER_END");
		break;
	//Oeffnen der Transportfach-Klappe, bevor das Transportfach-Objekt freigegeben wird
	case STATE_ADVENTCAL_FLAPOPEN:
		LOG_DEBUG("STATE_ADVENTCAL_FLAPOPEN_BEGIN");
		bot_servo(data, SERVO1, DOOR_OPEN);
		adventcal_state = STATE_ADVENTCAL_MOVEBACK;
		LOG_DEBUG("STATE_ADVENTCAL_FLAPOPEN_END");
		break;
	//Freigabe des Transportfach-Objekts...
	case STATE_ADVENTCAL_MOVEBACK:
		LOG_DEBUG("STATE_ADVENTCAL_MOVEBACK_BEGIN");
		//...durch rueckwaertiges Fahren
		bot_drive_distance(data, 0, -BOT_SPEED_FOLLOW, 6);
		adventcal_state = STATE_ADVENTCAL_TURNTOSTARTPOS;
		LOG_DEBUG("STATE_ADVENTCAL_MOVEBACK_END");
		break;
	//180Grad-Drehung zurueck in Ausgangsposition und schlieszen der Transportfach-Klappe
	case STATE_ADVENTCAL_TURNTOSTARTPOS:
		LOG_DEBUG("STATE_ADVENTCAL_TURNTOSTARTPOS_BEGIN");
		//nicht ganz 180 Grad, damit das Liniensuchverhalten weniger dazu tendiert, den Bot beim Start am naechsten Tag nicht in die falsche Richtung zu drehen, sodass keine ideale Neuausrichtung des Bots noetig ist
		bot_turn(data, 170);
		LOG_DEBUG("STATE_ADVENTCAL_TURNTOSTARTPOS_TURN_DONE");
		//bot_drive_distance(data, 0, BOT_SPEED_FOLLOW, 1);
		//LOG_DEBUG("STATE_ADVENTCAL_TURNTOSTARTPOS_MOVE1CM_DONE");
		bot_servo(data, SERVO1, DOOR_CLOSE);
		LOG_DEBUG("STATE_ADVENTCAL_TURNTOSTARTPOS_FLAP_CLOSED");
		adventcal_state = 99;
		LOG_DEBUG("STATE_ADVENTCAL_TURNTOSTARTPOS_END");
		break;
	//Default-Verhalten, in diesem Fall: Gar nichts tun (Ende des Verhaltens)
	default:
		LOG_DEBUG("default_BEGIN");
		return_from_behaviour(data);
		LOG_DEBUG("default_END");
		break;
	}

}

/*!
 * Rufe das Adventskalender-Verhalten auf
 * @param *caller	Der obligatorische Verhaltensdatensatz des Aufrufers
 */
void bot_adventcal(Behaviour_t * caller) {
	switch_to_behaviour(caller, bot_adventcal_behaviour, BEHAVIOUR_OVERRIDE);
	adventcal_state = STATE_ADVENTCAL_START;
}

#endif // BEHAVIOUR_ADVENTCAL_AVAILABLE
Hier und da ist die Lösung nicht so "smart" wie sie sein sollte, sodass der Bot sich manchmal für die falsche Richtung "entscheidet", wenn er die Linie nach bestimmten Aktionen wieder suchen muss, aber im großen und ganzen funktioniert das Verhalten, siehe:

https://peertube.social/videos/watch/d4 ... 5d510e96fa

Einen entsprechenden Patch für https://github.com/tsandmann/ct-bot schicke ich heute noch EAX, dem ich gar nicht genug für die geduldige Beantwortung unendlich vieler Nachfragen meinerseits danken kann. :)

Was die Kommentierung des Lösungswegs betrifft: Die meisten Fragen lassen sich im Nachhinein durch eine wirklich kleinteilige Kommentierung des Prototyp-Verhaltens klären. Das werde ich als Nächstes in Angriff nehmen.
Zuletzt geändert von anonybot am 01 Dez 2019, 21:36, insgesamt 1-mal geändert.
Von mir selbst verfasste (daher nicht zitierte) Inhalte dieses Beitrags sind zur Weiternutzung unter CC-BY-SA freigegeben +++ ct-Bot -> Libre-Bot? - Diskussion zur Zukunft des ct-Bots +++ anonybot sagt hello!

anonybot
Friends of Sonny
Friends of Sonny
Beiträge: 118
Registriert: 07 Okt 2015, 00:14

Re: Der "ct-Bot-Weihnachtskalender" - Programmieren lernen am Beispiel ohne Vorkenntnisse

Beitrag von anonybot » 01 Dez 2019, 13:33

Eine erste Version ist im develop-Code: https://github.com/tsandmann/ct-bot/com ... 047f724ace

Eine etwas weihnachtlichere Version der Sim-Karte ist auf dem Weg:
adventcal_2019-12-01_21-29-55.png
Von mir selbst verfasste (daher nicht zitierte) Inhalte dieses Beitrags sind zur Weiternutzung unter CC-BY-SA freigegeben +++ ct-Bot -> Libre-Bot? - Diskussion zur Zukunft des ct-Bots +++ anonybot sagt hello!

anonybot
Friends of Sonny
Friends of Sonny
Beiträge: 118
Registriert: 07 Okt 2015, 00:14

Re: Der "ct-Bot-Weihnachtskalender" - Programmieren lernen am Beispiel ohne Vorkenntnisse

Beitrag von anonybot » 16 Apr 2020, 22:23

Um die Sache hier etwas sauberer abzuschließen:

Alle Code-Bestandteile des Adventkalender-Verhaltens sind nun in einer ersten, halbwegs funktionierenden Version im develop-Code:

- https://github.com/tsandmann/ct-bot/blo ... dventcal.c
- https://github.com/tsandmann/ct-bot/blo ... dventcal.h

Die entsprechende Karte für den Sim:

- https://github.com/tsandmann/ct-sim/blo ... entcal.xml

Vielen Dank nochmals an eax für die viele Hilfe, ich freue mich schon auf das nächste Projekt! :D
Von mir selbst verfasste (daher nicht zitierte) Inhalte dieses Beitrags sind zur Weiternutzung unter CC-BY-SA freigegeben +++ ct-Bot -> Libre-Bot? - Diskussion zur Zukunft des ct-Bots +++ anonybot sagt hello!

Antworten