c't

c't-Projekte - Mailinglisten


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

Re: [ct-bot] Skriptsprache zur Bot-Programmierung

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 PM
To: "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 PM
To: "Entwicklung rund um den c't-bot" <ct-bot-entwickler@xxxxxxxxxxxxxxxxx>
Subject: [ct-bot] Skriptsprache zur Bot-Programmierung

Hallo,

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-Verhalten
verwenden, das da deutlich mehr kann (und das hiermit nicht ersetzt werden
soll).
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 es
mö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 Dateien
anzulegen, darum hatte ich das Verhalten nicht fertiggestellt - inzwischen
geht 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 zu
uBasic (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 Anfang
der Verhaltensdatei ist außerdem eine Definition der Syntax angegeben. Wer
Fragen 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@xxxxxxxxxxxxxxxxx
http://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 {