Absender: Frank Menzel
Datum: Sa, 26.11.2011 20:36:06
In-reply-to:
<07C94192229C4D7B9D57263A625F7C3B@FrankPC>
References:
<E171B4EB-B636-4646-A1B5-18365383D5A7@xxxxxxxxxxxxxxx> <07C94192229C4D7B9D57263A625F7C3B@FrankPC>
Hallo Timo,um das Ergebnis des Messverhaltens auch in uBasic abfragen zu können, so wie im ABL-Script, habe ich etwas anpassen müssen. Anbei dazu der Patch und das Solve_maze-Verhalten mit dem Messverhalten zur Abstandsmessung. Die Version vorhin konnte das Messverhalten noch nicht abfragen und griff daher direkt auf die Abstandssensoren zurück.
Gruß, Frank -------------------------------------------------- From: "Frank Menzel" <Menzelfr@xxxxxx> Sent: Saturday, November 26, 2011 5:07 PMTo: "Entwicklung rund um den c't-bot" <ct-bot-entwickler@xxxxxxxxxxxxxxxxx>; <mail@xxxxxxxxxxxxxxx>
Subject: Re: [ct-bot] Skriptsprache zur Bot-Programmierung
Hallo Timo, im Anhang habe ich die Version des solve_maze Verhaltens mal als uBasic Variante analog des ABL-Scriptes... Gruß, Frank -------------------------------------------------- From: "Timo Sandmann" <mail@xxxxxxxxxxxxxxx> Sent: Thursday, November 10, 2011 9:55 PMTo: "Entwicklung rund um den c't-bot" <ct-bot-entwickler@xxxxxxxxxxxxxxxxx>Subject: [ct-bot] Skriptsprache zur Bot-ProgrammierungHallo, es gibt jetzt ein neues Bot-Verhalten (bot_abl_behaviour), das ja vielleicht jemanden interessiert: Es führt Skript-Programme aus, die auf der SD-Karte oder (wenn sie klein genug sind) im EEPROM gespeichert sein können. Die Skripte starten dabei im Wesentlichen andere Bot-Verhalten über den RemoteCall-Mechanismus. Außerdem gibt es Kontrollstrukturen (if und for), Sprünge und einen Stack. Auf dem Stack wird auch das Ergebnis des gestarteten Verhaltens gespeichert, so dass das Skript darauf reagieren kann. Insgesamt handelt es sich jedoch nicht um eine vollständige Programmiersprache, es gibt z.B. keine Mathematischen Befehle oder Variablen. Wer das braucht, sollte stattdessen das uBasic-Verhaltenverwenden, das da deutlich mehr kann (und das hiermit nicht ersetzt werdensoll). Die Idee zu diesem Skript-Verhalten entstand schon vor ein paar Jahren,damals war der Programmspeicher auf dem Bot noch deutlich beschränkter als heute mit einem ATmega1284P. Daher ist das Verhalten so entworfen, dass esmöglichst klein ist (belegt ca. 2.7 KB Flash inkl. der Empfangsroutinen für Programme vom Sim) und die Syntax so, dass sie einfach zu parsen ist. Damals gab es allerdings noch keine Möglichkeit, auf der SD-Karte Dateienanzulegen, darum hatte ich das Verhalten nicht fertiggestellt - inzwischengeht das bekanntlich und deshalb habe ich es jetzt mal an den aktuellen Bot-Code angepasst und in SVN gestellt.Wer Interesse daran hat, kann es als (deutlich abgespekte!) Alternative zuuBasic (es wird derselbe Programm-Editor im Sim verwendet) einsetzen, ansonsten stört es nicht weiter, weil es nur ein Verhalten ist, das standardmäßig deaktiviert ist. Dokumentation gibt es noch keine, aber ein Beispiel-Programm und der Sim-Editor kann auf Knopfdruck auch ein Mini-Beispiel erzeugen. Am Anfangder Verhaltensdatei ist außerdem eine Definition der Syntax angegeben. WerFragen dazu hat, benutzt am besten einfach die Mailingliste. Ein (älteres) Video, wo der Bot ein "Labyrinth" per Skript löst (also im Prinzip ein vereinfachter Nachbau von solve_maze() in der Skriptsprache), habe ich mal mit in die Galerie des Wikis aufgenommen. Das solve_maze-Skript ist allerdings nicht sehr robust gegen Störungen und auch nur als Beispiel zu sehen, was man so damit anstellen kann. Noch zwei Hinweise: 1. Das Sim-Fenster bietet auch die Möglichkeit, ein geladenes oder eingegebenes Programm syntaktisch zu überprüfen, der erste Fehler wird dann rot hervorgehoben. Zusätzlich zur Syntax wird dabei übrigens auch überprüft, ob ein (per RemoteCall) zu startendes Verhalten auf dem Bot überhaupt vorhanden ist. 2. Die ursprüngliche Idee zu diesem Skript-Interpreter sah auch noch vor, ein kleines (PC-) Programm zu entwickeln, mit dem sich auf grafische Art und Weise ein Bot-Verhalten zusammenstellen (klicken) lässt. Und das Ergebnis hätte dann als solch ein Skript-Programm exportiert werden sollen, so dass man also ein Programm, das Unterverhalten aufruft und entsprechende Bedingungen auswertet, per Mausklick erzeugen kann. Dann bräuchte man weder mit C noch einer Skriptsprache zu arbeiten, um den Bot zu programmieren. Ich bin leider nie dazu gekommen, das anzugehen. Falls jemand Interesse haben sollte, so etwas umzusetzen, würden wir das natürlich gern mit ins Projekt integrieren. Gruß, Timo _______________________________________________ ct-bot-entwickler Mailingliste ct-bot-entwickler@xxxxxxxxxxxxxxxxx http://www.heise.de/bin/newsletter/listinfo/ct-bot-entwickler
_______________________________________________ ct-bot-entwickler Mailingliste ct-bot-entwickler@xxxxxxxxxxxxxxxxxhttp://www.heise.de/bin/newsletter/listinfo/ct-bot-entwickler
rem solve maze rem Vorlage war das ABL Script 10: rem Wand direkt voraus? call("RC", "bot_check_distance", 120, 15) d=call("beh_result") if d=0 then call("RC", "bot_turn", 90) rem Wand etwas weiter weg call("RC", "bot_check_distance", 220, 15) d=call("beh_result") if d=1 then gosub 1000 else gosub 2000 rem und in loop wieder zurueck goto 10 end 1000: rem zur Wand links drehen call("RC", "bot_goto_obstacle", 120, 1) rem in Fahrtrichtung drehen call("RC", "bot_turn", -90) rem wieder Abstand bestimmen call("RC", "bot_check_distance", 200, 15) d=call("beh_result") rem stueckchenweise vorfahren if d=1 then call("RC", "bot_goto_dist", 40, 1) else call("RC", "bot_goto_dist", 100, 1) return 2000: rem keine Wand mehr und Abbiegen call("RC", "bot_turn", -90) rem zur Ecke vorfahren call("RC", "bot_goto_dist", 100, 1) rem um die Ecke rum call("RC", "bot_turn", 90) call("RC", "bot_goto_dist", 220, 1) return
### Eclipse Workspace Patch 1.0 #P ct-Bot Index: include/bot-logic/available_behaviours.h =================================================================== --- include/bot-logic/available_behaviours.h (revision 1862) +++ include/bot-logic/available_behaviours.h (working copy) @@ -34,12 +34,12 @@ //#define BEHAVIOUR_DRIVE_SQUARE_AVAILABLE /*!< Demoverhalten im Quadrat fahren vorhanden? */ #define BEHAVIOUR_AVOID_BORDER_AVAILABLE /*!< Abgruenden ausweichen vorhanden? */ -#define BEHAVIOUR_AVOID_COL_AVAILABLE /*!< Hindernis ausweichen vorhanden? */ +//#define BEHAVIOUR_AVOID_COL_AVAILABLE /*!< Hindernis ausweichen vorhanden? */ //#define BEHAVIOUR_HANG_ON_AVAILABLE /*!< Erkennen des Haengenbleibens als Notfallverhalten? */ //#define BEHAVIOUR_GOTO_AVAILABLE /*!< goto vorhanden? */ //#define BEHAVIOUR_GOTOXY_AVAILABLE /*!< gotoxy vorhanden? */ #define BEHAVIOUR_GOTO_POS_AVAILABLE /*!< goto_pos vorhanden? */ -//#define BEHAVIOUR_GOTO_OBSTACLE_AVAILABLE /*!< goto_obstacle vorhanden? */ +#define BEHAVIOUR_GOTO_OBSTACLE_AVAILABLE /*!< goto_obstacle vorhanden? */ #define BEHAVIOUR_TURN_AVAILABLE /*!< turn vorhanden? */ //#define BEHAVIOUR_TURN_TEST_AVAILABLE /*!< turn_test vorhanden? */ //#define BEHAVIOUR_TEST_ENCODER_AVAILABLE /*!< Encoder-Test Verhalten vorhanden? */ @@ -55,7 +55,7 @@ #define BEHAVIOUR_SERVO_AVAILABLE /*!< Kontrollverhalten fuer die Servos */ -//#define BEHAVIOUR_PATHPLANING_AVAILABLE /*!< Pfadplanungsverhalten */ +#define BEHAVIOUR_PATHPLANING_AVAILABLE /*!< Pfadplanungsverhalten */ //#define BEHAVIOUR_DRIVE_STACK_AVAILABLE /*!< Abfahren der auf dem Stack gesicherten Koordinaten */ //#define BEHAVIOUR_OLYMPIC_AVAILABLE /*!< Olympiadenverhalten vorhanden? */ @@ -87,7 +87,7 @@ //#define BEHAVIOUR_SCAN_BEACONS_AVAILABLE /*!< Suchen von Landmarken zur Lokalisierung */ -//#define BEHAVIOUR_UBASIC_AVAILABLE /*!< uBasic Verhalten */ +#define BEHAVIOUR_UBASIC_AVAILABLE /*!< uBasic Verhalten */ //#define BEHAVIOUR_ABL_AVAILABLE /*!< ABL-Interpreter */ /* Aufgrund einer ganzen Reihe von Abhaengigkeiten sollte man beim Versuch Speicher Index: include/bot-logic/behaviour_ubasic.h =================================================================== --- include/bot-logic/behaviour_ubasic.h (revision 1862) +++ include/bot-logic/behaviour_ubasic.h (working copy) @@ -36,7 +36,18 @@ extern char ubasic_content; /**< aktuelles Zeichen des Basic-Programms */ extern uint16_t ubasic_ptr; /**< aktuelle Position im Basic-Programm */ +uint8_t result_behav; + +void ubasic_push_value(uint16_t value); + /** + * Rueckgabe ob das zuletzt aufgerufene Verhalten erfolgreich war oder nicht; in Remotecall wird dazu via ubasic_push_value aufgerufen und das Ergebnis + * nach result_behav gebracht; in Ubasic selbst kann mit dieser Routine das Ergebnis ermittelt werden + * \return True falls das Verhalten erfolgreich war sonst nicht, je nach Kontext des Verhaltens + */ +uint8_t behaviour_result(Behaviour_t * behaviour); + +/** * Startet das uBasic-Verhalten * \param *caller Zeiger auf den Verhaltensdatensatz des Aufrufers */ Index: ct-Bot.h =================================================================== --- ct-Bot.h (revision 1862) +++ ct-Bot.h (working copy) @@ -72,7 +72,7 @@ #define POS_STORE_AVAILABLE /*!< Positionsspeicher vorhanden */ -//#define MAP_AVAILABLE /*!< Aktiviert die Kartographie */ +#define MAP_AVAILABLE /*!< Aktiviert die Kartographie */ #define MAP_2_SIM_AVAILABLE /*!< Sendet die Map zur Anzeige an den Sim */ //#define SPEED_CONTROL_AVAILABLE /*!< Aktiviert die Motorregelung */ @@ -86,7 +86,7 @@ //#define MMC_AVAILABLE /*!< haben wir eine MMC/SD-Karte zur Verfuegung? */ //#define SPI_AVAILABLE /*!< verwendet den Hardware-SPI-Modus des Controllers, um mit der MMC zu kommunizieren. Muss ausserdem _immer_ an sein, wenn der Hardware-SPI-Umbau durchgefuehrt wurde! Hinweise in mcu/mmc.c beachten! */ //#define MMC_VM_AVAILABLE /*!< Virtual Memory Management mit MMC / SD-Card oder PC-Emulation */ -//#define BOT_FS_AVAILABLE /*!< Aktiviert das Dateisystem BotFS (auf MCU nur mit MMC moeglich) */ +#define BOT_FS_AVAILABLE /*!< Aktiviert das Dateisystem BotFS (auf MCU nur mit MMC moeglich) */ #define OS_AVAILABLE /*!< Aktiviert BotOS fuer Threads und Scheduling */ //#define EEPROM_EMU_AVAILABLE /*!< Aktiviert die EEPROM-Emulation fuer PC */ Index: bot-logic/basic/solve_maze_v2.txt =================================================================== --- bot-logic/basic/solve_maze_v2.txt (revision 0) +++ bot-logic/basic/solve_maze_v2.txt (revision 0) @@ -0,0 +1,45 @@ +rem solve maze +rem Vorlage war das ABL Script +10: +rem Wand direkt voraus? +call("RC", "bot_check_distance", 120, 15) +d=call("beh_result") +if d=0 then call("RC", "bot_turn", 90) + +rem Wand etwas weiter weg +call("RC", "bot_check_distance", 220, 15) +d=call("beh_result") +if d=1 then gosub 1000 else gosub 2000 + +rem und in loop wieder zurueck +goto 10 +end + + +1000: +rem zur Wand links drehen +call("RC", "bot_goto_obstacle", 120, 1) +rem in Fahrtrichtung drehen +call("RC", "bot_turn", -90) + +rem wieder Abstand bestimmen +call("RC", "bot_check_distance", 200, 15) +d=call("beh_result") +rem stueckchenweise vorfahren +if d=1 then call("RC", "bot_goto_dist", 40, 1) else call("RC", "bot_goto_dist", 100, 1) +return + + + +2000: +rem keine Wand mehr und Abbiegen +call("RC", "bot_turn", -90) + +rem zur Ecke vorfahren +call("RC", "bot_goto_dist", 100, 1) + +rem um die Ecke rum +call("RC", "bot_turn", 90) +call("RC", "bot_goto_dist", 220, 1) + +return Index: bot-logic/basic/solve_maze.txt =================================================================== --- bot-logic/basic/solve_maze.txt (revision 0) +++ bot-logic/basic/solve_maze.txt (revision 0) @@ -0,0 +1,53 @@ +rem solve maze +rem Vorlage war das ABL Script +10: +rem call("bot_speed", 450, 450) +rem Abstand zur Wand voraus +r=vpeek("sensDistR") +l=vpeek("sensDistL") + +rem Wand direkt voraus + +if l > 140 and r > 140 then call("RC", "bot_turn", 90) + + +rem Wand etwas weiter weg +r=vpeek("sensDistR") +l=vpeek("sensDistL") + +if l<220 OR r<220 then gosub 1000 else gosub 2000 + +rem und in loop wieder zurueck +goto 10 +end + + + + +1000: +rem zur Wand links drehen +call("RC", "bot_goto_obstacle", 120, 1) +rem in Fahrtrichtung drehen +call("RC", "bot_turn", -90) + +rem wieder Abstand bestimmen +r=vpeek("sensDistR") +l=vpeek("sensDistL") +rem stueckchenweise vorfahren +if l<200 OR r<200 then call("RC", "bot_goto_dist", 40, 1) else call("RC", "bot_goto_dist", 100, 1) +return + + + +2000: +rem keine Wand mehr und Abbiegen +call("RC", "bot_turn", -90) + +rem zur Ecke vorfahren +call("RC", "bot_goto_dist", 100, 1) + +rem um die Ecke rum +call("RC", "bot_turn", 90) +call("RC", "bot_goto_dist", 220, 1) + +return Index: Changelog.txt =================================================================== --- Changelog.txt (revision 1862) +++ Changelog.txt (working copy) @@ -1,5 +1,7 @@ CHANGELOG fuer c't-Bot ====================== +2011-11-26 Frank Menzel [Menzelfr@xxxxxx]: Anpassungen fuer uBasic: neue Routine beh_result zur Ermittlung des Ergebnisses eines Verhaltens (Messverhalten wie im ABL Script verwendet) + 2011-11-09 Timo Sandmann [mail@xxxxxxxxxxxxxxx]: Verhalten bot_abl_behaviour() zur Steuerung des Bots ueber eine Scriptsprache. Doku folgt. Siehe auch bot-logic/behaviour_abl.c 2011-11-06 Timo Sandmann [mail@xxxxxxxxxxxxxxx]: Makroblock-Alignment fuer Map optimiert Index: bot-logic/behaviour_ubasic.c =================================================================== --- bot-logic/behaviour_ubasic.c (revision 1862) +++ bot-logic/behaviour_ubasic.c (working copy) @@ -44,7 +44,7 @@ #include <stdio.h> #include <string.h> -//#define DEBUG_UBASIC_BEHAV /**< Debug-Schalter fuer das uBasic-Verhalten */ +#define DEBUG_UBASIC_BEHAV /**< Debug-Schalter fuer das uBasic-Verhalten */ #define PROG_FILE_NAME "/basic/basX.txt" /**< Name der Programmdateien, X wird durch 1 bis 9 ersetzt */ #define PROG_FILE_EXT ".txt" /**< Dateinamenerweiterung (PROG_FILE_NAME muss hierauf enden) */ @@ -128,6 +128,23 @@ } /** + * Rueckgabe ob das zuletzt aufgerufene Verhalten erfolgreich war oder nicht; in Remotecall wird dazu via ubasic_push_value aufgerufen und das Ergebnis + * nach result_behav gebracht; in Ubasic selbst kann mit dieser Routine das Ergebnis ermittelt werden + * \return True falls das Verhalten erfolgreich war sonst nicht, je nach Kontext des Verhaltens + */ +uint8_t behaviour_result(Behaviour_t * behaviour) { + behaviour=0;//diese Var ist eigentlich nicht notwendig, so wird aber bestehender Aufrufttyp benutzt und hier die Var verwendet sonst Warning + return result_behav; + +} + +void ubasic_push_value(uint16_t value) { + result_behav = value; + LOG_DEBUG("Var behav_res gesetzt auf: %1d", result_behav); + +} + +/** * Implementierung des Basic-Wait-Statements fuer ct-Bot. * Das eigentliche Warten erfolgt dabei ueber das Verhalten. */ Index: bot-logic/behaviour_pathplaning.c =================================================================== --- bot-logic/behaviour_pathplaning.c (revision 1862) +++ bot-logic/behaviour_pathplaning.c (working copy) @@ -51,8 +51,8 @@ #include "log.h" #include "pos_store.h" -//#define DEBUG_PATHPLANING // Schalter fuer Debugausgaben -//#define DEBUG_PATHPLANING_VERBOSE // zeichnet Zellen in die Map-Anzeige des Sim ein, rot: Hindernis, gruen: frei +#define DEBUG_PATHPLANING // Schalter fuer Debugausgaben +#define DEBUG_PATHPLANING_VERBOSE // zeichnet Zellen in die Map-Anzeige des Sim ein, rot: Hindernis, gruen: frei #define QUEUE_SIZE 32 /*!< Groesse des verwendeten Positionsspeichers */ @@ -135,7 +135,7 @@ #define END 99 /*! Begrenzung des Wellenzaehlers, d.h. obere Grenze als Abbruchbedingung */ -#define MAX_WAVECOUNTER 120 +#define MAX_WAVECOUNTER 150 static uint8_t wave_state = 0; /*!< Statusvariable */ @@ -226,18 +226,67 @@ } /*! - * Eintragen der Hindernisse in Lowres-Karte aus der Map-Highres-Karte + * findet die Grenzen des umgebenden Rechtecks von der Botposition zu den Zielkoordinaten in der Lowres-Pfadplanungsmap unabhaengig vom umgebenden Rechtecks der realen Map; werden in der realen Welt + * die Zielkoordinaten noch nicht gesehen, waeren diese Zielkoords noch nicht in der Map und somit ausserhalb des umgebenden Map-Rechtecks und es koennte kein Weg gefunden werden + * \param startwave X/Y-Lowres-Map Koordinate des Zielpunktes, von wo die Welle startet + * \param endkoord X/Y-Lowres-Map Koordinate der Botposition, welchs fuer die Welle die Endkoordinaten darstellen + * \param *start_x kleinste X-Koord des umgebenden Rechtecks fuer die Pfadfindung + * \param *start_y kleinste Y-Koord des umgebenden Rechtecks fuer die Pfadfindung + * \param *end_x groesste Y-Koord des umgebenden Rechtecks fuer die Pfadfindung + * \param *end_y groesste Y-Koord des umgebenden Rechtecks fuer die Pfadfindung */ +static void get_boundings(position_t startwave, position_t endkoord, int16_t * start_x, int16_t * start_y, int16_t * end_x, int16_t * end_y) { + +if (startwave.y > endkoord.y) { + *start_y = endkoord.y; + *end_y = startwave.y; +} else { + *start_y = startwave.y; + *end_y = endkoord.y; +} + +if (startwave.x > endkoord.x) { + *start_x = endkoord.x; + *end_x = startwave.x; +} else { + *start_x = startwave.x; + *end_x = endkoord.x; +} +*start_x -= 5; +if (*start_x < 0) *start_x = 0; +*end_x += 5; +*start_y -= 5; +if (*start_y < 0) *start_y = 0; +*end_y += 5; + +// Umrechnen des die Welt umschliessenden Rechtecks in Lowres-Koordinaten +/* if (world_to_map_lowres(map_get_min_x()) - 1 > *start_x) + *start_x = world_to_map_lowres(map_get_min_x()) - 1; + if (world_to_map_lowres(map_get_max_x()) + 1 > *end_x) + *end_x=world_to_map_lowres(map_get_max_x()) + 1; + if (world_to_map_lowres(map_get_min_y()) - 1 > *start_y) + *start_y=world_to_map_lowres(map_get_min_y()) - 1; + if (world_to_map_lowres(map_get_max_y()) + 1 > *end_y) + *end_y = world_to_map_lowres(map_get_max_y()) + 1; + *start_y = (*start_y > 0) ? *start_y : 0; // sicherstellen dass Grenzen positiv sind + *start_x = (*start_x > 0) ? *start_x : 0; +*/ +} + +/*! + * Eintragen der Hindernisse in der Lowres-Pfadplanungskarte aus der Map-Highres-Karte + */ static void set_hazards(void) { int16_t x, y; - // Umrechnen des die Welt umschliessenden Rechtecks in Lowres-Koordinaten + /* Grenzen finden innerhalb der Lowres Karte */ + //get_boundings(startwave, endkoord, &min_x, &min_y, &max_x, &max_y); min_x = world_to_map_lowres(map_get_min_x()) - 1; - max_x = world_to_map_lowres(map_get_max_x()) + 1; - min_y = world_to_map_lowres(map_get_min_y()) - 1; - max_y = world_to_map_lowres(map_get_max_y()) + 1; - min_y = (min_y > 0) ? min_y : 0; // sicherstellen dass Grenzen positiv sind - min_x = (min_x > 0) ? min_x : 0; + max_x = world_to_map_lowres(map_get_max_x()) + 1; + min_y = world_to_map_lowres(map_get_min_y()) - 1; + max_y = world_to_map_lowres(map_get_max_y()) + 1; + min_y = (min_y > 0) ? min_y : 0; // sicherstellen dass Grenzen positiv sind + min_x = (min_x > 0) ? min_x : 0; int16_t yw; @@ -316,6 +365,8 @@ return end_reached; } // Ende get_neighbour + + #ifdef DEBUG_PATHPLANING /*! * Zeigt einen Ausschnitt der Planungs-Map auf Konsole an; gut zum Pruefen wo Hindernisse gesehen werden und die Welle verlaeuft @@ -324,6 +375,8 @@ int16_t x, y; int16_t xw; int16_t yw; + int16_t start_x, end_x; + int16_t start_y, end_y; LOG_DEBUG("Wellenstart vom Zielpunkt %1d %1d", startwave.x, startwave.y); access_field_lowres(startwave, 2, 1); // vermerken des Wellen-Startpunktes @@ -331,29 +384,32 @@ access_field_lowres(endkoord, 88, 1); // Botpos vermerken /* Grenzen finden */ - int16_t start_y, end_y; - if (startwave.y > endkoord.y) { - start_y = endkoord.y; - end_y = startwave.y; - } else { - start_y = startwave.y; - end_y = endkoord.y; - } - int16_t start_x, end_x; - if (startwave.x > endkoord.x) { - start_x = endkoord.x; - end_x = startwave.x; - } else { - start_x = startwave.x; - end_x = endkoord.x; - } - start_x -= 5; - if (start_x < 0) start_x = 0; - end_x += 5; - start_y -= 5; - if (start_y < 0) start_y = 0; - end_y += 5; + get_boundings(startwave, endkoord, &start_x, &start_y, &end_x, &end_y); + /* Grenzen finden */ + /*int16_t start_y, end_y; + if (startwave.y > endkoord.y) { + start_y = endkoord.y; + end_y = startwave.y; + } else { + start_y = startwave.y; + end_y = endkoord.y; + } + int16_t start_x, end_x; + if (startwave.x > endkoord.x) { + start_x = endkoord.x; + end_x = startwave.x; + } else { + start_x = startwave.x; + end_x = endkoord.x; + } + start_x -= 5; + if (start_x < 0) start_x = 0; + end_x += 5; + start_y -= 5; + if (start_y < 0) start_y = 0; + end_y += 5;*/ + printf("y: "); for (y=end_y; y>=start_y; y--) { printf("%2d|", y); @@ -484,7 +540,10 @@ // ein paar notwendige Initialisierungen und Variablendeklarationen int8_t minval = 1; + int8_t mapval_tmp = 1; + int8_t tmpval = 1; position_t nextdest = {0, 0}; + int8_t haz_found = False; // Ausgehend vom Wellen-Ausgangspunkt, dem Zielpunkt, wird jeweils der Nachbar genommen mit dem kleinsten Wert pos = endkoord; @@ -531,14 +590,52 @@ nextdest.x = pos.x + i; nextdest.y = pos.y + j; - LOG_DEBUG("kleinster Wellenwert %1d Koord %1d %1d", minval, nextdest.x, nextdest.y); + // hier nun Logik zum Vergleich des gefundenenn Nachbarn mit geringerem Wellenwert auf seine weiteren Nachbarn + // es soll dann nur das Feld genommen werden ohne angrenzendem Hindernis-Nachbarn - // Wellenwert und Kennung fuer Nachbar gefunden setzen - mapval_min = minval; - neighbour_found = True; + position_t tmppos = nextdest; //den gerade untersuchten nachbarn zur weiteren nachbarschaftssuche verwenden + haz_found = False; + int8_t l; int8_t m; + int8_t loopend = False; + + mapval_tmp = 1; + mapval_min = 1; + for (l=-1; (l<=1) && !loopend; l++) { + for (m=-1; (m<=1) && !loopend; m++) { + tmppos.x += l; + tmppos.y += m; + tmpval = access_field_lowres(tmppos, 0, 0); // Mapwert auslesen + if (tmpval==1) { // der Nachbar ist Hindernis->Ende + loopend=True; + haz_found=True; + if (mapval_tmp==1) { + mapval_tmp = minval; // erst mal temporaer den ersten merken + if (nextdest.x<=60) + LOG_DEBUG("Feld %1d %1d hat Nachbar-Hindernis auf %1d %1d ",nextdest.x,nextdest.y,tmppos.x,tmppos.y); + } //if + } //if + } // FOR m + } // For l + + LOG_DEBUG("kleinster Wellenwert %1d Koord %1d %1d, an Hind %1d", minval, nextdest.x, nextdest.y, haz_found); + + if (!haz_found) { + // Wellenwert und Kennung fuer Nachbar gefunden setzen + mapval_min = minval; + neighbour_found = True; + LOG_DEBUG(">=>Kein Hind auf %1d %1d ",nextdest.x,nextdest.y); + } // if + } } } + } // while + + // falls es nur Felder mit Hindernis gab, dann das erste gemerkte nehmen + if (neighbour_found == False /*mapval_min==1 && mapval_tmp!=1*/ && haz_found) { + mapval_min=mapval_tmp; + neighbour_found = True; + LOG_DEBUG(">_>nur Felder mit Hindernis am Rand auf %1d %1d ",nextdest.x,nextdest.y); } // hier die Punkte jeweils in die Queue (Stack) einfuegen; das hier zuerst eingefuegte naechste Ziel ist ja bei der Wellenrueckverfolgung die naechste Position vom Bot ausgehend; Index: bot-logic/ubasic_call.c =================================================================== --- bot-logic/ubasic_call.c (revision 1862) +++ bot-logic/ubasic_call.c (working copy) @@ -62,6 +62,7 @@ { "bot_speed", .funct_ptr.VoidFunc2Int16 = ubasic_set_speed, VOID_FUNC_2INT16 }, { "beh_active", .funct_ptr.BoolFuncBeh = ubasic_behaviour_is_active, BOOL_FUNC_BEH }, { "RC", .funct_ptr.VoidFuncRC = bot_remotecall, VOID_FUNC_RC }, + { "beh_result", .funct_ptr.BoolFuncBeh = behaviour_result, BOOL_FUNC_BEH }, {"", {NULL}, 255} }; Index: bot-logic/behaviour_measure_distance.c =================================================================== --- bot-logic/behaviour_measure_distance.c (revision 1862) +++ bot-logic/behaviour_measure_distance.c (working copy) @@ -100,8 +100,11 @@ static int16_t right = 0; if (left == 0) { bot_measure_distance(data, &left, &right, max_diff); + LOG_DEBUG("Start measure_distance"); } else { exit_behaviour(data, (uint8_t) ((left <= range) || (right <= range))); + + LOG_DEBUG("Measure exit Res: %1d, left %1d right %1d",((left <= range) || (right <= range)),left,right); left = 0; } } Index: bot-logic/behaviour_remotecall.c =================================================================== --- bot-logic/behaviour_remotecall.c (revision 1862) +++ bot-logic/behaviour_remotecall.c (working copy) @@ -382,6 +382,9 @@ #ifdef BEHAVIOUR_ABL_AVAILABLE abl_push_value((uint16_t) result); #endif +#ifdef BEHAVIOUR_UBASIC_AVAILABLE + ubasic_push_value((uint16_t) result); +#endif } #ifdef COMMAND_AVAILABLE else {