heise online
  • c't
  • iX
  • Technology Review
  • Mac & i
  • mobil
  • Security
  • Netze
  • Open Source
  • Developer
  • c't-TV
  • Download
  • Telepolis
  • Resale
  • Foto
  • Autos
  • Preisvergleich
  • Stellenmarkt
  • Abo
  • weitere Angebote
    • Shop
    • Artikel-Archiv
    • Veranstaltungen
    • Whitepapers
    • heise-marktplatz
    • IT-Markt
    • Tarifrechner
    • Jobs bei Heise

c't Magazin
  • Startseite
  • Artikel
  • c't-Projekte
  • Hotline & FAQ
  • Treiber & mehr
  • Kolumnen
Software zu Projekten Allgemeine Hinweise
Archiv-Suche Newsletter RSS-FeedRSS

c't › c't-Projekte

Trac
  • Login
  • Help/Guide
  • About Trac
  • Preferences
  • Wiki
  • Timeline
  • Roadmap
  • Browse Source
  • View Tickets
  • Search

Context Navigation

  • Back to Patches

Patches: pathplaning.patch

File pathplaning.patch, 86.7 KB (added by bbe, 5 years ago)

Patch zur Pfadplanung

  • C:/botneu/ct-Bot/bot-logic/behaviour_avoid_border.c

     
    3737         
    3838        if (sensBorderR > BORDER_DANGEROUS) 
    3939                speedWishRight=-BOT_SPEED_NORMAL; 
     40                 
     41         // Start der registrierten Notfall-Routinen zum informieren der Verhalten 
     42        if (sensBorderL > BORDER_DANGEROUS || sensBorderR > BORDER_DANGEROUS) 
     43           start_registered_emergency_procs(); 
     44 
    4045} 
    4146#endif 
  • C:/botneu/ct-Bot/bot-logic/behaviour_map_go_destination.c

     
     1/* 
     2 * c't-Bot 
     3 *  
     4 * This program is free software; you can redistribute it 
     5 * and/or modify it under the terms of the GNU General 
     6 * Public License as published by the Free Software 
     7 * Foundation; either version 2 of the License, or (at your 
     8 * option) any later version. 
     9 * This program is distributed in the hope that it will be 
     10 * useful, but WITHOUT ANY WARRANTY; without even the implied 
     11 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
     12 * PURPOSE. See the GNU General Public License for more details. 
     13 * You should have received a copy of the GNU General Public 
     14 * License along with this program; if not, write to the Free 
     15 * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
     16 * MA 02111-1307, USA. 
     17 *  
     18 */   
     19 
     20/*! @file       behaviour_map_go_destination.c 
     21 *  @brief      Bot faehrt nach der erstellten Karte (bzw. wird online erstellt) zu einer bestimmten 
     22 *          Zielkoordinate und umgeht durch vorherige Pfadplanung nach der Potenzialfeldmethode  
     23 *          vorhandene Hindernisse; die Zielkoordinate ist zu Beginn die  
     24 *          Startposition und kann mittels Tastendruck(3) auf die aktuelle  
     25 *          Botposition geaendert werden; einfach den Bot im Raum umherfahren und bei Druecken der 4 
     26 *          findet der bot den Weg zur Startposition zurueck (oder falls 3 betaetigt wurde zu dieser 
     27 *          neuen Zielposition ) 
     28 
     29 * 
     30 *  @author     Frank Menzel (-alias achiem -Menzelfr@gmx.net) 
     31 *  @date           30.04.07 
     32*/ 
     33 
     34 
     35#include "bot-logic/bot-logik.h" 
     36#include "map.h" 
     37#include <stdlib.h> 
     38#include <math.h> 
     39#include "ui/available_screens.h" 
     40#include "display.h" 
     41#include "rc5.h" 
     42#include "rc5-codes.h" 
     43 
     44#ifdef BEHAVIOUR_MAP_GO_DESTINATION_AVAILABLE 
     45 
     46/*!< naechstes anzufahrendes Ziel laut Pfadplanung 
     47 */ 
     48uint16 next_x=0; 
     49uint16 next_y=0; 
     50 
     51/*!< Zwischenzielkoordinaten X Y des xy-Fahrverhaltens 
     52 */ 
     53static uint16 target_x=0;                                
     54static uint16 target_y=0;                                
     55 
     56// Teilerwert zur Potenzialberechnung des attraktiven Potenzials je nach Aufloesung und Suchumkreis 
     57#if MAP_RADIUS_FIELDS_GODEST <= 1  // MCU-Aufloesung 
     58   #define DIV_ATTPOT 1   
     59#else 
     60   #if MAP_RADIUS_FIELDS_GODEST > 9   // sehr hohe Aufloesung  
     61     #define DIV_ATTPOT 1000 
     62   #else 
     63     #define DIV_ATTPOT 10 
     64   #endif 
     65#endif 
     66 
     67#define MAXCOUNTER 100           // Zielsuche bis zu dieser Tiefe, hier wird Routine spaetestens beendet 
     68   
     69/*! Werte, wie bestimmte Mapfelder behandelt werden  
     70 */ 
     71 #define PATHNODES  127      // aus Pfadplanung  
     72 #define GOAL  127      // Ziel bekommt freieste Feldwahrscheinlichkeit 
     73  
     74  
     75/*! globale Zielkoordinaten fuer Pfadplanung; ist zuerst immer das Bot-Map-Startfeld, da dieses sonst nirgendwo anders 
     76 *  gespeichert ist; kann sonst via bot_set_destination auf beliebige Map-Pos gesetzt werden   
     77 */ 
     78uint16 dest_x_map=0; 
     79uint16 dest_y_map=0; 
     80  
     81/*! Zustandsvar der Verhalten nach aussen gezogen, um dieses im Botenverhalten korrekt init. zu koennen;nach Notaus 
     82 *  koennte diese sonst einen undef. Zustand haben 
     83 */ 
     84static uint8 gotoStatexy=0;  // Statusvar des xy-Fahr-Verhaltens 
     85 
     86#ifdef MEASURE_MOUSE_AVAILABLE 
     87  static uint8 statehangon=0;  // Statusvar des Haengon-Verhaltens 
     88#endif 
     89 
     90/*! True wenn Border_map_behaviour einen Abgrund erkannt und markiert hatte; 
     91 *  muss vom Anwenderprog auf False gesetzt werden und dient zur Erkennung ob Verhalten 
     92 *  zugeschlagen hat; ueber ueber registrierter Prozedur gesetzt vom Abgrundverhalten 
     93*/ 
     94uint8 border_fired=False; 
     95 
     96 
     97/*! True, wenn vom Haengenbleiben-Verhalten das Haengenbleiben des bots erkannt wurde 
     98 *  muss von Anwendung nach Auswertung wieder auf False gesetzt werden 
     99 */ 
     100uint8 hangon_behaviour_fired=False; 
     101 
     102 
     103 /*! Elternposition, d.h. Botposition vor neuer Position 
     104 */ 
     105static uint16 x_parent=0; 
     106static uint16 y_parent=0; 
     107 
     108 
     109// Notfallhandler, ausgefuehrt bei Abgrunderkennung; muss registriert werden 
     110void border_mapgo_handler(void){ 
     111 
     112  // Routine muss zuerst checken, ob map_go_destination auch gerade aktiv ist, da nur in diesem 
     113  // Fall etwas gemacht werden muss 
     114  if (!Behaviour_is_activated(bot_gotoxy_behaviour_map))  
     115      return; 
     116         
     117    border_fired=True;  // Setzen der Syncvar des Verhaltens, die immer abgefragt wird 
     118         
     119        bot_drive_distance(0,0,-BOT_SPEED_FOLLOW,10);// 10cm rueckwaerts nur bei Hindernis       
     120         
     121} 
     122 
     123 
     124// ============= eigenstaendiges Parallelverhalten zum eigentlichen Fahrverhalten ======= 
     125 
     126 
     127/*! Verhalten zum Erkennen des Haengenbleibens des Bots; wenn MEASURE_MOUSE_AVAILABLE gesetzt werden Maus- und 
     128 *  Encoderdaten miteinander verglichen; wird der Bot-Stillstand erkannt, wird etwas rueckwaerts  
     129 *  gefahren und die Syncvar hangon_behaviour_fired gesetzt, damit das Haengenbleiben vom Fahrverhalten erkannt  
     130 *  wird und reagiert werden kann; koennte eigentlich im bot auch generell als uebergeordnetes Verhalten  
     131 *  eingesetzt werden, hier jedoch aktiviert zum Start des Fahrverhaltens selbst und bei Ankunft deaktiviert 
     132 *  @param *data der Verhaltensdatensatz 
     133 */ 
     134#ifdef MEASURE_MOUSE_AVAILABLE  
     135void bot_check_hang_on_behaviour(Behaviour_t *data){ 
     136          
     137        switch (statehangon){ 
     138                case 0:          
     139                       statehangon++; 
     140                       break; 
     141                case 1: 
     142 
     143                  // Check auf Haengenbleiben mit Rad-Durchdreh-Erkennung mit Mausvergleich 
     144             // wenn Maus verfuegbar, so kann ein Haengenbleiben durch Vergleich der Encoder und 
     145             // Mauswerte festgestellt werden, wie auf bot-Webseite schon mal beschrieben 
     146            if  ( !((abs(v_enc_left-v_mou_left) < STUCK_DIFF)    &&  
     147                   (abs(v_enc_right-v_mou_right) < STUCK_DIFF) 
     148                  )) 
     149             {             
     150                                                    
     151                            // Syncvar setzen, dass Verhalten zugeschlagen hat 
     152                        hangon_behaviour_fired = True; 
     153                            
     154                            // etwas rueckwaerts fahren;  
     155                            #ifdef BEHAVIOUR_DRIVE_DISTANCE_AVAILABLE  
     156                              bot_drive_distance(data,0,-BOT_SPEED_FOLLOW,10); 
     157                            #endif 
     158                            break;  
     159                          } 
     160                        break; 
     161                default: 
     162                    // wird eigentlich nicht erreicht, da Endlosverhalten 
     163                        return_from_behaviour(data); 
     164                        break; 
     165        } 
     166} 
     167 
     168/*! Botenverhalten zum Starten des Haengenbleiben-Verhaltens 
     169 *  @param *caller der Verhaltensdatensatz 
     170 */ 
     171void bot_check_hang_on(Behaviour_t *caller) {    
     172        statehangon=0; 
     173        switch_to_behaviour(caller, bot_check_hang_on_behaviour,NOOVERRIDE); 
     174} 
     175 
     176#endif 
     177 
     178 
     179/*! Routine zum Setzen der Zielkoordinaten; wird 0 uebergeben, dann auf aktuelle Botposition setzen  
     180 *  @param x X-Map-Zielkoordinate 
     181 *  @param y Y-Map-Zielkoordinate 
     182 */ 
     183void bot_set_destination(uint16 x, uint16 y) {   
     184 
     185        if (x==0 && y==0) { 
     186          dest_x_map=world_to_map(x_pos); 
     187          dest_y_map=world_to_map(y_pos); 
     188        } 
     189        else { 
     190        dest_x_map = x; 
     191            dest_y_map = y; 
     192        } 
     193} 
     194 
     195 
     196 
     197 
     198// ===== notwendige Routinen zur Ermittlung der Potenziale fuer das eigentliche Fahrverhalten ======= 
     199 
     200/*! Ermittlung des Abstandes zwischen 2 Koordinaten; verwendet zur Potenzial-Abstandsermittlung zum Zielpunkt, 
     201 *  um eine heuristische Schaetzung vorzunehmen 
     202 * @param xs ys Map-Koordinaten des zu untersuchenden Punktes 
     203 * @param xd yd Map-Koordinaten des Zielpunktes 
     204 * @return liefert Quadrat-Abstand zwischen den Map-Punkten als heuristische Funktion zur Entfernungsschaetzung; 
     205 * je kleiner, desto mehr wird dieser Punkt bevorzugt behandelt 
     206 */ 
     207uint16 get_dist(uint16 xs, uint16 ys, uint16 xd, uint16 yd){ 
     208        int16 xt=xd - xs;        
     209        int16 yt=yd - ys; 
     210         
     211        /* Abstandsermittlung nach dem guten alten Pythagoras ohne Ziehen der Wurzel */ 
     212        return (xt*xt+yt*yt);    
     213 
     214} 
     215 
     216 
     217 
     218/*! ermittelt Abstossungs-Potenzial des Nodes xy, der bereits mit der Wahrscheinlichkeit eines  
     219 *  Hindernisses laut Map belegt ist (-128 - +127 sind moegliche Map-Werte) 
     220 *  das repulsive Potenzial ist am groessten umso naeher sich der Punkt am Hindernis befindet und 
     221 *  liefert das kleinste Potenzial fuer am weitesten vom Hindernis weg  
     222 * @param x x-Koord des zu untersuchenden Punktes 
     223 * @param y y-Koord des zu untersuchenden Punktes 
     224 * @param mapval Wert laut Map an Position xy 
     225 * @return repulsives Potenzial fuer Map-Hinderniswahrscheinlichkeit 
     226 */ 
     227uint16 get_rep_pot(uint16 x, uint16 y, int8 mapval) { 
     228         
     229        // bereits markierter Pfadpunkt bekommt Hinderniswert, sonst wuerde Richtung des schon markierten 
     230        // Weges bevorzugt werden; so also nicht genommen 
     231    if (mapval==PATHNODES)  
     232              mapval=-MAP_ART_HAZARD; 
     233         
     234        // alles groesser 0 ist Freiwahrscheinlichkeit, die beim Umherfahren fuer Freifelder eingetragen wird; 
     235        // daher auf 0 setzen mit Gleichbehandlung 
     236        if (mapval > 0) 
     237             mapval = 0; 
     238         
     239    // kleinerer Hinderniswert bekommt hiermit groesseres Abstossungspotenzial und wird in den positiven Bereich 
     240    // transferiert       
     241    return mapval * (-1) + 127;   
     242} 
     243 
     244 
     245 
     246 
     247/*! liefert Wert fuer das attraktive Potenzial des Zieles aus Abstandsfunktion; bewirkt das  
     248 *  Anziehen des Bots und Ablenken in Richtung Ziel; ist umso groesser je naeher der Punkt 
     249 *  sich am Ziel befindet; wie ein Trichter liegt diese Kraft auf der Karte; am groessten 
     250 *  ist die Kraft am Zielpunkt selbst, das Potenzial dort also am kleinsten; Potenzial ist  
     251 *  entgegengesetzt der Kraft, wird also in Richtung Ziel immer kleiner 
     252 * @param x x-Koord des zu untersuchenden Punktes 
     253 * @param y y-Koord des zu untersuchenden Punktes 
     254 * @param xdest x-Koord des Zieles 
     255 * @param ydest y-Koord des Zieles 
     256 * @return attraktives Potenzial aus Abstandsermittlung 
     257 */ 
     258uint16 get_att_pot(uint16 x, uint16 y, uint16 xdest, uint16 ydest) { 
     259  // Als heuristische Potenzialfunktion dient die Bestimmung des Abstandes zum Ziel, wobei der Punkt   
     260  // xy das kleinste Potential hat, welcher sich am nahesten am Ziel befindet und konvergiert dort gegen 0 
     261  // hoher Wert fuer hohen Abstand 
     262 return (DIV_ATTPOT <= 1)  ? 4 * get_dist(x,y,xdest,ydest) : (4 * get_dist(x,y,xdest,ydest)) / DIV_ATTPOT; 
     263} 
     264 
     265/*! liefert verdoppeltes repulsives Potenzial, falls der zu untersuchende Punkt auf den Elternnode verweist 
     266 *  somit Wahrscheinlichkeit hoeher, dass ein anderer Weg gegangen wird als wo er gerade herkommt 
     267 *  @param xs ys  betrachtete Map-Kooordinaten 
     268 *  @param reppot bereits ermitteltes Abstossungspotenzial von xs ys 
     269 *  @return Verdopplung von reppot oder 0  
     270 */ 
     271 uint16 pot_off_to_parent(uint16 xs, uint16 ys, uint16 reppot) { 
     272  return (map_in_dest(xs,ys,x_parent,y_parent)/*||map_in_dest(xs,ys,x_parent_par,y_parent_par)*/)/*(xs==x_parent && ys==y_parent)*/  ? reppot * 2 : 0; 
     273 } 
     274 
     275 
     276 
     277/*! liefert die Summe aller abstossenden Potenziale ohne anziehendes Zielpotenzial 
     278 * @param xs ys betrachtete Koordinaten 
     279 * @param xd yd Zielkoordinaten 
     280 * @return Summe aller repulsiven Potenziale 
     281 */ 
     282uint16 get_all_rep_pot(uint16 xs, uint16 ys, uint16 xd, uint16 yd) { 
     283         
     284        uint16 sumpot=0; 
     285         
     286        //falls der zu untersuchende Knoten der Zielknoten ist, keine Abstossungskraft mit Pot 0 
     287          if (!map_in_dest (xs,ys, xd,yd)) { 
     288                int16 avg=map_get_average_fields(xs,ys,MAP_RADIUS_FIELDS_GODEST_HALF); 
     289                sumpot = get_rep_pot(xs,ys,avg); 
     290          } 
     291           
     292        sumpot+=pot_off_to_parent(xs,ys,sumpot);  // Potenzial verdoppelt falls Elternnode derjenige ist 
     293         
     294    return sumpot;  // Rueckgabe des repulsiven Summenpotenzials 
     295} 
     296 
     297 
     298 
     299/*! ab dem Knoten x,y wird rundum fuer jeden Knoten das Potenzial ermittelt und der Knoten mit dem kleinsten  
     300 *  Wert bestimmt und in nextx y zurueckgegeben 
     301 *  dies ist die Hauptroutine zur Ermittlung des Potenzials in einem beliebigen Punkt 
     302 *  @param xdest, ydest Zielkoordinaten (zur Bestimmung des attraktiven Potenzials) 
     303 *  @param XP_START, YP_START  Startkoordinaten des bots 
     304 *  @param nextx nexty naechster Zwischenzielpunkt mit geringstem Potenzial 
     305 *  @param get_next_pathpoint Bei True wird der bereits mit Kennung versehene Pfad zum Ziel verfolgt und der  
     306 *    naechste bereits als Pfad gekennzeichnete Punkt zurueckgegeben; bei False wird Nachbar mit geringstem  
     307 *    Potenzial ermittelt fuer Pathplaning 
     308 *  @param roff Offsetradius zur Umkreissuche   
     309 */ 
     310void get_gradient(uint16 xdest, uint16 ydest,uint16 XP_START, uint16 YP_START,  
     311                  uint16 *nextx, uint16 *nexty, int8 get_next_pathpoint, uint8 roff) { 
     312  int8 i; 
     313  int8 j; 
     314  uint16 sumpot=0; 
     315   
     316  //minimalstes Potenzial wird sich hier gemerkt 
     317  uint16 minpot=9999;  //auf maximalen Wert setzen 
     318  uint16 x_minpos=0; 
     319  uint16 y_minpos=0; 
     320    
     321  // vorberechnete Spalten und Zeilenzaehler 
     322  uint16 xj=0; 
     323  uint16 yi=0; 
     324  uint16 sumpotrep=0; 
     325   
     326  uint16 x=XP_START; 
     327  uint16 y=YP_START; 
     328  
     329  // Rueckgabewerte erst mal initialisieren 
     330  *nextx=0; 
     331  *nexty=0; 
     332   
     333  int8 mapval=0;  // Wert des Mapfeldes 
     334   
     335  if (map_in_dest(dest_x_map,dest_y_map,XP_START,YP_START)) { // Start- ist schon Zielpunkt 
     336       *nextx=dest_x_map; 
     337       *nexty=dest_y_map; 
     338       return;   
     339  } 
     340         
     341  // Umkreisermittlung macht nur Sinn bei hoeherer Aufloesung 
     342  #if MAP_RADIUS_FIELDS_GODEST > 1 
     343    int8 radius = MAP_RADIUS_FIELDS_GODEST + roff;  // etwas weiter suchen 
     344    int16 rquad = radius * radius; 
     345    uint16 quad=0;                           // Quadratwert des Abstandes in der Schleife 
     346    uint16 roffq = (roff + 4) * (roff + 4);  // Wert ist Experimentwert um nicht zu viele Felder zu checken  
     347  #else  
     348    int8 radius = 1;  // sonst bei geringer Aufloesung direkter Nachbar  
     349  #endif  
     350  
     351      
     352     //nur innerhalb des Radiuskreises bleiben 
     353         for (i=-radius; i<=radius; i++) {//Zeilenzaehler 
     354                    yi = y + i; 
     355                      
     356                        for (j=-radius; j<=radius; j++) {//Spaltenzaehler 
     357                          xj = x + j; 
     358                             
     359                          #if MAP_RADIUS_FIELDS_GODEST > 1  // Umkreisfelder nur bei hoeherer Aufloesung, sonst 8Nachbarschaft 
     360                           if (radius>1)  
     361                             quad=i*i + j*j ;  
     362                               
     363                             if ((!get_next_pathpoint && (quad == rquad || quad==rquad-1 || quad==rquad+1)) || // Potermittlung 
     364                                 (get_next_pathpoint && quad >= MAP_RADIUS_FIELDS_GODEST_HALF_QUAD + roffq)) { // Umkreissuche des Weges 
     365                           
     366              #endif      
     367               
     368                            //Potenzial ermitteln an Indexposition; nicht Mittelpos 0,0 selbst 
     369                                if (((j!=0)||(i!=0))/* && xj>=0 && yi>=0*/) { 
     370 
     371                             // nur innerhalb der Rechteckgrenzen 
     372                             if (xj>=map_min_x && xj<=map_max_x && yi>=map_min_y && yi<=map_max_y) { 
     373                              //wenn nicht betretbar laut Map gar nicht erst auswerten und gleich uebergehen                      
     374                              mapval=map_get_field(xj,yi); 
     375                                
     376                              // entweder Pfad erst ermitteln oder den naechsten Punkt des Pfades zurueckgeben 
     377                              if ((/*(xj!=x_parent||yi!=y_parent)&&*/(mapval>-MAPFIELD_IGNORE)&& !get_next_pathpoint)|| 
     378                                   (get_next_pathpoint && mapval==PATHNODES && !map_in_dest(xj,yi,x_parent,y_parent) /*&& !map_in_dest(xj,yi,x_parent_par,y_parent_par)*//*(xj!=x_parent || yi!=y_parent)*/  )) {        
     379                                 sumpotrep=9999; 
     380                                 sumpot=9999; 
     381                                  
     382                                // Pfadverfolgung; bereits gekennzeichnete Pfadpunkte werden gesucht im Botumkreis 
     383                                // gibts mehrere, wird bei geringer Aufloesung derjenige mit kleinstem Abstand zum Ziel genommen         
     384                               sumpotrep=0; 
     385                               //koennte auch mehrere geben, daher den mit geringstem pot 
     386                               if (map_in_dest(xj,yi,dest_x_map,dest_y_map)) { 
     387                                sumpot = 0; 
     388                               } 
     389                               else { 
     390                                 if (get_next_pathpoint) { 
     391                                   sumpotrep=get_all_rep_pot(xj,yi,xdest,ydest); 
     392                                   sumpot=sumpotrep + get_att_pot(xj,yi,xdest,ydest); 
     393                                 } 
     394                                 else { 
     395                                   sumpotrep=get_all_rep_pot(xj,yi,xdest,ydest); 
     396                                   sumpot=sumpotrep + get_att_pot(xj,yi,xdest,ydest); 
     397                                 } 
     398                               } 
     399                                    //bei kleinerem Potenzial Werte merken, Abstossungspot muss auch > Ignore-Potenzial sein 
     400                                    if (sumpot<minpot && (get_next_pathpoint||(sumpotrep < 255 && !get_next_pathpoint))) { 
     401                                          //Node darf nicht existieren um Nachbarn einzufuegen, bei Gradabstieg aber auch wenn noch nicht existiert 
     402                                             minpot=sumpot;  // Potenzial nur mit Kosten zum Parent 
     403  
     404                                             x_minpos=xj; 
     405                                             y_minpos=yi; 
     406                                             *nextx=xj;    // Rueckgabewerte setzen 
     407                                             *nexty=yi;  
     408 
     409                                    }//if sumpot<minpot 
     410                                     
     411                              }//if Mapfeld nicht betretbar 
     412                             } //ausserhalb der Indexgrenzen          
     413                                }//if, Pos selbst 
     414             #if MAP_RADIUS_FIELDS_GODEST > 1           // nur bei hoeherer Aufloesung 
     415                           } //Suche war ab halben bis ganzem Botradius          
     416                         #endif 
     417                          } //for Spalten x->j                     
     418         } //for Zeilen y->i 
     419        // Botposition wird nun zur neuen Elternposition 
     420        x_parent=XP_START; 
     421        y_parent=YP_START;  
     422} 
     423 
     424 
     425 
     426// =================== endlich das eigentliche Fahrverhalten ================================ 
     427   
     428 
     429/*! Verhalten, damit der bot der eingetragenen Map-Pfadlinie folgt; das Verhalten richtet den bot zuerst  
     430 *  zum Endziel aus und faehrt in diese Richtung ohne Pfadplanung; erst wenn ein Hindernis voraus erkannt  
     431 *  wird, erfolgt eine Pfadplanung wobei in der Map die Pfadpunkte in bestimmter Umkreisentfernung vermerkt 
     432 *  werden; waehrend der Fahrt wird in der Map im Botumkreis der naechste Pfadpunkt gesucht und dieser  
     433 *  angefahren und bei erreichen des Punktes wiederum der Folgepunkt gesucht; erst wenn keiner gefunden werden  
     434 *  kann (durch Eintragen der Hinderniswahrscheinlichkeit) erfolgt eine neue Pfadplanung an Hand der Potenzialsuche  
     435 *  @param *data der Verhaltensdatensatz 
     436 */ 
     437void bot_gotoxy_behaviour_map(Behaviour_t *data){ 
     438        #define INITIAL_TURN    0 
     439        #define DRIVE_TO_NEXT   2 
     440        #define POS_REACHED         3 
     441        #define NEXT_POS            4 
     442        #define INITIAL_GETPATH 5 
     443        #define GO_PATH             6 
     444        #define CLEAR_MAP           7 
     445        #define CLEAR_MAP_FREEFIELDS 8 
     446        #define DIRECTION_GOAL       9 
     447        #define NEXT_IS_HAZARD      10 
     448         
     449        static uint16 diffx_last=0; 
     450        static uint16 diffy_last=0; 
     451         
     452        static uint8 laststate = 0;   
     453 
     454        int16 X_pos; 
     455        int16 Y_pos; 
     456 
     457        int16 xDiff=0; 
     458        int16 yDiff=0; 
     459     
     460    // zur Erkennung, falls mehrmals dasselbe Ziel angesteuert wird, dies aber nicht geht 
     461    static int16 last_xhaz=0; 
     462    static int16 last_yhaz=0; 
     463 
     464   // war Hindernis voraus, wird dessen Mappositionen bestimmt 
     465        uint16 x_nexthaz=0; 
     466    uint16 y_nexthaz=0; 
     467 
     468        //Map-Mauspopsition selbst 
     469        X_pos=world_to_map(x_pos); 
     470        Y_pos=world_to_map(y_pos); 
     471         
     472                //Jederzeit Schluss wenn Positionen Maus und Endziel uebereinstimmen 
     473         if (map_in_dest (X_pos, Y_pos,dest_x_map, dest_y_map)) { 
     474                gotoStatexy=POS_REACHED; 
     475                speedWishLeft=BOT_SPEED_STOP; 
     476                speedWishRight=BOT_SPEED_STOP; 
     477        } 
     478        else     
     479         {      // Check ob naechster Punkt ueberhaupt befahrbar ist     
     480                if (map_get_field(next_x,next_y)<=-MAPFIELD_IGNORE && gotoStatexy!=DIRECTION_GOAL && gotoStatexy!=NEXT_IS_HAZARD)        
     481                 gotoStatexy=INITIAL_GETPATH;  // Neubestimmung notwendig 
     482         }  
     483 
     484        // hier nun Aufruf der Funktionen nach den Verhaltenszustaenden 
     485        switch(gotoStatexy) { 
     486                case DIRECTION_GOAL:    // Ausrichten und Fahren zum Endziel, solange Weg frei 
     487                  next_x=dest_x_map;    // das naechste Ziel ist das Endziel 
     488                  next_y=dest_y_map; 
     489                  target_x = next_x;    // Zwischenziel identisch Endziel 
     490                  target_y = next_y;  
     491                  laststate = DIRECTION_GOAL;  // Kennung setzen dass ich aus Zielfahrt komme 
     492                  gotoStatexy=INITIAL_TURN; 
     493 
     494              // wenn Weg zum Ziel nicht frei ist oder Abgrund um Bot, dann gleich mit Pfadplaung weiter 
     495              if (value_in_circle(X_pos,Y_pos,MAP_RADIUS_FIELDS_GODEST_HALF,-128)) { 
     496                laststate = CLEAR_MAP;  // nicht mehr direction_goal 
     497                        gotoStatexy = CLEAR_MAP; 
     498              } 
     499               
     500                  break; 
     501                   
     502                case CLEAR_MAP: 
     503                   // MAP von altem Pfad und kuenstlichen Hindernissen befreien 
     504                   clear_map(-MAP_ART_HAZARD, -MAPFIELD_IGNORE);  
     505                   gotoStatexy=CLEAR_MAP_FREEFIELDS;     
     506                   break; 
     507                 
     508                case CLEAR_MAP_FREEFIELDS: 
     509                   // MAP nun von Freifeldern befreien-Originalmap wieder da ohne Freiwahrscheinlichkeiten voraus 
     510                   clear_map(-HAZPOT,127);  
     511                   gotoStatexy=INITIAL_GETPATH;  
     512                    
     513                   break; 
     514                 
     515                case INITIAL_GETPATH: 
     516                  #ifdef MEASURE_MOUSE_AVAILABLE 
     517                          deactivateBehaviour(bot_check_hang_on_behaviour);   
     518                  #endif 
     519                    // naechsten Punkt nach Potenzialfeldmethode ermitteln, Wert steht dann in next_x, next_y 
     520                    next_x=0; 
     521                    next_y=0; 
     522                    bot_path_bestfirst(data);   //Umschaltung Pfadsuche mit Deaktivierung dieses Verhaltens 
     523                    laststate=INITIAL_GETPATH;   
     524                    gotoStatexy=GO_PATH;            
     525                          
     526                        break; 
     527                         
     528                case GO_PATH: 
     529                    // kommt hierher nach Beendigung des Pfadplanungsverhaltens 
     530                    // Pfadplanung muss Ergebnis liefern, sonst gehts eben nicht weiter 
     531                                 
     532                        // Pfadplanung hat naechsten anzufahrenden Punk um den Bot ermittelt                 
     533            if (next_x==0 && next_y==0) {  // nichts gefunden -> Ende 
     534                                 gotoStatexy=POS_REACHED;  // Kein Ziel mehr gefunden go_path und Schluss  
     535                                 break; 
     536                        }        
     537            // Zwischenziel belegen  
     538                    target_x = next_x; 
     539                    target_y = next_y;           
     540                           
     541                        gotoStatexy=INITIAL_TURN;      // als naechstes Drehen zum Zwischenziel 
     542             
     543                        break; 
     544                         
     545                case INITIAL_TURN: 
     546                    // hier erfolgt Ausrichtung zum naechsten Zwischenzielpunkt durch Aufruf des bereits 
     547                    // vorhandenen bot_turn-Verhaltens 
     548                    xDiff = target_x-X_pos; 
     549                    yDiff = target_y-Y_pos; 
     550                    diffx_last=fabs(xDiff); 
     551                    diffy_last=fabs(yDiff);  
     552                        gotoStatexy=DRIVE_TO_NEXT;      // gedreht sind wir hiernach zum Zwischenziel, also fahren 
     553 
     554            // Umschaltung zum Drehverhalten; Drehung zum Zwischenziel wenn noetig 
     555                        bot_turn(data,bot_gotoxy_calc_turn(xDiff,yDiff));   
     556                         
     557                        // Aktivierung des Verhaltens der Haengenbleiben-Erkennung; laeuft parallel zu diesem  
     558                        // Fahr-Verhalten (falls es noch nicht laeuft); beim Haengenbleiben wird eine Sync-Variable 
     559                        // gesetzt (_fired), die hier ausgewertet und rueckgesetzt werden muss 
     560                #ifdef MEASURE_MOUSE_AVAILABLE 
     561                  bot_check_hang_on(0); 
     562                        #endif  
     563                        break; 
     564   
     565                 
     566                case DRIVE_TO_NEXT: 
     567                    // hier wird zum Zwischenziel gefahren mit Auswertung auf Haengenbleiben und Locherkennung 
     568                    xDiff=target_x-X_pos; 
     569                yDiff=target_y-Y_pos; 
     570 
     571                        // Position erreicht?  
     572                         if (map_in_dest (X_pos, Y_pos,target_x, target_y)) { 
     573                                                                          
     574                                //Zwischenziel erreicht, ist dies auch Endziel dann Schluss 
     575                                 if (map_in_dest (X_pos, Y_pos,dest_x_map, dest_y_map)) { 
     576                                    gotoStatexy=POS_REACHED;  // Endziel erreicht und Schluss 
     577                                    break;  
     578                                } 
     579                                else { 
     580                                      // Zwischenziel wurde erreicht; bei hoeherer Aufloesung ist der bot nur in der Naehe 
     581                                          gotoStatexy=NEXT_POS;  // zum Ermitteln der naechsten Position 
     582                                         
     583                                          // ist der Bot auf gewollte Zwischenzielpos, dann die Pfadkennnung 
     584                                          // wegnehmen, sonst kann es zu Endlosschleife im lok. Min. kommen 
     585                                          if (map_get_field(X_pos,Y_pos)==PATHNODES) 
     586                                                   map_set_field(X_pos,Y_pos,0); 
     587                                         
     588                                        // vorsichtige Weiterfahrt 
     589                                          speedWishLeft  = BOT_SPEED_FOLLOW; 
     590                                          speedWishRight = BOT_SPEED_FOLLOW; 
     591                                          break;                                                                 
     592                                }                                
     593                        }  //Ende Endzielauswertung 
     594                                  
     595                        // Check auf zu nah oder nicht befahrbar 
     596                        if  (sensDistL<=OPTIMAL_DISTANCE || sensDistR<=OPTIMAL_DISTANCE ||   // < 144mm 
     597                             map_get_field(target_x,target_y) <= -MAPFIELD_IGNORE ) {        // Mapposition nicht befahrbar 
     598                              
     599                             if (laststate==DIRECTION_GOAL) {   // Abbruch der Zielfahrt und Pfadsuche 
     600                              gotoStatexy=INITIAL_GETPATH; 
     601                              break; 
     602                             } 
     603                             else {  
     604                               if (map_in_dest(target_x,target_y,dest_x_map,dest_y_map)) {  // Schluss bei Endziel  
     605                     gotoStatexy=POS_REACHED;    
     606                     break; 
     607                               } 
     608                               else { 
     609                     gotoStatexy=NEXT_IS_HAZARD;  // Ziel noch nicht erreicht, naechstes Ziel aber Hindernis     
     610                     break; 
     611                               } 
     612                             }                        
     613                        }  
     614 
     615                         
     616                        // wenn Map-Abgrundverhalten Loch erkennt, da ja bot gerade ueber Abgrund gehangen hatte, ist 
     617                        // neue Wegsuche mit Hindernis voraus aufzuruefen 
     618                        // vom Notfallverhalten wurde durch die registrierte Proc Abgrundkennung gesetzt 
     619                         if  (border_fired) {    
     620               border_fired=False;  // wieder ruecksetzen, erst durch Abgrundverhalten neu gesetzt 
     621                           gotoStatexy=NEXT_IS_HAZARD;    // Hindernis voraus 
     622                           break; 
     623             } 
     624                         
     625                        //Abstand wird wieder groesser; neue Pfadsuche 
     626                        if (laststate!=DIRECTION_GOAL && ( diffx_last<fabs(xDiff)|| diffy_last<fabs(yDiff))) { 
     627                                gotoStatexy=NEXT_POS; 
     628                                speedWishLeft  = BOT_SPEED_FOLLOW;  // vorsichtige Weiterfahrt 
     629                                speedWishRight = BOT_SPEED_FOLLOW; 
     630                                break; 
     631                        } 
     632                         
     633                            
     634           // hier Check ob Haengenbleiben-Verhalten zugeschlagen hat; koennte genauso behandelt werden 
     635           // wie beim Abgrundverhalten mit Registrierung; wird aber hier immer ab- und zugeschaltet 
     636                   if (hangon_behaviour_fired) {    // Syncvar wurde vom H.-Verhalten gesetzt 
     637                         gotoStatexy=NEXT_IS_HAZARD;    // Hindernis voraus 
     638                         hangon_behaviour_fired=False;  // Syncvar wieder ruecksetzen 
     639                     break;      
     640                   }     
     641                  
     642                  
     643                    // hier ist der eigentliche Antrieb fuer das Fahren 
     644                        #ifdef PC 
     645                           speedWishLeft=BOT_SPEED_FAST; 
     646                           speedWishRight=BOT_SPEED_FAST; 
     647 
     648             #else 
     649                           speedWishLeft=BOT_SPEED_MEDIUM; 
     650                           speedWishRight=BOT_SPEED_MEDIUM; 
     651                         #endif  
     652                         
     653                 
     654            // Abstandsdifferenz aus diesem Durchlauf merken 
     655                        diffx_last=fabs(xDiff); 
     656                    diffy_last=fabs(yDiff);      
     657                        break; 
     658  
     659       case NEXT_IS_HAZARD: 
     660           // das naechste Ziel kann nicht erreicht werden und wird hinderniswahrscheinlicher 
     661           // Bot ist hier schon rueckwaerts gefahren, steht also nicht mehr auf Abgrundfeld 
     662           // wenn mehrmals hintereinander dasselbe Ziel ermittelt wird aber Hindernis darstellt, 
     663           // dann auch auf Hind. setzen 
     664           if   (last_xhaz==target_x && last_yhaz==target_y) {     // gleiches Ziel wie vorher erkannt  
     665             map_set_value_occupied(target_x,target_y,-MAP_ART_HAZARD);  // kuenstl. Hindernis 
     666              
     667           } 
     668           else { 
     669             last_xhaz=target_x;  // Hindernisziel aus diesem Durchlauf merken 
     670             last_yhaz=target_y; 
     671           } 
     672                   
     673           // 10 cm voraus Hindernisposition laut Map bestimmen 
     674               //get_mappos_dist(x_pos,y_pos,(heading * M_PI /180),100,&x_nexthaz,&y_nexthaz); 
     675               float alpha = (heading * M_PI /180); 
     676               x_nexthaz=get_mapposx_dist(x_pos,y_pos,alpha,100); 
     677               y_nexthaz=get_mapposy_dist(x_pos,y_pos,alpha,100); 
     678 
     679               //Abstand erhoehen auf 15cm falls Botpos ermittelt wurde 
     680               if (x_nexthaz==X_pos && y_nexthaz==Y_pos) { 
     681                   //get_mappos_dist(x_pos,y_pos,(heading * M_PI /180),150,&x_nexthaz,&y_nexthaz); 
     682                   x_nexthaz=get_mapposx_dist(x_pos,y_pos,alpha,150); 
     683                   y_nexthaz=get_mapposy_dist(x_pos,y_pos,alpha,150); 
     684               } 
     685            
     686                   // neue Pfadplanung wird erforderlich 
     687                   gotoStatexy=INITIAL_GETPATH;  
     688                                   
     689                   // Hohe Hinderniswahrscheinlichkeit mit Umfeldaktualisierung der -50 in Map eintragen  
     690                   map_set_value_occupied(x_nexthaz,y_nexthaz,-HAZPOT);  
     691                                                      
     692               // ist naechstes Ziel nicht Endziel, dann Richtung Hindernis mit Umfeld druecken 
     693                 if (!map_in_dest(target_x,target_y,dest_x_map,dest_y_map)) 
     694                               map_set_value_occupied(target_x,target_y,-HAZPOT);          
     695                           
     696                   break; 
     697  
     698   
     699   
     700        case NEXT_POS: 
     701                    // das naechste Zwischenziel wurde erreicht (geringe Aufloesung) oder bot befindet sich in gewissem 
     702                    // Umkreis (hohe Aufloesung); hier ist der naechste in der Map vermerkte Pfadpunkt zu suchen oder die 
     703                    // Pfadsuche neu anzustossen 
     704                                    // wichtig bei hoeherer Aufloesung: Der eigentliche Zielpunkt wird konkret kaum genau erreicht, daher 
     705                                    // diesen vom Pfad nehmen und im Umkreis suchen; Abstossungspot setzen damit Benachteiligung bei Neurechnung 
     706                                      if (value_in_circle(X_pos,Y_pos,MAP_RADIUS_FIELDS_GODEST_HALF,PATHNODES))          
     707                                          map_set_value_occupied (target_x,target_y,-HAZPOT); 
     708                                                                              
     709                      // Suche des naechsten Pfadpunktes in der Map zur Pfadverfolgung 
     710                      #if MAP_RADIUS_FIELDS_GODEST > 1 
     711                         // bei hoher Aufloesung mit Radiusumkreis entsprechend Aufloesungsfelder 
     712                         get_gradient(dest_x_map, dest_y_map, target_x,target_y,&next_x,&next_y,True, MAP_RADIUS_FIELDS_GODEST); 
     713                         if (next_x==0 && next_y==0)  
     714                                get_gradient(dest_x_map, dest_y_map, X_pos,Y_pos,&next_x,&next_y,True, MAP_RADIUS_FIELDS_GODEST); 
     715 
     716                          
     717                      #else 
     718                         // bei geringer MCU Aufloesung immer das naechste Mapfeld 
     719                         get_gradient(dest_x_map, dest_y_map, X_pos,Y_pos,&next_x,&next_y,True,0); 
     720                       #endif  
     721                                      
     722  
     723                    // bei freier Fahrt zum Endepunkt Zielfahrt 
     724                            if (map_way_free_fields(X_pos,Y_pos,dest_x_map,dest_y_map)) { 
     725                              gotoStatexy=DIRECTION_GOAL; 
     726                              break; 
     727                            }  
     728                      
     729                    if (next_x==0 && next_y==0) {  // neue Pfadsuche erforderlich mit Maploeschung 
     730                        gotoStatexy=CLEAR_MAP; 
     731                        break; 
     732                    }  
     733                      
     734                    // naechstes Zwischenziel ist der neu ermittelte Pfadpunkt laut Map 
     735                    target_x = next_x; 
     736                            target_y = next_y;  
     737                             
     738                                                     
     739                            // weiter zum Ausrichten auf neuen Pfadpunkt mit Drehung 
     740                            gotoStatexy=INITIAL_TURN; 
     741                               
     742                            // langsam weiterfahren   
     743                             #ifdef PC 
     744                                    speedWishLeft=BOT_SPEED_NORMAL; 
     745                                    speedWishRight=BOT_SPEED_NORMAL; 
     746 
     747                     #else 
     748                                    speedWishLeft=BOT_SPEED_MEDIUM; 
     749                                    speedWishRight=BOT_SPEED_MEDIUM; 
     750                                 #endif  
     751 
     752             break; 
     753         
     754               
     755                case POS_REACHED: 
     756                    // hier ist das gewuenschte Endziel erreicht 
     757                        gotoStatexy=DIRECTION_GOAL; 
     758                        // Parallelverhalten ausschalten da nicht mehr benoetigt 
     759                        #ifdef MEASURE_MOUSE_AVAILABLE 
     760                          deactivateBehaviour(bot_check_hang_on_behaviour);   
     761                        #endif 
     762                        return_from_behaviour(data); 
     763                        break; 
     764        } 
     765 
     766} 
     767 
     768 
     769 
     770 
     771/*! Bot faehrt auf eine bestimmt Map-Position relativ zu den akt. Botkoordinaten; globales Ziel 
     772 *  wird mit den neuen Koordinaten belegt bei Uebergabe xy ungleich 0 
     773 * @param *caller der Verhaltensdatensatz 
     774 * @param x zu der x-Botkoordinate relative anzufahrende Map-Position 
     775 * @param y zu der y-Botkoordinate relative anzufahrende Map-Position 
     776 */ 
     777void bot_gotoxy_map(Behaviour_t *caller, uint16 x, uint16 y){ 
     778        //Mauskoords in  Mapkoordinaten  
     779        uint16 X_pos = world_to_map(x_pos); 
     780        uint16 Y_pos = world_to_map(y_pos); 
     781         
     782        //globale Zielkoordinaten setzen, die fuer Pfadplaner Verwendung finden 
     783        if (x!=0 || y!=0) {       // fuer Fahrt relativ zu der Botposition 
     784          dest_x_map=X_pos + x; 
     785          dest_y_map=Y_pos + y; 
     786        } 
     787 
     788 
     789    /* Kollisions-Verhalten ausschalten bei hoeherer Aufloesung; hier kann mit groesserem  
     790     * Hindernis-Umkreis ein groesserer Abstand erzielt werden 
     791         */ 
     792         #ifdef BEHAVIOUR_AVOID_COL_AVAILABLE 
     793                                deactivateBehaviour(bot_avoid_col_behaviour); 
     794         #endif 
     795   
     796     
     797   /* Einschalten sicherheitshalber des on_the_fly Verhaltens, wird bei Notaus sonst deaktiviert 
     798    */ 
     799    #ifdef BEHAVIOUR_SCAN_AVAILABLE 
     800                activateBehaviour(bot_scan_onthefly_behaviour); 
     801        #endif 
     802        /* Einschalten sicherheitshalber des Abgrund-Verhaltens 
     803    */   
     804    #ifdef BEHAVIOUR_AVOID_BORDER_AVAILABLE 
     805                activateBehaviour(bot_avoid_border_behaviour); 
     806        #endif   
     807 
     808    gotoStatexy=DIRECTION_GOAL;  // auf Zielfahrt init. 
     809        switch_to_behaviour(caller, bot_gotoxy_behaviour_map, OVERRIDE);  // Umschaltung zum Fahr-Verhalten 
     810} 
     811 
     812 
     813/*! Verhalten laesst den Bot zum Endziel fahren, welches vorher auf eine bestimmte Botposition festgelegt wurde; 
     814 *  ansonsten ist das Ziel der Bot-Startpunkt 
     815 *  @param *caller der Verhaltensdatensatz 
     816 */ 
     817void bot_gotodest_map(Behaviour_t *caller){ 
     818        // zum bereits gesetztem Endziel gehen mit 0-Differenz 
     819        bot_gotoxy_map(caller, 0,0);       
     820} 
     821 
     822 
     823/*! Verhalten zur Generierung des Pfades vom Bot-Ausgangspunkt zum Ziel nach der Potenzialfeldmethode; 
     824 *  es wird der Weg ermittelt von der Botposition mit hohem Potenzial bis zum gewuenschten Ziel mit geringem 
     825 *  Potenzial; Um den Hindernissen herum existiert laut den Mapwerten ein abstossendes Potenzial und die  
     826 *  Entfernung zum Ziel dient als heuristisches Mittel fuer das global anziehende Potenzial; die Wegpunkte werden 
     827 *  mit bestimmter Kennung in die Map eingetragen und diese Pfadpunkte im Fahrverhalten gesucht und nacheinander 
     828 *  angefahren  
     829 *    
     830 * @param *data der Verhaltensdatensatz 
     831 */ 
     832void bot_path_bestfirst_behaviour(Behaviour_t *data){ 
     833        #define GET_PATH_INITIAL  0 
     834        #define GET_PATH_BACKWARD 1  
     835        #define REACHED_POS       9  
     836         
     837        static uint8 state=GET_PATH_INITIAL; 
     838        static uint8 pathcounter=0;  // Abbruchzaehler fuer Pfadermittlung 
     839 
     840    // ausgehend von diesem Punkt wird das Potenzial ermittelt 
     841    static uint16 X=0; 
     842    static uint16 Y=0; 
     843    static uint16 x_first=0;       // 1. anzufahrender Punkt laut Pfadplanung ab Botposition 
     844    static uint16 y_first=0; 
     845    static uint8 counter_noway=0; 
     846 
     847        switch (state){          
     848                case GET_PATH_INITIAL: 
     849                 
     850                        // alle als frei markierten Mappositionen > 0 wieder auf 0 setzen 
     851               clear_map(0,127);  // Loeschen der Freifelder, nicht der kuenstlichen Hindernisse 
     852                   
     853          // Bot-Map-Position ermitteln 
     854                  X=world_to_map(x_pos); 
     855                  Y=world_to_map(y_pos); 
     856                   
     857                  // Eltern init auf Botpos. 
     858                  x_parent=X; 
     859          y_parent=Y; 
     860           
     861          // erste anzufahrende Botposition init. 
     862          x_first=0; 
     863          y_first=0; 
     864                   
     865                  //  Pfadermittlung kann nun losgehen 
     866                  state=GET_PATH_BACKWARD; 
     867                  break; 
     868                         
     869                case GET_PATH_BACKWARD: 
     870             // Gradientenabstieg-naechste Koord mit kleinstem Potenzial ab Punkt X,Y ermitteln 
     871                        get_gradient(dest_x_map, dest_y_map, X,Y,&next_x,&next_y,False,0); 
     872 
     873             
     874            // Schluss falls kein Wert ermittelbar 
     875            if (next_x==0 && next_y==0) { 
     876                state = REACHED_POS; 
     877                break;   
     878            } 
     879             
     880            // am Endziel mit Pfadplanung angekommen und Schluss 
     881            if (map_in_dest(next_x,next_y,dest_x_map,dest_y_map)) { 
     882              map_set_field(dest_x_map,dest_y_map,PATHNODES);  // Endziel auch mit Pfadpunkt markieren    
     883              state = REACHED_POS; 
     884              if (x_first==0) {     
     885                 x_first=next_x; 
     886                 y_first=next_y; 
     887              } 
     888              break;     
     889            } 
     890                        
     891            // lokales Minimum -Sackgasse- wird erkannt; versucht hier rauszukommen durch Auffuellen  
     892               if ((next_x==X && next_y==Y) || value_in_circle(next_x,next_y,MAP_RADIUS_FIELDS_GODEST_HALF,PATHNODES) 
     893                 ) { 
     894                // hier wird der bereits beschrittene Weg erreicht, kein anderer Zielpunkt hat kleineres Pot 
     895                // Pot dieses Punktes nun kuenstlich vergrossern Richtung Hindernis und neu suchen 
     896                 
     897                // im halben Botradius auf kuenstl. Hindernis setzen  
     898                  map_update_occupied(next_x,next_y);           // Richtung Hindernis druecken mit Umfeld 
     899                  map_set_field(next_x,next_y,-MAP_ART_HAZARD); // lok. Min. direkt auf Punkt unpassierbar 
     900                  
     901                 map_update_occupied(X,Y);  //aktuelle Pos unwahrscheinlicher 
     902                   
     903                state=GET_PATH_INITIAL;                                // neue Pfadsuche  
     904                pathcounter++;                                         // Pfadsuchzaehler erhoeht 
     905                 if (pathcounter>MAXCOUNTER)                           // Schluss wenn Maximum erreicht 
     906                        state = REACHED_POS; 
     907 
     908                next_x=0;                                              // nix gefunden 
     909                next_y=0; 
     910                 
     911                break; 
     912            } 
     913            else {                          
     914               // ersten Punkt um botpos merken, da dieser sonst ueberschrieben werden kann durch  
     915               // Mapaktualisierung der Botpos 
     916               if (x_first==0) { 
     917                    x_first=next_x; 
     918                    y_first=next_y; 
     919                 }               
     920              } 
     921         
     922                    
     923            // Abfrage ob Bot-Zielposition erreicht wurde und damit Pfad erfolgreich bestimmt 
     924            if (state!=REACHED_POS && map_in_dest (world_to_map(x_pos),world_to_map(y_pos), dest_x_map,dest_y_map))  
     925                state = REACHED_POS; 
     926     
     927            // naechsten Zielpunkt in die Map eintragen 
     928            map_set_field(next_x,next_y,PATHNODES); 
     929 
     930            x_parent=X;  // als Parent den aktuellen Punkt merken 
     931            y_parent=Y; 
     932             
     933            X=next_x;    // der weiter zu untersuchende Punkt ist der Punkt aus Gradientenabstieg 
     934            Y=next_y; 
     935 
     936                        break;   
     937                         
     938                         
     939                default: 
     940                        state=GET_PATH_INITIAL; 
     941                        // zuerst mehrere Versuche starten fuer Zielfindung, falls dieses nicht ermittelt 
     942                        // werden konnte 
     943                        counter_noway++; 
     944                        if (next_x==0 && next_y==0 && (counter_noway < 4)) { 
     945                                if (counter_noway==1) { 
     946                                  state=GET_PATH_INITIAL; 
     947                                  pathcounter=0; 
     948                                  clear_map(-MAP_ART_HAZARD, -MAP_ART_HAZARD+10);  // Loeschen der kuenstlichen Hindernisse 
     949                                  break; 
     950                            } 
     951                            if (counter_noway==2) { 
     952                                  state=GET_PATH_INITIAL; 
     953                                  pathcounter=0; 
     954                                  clear_map(-MAP_ART_HAZARD, 127);  // Loeschen der kuenstlichen Hindernisse 
     955                                  break; 
     956                            } 
     957                           if (counter_noway==3) { 
     958                                  state=DIRECTION_GOAL; 
     959                                  break; 
     960                            } 
     961                          
     962                        } 
     963                        counter_noway=0; 
     964            next_x=x_first; // 1. Punkt des Weges ab Botposition zurueckgeben 
     965            next_y=y_first; 
     966            pathcounter=0; 
     967                        return_from_behaviour(data); 
     968                        break;  
     969        } 
     970} 
     971 
     972/*! Botenverhalten zum Aufruf des Pfadplanungs-Verhaltens 
     973 * @param *caller der Verhaltensdatensatz 
     974 */ 
     975void bot_path_bestfirst(Behaviour_t *caller) { 
     976         
     977        // Botposition in Map-Koordinaten berechnen 
     978        uint16 X = world_to_map(x_pos); 
     979        uint16 Y = world_to_map(y_pos); 
     980         
     981        if (!map_in_dest (X,Y, dest_x_map,dest_y_map)) { 
     982          // Ziel bekommt freieste Feldwahrscheinlichkeit        
     983          map_set_field(dest_x_map,dest_y_map,GOAL); 
     984                 
     985          // Botpos selbst erhaelt hohes Abstossungspotenzial    
     986          map_set_field(X,Y,-90);        
     987                 
     988          // Umschaltung zur Pfadplanung          
     989          switch_to_behaviour(caller, bot_path_bestfirst_behaviour,OVERRIDE); 
     990        } 
     991} 
     992 
     993 
     994 
     995 
     996 
     997#ifdef DISPLAY_AVAILABLE 
     998        #ifdef DISPLAY_MAP_GO_DESTINATION 
     999         
     1000        static void mapgo_disp_key_handler(void){ 
     1001                /* Keyhandling um Map-Verhalten zu starten*/ 
     1002                switch (RC5_Code){ 
     1003                        #ifdef PC 
     1004                        case RC5_CODE_1: 
     1005                               RC5_Code = 0; 
     1006                               print_map();      
     1007                               break; 
     1008                        #endif 
     1009                        case RC5_CODE_3:  
     1010                               RC5_Code = 0;     
     1011                               bot_set_destination(world_to_map(x_pos),world_to_map(y_pos)); 
     1012                               break; 
     1013                         case RC5_CODE_4:  
     1014                               RC5_Code = 0;     
     1015                               clear_map(-MAP_ART_HAZARD, -MAPFIELD_IGNORE);  // Loeschen der kuenstlichen Hindernisse und des alten Pfades fuer Neubeginn 
     1016                               next_x=0; 
     1017                               next_y=0; 
     1018                               bot_gotodest_map(0); 
     1019                              break; 
     1020                          case RC5_CODE_7:  
     1021                               // Volldrehung mit Mapaktualisierung 
     1022                               RC5_Code = 0;     
     1023                   bot_scan(0); 
     1024                               break;    
     1025                     }//case 
     1026          
     1027        }  // Ende Keyhandler 
     1028 
     1029 
     1030                /*!  
     1031                 * @brief       Display zum Start der Map-Routinen 
     1032                 */ 
     1033                void mapgo_display(void){ 
     1034 
     1035                  display_cursor(1,1); 
     1036                  display_printf("MAP last %1d %1d",dest_x_map,dest_y_map); 
     1037                  display_cursor(2,6); 
     1038                  display_printf(     "Bot %1d %1d",world_to_map(x_pos),world_to_map(y_pos)); 
     1039                  display_cursor(3,1); 
     1040                  display_printf("Pos Save/Goto: 3/4"); 
     1041                 // display_cursor(3,1); 
     1042                  //display_printf("fahre zu Pos : 4 "); 
     1043                  #ifdef PC 
     1044                    display_cursor(4,4); 
     1045                    display_printf("Print/Scan: 1/7"); 
     1046                  #else 
     1047                    display_cursor(4,10); 
     1048                    display_printf(         "Scan: 7"); 
     1049          #endif 
     1050                  mapgo_disp_key_handler();               // registrieren des Key-Handlers 
     1051                   
     1052                } 
     1053        #endif  // MAPGO_DISPLAY 
     1054#endif 
     1055 
     1056#endif  // BEHAVIOUR_MAP_GO_DESTINATION_AVAILABLE 
  • C:/botneu/ct-Bot/bot-logic/bot-logik.c

     
    7171#endif 
    7272 
    7373 
     74#define MAX_PROCS 3         /*!< Maximale Anzahl der registrierbaren Funktionen */ 
     75int8 count_arr_emerg = 0;       /*!< Anzahl der zurzeit registrierten Notfallfunktionen */ 
     76/*!< hier liegen die Zeiger auf die auszufuehrenden Abgrund Notfall-Funktionen */ 
     77static void (* emerg_functions[MAX_PROCS])(void) = {NULL}; 
     78 
     79/*! Routine zum Registrieren einer Notfallfunktion, die beim Ausloesen eines Abgrundsensors 
     80 *  aufgerufen wird; hierdurch kann ein Verhalten vom Abgrund benachrichtigt werden und 
     81 *  entsprechend dem Verhalten reagieren 
     82 * @param fkt die zu registrierende Routine, welche aufzurufen ist 
     83 * @return Index, den die Routine im Array einnimmt, bei -1 ist alles voll 
     84 */ 
     85int8 register_emergency_proc(void* fkt){ 
     86        if (count_arr_emerg == MAX_PROCS) return -1;    // sorry, aber fuer dich ist kein Platz mehr da :( 
     87        int8 proc_nr = count_arr_emerg++;               // neue Routine hinten anfuegen 
     88        emerg_functions[proc_nr] = fkt; // Pointer im Array speichern 
     89        return proc_nr; 
     90} 
     91 
     92/*! Beim Ausloesen eines Abgrundes wird diese Routine am Ende des Notfall-Abgrundverhaltens angesprungen  
     93 *  und ruft alle registrierten Prozeduren der Reihe nach auf  
     94 */ 
     95void start_registered_emergency_procs(void) { 
     96 uint8 i=0; 
     97        for (i=0; i<MAX_PROCS; i++){ 
     98                if (emerg_functions[i] != NULL) 
     99                    emerg_functions[i](); 
     100        } 
     101} 
     102 
    74103/*!  
    75104 * Das einfachste Grundverhalten  
    76105 * @param *data der Verhaltensdatensatz 
    … …  
    116145 
    117146        #ifdef BEHAVIOUR_SCAN_AVAILABLE 
    118147                // Verhalten, das die Umgebung des Bots on-the fly beim fahren scannt 
    119                 insert_behaviour_to_list(&behaviour, new_behaviour(155, bot_scan_onthefly_behaviour,ACTIVE)); 
    120          
    121                 // Verhalten, das einmal die Umgebung des Bots scannt 
    122                 insert_behaviour_to_list(&behaviour, new_behaviour(152, bot_scan_behaviour,INACTIVE)); 
     148                insert_behaviour_to_list(&behaviour, new_behaviour(202, bot_scan_onthefly_behaviour,ACTIVE)); 
     149        // vom Notfallverhalten wird Position des Abgrundes in Map eingetragen durch 
     150                // Aufruf dieser registrierten Proc 
     151                #ifdef MAP_AVAILABLE         
     152                  register_emergency_proc(&border_in_map_handler); 
     153                #endif   
     154                  // Verhalten, das einmal die Umgebung des Bots scannt 
     155                  insert_behaviour_to_list(&behaviour, new_behaviour(152, bot_scan_behaviour,INACTIVE)); 
    123156        #endif 
    124157         
    125158        // Alle Hilfsroutinen sind relativ wichtig, da sie auch von den Notverhalten her genutzt werden 
    … …  
    142175        #ifdef BEHAVIOUR_MEASURE_DISTANCE_AVAILABLE 
    143176                insert_behaviour_to_list(&behaviour, new_behaviour(145, bot_measure_distance_behaviour, INACTIVE));              
    144177        #endif 
     178         
     179        // Verhalten, um laut Map zu einem bestimmten Ziel zu fahren 
     180    #ifdef BEHAVIOUR_MAP_GO_DESTINATION_AVAILABLE 
     181        //insert_behaviour_to_list(&behaviour, new_behaviour(251, bot_set_border_in_map_behaviour,ACTIVE)); 
     182        insert_behaviour_to_list(&behaviour, new_behaviour(139, bot_path_bestfirst_behaviour,INACTIVE)); 
     183            //insert_behaviour_to_list(&behaviour, new_behaviour(137, bot_set_destination_behaviour,INACTIVE)); 
     184            #ifdef MEASURE_MOUSE_AVAILABLE 
     185              insert_behaviour_to_list(&behaviour, new_behaviour(137, bot_check_hang_on_behaviour,INACTIVE)); 
     186            #endif 
     187            insert_behaviour_to_list(&behaviour, new_behaviour(135, bot_gotoxy_behaviour_map,INACTIVE)); 
     188            bot_set_destination(0,0);  // auf aktuelle Botposition setzen (bei 0,0 sonst Mappos selbst) 
     189            // Registrierung zur Behandlung des Notfallverhaltens zum Rueckwaertsfahren 
     190            register_emergency_proc(&border_mapgo_handler); 
     191    #endif 
    145192 
    146193        #ifdef BEHAVIOUR_CATCH_PILLAR_AVAILABLE 
    147194                insert_behaviour_to_list(&behaviour, new_behaviour(44, bot_catch_pillar_behaviour,INACTIVE)); 
    … …  
    220267} 
    221268 
    222269/*! 
     270 * Rueckgabe von True, wenn das Verhalten gerade laeuft (aktiv ist) sonst False 
     271 * @param function Die Funktion, die das Verhalten realisiert. 
     272 * @return True wenn Verhalten aktiv sonst False 
     273 */ 
     274uint8 Behaviour_is_activated(BehaviourFunc function){ 
     275        Behaviour_t *job;                                               // Zeiger auf ein Verhalten 
     276 
     277        // Einmal durch die Liste gehen, bis wir den gewuenschten Eintrag haben  
     278        for (job = behaviour; job; job = job->next) { 
     279                if (job->work == function) 
     280                        return job->active; 
     281        } 
     282        return False; 
     283} 
     284 
     285 
     286/*! 
    223287 * liefert 1 zurueck, wenn function ueber eine beliebige Kette (job->caller->caller ....) von anderen Verhalten job aufgerufen hat 
    224288 * @param job Zeiger auf den Datensatz des aufgerufenen Verhaltens 
    225289 * @param function Das Verhalten, das urspruenglich aufgerufen hat 
  • C:/botneu/ct-Bot/bot-logic/behaviour_scan.c

     
    4040 
    4141         
    4242        #ifdef MAP_AVAILABLE 
     43         
     44 
    4345                static float last_x, last_y, last_head; 
    4446                 
    4547                float diff_x = fabs(x_pos-last_x); 
    … …  
    6971                                print_map(); 
    7072                        } 
    7173                */       
    72         #endif 
     74        #endif  //MAP_AVAILABLE 
    7375} 
    7476 
    7577 
    … …  
    141143//      update_map(x_pos,y_pos,heading,sensDistL,sensDistR); 
    142144//      print_map();     
    143145} 
     146 
     147#ifdef MAP_AVAILABLE 
     148        /*! eigentliche Aufrufroutine zum Eintragen des Abgrundes in den Mapkoordinaten, wenn 
     149  *  die Abgrundsensoren zugeschlagen haben   
     150  *  @param xy   aktuelle Bot-Koordinaten als Welt- (nicht Map-) Koordinaten 
     151  *  @param head Blickrichtung  
     152  */  
     153 void update_map_hole(float x, float y, float head){ 
     154         
     155    float h= head * M_PI /180;  // Umrechnung in Bogenmass  
     156   // uint8 border_behaviour_fired=False; 
     157 
     158    if (sensBorderL > BORDER_DANGEROUS) { 
     159       //Ort des linken Sensors in Weltkoordinaten (Mittelpunktentfernung) 
     160       float Pl_x = x - (DISTSENSOR_POS_B_SW * sin(h)); 
     161           float Pl_y = y + (DISTSENSOR_POS_B_SW * cos(h)); 
     162           update_map_sensor_hole(Pl_x,Pl_y,h); // Eintragen des Loches in die Map          
     163    } 
     164          
     165        if (sensBorderR > BORDER_DANGEROUS) {         
     166      //Ort des rechten Sensors in Weltkoordinaten (Mittelpunktentfernung) 
     167      float Pr_x = x + (DISTSENSOR_POS_B_SW * sin(h)); 
     168          float Pr_y = y - (DISTSENSOR_POS_B_SW * cos(h)); 
     169          update_map_sensor_hole(Pr_x,Pr_y,h); // Eintragen des Loches in die Map 
     170        } 
     171 
     172}  
     173 
     174/*! 
     175 *  Notfallhandler, ausgefuehrt bei Abgrunderkennung; muss registriert werden um 
     176 *  den erkannten Abgrund in die Map einzutragen 
     177 */ 
     178void border_in_map_handler(void){ 
     179 
     180  // Routine muss zuerst checken, ob on_the_fly auch gerade aktiv ist, da nur in diesem 
     181  // Fall etwas gemacht werden muss 
     182  if (!Behaviour_is_activated(bot_scan_onthefly_behaviour))  
     183      return; 
     184 
     185   /* bei Abgrunderkennung Position des Abgrundes in Map mit -128 eintragen */ 
     186   update_map_hole(x_pos,y_pos,heading); 
     187}        
    144188#endif 
     189 
     190#endif 
  • C:/botneu/ct-Bot/bot-logic/behaviour_gotoxy.c

     
    2525*/ 
    2626 
    2727#include "bot-logic/bot-logik.h" 
    28  
    29 #ifdef BEHAVIOUR_GOTOXY_AVAILABLE 
    3028#include <math.h> 
    31  
    32  
    33  
    34  
    35 /* Parameter fuer bot_gotoxy_behaviour-Verhalten */ 
    36 float target_x;                         /*!< Zielkoordinate X */ 
    37 float target_y;                         /*!< Zielkoordinate Y */ 
    38 float initialDiffX;                     /*!< Anfangsdifferenz in X-Richtung */ 
    39 float initialDiffY;                     /*!< Anfangsdifferenz in Y-Richtung */ 
    40  
    41  
    4229/*! 
    4330 * Auslagerung der Berechnung der benoetigten Drehung aus dem gotoxy_behaviour 
    4431 * @param xDiff 
    … …  
    6451        return toTurn; 
    6552} 
    6653 
     54#ifdef BEHAVIOUR_GOTOXY_AVAILABLE 
     55 
     56 
     57/* Parameter fuer bot_gotoxy_behaviour-Verhalten */ 
     58float target_x;                         /*!< Zielkoordinate X */ 
     59float target_y;                         /*!< Zielkoordinate Y */ 
     60float initialDiffX;                     /*!< Anfangsdifferenz in X-Richtung */ 
     61float initialDiffY;                     /*!< Anfangsdifferenz in Y-Richtung */ 
     62 
     63 
     64 
     65 
    6766/*! 
    6867 * Das Verhalten faehrt von der aktuellen Position zur angegebenen Position (x/y) 
    6968 * @param *data der Verhaltensdatensatz 
  • C:/botneu/ct-Bot/include/bot-logic/behaviour_gotoxy.h

     
    2929#define BEHAVIOUR_GOTOXY_H_ 
    3030 
    3131#include "bot-logic/bot-logik.h" 
     32/*! 
     33 * Auslagerung der Berechnung der benoetigten Drehung aus dem gotoxy_behaviour 
     34 * @param xDiff 
     35 * @param yDiff 
     36 */ 
     37int16 bot_gotoxy_calc_turn(float xDiff, float yDiff); 
    3238 
    3339#ifdef BEHAVIOUR_GOTOXY_AVAILABLE 
    3440/*! 
    … …  
    4551 * @param y Y-Ordinate an die der Bot fahren soll 
    4652 */ 
    4753void bot_gotoxy(Behaviour_t *caller, float x, float y); 
     54 
     55 
    4856#endif 
    4957 
    5058#endif /*BEHAVIOUR_GOTOXY_H_*/ 
  • C:/botneu/ct-Bot/include/bot-logic/behaviour_map_go_destination.h

     
     1/* 
     2 * c't-Bot 
     3 * 
     4 * This program is free software; you can redistribute it 
     5 * and/or modify it under the terms of the GNU General 
     6 * Public License as published by the Free Software 
     7 * Foundation; either version 2 of the License, or (at your 
     8 * option) any later version. 
     9 * This program is distributed in the hope that it will be 
     10 * useful, but WITHOUT ANY WARRANTY; without even the implied 
     11 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
     12 * PURPOSE. See the GNU General Public License for more details. 
     13 * You should have received a copy of the GNU General Public 
     14 * License along with this program; if not, write to the Free 
     15 * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
     16 * MA 02111-1307, USA. 
     17 * 
     18 */ 
     19 
     20/*! @file       behaviour_map_go_destination.h 
     21 * @brief       Verhalten 
     22 *          -zum Setzen eines Ziels mittel RC-Taste 
     23 *          -um zu diesem Ziel zu gehen von einer beliebigen MAP-Position aus unter Umgehung 
     24 *           aller zu diesem Zeitpunkt bekannten Hindernisse; Pfadplanung erfolgt mittels globaler 
     25 *           Potenzialfeldmethode und der berechneten Potenziale laut des erstellten MAP-Grids mit den 
     26 *           Hindernis-Wahrscheinlichkeiten 
     27 * 
     28 * @author      Frank Menzel (Menzelfr@gmx.net) 
     29 * @date        30.04.07 
     30*/ 
     31  
     32#include "bot-logic/bot-logik.h" 
     33 
     34#ifndef BEHAVIOUR_MAP_GO_DESTINATION_H_ 
     35#define BEHAVIOUR_MAP_GO_DESTINATION_H_ 
     36 
     37 
     38#ifdef BEHAVIOUR_MAP_GO_DESTINATION_AVAILABLE 
     39 
     40 
     41//globale Zielkoordinaten 
     42extern uint16 dest_x_map; 
     43extern uint16 dest_y_map; 
     44 
     45 
     46/*! True wenn Border_map_behaviour einen Abgrund erkannt und markiert hatte; 
     47 *  muss vom Anwenderprog auf False gesetzt werden und dient zur Erkennung ob Verhalten 
     48 *  zugeschlagen hat  
     49*/ 
     50extern uint8 border_behaviour_fired; 
     51 
     52  
     53/*! True, wenn vom Haengenbleiben-Verhalten das Haengenbleiben des bots erkannt wurde 
     54 *  muss von Anwendung nach Auswertung wieder auf False gesetzt werden 
     55 */ 
     56//static int8 hangon_behaviour_fired=False; 
     57 
     58 
     59/*! Verhalten zur Pfadplanung */ 
     60void bot_path_bestfirst(Behaviour_t *data); 
     61void bot_path_bestfirst_behaviour(Behaviour_t *data); 
     62 
     63 
     64/*! Verhalten zum Setzen der Zielkoordinaten */ 
     65//void bot_set_destination(Behaviour_t *data); 
     66//void bot_set_destination_behaviour(Behaviour_t *data); 
     67void bot_set_destination(uint16 x, uint16 y) ; 
     68 
     69/*! Verhalten zur Abgrunderkennung und eintragen in die Map */  
     70void bot_set_border_in_map_behaviour(Behaviour_t *data); 
     71 
     72/*! Verhalten zum Erkennen, falls bot haengenbleibt */ 
     73void bot_check_hang_on_behaviour(Behaviour_t *data); 
     74 
     75/*! Verhalten zum echten Abfahren des bots nach der Punkte-Wegeliste laut Pfadplanung zum global gesetzten Ziel*/ 
     76void bot_gotoxy_behaviour_map(Behaviour_t *data); 
     77void bot_gotodest_map(Behaviour_t *caller); 
     78 
     79 
     80/*! Display zum Aufruf der Mapgo-Routinen */ 
     81void mapgo_display(void); 
     82 
     83/*! Der Punkt xy befindet sich auf den Zielkoordinaten oder innerhalb eines Umkreises davon  */ 
     84//int8 map_in_dest (uint16 x, uint16 y, uint16 destx, uint16 desty); 
     85 
     86int8 register_emergency_proc(void* fkt); 
     87void border_mapgo_handler(void); 
     88 
     89 
     90#endif /* BEHAVIOUR_MAP_GO_DESTINATION_H_ */ 
     91#endif /* BEHAVIOUR_MAP_GO_DESTINATION_AVAILABLE */ 
  • C:/botneu/ct-Bot/include/bot-logic/available_behaviours.h

     
    99#define BEHAVIOUR_AVOID_BORDER_AVAILABLE        /*!< Abgruenden ausweichen vorhanden ?*/ 
    1010#define BEHAVIOUR_AVOID_COL_AVAILABLE   /*!< Hindernis ausweichen vorhanden ?*/ 
    1111//#define BEHAVIOUR_GOTO_AVAILABLE      /*!< goto vorhanden ?*/ 
    12 //#define BEHAVIOUR_GOTOXY_AVAILABLE    /*!< gotoxy vorhanden ?*/ 
     12#define BEHAVIOUR_GOTOXY_AVAILABLE      /*!< gotoxy vorhanden ?*/ 
    1313#define BEHAVIOUR_TURN_AVAILABLE        /*!< turn vorhanden ?*/ 
    1414 
    1515#define BEHAVIOUR_DRIVE_DISTANCE_AVAILABLE      /*!< strecke fahren vorhanden ?*/ 
    … …  
    1919#define BEHAVIOUR_SCAN_AVAILABLE        /*!< gegend scannen vorhanden ?*/ 
    2020#define BEHAVIOUR_SOLVE_MAZE_AVAILABLE  /*!< Wandfolger vorhanden ?*/ 
    2121//#define BEHAVIOUR_FOLLOW_LINE_AVAILABLE       /*!< Linienfolger vorhanden ?*/ 
     22#define BEHAVIOUR_MAP_GO_DESTINATION_AVAILABLE /*!< Fahren zu einem Ziel nach Pfadplanung*/ 
    2223 
    2324#define BEHAVIOUR_SERVO_AVAILABLE       /*!< Kontrollverhalten fuer die Servos */ 
    2425 
    … …  
    3738 */ 
    3839#ifndef MAP_AVAILABLE 
    3940        #undef BEHAVIOUR_SCAN_AVAILABLE 
     41        #undef BEHAVIOUR_MAP_GO_DESTINATION_AVAILABLE 
    4042#endif 
    4143 
    4244#ifdef BEHAVIOUR_GOTOXY_AVAILABLE 
    … …  
    100102 
    101103#include "bot-logic/behaviour_scan.h" 
    102104 
     105#include "bot-logic/behaviour_map_go_destination.h" 
    103106 
    104107#include "bot-logic/behaviour_solve_maze.h" 
    105108#include "bot-logic/behaviour_follow_line.h" 
  • C:/botneu/ct-Bot/include/bot-logic/bot-logik.h

     
    116116void deactivateBehaviour(BehaviourFunc function); 
    117117 
    118118/*! 
     119 * Rueckgabe von True, wenn das Verhalten gerade laeuft (aktiv ist) sonst False 
     120 * @param function Die Funktion, die das Verhalten realisiert. 
     121 * @return True wenn Verhalten aktiv sonst False 
     122 */ 
     123uint8 Behaviour_is_activated(BehaviourFunc function); 
     124 
     125/*! 
    119126 * Deaktiviert alle Verhalten bis auf Grundverhalten. Bei Verhaltensauswahl werden die Aktivitaeten vorher 
    120127 * in die Verhaltens-Auswahlvariable gesichert. 
    121128 */ 
    … …  
    158165 */ 
    159166void insert_behaviour_to_list(Behaviour_t **list, Behaviour_t *behave); 
    160167 
     168/*! Routine zum Registrieren einer Notfallfunktion, die beim Ausloesen eines Abgrundsensors 
     169 *  aufgerufen wird; hierdurch kann ein Verhalten vom Abgrund benachrichtigt werden und 
     170 *  entsprechend dem Verhalten reagieren 
     171 * @param fkt die zu registrierende Routine, welche aufzurufen ist 
     172 * @return Index, den die Routine im Array einnimmt, bei -1 ist alles voll 
     173 */ 
     174int8 register_emergency_proc(void* fkt); 
     175 
     176/*! Beim Ausloesen eines Abgrundes wird diese Routine am Ende des Notfall-Abgrundverhaltens angesprungen  
     177 *  und ruft alle registrierten Prozeduren der Reihe nach auf  
     178 */ 
     179void start_registered_emergency_procs(void);  
     180 
    161181/*!  
    162182 * @brief                       Erzeugt ein neues Verhalten  
    163183 * @param priority      Die Prioritaet 
  • C:/botneu/ct-Bot/include/bot-logic/behaviour_scan.h

     
    4242 */ 
    4343void bot_scan_behaviour(Behaviour_t *data); 
    4444 
     45 
     46/*! 
     47 *  Notfallhandler, ausgefuehrt bei Abgrunderkennung; muss registriert werden um 
     48 *  den erkannten Abgrund in die Map einzutragen 
     49 */ 
     50void border_in_map_handler(void);  
     51 
    4552/*!  
    4653 * Der Roboter faehrt einen Vollkreis und scannt dabei die Umgebung 
    4754 * @param Der aufrufer 
  • C:/botneu/ct-Bot/include/bot-local.h

     
    3737 
    3838#define DISTSENSOR_POS_FW       35      /*!< Abstand der Distanzsensoren von der Radachse (in fahrtrichtung)*/ 
    3939#define DISTSENSOR_POS_SW       32      /*!< Abstand der Distanzsensoren von der Mittelachse (in querrichtung)*/ 
     40#define DISTSENSOR_POS_B_SW   (DISTSENSOR_POS_SW + 5) /*!< Abgrundsensoren 5mm weiter aussen als Distsensoren*/ 
    4041 
    4142/* Parameter der Motorregelung */ 
    4243#define PID_Kp                          70                              /*!< PID-Parameter proportional */ 
    … …  
    105106 
    106107 
    107108/*! Konstante fuer das bot_follow_line_behaviour-Verhalten */ 
    108 #define LINE_SENSE                                      0x350   // Ab wann ist es Linie? (Fuer den Sim auf 350 setzen, helle Tischflaeche 50) 
     109#define LINE_SENSE                                      0x290   // Ab wann ist es Linie? (Fuer den Sim auf 350 setzen, helle Tischflaeche 50) 
    109110 
    110111 
    111112/* Konstanten fuer Verhaltensanzeige, Verhalten mit prio von bis sichtbar */ 
    112113#define PRIO_VISIBLE_MIN 3                      /*!< Prioritaet, die ein Verhalten mindestens haben muss, um angezeigt zu werden */ 
    113 #define PRIO_VISIBLE_MAX 154            /*!< Prioritaet, die ein Verhalten hoechstens haben darf, um angezeigt zu werden */ 
     114#define PRIO_VISIBLE_MAX 199            /*!< Prioritaet, die ein Verhalten hoechstens haben darf, um angezeigt zu werden */ 
    114115 
    115116 
    116117 
  • C:/botneu/ct-Bot/include/map.h

     
    5151        #define MAP_SECTION_POINTS 16   /*!< Kantenlaenge einer Section in Punkten ==> eine Section braucht MAP_SECTION_POINTS*MAP_SECTION_POINTS Bytes  */ 
    5252#endif 
    5353 
     54/*!  Suchkreis (Botdurchmesser) in Mapfelder je nach Aufloesung umgerechnet*/ 
     55#define MAP_RADIUS_FIELDS_GODEST          (BOT_DIAMETER * MAP_RESOLUTION / 100) /*!< Umkreisfelder fuer Pfadsuche */ 
     56/*! hier gleich Defines definieren, um kostspielige Berechnungen zu sparen */ 
     57#if MAP_RADIUS_FIELDS_GODEST / 2 < 1  
     58  #define MAP_RADIUS_FIELDS_GODEST_HALF 1  // sicherstellen dass nicht 0 auftritt 
     59#else 
     60  #define MAP_RADIUS_FIELDS_GODEST_HALF (MAP_RADIUS_FIELDS_GODEST / 2) 
     61#endif 
     62#define MAP_RADIUS_FIELDS_GODEST_HALF_QUAD (MAP_RADIUS_FIELDS_GODEST_HALF * MAP_RADIUS_FIELDS_GODEST_HALF) // halber Quadratradius 
     63 
     64#define MAPFIELD_IGNORE          20  /*!< negativer Schwellwert, bei dem Laut Map Hindernis gemeldet wird */ 
     65#define HAZPOT                   5   /*! hohe Hinderniswahrscheinlichkeit und trotzdem weiter beruecksichtigt */ 
     66#define MAP_ART_HAZARD           30  /*!< kuenstliches Hindernis in MAP fuer Pathplaning in lokalem Minimum */ 
     67 
     68 
    5469// Die folgenden Variablen/konstanten NICHT direkt benutzen, sondern die zugehoerigen Makros: get_map_min_x() und Co! 
    5570// Denn sonst erhaelt man Karten und nicht Weltkoordinaten! 
    5671#ifdef SHRINK_MAP_ONLINE 
    … …  
    123138 */ 
    124139float map_to_world(uint16 map_koord); 
    125140 
     141 
    126142/*! 
    127143 * PrÃŒft ob eine direkte Passage frei von Hindernissen ist 
     144 * @param  from_x Startort x Kartenkoordinaten 
     145 * @param  from_y Startort y Kartenkoordinaten 
     146 * @param  to_x Zielort x Kartenkoordinaten 
     147 * @param  to_y Zielort y Kartenkoordinaten 
     148 * @return 1 wenn alles frei ist 
     149 */ 
     150uint8 map_way_free_fields(uint16 from_x, uint16 from_y, uint16 to_x, uint16 to_y); 
     151/*! 
     152 * PrÃŒft ob eine direkte Passage frei von Hindernissen ist 
    128153 * @param  from_x Startort x Weltkoordinaten 
    129154 * @param  from_y Startort y Weltkoordinaten 
    130155 * @param  to_x Zielort x Weltkoordinaten 
    … …  
    134159int8 map_way_free(float from_x, float from_y, float to_x, float to_y); 
    135160 
    136161/*! 
     162 * Setzt den Wert eines Feldes auf den angegebenen Wert 
     163 * @param x x-Ordinate der Karte (nicht der Welt!!!) 
     164 * @param y y-Ordinate der Karte (nicht der Welt!!!) 
     165 * @param value neuer wert des Feldes (> 0 heisst frei, <0 heisst belegt 
     166 */ 
     167void map_set_field(uint16 x, uint16 y, int8 value); 
     168 
     169/*! 
     170 * markiert ein Feld als belegt -- drueckt den Feldwert etwas mehr in Richtung "belegt" 
     171 * @param x x-Ordinate der Karte (nicht der Welt!!!) 
     172 * @param y y-Ordinate der Karte (nicht der Welt!!!) 
     173 */ 
     174void map_update_occupied (uint16 x, uint16 y); 
     175 
     176/*! 
     177 * setzt ein Map-Feld auf einen Wert mit Umfeldaktualisierung; Hindernis wird mit halben Botradius 
     178 * eingetragen, da die Pfadpunkte im ganzen Umkreis liegen und nicht ueberschrieben werden duerfen; 
     179 * Abgrund/ Loch wird aber auch im ganzen Botradius eingetragen; bei geringer MCU-Aufloesung ohne Umfeld mit 
     180 * direktem Eintragen des Wertes auf xy; Umfeld wird dann in Richtung Hindernis gedrueckt  
     181 * @param xy  Map-Koordinaten 
     182 * @param val im Umkreis einzutragender Wert 
     183 */ 
     184void map_set_value_occupied (uint16 x, uint16 y, int8 val); 
     185 
     186 
     187/*! markiert die Mapkoordinaten als Loch zum entsprechenden Abgrundsensor 
     188 *  xy  bereits berechnete Koordinaten nach links rechts vom Mittelpunkt in Hoehe des Sensors 
     189 *  h   Blickrichtung bereits umgerechnet in Bogenmass 
     190 */ 
     191void update_map_sensor_hole(float x, float y, float h); 
     192 
     193        /*! gibt True zurueck wenn Map-Wert value innerhalb des Umkreises radius von xy liegt sonst False; 
     194         *  wird verwendet zum Check, ob sich ein Punkt (naechster Pfadpunkt, Loch) innerhalb eines bestimmten 
     195         *  Umkreises befindet; findet nur Verwendung bei hoeherer Aufloesung 
     196         *  @param xy Map-Koordinaten 
     197         *  @param radius Radius des Umfeldes 
     198         *  @param value Mapwert des Vergleiches 
     199         *  @return True wenn Wert value gefunden 
     200         */ 
     201        uint8 map_get_value_field_circle(uint16 x, uint16 y, uint8 radius, int8 value); 
     202 
     203/*! 
     204 * ermittelt ob der Wert val innerhalb des Umkreises mit Radius r von xy liegt; bei geringer MCU-Aufloesung direkter 
     205 * Vergleich mit xy 
     206 * @param xy  Map-Koordinaten 
     207 * @param radius Vergleichsradius (halber Suchkreis) 
     208 * @param val Vergleichswert 
     209 * @return True wenn Wert val gefunden sonst False 
     210 */ 
     211uint8 value_in_circle (uint16 x, uint16 y, uint8 radius, int8 val); 
     212  
     213/*! Routine ermittelt ab dem vom Mittelpunkt links/ rechts versetzten Punkt xp yp, in Blickrichtung 
     214 *  dist mm von den Abgrundsensoren voraus, die X-Mapkoordinate  
     215 *  verwendet zur Map-Lochmarkierung; kann aber allgemeingueltig verwendet werden um 
     216 *  Mapkoordinaten zu erhalten in einem bestimmten Abstand voraus 
     217 * @param xp yp Koord vom Mittelpunkt des bots verschoben 
     218 * @param h Blickrichtung 
     219 * @param dist Abstand voraus in mm 
     220 * @return berechnete X-Mapkoordinate  
     221 */ 
     222uint16 get_mapposx_dist(float xp, float yp, float h, uint16 dist);  
     223 
     224/*! Routine ermittelt ab dem vom Mittelpunkt links/ rechts versetzten Punkt xp yp, in Blickrichtung 
     225 *  dist mm von den Abgrundsensoren voraus, die Y-Mapkoordinate  
     226 *  verwendet zur Map-Lochmarkierung; kann aber allgemeingueltig verwendet werden um 
     227 *  Mapkoordinaten zu erhalten in einem bestimmten Abstand voraus 
     228 * @param xp yp Koord vom Mittelpunkt des bots verschoben 
     229 * @param h Blickrichtung 
     230 * @param dist Abstand voraus in mm 
     231 * @return berechnete X-Mapkoordinate  
     232 */  
     233uint16 get_mapposy_dist(float xp, float yp, float h, uint16 dist) ; 
     234 
     235/*! 
     236 * liefert den Durschnittswert um einen Punkt der Karte herum 
     237 * @param x x-Ordinate der Karte 
     238 * @param y y-Ordinate der Karte 
     239 * @return Wert des Durchschnitts um das Feld (>0 heisst frei, <0 heisst belegt 
     240 */ 
     241int8 map_get_average_fields (uint16 x, uint16 y, uint16 radius); 
     242  
     243/*! 
     244 * Check, ob die MAP-Koordinate xy mit destxy identisch ist (bei kleinen Aufloesungen) oder sich 
     245 * innerhalb des halben Radius-Umkreises befindet (hoehere Aufloesungen); z.B. verwendet um das 
     246 * Zielfahren mit gewisser Toleranz zu versehen 
     247 * @param x x-Ordinate der Karte (nicht der Welt!!!) 
     248 * @param y y-Ordinate der Karte (nicht der Welt!!!) 
     249 * @param destx Ziel-x-Ordinate der Karte (nicht der Welt!!!) 
     250 * @param desty Ziel-y-Ordinate der Karte (nicht der Welt!!!) 
     251 * @return True wenn xy im Umkreis vorhanden oder identisch ist 
     252 */ 
     253uint8 map_in_dest (uint16 x, uint16 y, uint16 destx, uint16 desty);  
     254  
     255/*! Loescht die Mapfelder, die in einem bestimtmen Wertebereich min_val max_val liegen, d.h. diese 
     256 *  werden auf 0 gesetzt  
     257 *  @param min_val minimaler Wert 
     258 *  @param max_val maximaler Wert 
     259 */  
     260void clear_map(int8 min_val, int8 max_val); 
     261 
     262/*! 
    137263 * Zeigt die Karte an 
    138264 */ 
    139265void print_map(void); 
  • C:/botneu/ct-Bot/map.c

     
    3131#include "mini-fat.h" 
    3232#include "mmc-vm.h" 
    3333 
     34 
    3435#ifdef MAP_AVAILABLE 
    3536#include <math.h> 
    3637#include <stdlib.h> 
    … …  
    6667#define MAP_STEP_FREE           2       /*!< Um diesen Wert wird ein Feld inkrementiert, wenn es als frei erkannt wird */ 
    6768#define MAP_STEP_OCCUPIED       10      /*!< Um diesen Wert wird ein Feld dekrementiert, wenn es als belegt erkannt wird */ 
    6869 
    69 #define MAP_RADIUS                      10      /*!< Umkreis einen Messpunkt, der als Besetzt aktualisiert wird (Streukreis) [mm]*/ 
     70#define MAP_RADIUS                      50      /*!< Umkreis einen Messpunkt, der als Besetzt aktualisiert wird (Streukreis) [mm]*/ 
    7071#define MAP_RADIUS_FIELDS       (MAP_RESOLUTION*MAP_RADIUS/1000)        /*!< Umkreis einen Messpunkt, der als Besetzt aktualisiert wird (Streukreis) [Felder]*/ 
    7172 
    7273#define MAP_PRINT_SCALE                         /*!< Soll das PGM eine Skala erhalten */ 
    7374#define MAP_SCALE       (MAP_RESOLUTION/2)      /*!< Alle wieviel Punkte kommt wein Skalen-Strich */ 
    7475 
     76#define FREE_BOUNDERY (125-MAP_STEP_FREE)   /*!< Frei Aktualisierung nur bis zu diesem Wert wegen Pfadplanung */ 
     77 
    7578#ifdef SHRINK_MAP_ONLINE 
    7679        uint16 map_min_x=MAP_SIZE*MAP_RESOLUTION/2; /*!< belegter Bereich der Karte [Kartenindex]: kleinste X-Koordinate */ 
    7780        uint16 map_max_x=MAP_SIZE*MAP_RESOLUTION/2; /*!< belegter Bereich der Karte [Kartenindex]: groesste X-Koordinate */ 
    … …  
    366369 * @param y y-Ordinate der Karte (nicht der Welt!!!) 
    367370 */ 
    368371void map_update_free (uint16 x, uint16 y) { 
    369   map_update_field(x,y,MAP_STEP_FREE); 
     372  if (map_get_field(x,y) < FREE_BOUNDERY)  // nicht groesser als Grenzwert 
     373    map_update_field(x,y,MAP_STEP_FREE); 
    370374} 
    371375 
    372376/*! 
    … …  
    446450                d=dist; 
    447451                 
    448452                 
    449          
    450         // Hinderniss, dass der Sensor sieht in Weltkoordinaten 
    451         float PH_x = x + (DISTSENSOR_POS_FW + d) * cos(h); 
    452         float PH_y = y + (DISTSENSOR_POS_FW + d) * sin(h); 
    453         // Hinderniss, dass der linke Sensor sieht in Kartenkoordinaten 
    454         uint16 PH_X = world_to_map(PH_x); 
    455         uint16 PH_Y = world_to_map(PH_y); 
    456          
     453        // liefert die Mapkoordinaten im Abstand dist vom Punkt xy 
     454        uint16 PH_X=get_mapposx_dist(x,y,h,dist); 
     455        uint16 PH_Y=get_mapposy_dist(x,y,h,dist); 
     456 
    457457        if ((dist > 80 ) && (dist <SENS_IR_INFINITE)) 
    458458                        map_update_occupied(PH_X,PH_Y); 
    459459         
    … …  
    569569          for (i=0; i<dX; ++i) { 
    570570                 for (w=-width; w<= width; w++) // wir mÃŒssen die ganze Breite des absuchen 
    571571//                       map_set_field(lX+i*sX, lY+w,-126); 
    572                      if (map_get_field(lX+i*sX, lY+w) <0) // ein hinderniss reicht fÃŒr den Abbruch 
    573                        return 0; 
     572                     if (map_get_field(lX+i*sX, lY+w) < -MAPFIELD_IGNORE) // ein hinderniss reicht fÃŒr den Abbruch 
     573                       return False; 
    574574                   
    575575            lh += dY; 
    576576            if (lh >= dX) { 
    … …  
    583583          for (i=0; i<dY; ++i) { 
    584584                 for (w=-width; w<= width; w++) // wir mÃŒssen die ganze Breite des absuchen 
    585585//                       map_set_field(lX+w, lY+i*sY,126); 
    586                          if (map_get_field (lX+w, lY+i*sY) <0 ) //ein hinderniss reicht fÃŒr den Abbruch 
    587                        return 0; 
     586                         if (map_get_field (lX+w, lY+i*sY) <-MAPFIELD_IGNORE ) //ein hinderniss reicht fÃŒr den Abbruch 
     587                       return False; 
    588588            lh += dX; 
    589589            if (lh >= dY) { 
    590590              lh -= dY; 
    … …  
    593593          } 
    594594        } 
    595595         
    596         return 1; 
     596        return True; 
    597597} 
    598598 
    599599 
    … …  
    603603 * @param  from_y Startort y Weltkoordinaten 
    604604 * @param  to_x Zielort x Weltkoordinaten 
    605605 * @param  to_y Zielort y Weltkoordinaten 
    606  * @return 1 wenn alles frei ist 
     606 * @return True wenn alles frei ist sonst False 
    607607 */ 
    608608int8 map_way_free(float from_x, float from_y, float to_x, float to_y){ 
    609609        return map_way_free_fields(world_to_map(from_x),world_to_map(from_y),world_to_map(to_x),world_to_map(to_y)); 
    610610}        
    611611 
     612        /*! gibt True zurueck wenn Map-Wert value innerhalb des Umkreises radius von xy liegt sonst False; 
     613         *  wird verwendet zum Check, ob sich ein Punkt (naechster Pfadpunkt, Loch) innerhalb eines bestimmten 
     614         *  Umkreises befindet; findet nur Verwendung bei hoeherer Aufloesung 
     615         *  @param xy Map-Koordinaten 
     616         *  @param radius Radius des Umfeldes 
     617         *  @param value Mapwert des Vergleiches 
     618         *  @return True wenn Wert value gefunden 
     619         */ 
     620        uint8 map_get_value_field_circle(uint16 x, uint16 y, uint8 radius, int8 value) { 
     621        int16 dX,dY; 
     622        uint16 h=radius*radius; 
     623                for(dX = -radius; dX <= radius; dX++){ 
     624              for(dY = -radius; dY <= radius; dY++) { 
     625                   if(dX*dX + dY*dY <= h)                           // Vergleich nur innerhalb des Umkreises 
     626                         if (map_get_field(x + dX, y + dY)==value)  // Mapwert hat Vergleichswert ? 
     627                                return True;                                // dann Schluss mit True 
     628              } 
     629                } 
     630                return False;                                       // kein Feldwert ist identisch im Umkreis 
     631        } 
     632         
     633/*! 
     634 * ermittelt ob der Wert val innerhalb des Umkreises mit Radius r von xy liegt; bei geringer MCU-Aufloesung direkter 
     635 * Vergleich mit xy 
     636 * @param xy  Map-Koordinaten 
     637 * @param radius Vergleichsradius (halber Suchkreis) 
     638 * @param val Vergleichswert 
     639 * @return True wenn Wert val gefunden 
     640 */ 
     641uint8 value_in_circle (uint16 x, uint16 y, uint8 radius, int8 val) { 
     642 
     643  #if MAP_RADIUS_FIELDS_GODEST > 0 
     644          uint8 r; 
     645      for (r=1; r<=radius; r++){          // Botradius 
     646                        if (map_get_value_field_circle(x,y,r,val))      // Schluss sobald Wert erkannt wird 
     647                          return True; 
     648          } 
     649          return False;                                         // Wert nicht vorhanden 
     650  #else 
     651        return map_get_field(x,y)==val;                             // niedrige Aufloesung, direkter Feldvergleich 
     652  #endif 
     653} 
     654 
     655/*! 
     656 * Check, ob die MAP-Koordinate xy mit destxy identisch ist (bei kleinen Aufloesungen) oder sich 
     657 * innerhalb des halben Radius-Umkreises befindet (hoehere Aufloesungen); z.B. verwendet um das 
     658 * Zielfahren mit gewisser Toleranz zu versehen 
     659 * @param x x-Ordinate der Karte (nicht der Welt!!!) 
     660 * @param y y-Ordinate der Karte (nicht der Welt!!!) 
     661 * @param destx Ziel-x-Ordinate der Karte (nicht der Welt!!!) 
     662 * @param desty Ziel-y-Ordinate der Karte (nicht der Welt!!!) 
     663 * @return True wenn xy im Umkreis vorhanden oder identisch ist 
     664 */ 
     665uint8 map_in_dest (uint16 x, uint16 y, uint16 destx, uint16 desty) { 
     666  // MAP_RADIUS_FIELDS_GODEST sind die Mapfelder im Botdurchmesser fuer Suchkreis 
     667  #if MAP_RADIUS_FIELDS_GODEST > 1 // gilt nur fuer hoehere Aufloesungen, sonst direkter Vergleich 
     668          //Distanzen in Mapfelder 
     669          int16 distx=destx-x; 
     670          int16 disty=desty-y; 
     671          // Radius, also Abstand ermitteln; Wurzel ziehen spare ich mir 
     672          return distx*distx + disty*disty <= MAP_RADIUS_FIELDS_GODEST_HALF_QUAD; 
     673 
     674  #else 
     675    //bei geringer Aufloesung (MCU) direkt mit Zielkoords vergleichen 
     676        return  (x==destx && y==desty); 
     677  #endif 
     678} 
     679 
     680#if MAP_RADIUS_FIELDS_GODEST > 0 
     681 
     682    /*! Map-Umfeldaktualisierung mit einem bestimmten Wert ab einer Position xy mit Radius r bei 
     683     *  hoeherer Aufloesung; z.B. verwendet zur Lochmarkierung in einem Umkreis, Hinderniswahrscheinlichkeit 
     684     *  @param xy Map-Koordinaten 
     685     *  @param radius Radius des Umfeldes 
     686     *  @param value Mapwert; nur eingetragen wenn aktueller Mapwert groesser value ist 
     687     */ 
     688        void map_set_value_field_circle(uint16 x, uint16 y, int8 radius, int8 value) { 
     689                int16 dX,dY; 
     690            uint16 h=radius*radius; 
     691                for(dX = -radius; dX <= radius; dX++){ 
     692              for(dY = -radius; dY <= radius; dY++) { 
     693                   if(dX*dX + dY*dY <= h)                           // nur innerhalb des Umkreises 
     694                         if (map_get_field(x + dX, y + dY)>value)   // Mapwert hoeher Richtung frei ? 
     695                                  map_set_field (x + dX, y + dY,value); // dann Wert eintragen 
     696              } 
     697                } 
     698        } 
     699 
     700#endif  // hoehere Aufloesung 
     701 
     702 
     703 
     704/*! 
     705 * setzt ein Map-Feld auf einen Wert mit Umfeldaktualisierung; Hindernis wird mit halben Botradius 
     706 * eingetragen, da die Pfadpunkte im ganzen Umkreis liegen und nicht ueberschrieben werden duerfen; 
     707 * Abgrund/ Loch wird aber auch im ganzen Botradius eingetragen; bei geringer MCU-Aufloesung ohne Umfeld mit 
     708 * direktem Eintragen des Wertes auf xy; Umfeld wird dann in Richtung Hindernis gedrueckt 
     709 * @param xy  Map-Koordinaten 
     710 * @param val im Umkreis einzutragender Wert 
     711 */ 
     712void map_set_value_occupied (uint16 x, uint16 y, int8 val) { 
     713 
     714  #if MAP_RADIUS_FIELDS_GODEST > 0              // bei hoeherer Aufloesung 
     715          uint8 r; 
     716          uint8 maxr; 
     717 
     718          if (val==-128) 
     719              maxr=MAP_RADIUS_FIELDS_GODEST;        // Loch wird mit ganzem Botradius eingetragen 
     720            else 
     721              maxr=MAP_RADIUS_FIELDS           ;   // im Normalfall halber Botradius 
     722 
     723          for (r=1; r<=maxr; r++)                   // in Map mit dem Radius um xy eintragen 
     724                        map_set_value_field_circle(x,y,r,val); 
     725 
     726  #else                                         // bei geringer MCU-Aufloesung direkt auf xy 
     727        if (map_get_field(x,y)>val)                 // nur Eintragen wenn aktueller Wert freier ist 
     728                  map_set_field(x,y,val);               // damit auch -128 Lochwert eingetragen wird 
     729 
     730  #endif 
     731 
     732  // Punkt xy nun in Richtung Hindernis druecken mit Umfeld; falls Wert fuer kuenstl. Hindernis erreicht 
     733  // muss Wert aber so bleiben, damit diese Mapfelder bei Neuberechnung der Map-Potenziale erkannt und wieder 
     734  // freigegeben werden koennen zur Neuberuecksichtigung 
     735  if (val != -MAP_ART_HAZARD)  
     736       map_update_occupied(x,y); 
     737} 
     738 
     739 
     740/*! Loescht die Mapfelder, die in einem bestimtmen Wertebereich min_val max_val liegen, d.h. diese 
     741 *  werden auf 0 gesetzt  
     742 *  @param min_val minimaler Wert 
     743 *  @param max_val maximaler Wert 
     744 */  
     745void clear_map(int8 min_val, int8 max_val){ 
     746                 
     747                uint16 x,y; 
     748                int8 tmp; 
     749         // Mapfelder durchlaufen 
     750                 for (y=map_min_y; y<= map_max_y; y++) { 
     751                         
     752                          for (x=map_max_x; x>= map_min_x; x--) { 
     753                
     754                                tmp=map_get_field(x,y);                          
     755 
     756                                if (tmp>=min_val && tmp<= max_val) // alles zwischen Intervall auf 0 setzen 
     757                                    map_set_field(x,y,0);  
     758                        }                   
     759                } 
     760        }  
     761 
     762 
     763/*! Routine ermittelt ab dem vom Mittelpunkt links/ rechts versetzten Punkt xp yp, in Blickrichtung 
     764 *  dist mm von den Abgrundsensoren voraus, die Mapkoordinaten XY 
     765 *  verwendet zur Map-Lochmarkierung; kann aber allgemeingueltig verwendet werden um 
     766 *  Mapkoordinaten zu erhalten in einem bestimmten Abstand voraus 
     767 * @param xp yp Koord vom Mittelpunkt des bots verschoben 
     768 * @param h Blickrichtung 
     769 * @param X Y berechnete Mapkoordinate im Abstand dist ab Hoehe Abstandssensoren 
     770 * @param dist Abstand voraus in mm 
     771 */ 
     772uint16 get_mapposx_dist(float xp, float yp, float h, uint16 dist) { 
     773 
     774        // Hinderniss auf X-Koord, dass der Sensor sieht in Weltkoordinaten 
     775        float PH_x = xp + (DISTSENSOR_POS_FW + dist) * cos(h); 
     776 
     777        // Hinderniss, welches der Sensor sieht in, umgerechnet in Karten-Map-Koordinaten 
     778        return world_to_map(PH_x); 
     779} 
     780 
     781uint16 get_mapposy_dist(float xp, float yp, float h, uint16 dist) { 
     782 
     783        // Hinderniss auf Y-Koord, dass der Sensor sieht in Weltkoordinaten 
     784        float PH_y = yp + (DISTSENSOR_POS_FW + dist) * sin(h); 
     785 
     786        // Hinderniss, welches der Sensor sieht in, umgerechnet in Karten-Map-Koordinaten 
     787        return  world_to_map(PH_y); 
     788} 
     789 
     790/*! markiert die Mapkoordinaten als Loch zum entsprechenden Abgrundsensor 
     791 *  xy  bereits berechnete Koordinaten nach links rechts vom Mittelpunkt in Hoehe des Sensors 
     792 *  h   Blickrichtung bereits umgerechnet in Bogenmass 
     793 */ 
     794void update_map_sensor_hole(float x, float y, float h){ 
     795 
     796 
     797        uint16 PH_X=0; 
     798        uint16 PH_Y=0; 
     799 
     800    // 0 mm voraus Loch ab Abgrundsensoren 
     801        PH_X=get_mapposx_dist(x,y,h,0); 
     802        PH_Y=get_mapposy_dist(x,y,h,0); 
     803 
     804        // nur wenn noch nicht als Loch gekennzeichnet auf Umgebungskreis Loch vermerken 
     805        if (map_get_field(PH_X,PH_Y) > -128) 
     806                        map_set_value_occupied(PH_X,PH_Y,-128); 
     807 
     808 
     809} 
     810 
    612811#ifdef PC 
    613812        /*! 
    614813         * Schreibt einbe Karte in eine PGM-Datei 
  • C:/botneu/ct-Bot/pc/tcp.c

     
    188188        uint8 * ptr = data; 
    189189         
    190190        if ((sendBufferPtr + length) > sizeof(sendBuffer)){ 
    191                 printf("%s() %s:%u: sendBuffer filled with %u/%lu Bytes, another %u bytes pending. Full! Aborting copy!\n",__FUNCTION__,__FILE__, __LINE__,sendBufferPtr,sizeof(sendBuffer),length); 
     191                //printf("%s() %s:%u: sendBuffer filled with %u/%lu Bytes, another %u bytes pending. Full! Aborting copy!\n",__FUNCTION__,__FILE__, __LINE__,sendBufferPtr,sizeof(sendBuffer),length); 
    192192 
    193193                printf("  ==> Trying to recover by calling flushSendBuffer()\n"); 
    194194                flushSendBuffer();  
  • C:/botneu/ct-Bot/Changelog.txt

     
    11CHANGELOG fuer c't-Bot 
    22====================== 
     32007-05-19 Frank Menzel  [Menzelfr@gmx.net]: Pfadplanungsverhalten map_go_destination und informieren ÃŒber Abgrund via Registrierung 
     4 
    352007-05-13 Timo Sandmann [mail@timosandmann.de]: Bugfix in motor-low.h, vorlaeufiger Workaround fuer solve_maze() und Kommentar in mmc-low.S korrigiert 
    46 
    572007-05-09 Benjamin Benz [bbe@heise.de]: Bugfix in map.c 
  • C:/botneu/ct-Bot/.cdtbuild

     
    1010<option id="gnu.c.compiler.option.include.paths.387475860" superClass="gnu.c.compiler.option.include.paths" valueType="includePath"> 
    1111<listOptionValue builtIn="false" value="&quot;${ProjDirPath}&quot;"/> 
    1212<listOptionValue builtIn="false" value="&quot;${ProjDirPath}/include&quot;"/> 
    13 <listOptionValue builtIn="false" value="&quot;C:\Programme\MinGW\include&quot;"/> 
    14 <listOptionValue builtIn="false" value="&quot;C:\Programme\pthreads\pthreads.2&quot;"/> 
     13<listOptionValue builtIn="false" value="&quot;C:\MinGW\include&quot;"/> 
     14<listOptionValue builtIn="false" value="&quot;C:\pthreads\pthreads.2&quot;"/> 
    1515</option> 
    1616<option id="gnu.c.compiler.option.preprocessor.def.symbols.1823712582" superClass="gnu.c.compiler.option.preprocessor.def.symbols" valueType="definedSymbols"> 
    1717<listOptionValue builtIn="false" value="PC"/> 
    … …  
    2727<listOptionValue builtIn="false" value="pthreadGC2"/> 
    2828</option> 
    2929<option id="gnu.c.link.option.paths.142594843" superClass="gnu.c.link.option.paths" valueType="stringList"> 
    30 <listOptionValue builtIn="false" value="&quot;C:\Programme\pthreads\Pre-built.2\lib&quot;"/> 
    31 <listOptionValue builtIn="false" value="&quot;C:\Programme\MinGW\lib&quot;"/> 
     30<listOptionValue builtIn="false" value="&quot;C:\pthreads\Pre-built.2\lib&quot;"/> 
     31<listOptionValue builtIn="false" value="&quot;C:\MinGW\lib&quot;"/> 
    3232</option> 
    3333<option id="gnu.c.link.option.noshared.1812776571" superClass="gnu.c.link.option.noshared" value="true" valueType="boolean"/> 
    3434</tool> 
  • C:/botneu/ct-Bot/ui/gui.c

     
    121121        #ifdef RAM_DISPLAY_AVAILABLE 
    122122                register_screen(&ram_display); 
    123123        #endif 
     124        // auch nur wenn Verhalten aktiv ist 
     125        #ifdef BEHAVIOUR_MAP_GO_DESTINATION_AVAILABLE 
     126         #ifdef DISPLAY_MAP_GO_DESTINATION 
     127                register_screen(&mapgo_display); 
     128         #endif 
     129        #endif 
    124130} 
    125131 
    126132#endif  // DISPLAY_AVAILABLE 
  • C:/botneu/ct-Bot/ui/available_screens.h

     
    3535 
    3636#define SENSOR_DISPLAY_AVAILABLE                /*!< zeigt die Sensordaten an */ 
    3737//#define DISPLAY_REGELUNG_AVAILABLE            /*!< Gibt Debug-Infos der Motorregelung aus */ 
    38 //#define DISPLAY_BEHAVIOUR_AVAILABLE           /*!< zeigt Verhalten an */ 
     38#define DISPLAY_BEHAVIOUR_AVAILABLE             /*!< zeigt Verhalten an */ 
    3939//#define MISC_DISPLAY_AVAILABLE                        /*!< aehm ja, der Rest irgendwie... */ 
    4040#define DISPLAY_ODOMETRIC_INFO                  /*!< zeigt Positions- und Geschwindigkeitsdaten an */ 
    4141#define DISPLAY_MMC_INFO                                /*!< Zeigt die Daten der MMC-Karte an */ 
    4242//#define RESET_INFO_DISPLAY_AVAILABLE  /*!< Zeigt Informationen ueber Resets an */ 
    4343#define RAM_DISPLAY_AVAILABLE                   /*!< Ausgabe des freien RAMs */ 
    4444 
     45#define DISPLAY_MAP_GO_DESTINATION      /*!< Steuerung Map-Verhalten auf diesem Screen */ 
     46 
    4547#ifndef SPEED_CONTROL_AVAILABLE 
    4648        #undef DISPLAY_REGELUNG_AVAILABLE 
    4749#endif 
  • C:/botneu/ct-Bot/.settings/org.eclipse.cdt.managedbuilder.core.prefs

     
    1 #Thu Mar 29 15:23:55 CEST 2007 
    2 cdt.managedbuild.config.gnu.exe.debug.1197043799/internalBuilder/enabled=false 
    3 cdt.managedbuild.config.gnu.exe.debug.1197043799/internalBuilder/ignoreErr=true 
    4 eclipse.preferences.version=1 
    5 environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.exe.debug.1077176217=<?xml version\="1.0" encoding\="UTF-8"?>\n<environment>\n<variable name\="CPATH" operation\="remove"/>\n<variable name\="C_INCLUDE_PATH" operation\="remove"/>\n</environment>\n 
    6 environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.exe.debug.1197043799=<?xml version\="1.0" encoding\="UTF-8"?>\n<environment>\n<variable name\="CPATH" operation\="remove"/>\n<variable name\="C_INCLUDE_PATH" operation\="remove"/>\n</environment>\n 
    7 environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.exe.debug.1197043799.2016949464=<?xml version\="1.0" encoding\="UTF-8"?>\n<environment>\n<variable name\="CPATH" operation\="remove"/>\n<variable name\="C_INCLUDE_PATH" operation\="remove"/>\n</environment>\n 
    8 environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.exe.debug.1077176217=<?xml version\="1.0" encoding\="UTF-8"?>\n<environment>\n<variable name\="LIBRARY_PATH" operation\="remove"/>\n</environment>\n 
    9 environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.exe.debug.1197043799=<?xml version\="1.0" encoding\="UTF-8"?>\n<environment>\n<variable name\="LIBRARY_PATH" operation\="remove"/>\n</environment>\n 
    10 environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.exe.debug.1197043799.2016949464=<?xml version\="1.0" encoding\="UTF-8"?>\n<environment>\n<variable name\="LIBRARY_PATH" operation\="remove"/>\n</environment>\n 
    11 environment/project=<?xml version\="1.0" encoding\="UTF-8"?>\n<environment/>\n 
    12 environment/project/cdt.managedbuild.config.gnu.exe.debug.1077176217=<?xml version\="1.0" encoding\="UTF-8"?>\n<environment/>\n 
    13 environment/project/cdt.managedbuild.config.gnu.exe.debug.1197043799=<?xml version\="1.0" encoding\="UTF-8"?>\n<environment>\n<variable delimiter\="\:" name\="PATH" operation\="append" value\="/usr/local/avr/bin"/>\n</environment>\n 
     1#Thu May 17 21:04:18 CEST 2007 
     2cdt.managedbuild.config.gnu.exe.debug.1077176217/internalBuilder/enabled=false 
     3cdt.managedbuild.config.gnu.exe.debug.1077176217/internalBuilder/ignoreErr=true 
     4cdt.managedbuild.config.gnu.exe.debug.1197043799/internalBuilder/enabled=false 
     5cdt.managedbuild.config.gnu.exe.debug.1197043799/internalBuilder/ignoreErr=true 
     6eclipse.preferences.version=1 
     7environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.exe.debug.1077176217=<?xml version\="1.0" encoding\="UTF-8"?>\n<environment>\n<variable name\="CPATH" operation\="remove"/>\n<variable name\="C_INCLUDE_PATH" operation\="remove"/>\n</environment>\n 
     8environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.exe.debug.1197043799=<?xml version\="1.0" encoding\="UTF-8"?>\n<environment>\n<variable name\="CPATH" operation\="remove"/>\n<variable name\="C_INCLUDE_PATH" operation\="remove"/>\n</environment>\n 
     9environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.exe.debug.1197043799.2016949464=<?xml version\="1.0" encoding\="UTF-8"?>\n<environment>\n<variable name\="CPATH" operation\="remove"/>\n<variable name\="C_INCLUDE_PATH" operation\="remove"/>\n</environment>\n 
     10environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.exe.debug.1077176217=<?xml version\="1.0" encoding\="UTF-8"?>\n<environment>\n<variable name\="LIBRARY_PATH" operation\="remove"/>\n</environment>\n 
     11environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.exe.debug.1197043799=<?xml version\="1.0" encoding\="UTF-8"?>\n<environment>\n<variable name\="LIBRARY_PATH" operation\="remove"/>\n</environment>\n 
     12environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.exe.debug.1197043799.2016949464=<?xml version\="1.0" encoding\="UTF-8"?>\n<environment>\n<variable name\="LIBRARY_PATH" operation\="remove"/>\n</environment>\n 
     13environment/project=<?xml version\="1.0" encoding\="UTF-8"?>\r\n<environment/>\r\n 
     14environment/project/cdt.managedbuild.config.gnu.exe.debug.1077176217=<?xml version\="1.0" encoding\="UTF-8"?>\r\n<environment/>\r\n 
     15environment/project/cdt.managedbuild.config.gnu.exe.debug.1197043799=<?xml version\="1.0" encoding\="UTF-8"?>\n<environment>\n<variable delimiter\="\:" name\="PATH" operation\="append" value\="/usr/local/avr/bin"/>\n</environment>\n 
  • C:/botneu/ct-Bot/ct-Bot.h

     
    3131/************************************************************ 
    3232* Module switches, to make code smaller if features are not needed 
    3333************************************************************/ 
    34 //#define LOG_CTSIM_AVAILABLE           /*!< Logging zum ct-Sim (PC und MCU) */ 
     34#define LOG_CTSIM_AVAILABLE             /*!< Logging zum ct-Sim (PC und MCU) */ 
    3535//#define LOG_DISPLAY_AVAILABLE         /*!< Logging ueber das LCD-Display (PC und MCU) */ 
    3636//#define LOG_UART_AVAILABLE            /*!< Logging ueber UART (NUR fuer MCU) */ 
    3737//#define LOG_STDOUT_AVAILABLE          /*!< Logging auf die Konsole (NUR fuer PC) */ 
    … …  
    6969 
    7070#define BEHAVIOUR_AVAILABLE /*!< Nur wenn dieser Parameter gesetzt ist, exisitiert das Verhaltenssystem */ 
    7171 
    72 //#define MAP_AVAILABLE /*!< Aktiviere die Kartographie */ 
     72#define MAP_AVAILABLE /*!< Aktiviere die Kartographie */ 
    7373 
    7474//#define SPEED_CONTROL_AVAILABLE /*!< Aktiviert die Motorregelung */ 
    7575//#define ADJUST_PID_PARAMS             /*!< macht PID-Paramter zur Laufzeit per FB einstellbar */ 

Download in other formats:

  • Original Format

Trac Powered

Powered by Trac 0.11.7
By Edgewall Software.

http://www.ctmagazin.de/
http://www.ctmagazin.de/projekte/

  • Datenschutzhinweis
  • Impressum
  • Kritik, Anregungen bitte an c't-WWW
  • Mediadaten
  • Copyright © 2011 Heise Zeitschriften Verlag
  • International: The H, The H Security, The H Open Source