## c't-Projekte - Mailinglisten

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

### AW: [ct-bot] neues Verhalten bot_drive_line_shortest_way...

Absender: Frank Menzel
Datum: Do, 08.01.2009 22:04:35
In-reply-to: <587DE1BA-C1EF-4E1D-80D9-EC04CA468156@xxxxxxxxxxxxxxx>

    Hi Timo,
    habe jetzt den Linienfolger rausgezogen und die vorhandenen Versionen
    dazu mit Nummern versehen (analog catch_pillar). Die Version ist
    abfragbar und es kommt eine Warnung, wenn für dieses Verhalten nicht der
    jetzige mit Nummer 3 verwendet wird. Andere können ebenfalls (mit
    Warnung) benutzt werden, die dann vom Cancelverhalten an Kreuzungen
    abgebrochen werden. Aber bei meinen Versuchen klappt es nur sehr gut mit
    dem neuen Linienfolger.
    Das mit dem grünen Startfeld habe ich auch gelöst. Dieses wird erst
    ausgewertet ab der 1. Kreuzung.
    Vielleicht schaffe ich es auch noch, eine Drehumkehr am Ende einer Linie
    auch ohne das Grüne Umkehrfeld zu erkennen. Dies dann aber später...
    Erst mal soweit, Patch im Anhang.

    Gruß, Frank

    -----Ursprüngliche Nachricht-----
    Von: ct-bot-entwickler-bounces@xxxxxxxxxxxxxxxxx
    [mailto:ct-bot-entwickler-bounces@xxxxxxxxxxxxxxxxx] Im Auftrag von Timo
    Sandmann
    Gesendet: Mittwoch, 7. Januar 2009 13:53
    An: Entwicklung rund um den c't-bot
    Betreff: Re: [ct-bot] neues Verhalten bot_drive_line_shortest_way...

    Hi Frank,

    Am 07.01.2009 um 08:06 schrieb Frank Menzel:
    > Hallo Timo,
    > zu 2.) den Linienfolger habe ich eingebaut, weil darin ein paar
    > Kennungen, sprich Variable, gesetzt werden nach Erkennen des
    > Umkehrfeldes und bei diesem Linienfolger der Bot nicht nur auf der
    > Kante
    > fährt sondern auch wenn beide Sensoren sich auf der Linie befinden.

    das könnte man aber ja auch über das Cancel-Verhalten machen oder wie
    bei drive_area() mit einem extra Verhalten, das die Überwachung
    übernimmt. Was ich so etwas unglücklich finde ist, dass man den Code
    zur Linienverfolgung doppelt pflegen muss. Wenn der Linienfolger
    verbessert wird, profitiert line_shortest_way() noch nicht davon und
    man muss erst mühsam die Änderungen oder Bugfixes übertragen. Darum
    wäre es mittel- und langfristig schöner, wenn das Verhalten auf
    bot_follow_line() zurückgreifen würde.

    > Zu 1.) nach shortest_wa_forward sollte er gewisse Strecke vorfahren,
    > dann die Linie finden und via Linienfolger weitermachen... Auch der
    > Original-Linienfolger dreht sich manchmal endlos, wenn er die Linie
    > einfach nicht wieder findet...

    Aber ich glaube er dreht noch auf dem grünen Feld, bevor er überhaupt
    etwas vor gefahren ist.

    > X- oder Y-Kooridnaten sind völlig belanglos, Hauptsache Linie und
    > Kreuzungen finden und richtiges Setzen der Kennung auf Vor-Rückwärts
    > siehe 1. bzw. Doku.

    Ja das habe ich dann auch gemerkt, als die die Doku komplett gelesen
    hatte... ;-)
    So verstehe ich allerdings noch weniger, warum er dann den falschen
    Weg auswählt an der nächsten Kreuzung.

    Gruß,
    Timo
    _______________________________________________
    ct-bot-entwickler Mailingliste
    ct-bot-entwickler@xxxxxxxxxxxxxxxxx
    http://www.heise.de/bin/newsletter/listinfo/ct-bot-entwickler

    Index: C:/botneu/ct-Bot/bot-logic/behaviour_drive_line_shortest_way.c
    ===================================================================
    --- C:/botneu/ct-Bot/bot-logic/behaviour_drive_line_shortest_way.c	(revision 0)
    +++ C:/botneu/ct-Bot/bot-logic/behaviour_drive_line_shortest_way.c	(revision 0)
    @@ -0,0 +1,634 @@
    +/*
    + * 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_drive_line_shortest_way.c
    + * @brief 	Linienverfolger, der an Kreuzungen eine bestimmte Vorzugsrichtung einschlaegt (links) und diesen Weg weiterverfolgt, bis das Ziel
    + *          (gruenes Feld an Wand) gefunden ist; Linien muessen immer an einem gruenen Feld ohne Hindernis enden, damit der botein Ende erkennt und
    + *          umdrehen kann
    + *          Die Kreuzungen und der eingeschlagene Weg werden auf dem Stack vermerkt, Wege die nicht zum Ziel fuehren vergessen; Am Ziel angekommen
    + *          steht im Stack der kuerzeste Weg; Es kann nun via Display auf dem kuezesten Weg zum Ausgangspunkt zurueckgefahren werden oder der Bot wieder
    + *          manuell an den Start gestellt werden und das Ziel auf kuerzestem Weg angefahren werden
    + * @author 	Frank Menzel (Menzelfr@xxxxxx)
    + * @date 	21.12.2008
    + */
    +
    +#include "bot-logic/bot-logik.h"
    +
    +#ifdef BEHAVIOUR_DRIVE_LINE_SHORTEST_WAY_AVAILABLE
    +
    +#include "pos_store.h"
    +#include "rc5-codes.h"
    +#include "math_utils.h"
    +
    +#define DEBUG_BEHAVIOUR_DRIVE_LINE_SHORTEST_WAY		// Schalter fuer Debug-Code
    +
    +#ifndef LOG_AVAILABLE
    +#undef DEBUG_BEHAVIOUR_DRIVE_LINE_SHORTEST_WAY
    +#endif
    +#ifndef DEBUG_BEHAVIOUR_DRIVE_LINE_SHORTEST_WAY
    +#undef LOG_DEBUG
    +#define LOG_DEBUG(a, ...) {}
    +#endif
    +
    +/*! Version des Linefolgers, der optimal fuer dieses Verhalten ist */
    +#define OPTIMAL_LINE_BEHAVIOUR_VERSION 3
    +
    +#if FOLLOW_LINE_VERSION != OPTIMAL_LINE_BEHAVIOUR_VERSION
    +  #warning "optimal nur mit Version 3 des Linienfolgers"
    +#endif
    +
    +/*! Statusvariable des Verhaltens */
    +static int8 lineState=0;
    +
    +/*! Farbe des Umkehr- und Zielfeldes, via Default auf Gruen festgelegt */
    +#define GROUND_GOAL_DEF      GROUND_GOAL
    +
    +/*! Positionsspeicher, den das Verhalten benutzt zum Speichern der Weginfos */
    +static pos_store_t * pos_store = NULL;
    +/*! Statischer Speicher fuer pos_store */
    +static position_t pos_store_data[POS_STORE_SIZE];
    +
    +/*!
    + * Zeit zwischen zwei Korrekturen [ms]. Groessere Werte bewirken "ruhigeres" Fahren,
    + * erhoehen damit aber auch die Reaktionszeit (z.B. bei scharfen Kurven problematisch)
    + */
    +#define	CORRECTION_DELAY	150
    +
    +/*! Kennungen, welcher der Bordersensoren zugeschlagen hat zur Erkennung der Kreuzungen, notwendig
    +*   weil sicht nicht immer beide gleichzeitig ueber Kreuzungslinie befinden
    +*/
    +static uint8_t border_side_l_fired=0;
    +static uint8_t border_side_r_fired=0;
    +
    +/*! bevorzugte Richtung an Kreuzungen; 1 zuerst immer nach links, -1 rechts */
    +#define START_SIDEWISH 1
    +
    +/*! Variable, die im Verhalten die Richtung an Kreuzung bestimmt; zum Beginn auf bevorzugte Startrichtung gesetzt */
    +static int8_t sidewish=START_SIDEWISH;
    +
    +/*! Kennung ob bot sich von Kreuzung weg bewegt und einen Weg entdeckt (vorwaerts) oder sich auf dem Rueckweg befindet nach
    + *  Erkennen der gruenen Umkehrfarbe */
    +static uint8_t way_back=0;
    +
    +
    +/*! eingeschlagene Richtung an Kreuzung ausgehend von urspruenglichem Ankunftsweg */
    +static int16_t direction_counter=0;
    +
    +/*! Kreuzungstyp, hier nur die X-Kreuzungen erlaubt (4 Seiten); mitgefuehrt fuer moegliche Erweiterungen */
    +static int16_t crosstype=0;
    +
    +/*! Zusatnd des Verhaltens, ob Linienfolger Weg erst suchen soll oder den bereits im Stack befindlichen kuerzesten Weg abfahren soll;
    + *  zum Abfahren des kuerzesten Weges aus Stack ist Wert True sonst False
    + */
    +static uint8_t go_stack_way=0;
    +
    +/*! an der 1. Kreuzung wird Kennung gesetzt und erst ab dann ein Umkehrfeld ausgewertet
    + */
    +static uint8_t crossing_reached=0;
    +
    +/*! Zustaende des Verhaltens */
    +#define GO_TO_LINE	              0
    +#define CHECK_LINE	              1
    +#define GO_FORWARD                2
    +#define TURN_SIDEWISH_ON_CROSSING 3
    +#define GO_FORWARD_AFTER_TURN     4
    +#define CHECK_BORDER              5
    +#define TURN_ON_GREEN             6
    +
    +
    +/*!
    + * Push der Kreuzungsinformationen, etwas tricky dazu der eigentliche Positionsspeicher benutzt
    + * @param crosstype	Typ der Kreuzung (jetzt nur 1 Typ, gedacht fuer spaetere Erweiterungen und weil Postyp sowieso 2 Params hat)
    + * @param direction	eingeschlagener Weg an der Kreuzung
    + */
    +static void push_stack_crossing(int16_t crosstype, int16_t direction) {
    +   position_t p_temp;  // Stack erlaubt nur Speicherung von Positionstypen
    +   p_temp.x=crosstype;
    +   p_temp.y=direction;
    +
    +	// der eigentliche Push der Kreuzungsinformation
    +	pos_store_push(pos_store, p_temp);
    +
    +}
    +
    +/*!
    + * Holt eine Kreuzungsinformation vom Stack (Bot auf Rueckweg an Kreuzung oder Stackabfahren vom Ziel zum Start)
    + * @param *crosstype Kreuzungstyp
    + * @param *direction zuletzt eingeschlagene Richtung
    + * @return True wenn erfolgreich, False falls Stack leer ist
    + */
    +static uint8_t pop_stack_crossing(int16_t *crosstype, int16_t *direction) {
    +    position_t p_temp;  // Stack erlaubt nur Speicherung von Positionstypen
    +	if (!pos_store_pop(pos_store, &p_temp))
    +		return False;
    +    *crosstype = p_temp.x;
    +    *direction = p_temp.y;
    +
    +	return True;
    +}
    +
    +/*!
    + * Holt eine Kreuzung von vorn aus dem Stack (in dem Fall Queue) zum Abfahren von Start- zum Zielpunkt
    + * @param *crosstype Kreuzungstyp
    + * @param *direction zuletzt eingeschlagene Richtung
    + * @return True wenn erfolgreich, False falls Stack leer ist
    + */
    +static uint8_t dequeue_stack_crossing(int16_t *crosstype, int16_t *direction) {
    +    position_t p_temp;  // Stack erlaubt nur Speicherung von Positionstypen
    +	if (!pos_store_dequeue(pos_store, &p_temp))
    +		return False;
    +    *crosstype = p_temp.x;
    +    *direction = p_temp.y;
    +
    +	return True;
    +}
    +
    +/*! Prueft ob sich der Bot auf dem definierten Umkehr- Zielfeld befindet (via Default gruen; gut im Simulator verwendbar)
    + *  @return True falls Bot sich auf dem Farbfeld befindet sonst False
    + */
    +uint8_t green_field(void) {
    +  if (crossing_reached && ((sensLineL>GROUND_GOAL_DEF-10 && sensLineL<GROUND_GOAL_DEF+10) ||
    +			    (sensLineR>GROUND_GOAL_DEF-10 && sensLineR<GROUND_GOAL_DEF+10)))
    +     return True;
    +
    +  return False;
    +}
    +
    +/*!  Prueft ob der Bot sich auf dem Ziel befindet, also wenn er auf dem definierten Farbfeld steht und Hindernis dahinter
    + *   @return True falls bot sich auf dem Zielfarbfeld befindet sonst False
    + */
    +uint8_t goal_reached(void) {
    +	if (green_field() && sensDistL<300 && sensDistR<300)
    +		return True;
    +
    +	return False;
    +
    +}
    +
    +
    +/* Linienfolger abbrechen, die sich  nicht selbst beenden bei Kreuzungen
    + * der Linienfolger 3 macht dies schon von sich aus
    + */
    +#if FOLLOW_LINE_VERSION != OPTIMAL_LINE_BEHAVIOUR_VERSION
    +
    +static int16_t lastpos_x=0;
    +static int16_t lastpos_y=0;
    +
    +/*! Mapzugriff der Observer nach dieser gefahrenen Strecke in mm
    + */
    +#define CHECK_DISTANCE 30
    +#define CHECK_DISTANCE_QUAD (CHECK_DISTANCE * CHECK_DISTANCE)  // Quadrat der gefahrenen Strecke
    +
    +
    +/*! Prueft ob der Bot schon eine bestimmte Strecke gefahren ist seit dem letzten Observerdurchgang
    + * @param  *last_xpoint   letzte gemerkte X-Koordinate
    + * @param  *last_ypoint   letzte gemerkte Y-Koordinate
    + * @return True, wenn Bot schon gewisse Strecke gefahren ist und Map zu checken ist sonst False
    + */
    +static uint8_t distance_reached(int16_t * last_xpoint,int16_t * last_ypoint) {
    +
    +	// Abstand seit letztem Observerlauf ermitteln
    +	uint16_t diff = get_dist(x_pos, y_pos, *last_xpoint, *last_ypoint);
    +
    +	//erst nach gewissem Abstand oder gleich bei noch initialem Wert Mappruefung
    +	if (diff >= CHECK_DISTANCE_QUAD) {
    +		*last_xpoint = x_pos;
    +		*last_ypoint = y_pos;
    +		return True;
    +	}
    +	return False;
    +}
    +
    +
    +/*!  Prueft ob der Bot sich auf einer Kreuzung befindet; weil Abgrundsensoren nicht gleichzeitig ueber Kreuzungslinie erscheinen, werden hier Kennungen fuer
    + *   die beiden Abgrundsensoren verwendet falls Linie erkannt wurde;Wird innerhalb der naechsten 3cm die andere Seite auch erkannt, so steht Bot auf Kreuzung
    + *   @return True falls bot sich auf Kreuzung befindet sonst False
    + */
    +uint8_t check_crossing(void) {
    +
    +     if (goal_reached()) {
    +		LOG_DEBUG("Ziel erreicht und Ende");
    +		lineState=99; // Verhalten Ende
    +		return True;
    +	 }
    +  	 if (green_field()) {
    +  	 	way_back=True;
    +		LOG_DEBUG("auf Gruen Umkehr");
    +		lineState=TURN_ON_GREEN; // weiter mit Eintritt nach Gruenerkennung
    +		return True;
    +	 }
    +
    +	if (sensBorderL > BORDER_DANGEROUS || sensBorderR > BORDER_DANGEROUS) {
    +			// Kennungen setzen auf Querlinie erkannt links oder rechts voraus, also wenn Abgrundsensor Linie (vorausgesetzt Abgrund gibt es nicht) erkennt
    +			if (sensBorderR > BORDER_DANGEROUS)
    +			  border_side_r_fired=True;
    +			else
    +			  border_side_l_fired=True;
    +
    +			// Beide erkennen Querlinie
    +			if (sensBorderL > BORDER_DANGEROUS && sensBorderR > BORDER_DANGEROUS) {
    +			 	 border_side_l_fired=True;
    +			 	 border_side_r_fired=True;
    +			 }
    +
    +			if (border_side_l_fired && border_side_r_fired ) {
    +		      LOG_DEBUG("beide zugeschlagen l/r %1d %1d!!!",sensBorderL,sensBorderR);
    +
    +			  return True;
    +	        }
    +	        if (border_side_l_fired || border_side_r_fired) {
    +	          LOG_DEBUG("l oder r: %1d %1d",border_side_l_fired,border_side_r_fired);
    +	        }
    +
    +		}
    +
    +
    +	if (distance_reached(&lastpos_x,&lastpos_y)) {
    +	  LOG_DEBUG("ABstand gefahren und false");
    +	  border_side_l_fired=False;
    +	  border_side_r_fired=False;
    +	}
    +
    +
    +	return False;
    +
    +}
    +#else
    +
    +/*!  Prueft ob der Bot sich auf Umkehr- oder Zielfeld befindet; hier wurde der optimal Linienfolger gestartet, der sich beendet bei Kreuzungen oder Abgruenden
    + *   @return True falls bot sich auf Ziel- oder Umkehrfeld befindet sonst False
    + */
    +uint8_t check_crossing(void) {
    +     if (goal_reached()) {
    +		LOG_DEBUG("Ziel erreicht und Ende");
    +		lineState=99; // Verhalten Ende
    +		return True;
    +	 }
    +  	 if (green_field()) {
    +  	 	way_back=True;
    +		LOG_DEBUG("auf Gruen Umkehr");
    +        lineState=TURN_ON_GREEN; // weiter mit Eintritt nach Gruenerkennung
    +		return True;
    +	 }
    +	 return False;
    +}
    +#endif
    +
    +/* Check-Routine zum Erkennen ob sich bot schon auf der Linie befindet
    + * @return True wenn mindestens ein Liniensensor die Linie erkennt
    + */
    +static uint8_t check_line_sensors(void) {
    +  if (sensLineL >= LINE_SENSE || sensLineR >= LINE_SENSE)
    +  	return True;
    +
    +  return False;
    +}
    +
    +
    +/*!
    + * Das eigentliche Verhalten, welches den bot einer Linie folgen laesst, X-Kreuzungen erkennt und
    + * dann in bestimmter Reihenfolge die Abzweigungen entlangfaehrt bis zu seinem Ziel (gruenes Feld an Hindernis); die
    + * Kreuzungen werden enweder neu im Stack angelegt oder von dort geholt und die Wegeinfos dort wieder vermerkt; eine Kreuzung
    + * wird vergessen, wenn kein Weg von dort zum Ziel gefuehrt hatte; Verhalten laesst den bot ebenefalls den bereits gemerkten Weg
    + * zum Ziel oder von dort rueckwaerts direkt auf kuerzestem Weg zum Ausgangspunkt fahren
    + * @param *data	Verhaltensdatensatz
    + */
    +void bot_drive_line_shortest_way_behaviour(Behaviour_t * data) {
    +
    +	switch (lineState) {
    +		case GO_TO_LINE:  // bot faehrt gewisse Strecke vorwaerts bis zur Linie
    +
    +        // naechster Verhaltenszustand
    +		lineState=CHECK_LINE;
    +
    +		// falls vom Ziel rueckwaerts gefahren werden soll und bot ist noch auf Zielendposition, dann erst einmal drehen
    +		if (goal_reached()&& way_back) {
    +			(bot_turn(data,180));
    +			break; // im selben Verhaltensstatus weiter mit Liniensuche Strecke voraus fahren
    +		}
    +		else {
    +		  bot_goto_dist(data, 600, 1);                                            // maximal 60cm vorwaerts bis Linie voraus
    +		  bot_cancel_behaviour(data, bot_goto_pos_behaviour,check_line_sensors);  // Ende der Vorwaertsfahrt wenn Linie erkannt wurde
    +		}
    +		break;
    +
    +	case CHECK_LINE:  // laesst hier den bot eine Linie folgen
    +
    +    // Linienfolger-Verhalten starten
    +    bot_follow_line(data);
    +    LOG_DEBUG("Start Linienfolger l/r %1d %1d, Version %1d",sensLineL,sensLineR,FOLLOW_LINE_VERSION);
    +
    +    // cancel nur fuer die Linienfolger, die nicht Kreuzungen oder Abgrund erkennen
    +    // der optimale Linienfolger 3 macht dies von sich aus
    +#if FOLLOW_LINE_VERSION != OPTIMAL_LINE_BEHAVIOUR_VERSION
    +    // fuer Cancel-Check_Verhalten letzten Positionen, also Botpos, belegen
    +    lastpos_x=x_pos;
    +    lastpos_y=y_pos;
    +
    +    // ebenfalls Kennungen initialisieren fuer Endeerkennung der Kreuzungen
    +    border_side_l_fired=False;
    +	border_side_r_fired=False;
    +#endif
    +    bot_cancel_behaviour(data, bot_follow_line_behaviour,check_crossing);
    +
    +    lineState=CHECK_BORDER; // naechster Zustand
    +	break;
    +
    +	case CHECK_BORDER:  // kleines Stueck vorfahren fuer Abgrundcheck
    +	    lineState=GO_FORWARD;       // naechster Verhaltenszustand
    +	    bot_goto_dist(data, 20, 1); // 2cm vorfahren, Liniensensoren sind dann runter von Linie, falls nicht Abgrund
    +	    deactivateBehaviour(bot_cancel_behaviour_behaviour);  // Cancelverhalten fuer Linienfolger beenden
    +	    crossing_reached=True;      // Kennung setzen, ab jetzt auch Gruenfelder fuer Umkehr ausgewertet
    +	    break;
    +
    +	case GO_FORWARD:  // Erkennung ob Abgrund und Ende, falls nicht weiter bis Liniensensoren auf Krezung
    +	    if (sensBorderL > BORDER_DANGEROUS || sensBorderR > BORDER_DANGEROUS) {
    +				LOG_DEBUG("Abgrund und Ende %1d %1d",sensBorderL ,sensBorderR);
    +				lineState=99;                 // Verhalten Ende
    +				break;
    +			}
    +	    lineState=TURN_SIDEWISH_ON_CROSSING;  // naechster Verhaltenszustand
    +	    bot_goto_dist(data, 20, 1);           //vorfahren bis Liniensensoren ideal auf Kreuzung stehen zur Drehung
    +	    break;
    +
    +	case TURN_SIDEWISH_ON_CROSSING:  // Festlegen und Ausfuehren der Drehung je nach Richtung und Fahrlogik (Stackfahren vor oder zurueck)
    +	    // beim Rueckweg way_back==True vom Stack hier die Kreuzung holen; bei Hinweg neu auf den
    +	    // Stack legen
    +
    +	    LOG_DEBUG("vor turn 90 l/r %1d %1d,way_back  %1d",sensLineL,sensLineR,way_back);
    +
    +	    lineState=GO_FORWARD_AFTER_TURN;  // naechster Verhaltenszustand
    +
    +        if (!go_stack_way) { // Logik Zielsuchen, kein Stackfahren
    +
    +	     if (way_back) {  // bot auf Rueckweg nach Wegende mit Gruenfeld
    +
    +	      if (!pop_stack_crossing(&crosstype,&direction_counter)) {
    +	      	LOG_DEBUG("kein Pop moeglich");
    +	      	lineState=99;                 // Verhalten Ende
    +			break;
    +	      }
    +	      direction_counter++;
    +
    +	      LOG_DEBUG("---X vom Stack nehmen wg. back %1d counter %1d",way_back,direction_counter);
    +	      if (direction_counter<=3){
    +	      	push_stack_crossing(1,direction_counter);
    +	      	way_back=False;  // wird wieder zu vorwaerts
    +	      	LOG_DEBUG("wieder push, back %1d counter %1d",way_back,direction_counter);
    +	      }
    +	      else
    +	      	LOG_DEBUG("X wird vergessen-irrelevant");
    +
    +	     }
    +	     else {  // Bot kommt auf Vorwaertsfahrt an Kreuzung an
    +
    +	       direction_counter=1;                        // ersten Weg nehmen
    +	       push_stack_crossing(1,direction_counter);   // Kreuzung und Weg auf Stack legen
    +	       LOG_DEBUG(">> X ist neu vorw. und Push, counter %1d",direction_counter);
    +	       way_back=False;                             // jedenfalls auf vorwaerts
    +	     }
    +        }
    +        else {  // hier soll der im Stack liegende kuerzeste Weg abgefahren werden
    +        	LOG_DEBUG("Stack abfahren und Richtung aus Stack");
    +
    +	           // Unterscheidung fuer Vorwaerts und Rueckwaerts,
    +	           // bei vorwaerts wurde Bot wieder an Ausgangspunkt gesetzt und faehrt zum Ziel
    +	           // bei rueckwaerts faehrt bot vom Ziel zurueck zum Anfang der Linie bis Stack leer ist an Ankunft 1.Kreuzung	ab Start
    +	           // gespeicherter Richtungswert muss je nach vorwaerts oder rueckwaerts anders interpretiert werden
    +	        	if (way_back) {
    +	        	 // Weg rueckwaerts heisst Weg vom Ziel zurueckzufahren, also via Pop von Kreuzung zu Kreuzung hangeln
    +	        	 if (!pop_stack_crossing(&crosstype,&direction_counter)) {
    +	      	       LOG_DEBUG("kein Pop moeglich");
    +	      	       lineState=99;
    +			       break;
    +	             }
    +
    +	        	// je nach Start-Ausgangs-Richtungswahl Richtungswert interpretieren
    +	        	if (START_SIDEWISH==1) {  //links bevorzugt
    +
    +	        	 if (direction_counter==1) {
    +	        		LOG_DEBUG("nach rechts");
    +	        		sidewish=-1;
    +	        	   }
    +	        	 if (direction_counter==3) {
    +	        		LOG_DEBUG("nach links");
    +	        		sidewish=1;
    +	        	  }
    +	        	}
    +	        	else {                    // rechts bevorzugt
    +	        		LOG_DEBUG("neg wg. rechts zuerst");
    +	        		if (direction_counter==1) {
    +	        		LOG_DEBUG("nach links");
    +	        		sidewish=1;
    +	        	   }
    +	        	 if (direction_counter==3) {
    +	        		LOG_DEBUG("nach rechts");
    +	        		sidewish=-1;
    +	        	  }
    +	        	}
    +
    +	        	}  // Ende zurueck vom Ziel
    +	        	else {
    +	        	  // bot soll hier den kuerzesten Weg vom Start- zum Zielpunkt abfahren, d.h. bot befindet sich wieder
    +	        	  // am Startpunkt (manuell hingesetzt/ gefahren) und muss sich den jeweils 1. Stackwert holen und abfahren
    +	        	  if (!dequeue_stack_crossing(&crosstype,&direction_counter)) {
    +	      	        LOG_DEBUG("kein dequeue moeglich");
    +	      	        lineState=99;
    +			        break;
    +	               }
    +
    +	            // auch hier je nach Wunsch-Start-Richtungswahl die Richtung interpretieren
    +	        	if (START_SIDEWISH==1) {
    +	        	  if (direction_counter==1) {  // links bevorzugt
    +	        		LOG_DEBUG("nach links");
    +	        		sidewish=1;
    +	        	  }
    +	        	 if (direction_counter==3) {
    +	        		LOG_DEBUG("nach rechts");
    +	        		sidewish=-1;
    +	        	  }
    +	        	}
    +	        	else {                         // rechts bevorzugt
    +	        		LOG_DEBUG("neg wegen rechts zuerst");
    +	        		 if (direction_counter==1) {
    +	        		LOG_DEBUG("nach rechts");
    +	        		sidewish=-1;
    +	        	  }
    +	        	 if (direction_counter==3) {
    +	        		LOG_DEBUG("nach links");
    +	        		sidewish=1;
    +	        	  }
    +	        	}
    +
    +	        	}
    +
    +	        	LOG_DEBUG("X Richtg. %1d",direction_counter);
    +
    +	        	if (direction_counter==2) {
    +	        		LOG_DEBUG("geradeaus");
    +	        		break;// ohne Drehung weiter
    +	        	}
    +        }
    +        // Drehung 90 Grad ausfuehren
    +        bot_turn(data,sidewish * 90);
    +	    break;
    +
    +	case GO_FORWARD_AFTER_TURN:    // hierher nach 90 Grad Drehung in gewuenschte Richtung
    +	    BLOCK_BEHAVIOUR(data, 500); // etwas warten
    +	    LOG_DEBUG("etwas vor nach Dreh l/r %1d %1d",sensLineL,sensLineR);
    +
    +	    // geht dann wieder mit Linienfolger weiter
    +	    lineState=CHECK_LINE;       // naechster Verhaltenszustand
    +
    +	    bot_goto_dist(data, 50, 1); //vorfahren, Linesensoren sind dann auf Kreuzung
    +	    border_side_l_fired=False;  // Kennungen ruecksetzen
    +        border_side_r_fired=False;
    +	    break;
    +
    +	case TURN_ON_GREEN:    // hierher nach Erkennung des Gruenfeldes mit Richtungsumkehr
    +	    LOG_DEBUG("Gruen erkannt und Umkehr");
    +	    deactivateBehaviour(bot_cancel_behaviour_behaviour);  // Cancelverhalten fuer Linienfolger beenden
    +	    BLOCK_BEHAVIOUR(data, 500); // evtl. etwas warten
    +	    lineState=CHECK_LINE;  //
    +	    bot_turn(data,180);
    +	    break;
    +
    +	case 99:  // Verhaltensende
    +	    LOG_DEBUG("Ende Behav. l/r %1d %1d",sensLineL,sensLineR);
    +	    return_from_behaviour(data);
    +		break;
    +	}
    +
    +}
    +
    +/*!
    + * Startet das Verhalten
    + * @param	*caller Verhaltensdatensatz des Aufrufers
    + */
    +void bot_drive_line_shortest_way(Behaviour_t * caller) {
    +	switch_to_behaviour(caller, bot_drive_line_shortest_way_behaviour, NOOVERRIDE);
    +	//border_side_r=0;
    +	lineState=0;
    +	border_side_l_fired=0;
    +	border_side_r_fired=0;
    +	sidewish=START_SIDEWISH;
    +	way_back=False;
    +	go_stack_way=False;
    +	pos_store = pos_store_create(get_behaviour(bot_follow_line_behaviour), pos_store_data);
    +	direction_counter=0;
    +	crossing_reached=0;
    +
    +	/* stoerende Notfallverhalten aus */
    +#ifdef BEHAVIOUR_AVOID_COL_AVAILABLE
    +	deactivateBehaviour(bot_avoid_col_behaviour);
    +#endif
    +#ifdef BEHAVIOUR_AVOID_BORDER_AVAILABLE
    +	deactivateBehaviour(bot_avoid_border_behaviour);
    +#endif
    +}
    +/*  Falls Linienfolger Linie nicht findet kann hier weitergefuehrt werden nach manuellem richtigen wiederausrichten
    + */
    +void bot_drive_line_shortest_way_continue(Behaviour_t * caller) {
    +	switch_to_behaviour(caller, bot_drive_line_shortest_way_behaviour, NOOVERRIDE);
    +	lineState=0;
    +	border_side_l_fired=0;
    +	border_side_r_fired=0;
    +
    +}
    +
    +/*  Falls Linienfolger Linie nicht findet kann hier weitergefuehrt werden nach manuellem richtigen wiederausrichten
    + */
    +void bot_drive_line_shortest_way_forward(Behaviour_t * caller) {
    +	switch_to_behaviour(caller, bot_drive_line_shortest_way_behaviour, NOOVERRIDE);
    +	lineState=0;
    +	border_side_l_fired=0;
    +	border_side_r_fired=0;
    +	go_stack_way=True;
    +	way_back=False;
    +	crossing_reached=0;
    +
    +}
    +void bot_drive_line_shortest_way_backward(Behaviour_t * caller) {
    +	switch_to_behaviour(caller, bot_drive_line_shortest_way_behaviour, NOOVERRIDE);
    +	lineState=0;
    +	border_side_l_fired=0;
    +	border_side_r_fired=0;
    +	go_stack_way=True;
    +	way_back=True;
    +	crossing_reached=0;
    +
    +}
    +
    +
    +/*!
    + * Keyhandler zur Verwendung via Fernbedienung auf dem Display zum Stackanfahren
    + */
    +#ifdef DISPLAY_DRIVE_LINE_SHORTEST_WAY_AVAILABLE
    +static void driveline_disp_key_handler(void) {
    +	switch (RC5_Code) {
    +
    +
    +		case RC5_CODE_5:
    +		/* Verhalten starten zum Anfahren der Stackpunkte */
    +		RC5_Code = 0;
    +		bot_drive_line_shortest_way(NULL);
    +		break;
    +
    +		case RC5_CODE_6:
    +		/* Verhalten zum Speichern relevanter Wegepopsitionen zum Spaeteren Zurueckfahren */
    +		RC5_Code = 0;
    +		bot_drive_line_shortest_way_continue(NULL);
    +		break;
    +
    +        case RC5_CODE_8:
    +		/* Zueckfahren vom Ziel zum Ausgangspunkt auf kuerzestem gespeicherten Weg */
    +		RC5_Code = 0;
    +		bot_drive_line_shortest_way_forward(NULL);
    +		break;
    +		case RC5_CODE_9:
    +		/* Zueckfahren vom Ziel zum Ausgangspunkt auf kuerzestem gespeicherten Weg */
    +		RC5_Code = 0;
    +		bot_drive_line_shortest_way_backward(NULL);
    +		break;
    +
    +
    +	} // switch
    +} // Ende Keyhandler
    +
    +
    +/*!
    + * Display zum Verhalten
    + */
    +void drive_line_shortest_way_display(void) {
    +	display_cursor(1, 1);
    +	display_printf("DRIVE_LINE_S_WAY");
    +	//display_cursor(2, 1);
    +	//display_printf("Save/Del      : 3/8");
    +	display_cursor(2, 1);
    +	display_printf("GoLine/Continue:5/6");
    +	display_cursor(4, 1);
    +	display_printf("GoWayForw/Back:8/9");
    +
    +	driveline_disp_key_handler(); // aufrufen des Key-Handlers
    +}
    +#endif	// DISPLAY_DRIVE_LINE_SHORTEST_WAY_AVAILABLE
    +
    +
    +#endif	// BEHAVIOUR_DRIVE_LINE_SHORTEST_WAY_AVAILABLE
    Index: C:/botneu/ct-Bot/bot-logic/bot-logik.c
    ===================================================================
    --- C:/botneu/ct-Bot/bot-logic/bot-logik.c	(revision 1530)
    +++ C:/botneu/ct-Bot/bot-logic/bot-logik.c	(working copy)
    @@ -284,6 +284,11 @@
     		// Verhalten um einer Linie zu folgen
     		insert_behaviour_to_list(&behaviour, new_behaviour(70, bot_follow_line_behaviour, INACTIVE));
     	#endif
    +
    +	#ifdef BEHAVIOUR_DRIVE_LINE_SHORTEST_WAY_AVAILABLE
    +		// Linie folgen ueber Kreuzungen hinweg zum Ziel, kuerzester Weg befindet sich danach im Stack
    +		insert_behaviour_to_list(&behaviour, new_behaviour(69, bot_drive_line_shortest_way_behaviour, INACTIVE));
    +	#endif

     	#ifdef BEHAVIOUR_OLYMPIC_AVAILABLE
     		// unwichtigere Hilfsverhalten
    Index: C:/botneu/ct-Bot/bot-logic/behaviour_follow_line.c
    ===================================================================
    --- C:/botneu/ct-Bot/bot-logic/behaviour_follow_line.c	(revision 1530)
    +++ C:/botneu/ct-Bot/bot-logic/behaviour_follow_line.c	(working copy)
    @@ -15,7 +15,7 @@
      * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
      * MA 02111-1307, USA.
      *
    - */
    + */

     /*!
      * @file 	behaviour_follow_line.c
    @@ -29,77 +29,9 @@

     #ifdef BEHAVIOUR_FOLLOW_LINE_AVAILABLE

    -//#define OLD_VERSION	/*!< aktiviert die alte Version den Linienverfolgers mit Eckendetektion (hat Probleme mit SPEED_CONTROL) */

    -#ifndef OLD_VERSION
    -#include "timer.h"
    +#if FOLLOW_LINE_VERSION == 1  // urspruenglich altes Linienverhalten

    -/*!
    - * Zeit zwischen zwei Korrekturen [ms]. Groessere Werte bewirken "ruhigeres" Fahren,
    - * erhoehen damit aber auch die Reaktionszeit (z.B. bei scharfen Kurven problematisch)
    - */
    -#define	CORRECTION_DELAY	150
    -
    -/*!
    - * Folgt einer Linie. Der linke Liniensensor ist dabei auf der Linie, der Rechte daneben.
    - * Der Bot faehrt also auf der rechten Kante der Linie. Sie sollte in etwa die Breite
    - * beider CNY70 haben.
    - * @param *data	Verhaltensdatensatz
    - */
    -void bot_follow_line_behaviour(Behaviour_t * data) {
    -	static int16_t lastLeft = 0;
    -	static int16_t lastRight= 0;
    -	static uint8_t lastCorrection = 0;
    -	static uint32_t lastCorrectionTime = 0;
    -	uint8_t correction = 0;
    -
    -	if (sensLineL >= LINE_SENSE && sensLineR < LINE_SENSE) {
    -		/* Bot faehrt auf rechter Linienkante */
    -		speedWishLeft  = BOT_SPEED_SLOW;
    -		speedWishRight = BOT_SPEED_SLOW;
    -	} else if (sensLineL < LINE_SENSE) {
    -		/* Bot fahert rechts neben der Linie */
    -		speedWishLeft  = -BOT_SPEED_FOLLOW;
    -		speedWishRight = BOT_SPEED_FOLLOW;
    -		correction = 1;
    -	} else {
    -		/* Bot faehrt auf der Linie */
    -		speedWishLeft  = BOT_SPEED_FOLLOW;
    -		speedWishRight = -BOT_SPEED_FOLLOW;
    -		correction = 2;
    -	}
    -
    -	if (lastCorrection != correction && !timer_ms_passed(&lastCorrectionTime, CORRECTION_DELAY)) {
    -		/* Falls die letzte Korrektur gerade erst war, reagieren wir (noch) nicht */
    -		speedWishLeft  = lastLeft;
    -		speedWishRight = lastRight;
    -		return;
    -	}
    -
    -	/* neue Werte merken */
    -	lastCorrection = correction;
    -	lastLeft  = speedWishLeft;
    -	lastRight = speedWishRight;
    -}
    -
    -/*!
    - * Folgt einer Linie. Der linke Liniensensor ist dabei auf der Linie, der Rechte daneben.
    - * Der Bot faehrt also auf der rechten Kante der Linie. Sie sollte in etwa die Breite
    - * beider CNY70 haben.
    - * @param	*caller Verhaltensdatensatz des Aufrufers
    - */
    -void bot_follow_line(Behaviour_t * caller) {
    -	switch_to_behaviour(caller, bot_follow_line_behaviour, NOOVERRIDE);
    -	/* stoerende Notfallverhalten aus */
    -#ifdef BEHAVIOUR_AVOID_COL_AVAILABLE
    -	deactivateBehaviour(bot_avoid_col_behaviour);
    -#endif
    -#ifdef BEHAVIOUR_AVOID_BORDER_AVAILABLE
    -	deactivateBehaviour(bot_avoid_border_behaviour);
    -#endif
    -}
    -
    -#else	// OLD_VERSION
     /* Konstanten fuer das Verhalten */
     #define CORNER_LEFT					1
     #define CORNER_RIGHT				2
    @@ -248,5 +180,182 @@
     	lineState=CHECK_LINE;
     	cornerDetected=False;
     }
    +
    +#elif FOLLOW_LINE_VERSION == 2    // neuere Version des Linienfolgers
    +#include "timer.h"
    +
    +/*!
    + * Zeit zwischen zwei Korrekturen [ms]. Groessere Werte bewirken "ruhigeres" Fahren,
    + * erhoehen damit aber auch die Reaktionszeit (z.B. bei scharfen Kurven problematisch)
    + */
    +#define	CORRECTION_DELAY	150
    +
    +/*!
    + * Folgt einer Linie. Der linke Liniensensor ist dabei auf der Linie, der Rechte daneben.
    + * Der Bot faehrt also auf der rechten Kante der Linie. Sie sollte in etwa die Breite
    + * beider CNY70 haben.
    + * @param *data	Verhaltensdatensatz
    + */
    +void bot_follow_line_behaviour(Behaviour_t * data) {
    +	static int16_t lastLeft = 0;
    +	static int16_t lastRight= 0;
    +	static uint8_t lastCorrection = 0;
    +	static uint32_t lastCorrectionTime = 0;
    +	uint8_t correction = 0;
    +
    +	if (sensLineL >= LINE_SENSE && sensLineR < LINE_SENSE) {
    +		/* Bot faehrt auf rechter Linienkante */
    +		speedWishLeft  = BOT_SPEED_SLOW;
    +		speedWishRight = BOT_SPEED_SLOW;
    +	} else if (sensLineL < LINE_SENSE) {
    +		/* Bot fahert rechts neben der Linie */
    +		speedWishLeft  = -BOT_SPEED_FOLLOW;
    +		speedWishRight = BOT_SPEED_FOLLOW;
    +		correction = 1;
    +	} else {
    +		/* Bot faehrt auf der Linie */
    +		speedWishLeft  = BOT_SPEED_FOLLOW;
    +		speedWishRight = -BOT_SPEED_FOLLOW;
    +		correction = 2;
    +	}
    +
    +	if (lastCorrection != correction && !timer_ms_passed(&lastCorrectionTime, CORRECTION_DELAY)) {
    +		/* Falls die letzte Korrektur gerade erst war, reagieren wir (noch) nicht */
    +		speedWishLeft  = lastLeft;
    +		speedWishRight = lastRight;
    +		return;
    +	}
    +
    +	/* neue Werte merken */
    +	lastCorrection = correction;
    +	lastLeft  = speedWishLeft;
    +	lastRight = speedWishRight;
    +}
    +
    +/*!
    + * Folgt einer Linie. Der linke Liniensensor ist dabei auf der Linie, der Rechte daneben.
    + * Der Bot faehrt also auf der rechten Kante der Linie. Sie sollte in etwa die Breite
    + * beider CNY70 haben.
    + * @param	*caller Verhaltensdatensatz des Aufrufers
    + */
    +void bot_follow_line(Behaviour_t * caller) {
    +	switch_to_behaviour(caller, bot_follow_line_behaviour, NOOVERRIDE);
    +	/* stoerende Notfallverhalten aus */
    +#ifdef BEHAVIOUR_AVOID_COL_AVAILABLE
    +	deactivateBehaviour(bot_avoid_col_behaviour);
    +#endif
    +#ifdef BEHAVIOUR_AVOID_BORDER_AVAILABLE
    +	deactivateBehaviour(bot_avoid_border_behaviour);
    +#endif
    +}
    +
    +#elif FOLLOW_LINE_VERSION == 3  // neueste Version des Linienfolgers, die mit drive_line_shortest_way entstanden ist
    +
    +/*!
    + * Zeit zwischen zwei Korrekturen [ms]. Groessere Werte bewirken "ruhigeres" Fahren,
    + * erhoehen damit aber auch die Reaktionszeit (z.B. bei scharfen Kurven problematisch)
    + */
    +#define	CORRECTION_DELAY	150
    +
    +/*! Kennungen, welcher der Bordersensoren zugeschlagen hat zur Erkennung der Kreuzungen, notwendig
    +*   weil sicht nicht immer beide gleichzeitig ueber Kreuzungslinie befinden
    +*/
    +static uint8_t border_side_l_fired=0;
    +static uint8_t border_side_r_fired=0;
    +
    +/*!
    + * Folgt einer Linie. Der linke Liniensensor oder auch beide sind dabei auf der Linie.
    + * Version optimal fuer behaviour_drive_line_shortest_way
    + * @param *data	Verhaltensdatensatz
    + */
    +void bot_follow_line_behaviour(Behaviour_t * data) {
    +	static int16_t lastLeft = 0;
    +	static int16_t lastRight= 0;
    +	static uint8_t lastCorrection = 0;
    +	static uint32_t lastCorrectionTime = 0;
    +	uint8_t correction = 0;
    +
    +	if (sensLineL >= LINE_SENSE) {
    +		/* Bot faehrt auf linker Linienkante oder beide Sensoren auf Linie */
    +		speedWishLeft  = BOT_SPEED_SLOW;
    +		speedWishRight = BOT_SPEED_SLOW;
    +		correction = 0;
    +
    +	 if (sensBorderL > BORDER_DANGEROUS || sensBorderR > BORDER_DANGEROUS) {
    +
    +			// Kennungen setzen auf Querlinie erkannt links oder rechts voraus, also wenn Abgrundsensor Linie (vorausgesetzt Abgrund gibt es nicht) erkennt
    +			if (sensBorderR > BORDER_DANGEROUS)
    +			  border_side_r_fired=True;
    +			else
    +			  border_side_l_fired=True;
    +
    +			// Beide erkennen Querlinie, ist Abgrund oder auch moeglicherweise X-Kreuzung
    +			if (sensBorderL > BORDER_DANGEROUS && sensBorderR > BORDER_DANGEROUS) {
    +			 	 border_side_l_fired=True;
    +			 	 border_side_r_fired=True;
    +			 }
    +
    +			if (border_side_l_fired && border_side_r_fired ) {
    +		      //LOG_DEBUG("beide zugeschlagen Ende !!!");
    +		      return_from_behaviour(data);
    +	        }
    +
    +		}
    +		else {
    +
    +		if (lastLeft<0 || lastRight<0) {
    +           // bei Wechsel zu geradeaus Abgrundsensorkennungen ruecksetzen
    +		   border_side_l_fired=False;
    +		   border_side_r_fired=False;
    +		}
    +	 }
    +
    +	} else if (sensLineL < LINE_SENSE && sensLineR < LINE_SENSE && !border_side_r_fired) {
    +		/* Linker Sensor und rechter nicht auf Linie, dann rechts daneben und links drehen */
    +		speedWishLeft  = -BOT_SPEED_FOLLOW;
    +		speedWishRight = BOT_SPEED_FOLLOW;
    +		correction = 1;
    +	} else {
    +		/* Bot befindet sich links von der Linie und rechts drehen */
    +		speedWishLeft  = BOT_SPEED_FOLLOW;
    +		speedWishRight = -BOT_SPEED_FOLLOW;
    +		correction = 2;
    +	}
    +
    +	if (lastCorrection != correction && !timer_ms_passed(&lastCorrectionTime, CORRECTION_DELAY)) {
    +		/* Falls die letzte Korrektur gerade erst war, reagieren wir (noch) nicht */
    +		speedWishLeft  = lastLeft;
    +		speedWishRight = lastRight;
    +		return;
    +	}
    +
    +	/* neue Werte merken */
    +	lastCorrection = correction;
    +	lastLeft  = speedWishLeft;
    +	lastRight = speedWishRight;
    +}
    +
    +/*!
    + * Folgt einer Linie. Der linke Liniensensor oder auch beide sind dabei auf der Linie.
    + * Der Bot faehrt also auf der rechten Kante der Linie. Sie sollte in etwa die Breite
    + * beider CNY70 haben.
    + * @param	*caller Verhaltensdatensatz des Aufrufers
    + */
    +void bot_follow_line(Behaviour_t * caller) {
    +	switch_to_behaviour(caller, bot_follow_line_behaviour, NOOVERRIDE);
    +
    +	// Kennungen init.
    +	border_side_l_fired=False;
    +	border_side_r_fired=False;
    +
    +	/* stoerende Notfallverhalten aus */
    +#ifdef BEHAVIOUR_AVOID_COL_AVAILABLE
    +	deactivateBehaviour(bot_avoid_col_behaviour);
    +#endif
    +#ifdef BEHAVIOUR_AVOID_BORDER_AVAILABLE
    +	deactivateBehaviour(bot_avoid_border_behaviour);
    +#endif
    +}
    +
     #endif	// OLD_VERSION
     #endif	// BEHAVIOUR_FOLLOW_LINE_AVAILABLE
    Index: C:/botneu/ct-Bot/Changelog.txt
    ===================================================================
    --- C:/botneu/ct-Bot/Changelog.txt	(revision 1530)
    +++ C:/botneu/ct-Bot/Changelog.txt	(working copy)
    @@ -1,5 +1,6 @@
     CHANGELOG fuer c't-Bot
     ======================
    +2009-01-08 Frank Menzel [Menzelfr@xxxxxxx]:  neues Verhalten drive_line_shortest_way und hierfuer neuer Linienfolger; Linienfolger mit Versionen auswaehlbar
     2009-01-07 Timo Sandmann [mail@xxxxxxxxxxxxxxx]: ADC-Code optimiert

     2008-11-21 Timo Sandmann [mail@xxxxxxxxxxxxxxx]: Bot sendet Map-Updates an den Sim, wenn MAP_2_SIM_AVAILABLE eingeschaltet ist. Der entscheidende Parameter ist MAP_2_SIM_BUFFER_SIZE in include/map.h
    Index: C:/botneu/ct-Bot/ct-Bot.h
    ===================================================================
    --- C:/botneu/ct-Bot/ct-Bot.h	(revision 1530)
    +++ C:/botneu/ct-Bot/ct-Bot.h	(working copy)
    @@ -53,7 +53,7 @@
     #define MEASURE_MOUSE_AVAILABLE			/*!< Geschwindigkeiten werden aus den Maussensordaten berechnet */
     //#define MEASURE_COUPLED_AVAILABLE		/*!< Geschwindigkeiten werden aus Maus- und Encoderwerten ermittelt und gekoppelt */

    -//#define POS_STORE_AVAILABLE  /*!< Positionsspeicher vorhanden */
    +#define POS_STORE_AVAILABLE  /*!< Positionsspeicher vorhanden */

     //#define WELCOME_AVAILABLE	/*!< kleiner Willkommensgruss */

    Index: C:/botneu/ct-Bot/include/bot-logic/behaviour_drive_line_shortest_way.h
    ===================================================================
    --- C:/botneu/ct-Bot/include/bot-logic/behaviour_drive_line_shortest_way.h	(revision 0)
    +++ C:/botneu/ct-Bot/include/bot-logic/behaviour_drive_line_shortest_way.h	(revision 0)
    @@ -0,0 +1,65 @@
    +/*
    + * 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_drive_line_shortest_way.c
    + * @brief 	Linienverfolger, der an Kreuzungen eine bestimmte Vorzugsrichtung einschlaegt (links) und diesen Weg weiterverfolgt, bis das Ziel
    + *          (gruenes Feld an Wand) gefunden ist; Linien muessen immer an einem gruenen Feld ohne Hindernis enden, damit der botein Ende erkennt und
    + *          umdrehen kann
    + *          Die Kreuzungen und der eingeschlagene Weg werden auf dem Stack vermerkt, Wege die nicht zum Ziel fuehren vergessen; Am Ziel angekommen
    + *          steht im Stack der kuerzeste Weg; Es kann nun via Display auf dem kuezesten Weg zum Ausgangspunkt zurueckgefahren werden oder der Bot wieder
    + *          manuell an den Start gestellt werden und das Ziel auf kuerzestem Weg angefahren werden
    + * @author 	Frank Menzel (Menzelfr@xxxxxx)
    + * @date 	21.12.2008
    + */
    +
    +#include "bot-logic/bot-logik.h"
    +
    +#ifndef BEHAVIOUR_DRIVE_LINE_SHORTEST_WAY_H_
    +#define BEHAVIOUR_DRIVE_LINE_SHORTEST_WAY_H_
    +
    +#ifdef BEHAVIOUR_DRIVE_LINE_SHORTEST_WAY_AVAILABLE
    +
    +/*!
    + * Das eigentliche Verhalten, welches den bot einer Linie folgen laesst, X-Kreuzungen erkennt und
    + * dann in bestimmter Reihenfolge die Abzweigungen entlangfaehrt bis zu seinem Ziel (gruenes Feld an Hindernis); die
    + * Kreuzungen werden enweder neu im Stack angelegt oder von dort geholt und die Wegeinfos dort wieder vermerkt; eine Kreuzung
    + * wird vergessen, wenn kein Weg von dort zum Ziel gefuehrt hatte; Verhalten laesst den bot ebenefalls den bereits gemerkten Weg
    + * zum Ziel oder von dort rueckwaerts direkt auf kuerzestem Weg zum Ausgangspunkt fahren
    + * @param *data	Verhaltensdatensatz
    + */
    +void bot_drive_line_shortest_way_behaviour(Behaviour_t *data);
    +
    +/*!
    + * Startet das Verhalten
    + * @param	*caller Verhaltensdatensatz des Aufrufers
    + */
    +void bot_drive_line_shortest_way(Behaviour_t *caller);
    +
    +/*  Falls Linienfolger Linie nicht findet kann hier weitergefuehrt werden nach manuellem richtigen wiederausrichten
    + */
    +void bot_drive_line_shortest_way_continue(Behaviour_t * caller) ;
    +
    +/*!
    + * Display zum Verhalten
    + */
    +void drive_line_shortest_way_display(void);
    +
    +#endif	// BEHAVIOUR_DRIVE_LINE_SHORTEST_WAY_AVAILABLE
    +#endif	/*BEHAVIOUR_DRIVE_LINE_SHORTEST_WAY_H_*/
    Index: C:/botneu/ct-Bot/include/bot-logic/available_behaviours.h
    ===================================================================
    --- C:/botneu/ct-Bot/include/bot-logic/available_behaviours.h	(revision 1530)
    +++ C:/botneu/ct-Bot/include/bot-logic/available_behaviours.h	(working copy)
    @@ -57,6 +57,8 @@

     //#define BEHAVIOUR_DRIVE_AREA_AVAILABLE /*!< flaechendeckendes Fahren mit Map */

    +#define BEHAVIOUR_DRIVE_LINE_SHORTEST_WAY_AVAILABLE /*!< Linienfolger ueber Kreuzungen zum Ziel */
    +
     /* Aufgrund einer ganzen reihe von Abhaengigkeiten sollte man beim Versuch Speicher
      * zu sparen, zuerst mal bei den Hauptverhalten ausmisten, sonst kommen die
      * Unterverhalten durch die Hintertuer wieder rein */
    @@ -65,7 +67,7 @@
     	#undef BEHAVIOUR_DRIVE_AREA_AVAILABLE
     	#undef BEHAVIOUR_PATHPLANING_AVAILABLE
     #endif
    -
    +
     #ifndef POS_STORE_AVAILABLE
     #ifdef BEHAVIOUR_DRIVE_AREA_AVAILABLE
     	#warning "drive_area() geht nur, wenn POS_STORE_AVAILABLE"
    @@ -75,7 +77,11 @@
     	#warning "Pfadplanung geht nur, wenn POS_STORE_AVAILABLE"
     	#undef BEHAVIOUR_PATHPLANING_AVAILABLE
     #endif
    +#ifdef BEHAVIOUR_DRIVE_LINE_SHORTEST_WAY_AVAILABLE
    +	#warning "Drive_line_shortest_way geht nur, wenn POS_STORE_AVAILABLE"
    +	#undef BEHAVIOUR_DRIVE_LINE_SHORTEST_WAY_AVAILABLE
     #endif
    +#endif

     #ifdef BEHAVIOUR_DRIVE_AREA_AVAILABLE
     	#define BEHAVIOUR_GOTO_POS_AVAILABLE
    @@ -95,6 +101,12 @@
     	#define BEHAVIOUR_GOTO_POS_AVAILABLE
     #endif

    +#ifdef BEHAVIOUR_DRIVE_LINE_SHORTEST_WAY_AVAILABLE
    +	#define BEHAVIOUR_GOTO_POS_AVAILABLE
    +	#define BEHAVIOUR_CANCEL_BEHAVIOUR_AVAILABLE
    +	#define BEHAVIOUR_FOLLOW_LINE_AVAILABLE
    +#endif
    +
     #ifdef BEHAVIOUR_AVOID_COL_AVAILABLE
     	#define BEHAVIOUR_TURN_AVAILABLE
     	#define BEHAVIOUR_FACTOR_WISH_AVAILABLE
    @@ -242,5 +254,7 @@

     #include "bot-logic/behaviour_pathplaning.h"

    +#include "bot-logic/behaviour_drive_line_shortest_way.h"
    +
     #endif	// BEHAVIOUR_AVAILABLE
     #endif	/*AVAILABLE_BEHAVIOURS_H_*/
    Index: C:/botneu/ct-Bot/include/bot-logic/behaviour_follow_line.h
    ===================================================================
    --- C:/botneu/ct-Bot/include/bot-logic/behaviour_follow_line.h	(revision 1530)
    +++ C:/botneu/ct-Bot/include/bot-logic/behaviour_follow_line.h	(working copy)
    @@ -31,6 +31,8 @@

     #ifdef BEHAVIOUR_FOLLOW_LINE_AVAILABLE

    +#define FOLLOW_LINE_VERSION	3	/*!< Version 1: Altes Verfahren; Version 2: auf linke Kante gefahren; Version 3: linke Kante als auch beide */
    +
     /*!
      * Folgt einer Linie, sobald beide Liniensensoren ausloesen
      * Die Linie sollte in etwa die Breite beider CNY70 haben
    Index: C:/botneu/ct-Bot/ui/gui.c
    ===================================================================
    --- C:/botneu/ct-Bot/ui/gui.c	(revision 1530)
    +++ C:/botneu/ct-Bot/ui/gui.c	(working copy)
    @@ -292,7 +292,10 @@
     	#ifdef BEHAVIOUR_PATHPLANING_AVAILABLE
     		register_screen(&pathplaning_display);
     	#endif
    +	#ifdef BEHAVIOUR_DRIVE_LINE_SHORTEST_WAY_AVAILABLE
    +		register_screen(&drive_line_shortest_way_display);
     	#endif
    +	#endif
     }

     #endif	// DISPLAY_AVAILABLE
    Index: C:/botneu/ct-Bot/ui/available_screens.h
    ===================================================================
    --- C:/botneu/ct-Bot/ui/available_screens.h	(revision 1530)
    +++ C:/botneu/ct-Bot/ui/available_screens.h	(working copy)
    @@ -46,6 +46,7 @@
     #define DISPLAY_TRANSPORT_PILLAR        /*!< Steuerung Transport-Pillar-Verhalten auf diesem Screen */
     #define DISPLAY_DRIVE_STACK_AVAILABLE	/*!< Steuerung Stack-Verhalten auf diesem Screen */
     #define PATHPLANING_DISPLAY				/*!< Display zur Pfadplanung */
    +#define DISPLAY_DRIVE_LINE_SHORTEST_WAY_AVAILABLE	/*!< Steuerung des Verhaltens auf diesem Screen */

     #ifndef SPEED_CONTROL_AVAILABLE
     	#undef DISPLAY_REGELUNG_AVAILABLE
    Index: C:/botneu/ct-Bot/.settings/org.eclipse.cdt.core.prefs
    ===================================================================
    --- C:/botneu/ct-Bot/.settings/org.eclipse.cdt.core.prefs	(revision 0)
    +++ C:/botneu/ct-Bot/.settings/org.eclipse.cdt.core.prefs	(revision 0)
    @@ -0,0 +1,3 @@
    +#Thu Jan 08 21:20:56 CET 2009
    +eclipse.preferences.version=1
    +indexerId=org.eclipse.cdt.core.fastIndexer

- Antworten:
  - Re: [ct-bot] neues Verhalten bot_drive_line_shortest_way...
    - From: Timo Sandmann

- Referenzen:
  - Re: [ct-bot] neues Verhalten bot_drive_line_shortest_way...
    - From: Timo Sandmann

- Voriger (Datum): Re: [ct-bot] neues Verhalten bot_drive_line_shortest_way..., Frank Menzel
- Nächster (Datum): Re: [ct-bot] neues Verhalten bot_drive_line_shortest_way..., Timo Sandmann
- Voriger (Thread): Re: [ct-bot] neues Verhalten bot_drive_line_shortest_way..., Frank Menzel
- Nächster (Thread): Re: [ct-bot] neues Verhalten bot_drive_line_shortest_way..., Timo Sandmann
- Indizes:
  - Datum
  - Thread