Ich hab mit ein Bitfield Array erstellt, mit dem ich die Karte vom Grundstück abbilde:
1. Feld 3 Bit: Zähler für Felder in denen der Roboter schon war
2. Feld 4 Bit: Zähler für temporäre Hindernisse: Wenn der Roboter selbst ein Hinderniss erkennt, soll hier der Wert hochgezählt werden
3. Feld 1 Bit: Bit setzen wenn das Feld blockiert ist, zB Haus, ist fix in Karte_init vorgegeben.
Der Roboter ist schon seit letztem Jahr mit der Karte unterwegs, bisher wurden nur Felder 1 und 3 verwendet.
Jetzt wollte ich auch Feld 2 verwenden, um damit eine teilweise selbstlernende Karte umzusetzen.
Wenn aber Werte in Feld 2 geschrieben werden (Funktion Karte_Temp_schreiben), wird auch zumindest Feld 3 verändert. Ob auch Feld 1 zufällig verändert wird kann ich nicht bestätigen da immer sehr viele Felder betroffen sind. Zumindest ist mir nicht aufgefallen dass diese auf einmal niedrigere Werte hätten, also sollte es passen.
Es werden oft gleich ganze Spalten (y) von Feld 3 verändert. Hatte zuerst das EEPROM in Verdacht, aber seitdem ich die Funktion Karte_Temp_schreiben deaktiviert habe, passt die Karte wieder. (Übertrage die Daten vom EEPROM ins Excel für eine übersichtliche Ansicht der Karte)
Damit es ja keine Fehler gibt wie über die Array Grenzen hinaus schreiben oder lesen, wird das Array nur über die unten gezeigten Funktionen beschrieben/gelesen.
Unten der Code, wo liegt der Fehler?
Mit falschen Werten in Feld 3 funktioniert die Navigation nicht mehr.
LG!
allgemeine defines der Karte:
Code:
#define grund_x 46 // Anzahl Felder W-O
#define grund_y 84 //Anzahl Felder S-O
#define kartenfeld 50 // Größe eines Kartenfeldes in 1cm Einheit
#define zielbereich 80 // auf 80*x cm genau soll Ziel erreicht werden
#define besetzt 1
#define pos_x_max (grund_x*kartenfeld-1)
#define pos_y_max (grund_y*kartenfeld-1)
// für A*
#define max_x_karte (grund_x/2-2)
#define max_y_karte (grund_y/2-2)
#define max_x (max_x_karte-1)
#define max_y (max_y_karte-1)
#define kartenfeld_navi (kartenfeld*2)
karte.h:
Code:
extern unsigned char Karte_lesen(unsigned char x, unsigned char y); /* liest 1x gemaehtes Felder */
extern unsigned char Karte_lesen_navi(unsigned char x, unsigned char y); /* liest 4x fixbesetze Felder */
extern unsigned char Karte_lesen_naviII(unsigned char x, unsigned char y);/* liest 1x fixbesetze Felder */
extern void Karte_schreiben(unsigned char x, unsigned char y, unsigned char wert); /* schreibt 1x gemaehtes Felder */
extern unsigned char Karte_Temp_lesen(unsigned char x, unsigned char y); /* liest 1x temp Felder */
extern void Karte_Temp_schreiben(unsigned char x, unsigned char y, unsigned char wert); /* schreibt 1x temp Felder */
extern void Karte_init(void); // besetzte Felder der Karte festlegen
extern void Karte_schreiben_init(unsigned char x, unsigned char y); /* schreibt 1x besetzt Felder */
extern void Karte_loeschen(void); // komplett löschen
Karte.c:
Code:
#include <stdlib.h>
#include "karte.h"
#include <allgemeine_defines.h>
static struct
{
unsigned char gemaeht:3;
unsigned char temp_besetzt:4;
unsigned char fixbesetzt:1;
} Karte[grund_x+1][grund_y+1];
/*+++++++++++++++ Karte bearbeiten ++++++++++++++++++++++*/
inline unsigned char Karte_lesen(unsigned char x, unsigned char y)
{
unsigned char wert;
if ((x<grund_x)&&(y<grund_y))
{
if (Karte[x][y].fixbesetzt!=0) wert=100; // beim überprüfen auf fertig gemäht müssen die besetzten Felder mitgezählt werden.
else wert=Karte[x][y].gemaeht;
}
else wert=255;
return(wert);
}
// 4 Felder auf 1x lesen, Navi verwendet Karte mit nur 1/4 Auflösung!!!!
inline unsigned char Karte_lesen_navi(unsigned char x, unsigned char y)
{
unsigned char wert;
wert=0;
if (((x*2+1)<grund_x)&&((y*2+1)<grund_y))
{
wert=Karte[x*2][y*2].fixbesetzt;
wert=wert+Karte[x*2][y*2+1].fixbesetzt;
wert=wert+Karte[x*2+1][y*2].fixbesetzt;
wert=wert+Karte[x*2+1][y*2+1].fixbesetzt;
}
else wert=255;
return(wert);
}
inline unsigned char Karte_lesen_naviII(unsigned char x, unsigned char y)
{
unsigned char wert;
wert=0;
if ((x<grund_x)&&(y<grund_y))
{
wert=Karte[x][y].fixbesetzt;
}
else wert=1;
return(wert);
}
inline void Karte_schreiben(unsigned char x, unsigned char y, unsigned char wert)
{
if ((x<grund_x)&&(y<grund_y))
{
if(Karte[x][y].fixbesetzt==0)
{
if (wert==0)
{
if (Karte[x][y].gemaeht<7) Karte[x][y].gemaeht++;
}
else
{if (wert>7) wert=7;
Karte[x][y].gemaeht=wert;
}
}
}
}
inline unsigned char Karte_Temp_lesen(unsigned char x, unsigned char y)
{
unsigned char wert;
if ((x<grund_x)&&(y<grund_y))
{
wert=Karte[x][y].temp_besetzt;
}
else wert=0;
return(wert);
}
inline void Karte_Temp_schreiben(unsigned char x, unsigned char y, unsigned char wert)
{
if ((x<grund_x)&&(y<grund_y))
{
if (wert==0)
{
if (Karte[x][y].temp_besetzt<=1) Karte[x][y].temp_besetzt=9;
if (Karte[x][y].temp_besetzt<13) Karte[x][y].temp_besetzt++;
}
else
{
if (wert>14) wert=14;
Karte[x][y].temp_besetzt=wert;
}
}
}
void Karte_schreiben_init(unsigned char x, unsigned char y)
{
if ((x<grund_x)&&(y<grund_y))
{
Karte[x][y].fixbesetzt=1;
}
}
/*++++++++++++++++++ Karte init +++++++++++++++++++++++++++*/
void Karte_init(void) // besetzte Felder der Karte festlegen
{unsigned char x,y;
// Tor
Karte_schreiben_init(14,0);Karte_schreiben_init(16,0);Karte_schreiben_init(18,0);
Karte_schreiben_init(15,0);Karte_schreiben_init(17,0);Karte_schreiben_init(19,0);
// Kompost
// Karte_schreiben_init(4,82,besetzt);Karte_schreiben_init(5,82,besetzt);Karte_schreiben_init(4,81,besetzt);
for (x=2;x<=3;x++)
{for (y=77;y<=79;y++)
Karte_schreiben_init(x,y);
}
// Ecke Terasse Garagenmauer schwer erreichbar
// Karte_schreiben_init(17,29,besetzt);
// Zaun hinten
for (x=26;x<grund_x;x++) // Zaun hinten schief
Karte_schreiben_init(x,83);
for (x=28;x<grund_x;x++) // Büsche
Karte_schreiben_init(x,82);
for (x=28;x<grund_x;x++) // Büsche
Karte_schreiben_init(x,81);
for (y=72;y<grund_y;y++) // Büsche
Karte_schreiben_init(44,y);
// Zaun links
for (y=22;y<grund_y;y++)
Karte_schreiben_init(0,y);
for (y=64;y<grund_y;y++)
Karte_schreiben_init(1,y);
// Zaun rechts
for (y=46;y<grund_y;y++)
Karte_schreiben_init(45,y);
for (x=28;x<grund_x;x++)
Karte_schreiben_init(x,0);
//Haus
for (x=14;x<=38;x++)
{for (y=38;y<=60;y++)
Karte_schreiben_init(x,y);
}
// Garage
for (x=8;x<=16;x++)
{for (y=32;y<=47;y++)
Karte_schreiben_init(x,y);
}
for (x=10;x<=16;x++) // //schwer erreichbar ==> nicht als leeres Feld suchen und anfahren lassen, aber auch nicht für Zufallsfahrt blockieren
{for (y=18;y<=31;y++)
Karte_schreiben(x,y,3);
}
for (y=18;y<=32;y++) // Garagenmauern, notwendig für A*
{ Karte_schreiben_init(9,y);
Karte_schreiben_init(16,y);
}
// Terasse
for (x=16;x<=28;x++)
{for (y=30;y<=37;y++)
Karte_schreiben_init(x,y);
}
//Spielhaus
for (x=39;x<=42;x++)
{for (y=8;y<=12;y++)
Karte_schreiben_init(x,y);
}
//Sandkiste
for (x=40;x<=42;x++)
{for (y=15;y<=18;y++)
Karte_schreiben_init(x,y);
}
}
void Karte_loeschen(void)
{
unsigned char x,y;
for (x=0;x<grund_x;x++) // Karte komplett löschen
{
for (y=0;y<grund_y;y++)
{
Karte[x][y].fixbesetzt=0;
Karte[x][y].temp_besetzt=1;
Karte[x][y].gemaeht=1;
}
}
}
Lesezeichen