PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : "Hindernisfahrt"



timmy19
28.12.2013, 14:12
Hallo ich bin neu hier.

Nun zu meinem Problem:

Ich muss für die Schule ein Programm schreiben, bei der ein Roboter Hindernisse UMfahren muss. Leider komm ich nicht derzeit noch nicht soweit, da ich ein Problem habe. Der Roboter erkennt das Hindernis und fährt links. Nach einer Weile sollte er wieder nach rechts fahren, was er aber konsequent nicht tut. Wollte das eigentlich mit einem Infrarotsensor regeln(es gibt einen bestimmten Boden vorgegeben), bekomm das aber nicht hin. Habe was dazu geschrieben, aber irgendwie reagiert der Roboter nicht darauf. Vielleicht könnt ihr mir sagen was der Fehler ist. Das ist aber nur mein erstes Problem.

Das zweite:

Nachdem der Roboter nach rechts gefahren ist, fährt er ja auf das nächste Hindernis zu. Nun sollte er, wenn er das Hindernis erkennt, aber nicht nach links, sondern jetzt nach rechts fahren. Habe es versucht mit einer Variable x dies zu regeln, also dass beim ersten Hindernis X=1, beim zweiten X=-1 und so weiter und so fort. Das klappt aber nicht, dann fährt der Roboter immer nur vor und zurück.


#include "qfixMiniBoard.h"
#include "qfixLCD.h"


const int SENSOR3 = 3;
int SENSOR1 = 1;
int SENSOR2 = 2;
int SENSOR = 0;

MiniBoard robot;
LCD lcd;


int main(){
{
int i=0;
int mitt = 0;
int x = 1;

while(1){
int i = robot.analog(1) ;
int mitt= robot.analog(3);


if (i > 75){
robot.motors(250,250); //geradeaus
}
else{
robot.motors(-200*x,200*x); //drehung
msleep(300);
if( mitt > 185){
robot.motors(100,-100);
msleep(300);
x= x*(-1);




}
}


}


}
}








Ich hoffe ihr könnt mir helfen.

PS: Falls das hier, das falsche Forum ist, tut es mir Leid, hab kein anderes gefunden...

021aet04
28.12.2013, 17:21
Warum rechnest du x=x*(-1) ?

Ich würde einfach den else Zweig anpassen. Für die Drehrichtung nimmst du eine Variable. Du änderst einfach den Zustand zwischen 0 und 1.

...
...
else
{
if (drehrichtung == 0)
{

robot.motors(-200, 200);
drehrichtung = 1;

}
else
{

robot.motors(200, -200);
drehrichtung = 0;

}

msleep(300);

}


Bei Rechnungsaktionen muss man aufpassen das du den Controller nicht überforderst. Ohne Rechnen ist der Controller auch schneller, da es resourcenschonender ist. Man verwenden auch wenn möglich keine Rechenaktrionen sondern Konstanten (z.B. U=2 x pi x r => U = 6,28 x r).

MfG Hannes

timmy19
29.12.2013, 14:45
Danke dir.

Das Problem ist nun aber genau dasselbe, wie wenn ich mit x = x*(-1) rechne. Der Roboter bewegt sich immer nur vor und zurück.
Was ist das Problem?


#include "qfixMiniBoard.h"
#include "qfixLCD.h"


const int SENSOR3 = 3;
int SENSOR1 = 1;
int SENSOR2 = 2;
int SENSOR = 0;

MiniBoard robot;
LCD lcd;


int main(){
{
int i=0;
int mitt = 0;
int drehrichtung = 0;

while(1){
int i = robot.analog(1) ;
int mitt= robot.analog(3);


if (i > 75){
robot.motors(250,250); //geradeaus
}
else
{if (drehrichtung == 0)
{
robot.motors(-200, 200);
drehrichtung = 1;}
else
{
robot.motors(200, -200);
drehrichtung = 0;}
msleep(300);
}



}
}


}

021aet04
29.12.2013, 14:53
Welcher Bereich wird bei der Drehzahl genutzt? Hast du Tasten oder Potis auf dem Roboter die du verwenden kannst?

Du könntest éinmal versuchen statt -200 z.B. 100 eintragen. Ich vermute (ich kenne dein System nicht) das der Wertebereich von -127 bis +128 oder 0 bis 255 geht (das wäre genau ein Byte).

MfG Hannes

timmy19
29.12.2013, 15:05
Ich habe Tasten zum Starten des Roboters und der Drehzahlbereich geht von -255 bis 255.

Wenn ich das mit 100 versuche löst es das Problem leider nicht, der Roboter bewegt sich einfach nur langsamer hin und her...

Edit: Ich glaube, das Problem liegt einfach in der Regelung mit "rechts" und "links" (das was ich mit x= x*(-1) lösen wollte.

021aet04
29.12.2013, 16:03
Gib einmal die ganzen "int ..." aus der main Funktion hinaus (vor "main {"). Dann könntest du einmal versuchen ohne Analogauswertung die Motoren drehen lassen.

z.B.
main
{
while(1)

{

robot.motors (200,200);
msleep(1000);
robot.motors (-200,200);
msleep(1000);
robot.motors(200,-200);
msleep(1000);

}
}


Wenn das funktioniert hast du ein Problem mit der Analogauswertung. Eventuell passt der Messwert nicht. Ich habe etwas von "LCD" gelesen, hast du eines? Eventuell kannst du dir den Messwert ausgeben lassen.

MfG Hannes

timmy19
30.12.2013, 12:24
Das klappt. Kann mir aber nicht vorstellen, dass das ein falscher Messwert ist, vorallem da der ja in dem Falle ja gar nicht relevant ist, denn er gehört ja zum Ultraschall. Was könnte es denn noch sein? Bin ganz verzweifelt, denn wenn ich die links rechts- Regelung rausnehm klappt alles, was ich möchte...

Achso und nein, ich hab kein LCD, die Werte haben wir in der Schule gemessen. Ist ja auch nur der "Abstand" zum Hindernis.

Edit: Mein aktueller Code:


#include "qfixMiniBoard.h"
#include "qfixLCD.h"


const int SENSOR3 = 3;
int SENSOR1 = 1;
int SENSOR2 = 2;
int SENSOR = 0;

MiniBoard robot;
LCD lcd;

int i=0;
int mitt = 0;
int drehrichtung = 0;


int main(){
{
while(1){
int i = robot.analog(1) ;


if (i > 75){
robot.motors(250,250); //geradeaus
}
else
{if (drehrichtung == 0)
{
robot.motors(-200, 200);
drehrichtung = 1;
}
else
{
robot.motors(200, -200);
drehrichtung = 0;
}
msleep(2500);
if( mitt > 185){
robot.motors(100,-100);
msleep(300);
}

-schumi-
30.12.2013, 13:20
Du solltest dir unbedingt eine übersichtliche Einrückung angewöhnen! Das unterschätzt man als Anfänger, aber sowas erhöht die Lesbarkeit ungemein ;) (und dann kommt auch nicht so ein Durcheinander raus, z.B. zu viele { und } (nach main) oder eine Variable zwei mal als Int deklariert (i) usw)

So ganz kann ich deinen Code auch nicht nachvollziehen wenn ich ehrlich bin (was soll "mitt" sein?).. Aber ich glaube dein Hauptproblem ist, dass du bei einem Abstand von <75 (also z.B. 74) kurz (300ms) nach links drehst, und dann gleich wieder geradeaus fährst weil der Abstand jetzt ja >75 (also z.B. 76) ist. Somit zuckelt der Robo nur etwas umher...

Als inspiration (sollte eigentlich lauffähig sein wenn ich keine Tippfehler gemacht habe und dein Sensor einen Abstand von 120 messen kann):


#include "qfixMiniBoard.h"
#include "qfixLCD.h"


const int SENSOR3 = 3;
int SENSOR1 = 1;
int SENSOR2 = 2;
int SENSOR = 0;

MiniBoard robot;
LCD lcd;

#define geradeaus 0
#define linksDrehung 1
#define rechtsDrehung 2

#define hindernis 75
#define freieSicht 120 // Wenn der Robo etwas nach links fährt, aber dann gegen das Hindernis, ist dieser Wert zu klein

#define True 1
#define False 0

int main()
{
int abstand=0;
unsigned char drehrichtung = geradeaus; // unsigned char = 8bit integer von 0 bis 255, braucht weniger Platz im RAM
unsigned char schonNachLinksAusgewichen = False;

while(1)
{
abstand = robot.analog(1);
if( drehrichtung == geradeaus)
{
robot.motors(250,250); //geradeaus fahren
if( abstand < hindernis)
{
if(schonNachLinksAusgewichen == False)
drehrichtung = linksDrehung;
else
drehrichtung = rechtsDrehung;
}
}
if( drehrichtung == linksDrehung )
{
robot.motors(-200, 200); // nach links drehen
if( abstand >= freieSicht )
{
drehrichtung = geradeaus;
schonNachLinksAusgewichen = True;
}
}
if( drehrichtung == rechtsDrehung )
{
robot.motors(200, -200); // nach rechts drehen
if( abstand >= freieSicht )
{
drehrichtung = geradeaus;
schonNachLinksAusgewichen = False; // Er ist zwar schon mal nach links ausgewichen, aber inzwischen auch schon rechtsrum, also wieder von vorne
}
}
}
}

timmy19
30.12.2013, 13:57
Wow danke, das hilft mir schon nen ganzes Stück weiter. Nur ein Problem hab ich:

Wenn der Robo die Linksdrehung gemacht hat, fährt der bei deinem Code plötzlich rückwärts weiter. Das kann ich nicht ganz nachvollziehen. Kannst du mir da helfen?

PS: "mitt" sollte ein Infrarotsensor sein, den ich zwischendrin eingebaut hatte, aber nicht funktionierte und daher wieder rausstrich(der muss aber noch rein!)

-schumi-
30.12.2013, 14:11
Wenn der Robo die Linksdrehung gemacht hat, fährt der bei deinem Code plötzlich rückwärts weiter. Das kann ich nicht ganz nachvollziehen.

Das kann ich auch nicht nachvollziehen... Es ist ja gar kein "robot.motors(xxx,yyy);" mit zwei negativen Werten im Programm drin :confused:

[EDIT]
Kann es sein, dass es sich bei deinem Robo um diesen hier handelt: http://en.wikipedia.org/wiki/Qfix_robot_kit ?
Das Umfahren von Hindernissen ist nämlich mit mehreren Abstandssensoren deutlich einfacher/zuverlässiger..

timmy19
30.12.2013, 18:07
Seltsam. Hab es jetzt mal anders gemacht, nämlich ihn manuell geradeaus fahren lassen, nicht mit dem Befehl "drehrichtung = geradeaus", dann klappt es komischerweise. Die Technik ist manchmal verwirrend.

Ja, der Roboter ist es. Wir sollen das Hindernisumfahren aber mit einem Infrarotsensor regeln, denn wir haben ein Boden, der eingefärbt ist(dunkel zu hell zu dunkel). Zudem ist die Seitenbegrenzung nicht so hoch, dass man sie mit dem Ultraschall sehen könnte.

Nun meine weitere Frage: Glaubt ihr, der folgende Code könnte im Prinzip funktionieren? Mein Problem war bisher, dass sich der Robo nur gedreht hat, da er sich beim dunklen Boden drehen sollte. Aber eigentlich wollte ich das erst, nachdem er das erste Hindernis entdeckt, die Drehung gemacht und richtung "freier" Seite gefahren ist. Wie kann ich das schreiben, sodass er sich nicht "verwirren" lässt?


#include "qfixMiniBoard.h"
#include "qfixLCD.h"


const int SENSOR3 = 3;
int SENSOR1 = 1;
int SENSOR2 = 2;
int SENSOR = 0;

MiniBoard robot;
LCD lcd;

#define geradeaus 0
#define linksDrehung 1
#define rechtsDrehung 2

#define hindernis 75
#define freieSicht 120 // Wenn der Robo etwas nach links fährt, aber dann gegen das Hindernis, ist dieser Wert zu klein

#define True 1
#define False 0

int main()
{
int abstand=0;
//int infrarot= 0;
unsigned char drehrichtung = geradeaus; // unsigned char = 8bit integer von 0 bis 255, braucht weniger Platz im RAM
unsigned char schonNachLinksAusgewichen = False;

while(1)
{
abstand = robot.analog(1);
//infrarot = robot.analog(3);
if( drehrichtung == geradeaus)
{
robot.motors(-250,-250); //geradeaus fahren
if( abstand < hindernis)
{
if(schonNachLinksAusgewichen == False)
drehrichtung = linksDrehung;
else
drehrichtung = rechtsDrehung;
}
}
if( drehrichtung == linksDrehung )
{
robot.motors(-200, 200); // nach links drehen
if( abstand >= freieSicht )
{
robot.motors(250,250)
schonNachLinksAusgewichen = True;
//msleep(500);
//if( infrarot > 185){
//robot.motors(100,-100);
//msleep(500);

}
}
if( drehrichtung == rechtsDrehung )
{
robot.motors(200, -200); // nach rechts drehen
if( abstand >= freieSicht )
{
robot.motors(250,250)
schonNachLinksAusgewichen = False;
//msleep(500);
//if( infrarot > 185){
//robot.motors(-100,100);

// Er ist zwar schon mal nach links ausgewichen, aber inzwischen auch schon rechtsrum, also wieder von vorne





}
}
}

}

021aet04
30.12.2013, 22:32
Ich würde es in etwa so machen (nur die while Schleife als Pseudocode):


while(1)
{

Lese Ultraschall
if (Ultraschall < Limit)
{

Hinderniss = true

}



if (Hinderniss == false)
{

Motoren (200,200)


}
else
{

if (drehung == links)
{

Motoren (-200, 200)
drehung = rechts

}
else
{

Motoren (200, -200)
drehung = links

}

Lese Linie

if (Linie < Limit)
{

Hinderniss = false

}

}

}


Du musst vermutlich noch ein Delay (msleep) einfügen.

MfG Hannes

timmy19
02.01.2014, 13:08
Wie geht das "Lese" ?

Mir fehlt derzeit eigentlich nur noch der Infrarotsensor, also das von dir beschriebene "Lese Linie".... nur wie geht das? Der Rest klappt soweit.


#include "qfixMiniBoard.h"
#include "qfixLCD.h"


const int SENSOR3 = 3;
int SENSOR1 = 1;
int SENSOR2 = 2;
int SENSOR = 0;

MiniBoard robot;
LCD lcd;

#define geradeaus 0
#define linksDrehung 1
#define rechtsDrehung 2

#define hindernis 85
#define freieSicht 150 // Wenn der Robo etwas nach links fährt, aber dann gegen das Hindernis, ist dieser Wert zu klein

#define True 1
#define False 0

int main()
{
int abstand=0;
//int infrarot= 0;
unsigned char drehrichtung = geradeaus; // unsigned char = 8bit integer von 0 bis 255, braucht weniger Platz im RAM
unsigned char schonNachLinksAusgewichen = False;

while(1)
{
abstand = robot.analog(1);
//infrarot = robot.analog(3);
if( drehrichtung == geradeaus)
{
robot.motors(-250,-250); //geradeaus fahren
if( abstand < hindernis)
{
if(schonNachLinksAusgewichen == False)
drehrichtung = linksDrehung;
else
drehrichtung = rechtsDrehung;
}
}
if( drehrichtung == linksDrehung )
{
robot.motors(-200, 200); // nach links drehen
if( abstand >= freieSicht )
{
robot.motors(250,250);
msleep(500);
schonNachLinksAusgewichen = True;
//msleep(500);
//if( infrarot > 185){
//robot.motors(100,-100);
//msleep(500);

}
}
if( drehrichtung == rechtsDrehung )
{
robot.motors(200, -200); // nach rechts drehen
if( abstand >= freieSicht )
{
robot.motors(250,250);
msleep(500);
schonNachLinksAusgewichen = False;
//msleep(500);
//if( infrarot > 185){
//robot.motors(-100,100);

// Er ist zwar schon mal nach links ausgewichen, aber inzwischen auch schon rechtsrum, also wieder von vorne





}
}
}

}

021aet04
02.01.2014, 20:05
"Lese Linie" wäre bei dir "infrarot = robot.analog(3);", "Lese Ultraschall" wäre "abstand = robot.analog (1);"

MfG Hannes

timmy19
03.01.2014, 11:25
Danke dir. :)
Das Delay(msleep) muss NACH dem Infrarot oder davor? Hab es derzeit davor. Also so:


#include "qfixMiniBoard.h"
#include "qfixLCD.h"


const int SENSOR3 = 3;
int SENSOR1 = 1;
int SENSOR2 = 2;
int SENSOR = 0;

MiniBoard robot;
LCD lcd;

#define geradeaus 0
#define linksDrehung 1
#define rechtsDrehung 2

#define hindernis 85
#define freieSicht 150 // Wenn der Robo etwas nach links fährt, aber dann gegen das Hindernis, ist dieser Wert zu klein

#define True 1
#define False 0

int main()
{
int abstand=0;
unsigned char drehrichtung = geradeaus; // unsigned char = 8bit integer von 0 bis 255, braucht weniger Platz im RAM
unsigned char schonNachLinksAusgewichen = False;

while(1)
{
abstand = robot.analog(1);

if( drehrichtung == geradeaus)
{
robot.motors(-250,-250); //geradeaus fahren
if( abstand < hindernis)
{
if(schonNachLinksAusgewichen == False)
drehrichtung = linksDrehung;
else
drehrichtung = rechtsDrehung;
}
}
if( drehrichtung == linksDrehung )
{
robot.motors(-200, 200); // nach links drehen
if( abstand >= freieSicht )
{
robot.motors(250,250);
msleep(500);
schonNachLinksAusgewichen = True;

infrarot = robot.analog(3);

//msleep(500);
if( infrarot > 185){
robot.motors(100,-100);
int infrarot = 0;

}
}
if( drehrichtung == rechtsDrehung )
{
robot.motors(200, -200); // nach rechts drehen
if( abstand >= freieSicht )
{
robot.motors(250,250);
msleep(500);
schonNachLinksAusgewichen = False;

infrarot = robot.analog(3);

//msleep(500);
if( infrarot > 185){
robot.motors(-100,100);
int infrarot = 0;


// Er ist zwar schon mal nach links ausgewichen, aber inzwischen auch schon rechtsrum, also wieder von vorne





}
}
}

}


Edit: Der Robo möchte einfach nicht auf das infrarot reagieren. Alles andere macht er jetzt, nur das Infrarot nicht. Was mach ich um Himmels willen falsch? Ich verzweifle...
Und noch was: Komischerweise fährt der Robo immer auf das Hindernis zu, dreht sich kurz zuvor und bleibt dann mit dem rechten Rad etwas hängen, dreht sich aber weiter. Das macht er, egal wie ich "Hindernis" und "freie Sicht" verändere. Woran liegt das und wie kann ich das ändern(also, dass er sich schon früher dreht)?

021aet04
04.01.2014, 18:45
Was macht er nicht? Beschreibe genau was er macht (z.B. fährt geradeaus, trifft auf Hindernis, dreht sich nach links und fährt nicht mehr geradeaus sondern dreht weiter).

Grundsätzlich entspricht das Programm nicht dem was ich oben als Pseudocode geschrieben habe (ist aber egal). An deiner Stelle würde ich nicht nur mit einfachen "If" Anweisungen sondern mit "If-else" Anweisungen arbeiten. Der Grund ist relativ einfach. Als Beispiel:

if (drehrichtung == linksdrehung)
{
...

...

...

drehrichtung = rechtsdrehung;
}

if (drehrichtung == rechtsdrehung)
{
...

...

...

drehrichtung = linksdrehung;
}


Somit wird zuerst die Schleife mit Linksdrehung ausgeführt, dort wird der Wert geändert. Anschließend wird in der nächsten Schleife auf Rechtsdrehung geprüft, diese ist auch war und wird deswegen ausgeführt. Wenn du stattdessen ein else einsetzt ist das nur eine Schleife und der else Zweig wird nicht ausgeführt (außer wenn das Programm wieder auf diese if Schleife kommt).

Wenn du auf mehrere Werte prüfen willst kannst du z.B so schreiben
if (variable == 1)
{
}
else if (variable == 2)
{
}
else
{
}

Wo die Delays hinkommen ist grundsätzlich egal (optimal wäre wenn du garkeines brauchst da der Controller in dieser Zeit nichts macht). Du musst immer bedenken was passiert wenn du das Delay an einen Platz setzt.
Als Beispiel du liest einen Sensor ein und steuerst daraufhin einen Motor an.

Lese Infrarot
Delay
if (Infrarot <100)
{
Motor (200,-200)
}
Motor (200,200)
So wie das Programm jetzt ist ist es sinnlos, da du nach dem Einlesen des Sensors zwar den Motor so ansteuerst das er ausweicht, jedoch im "selben" Moment den Motor wieder geradeausfahren lässt. Das Motor (200,-200) wirst du nicht merken da das viel zu schnell geht, gleichzeitig ist das Delay sinnlos da du nach dem auslesen wartest bis du den Motor ansteuerst.

Wenn du hingegen das Delay nach Motor(200,-200) hinschreibst wird der für die Zeit des Delays in die Gegenrichtung drehen. Dann ist es sinnvoller. In etwa so:

Lese Infrarot
if (Infrarot < 100)
{
Motor (200, -200)
Delay
}
Motor (200, 200)




Wenn du die Entfernung auf die er reagiert ändern willst musst du den Wert des Limits ändern. Du musst wissen üb der Wert proportional oder nicht proportional zur Entfernung ist. Je nachdem muss der Wert größer oder kleiner werden. Wenn du es nicht weißt wäre es am einfachsten wenn du ein Messgerät nimmst und misst.

Das mit dem Hängenbleiben könntest du lösen indem du die Werte für rechten Motor und linken Motor änderst. z.B. Motor(0, -200) => ein Motor steht und der andere Dreht mit Geschw. 200.

So wie ich dein Programm jetzt verstanden habe (habe mir jetzt den Zeig für Linksdrehung angeschaut):
> Du fährst vorwärts bis zum Hindernis
> drehst nach links bis kein Hindernis erkannt wurde
> anschließend fährst du zurück bis das Infrarot über einem Limit ist
> jetzt fährst du langsamer als vorher nach rechts (motor (-100, 100))

Geradeaus fährst du garnichmehr da du die Variable Drehrichtung nicht mehr auf geradeaus stellst.

MfG Hannes

timmy19
04.01.2014, 23:46
Also bisher macht der Robo folgendes:

Er fährt geradeaus, bis er das Hindernis erkennt. Leider erkennt er dieses erst minimal davor, sodass er bei der Linksdrehung mit dem Rechten Rad hängenbleibt.
Das Problem ist: Wenn ich den Wert des "Hinderniserkennens" erhöhe, erkennt er plötzlich NICHTS mehr und fährt gegen das Hindernis. Wo liegt dabei das Problem und wie bekomme ich es hin, dass er das Hindernis früher erkennt? Ein Messgerät habe ich leider nicht.

Desweiteren hab ich nun was ausprobiert: Nachdem er linksgedreht hat, hab ich mal ein weiteres Hindernis hingestellt. Eigentlich sollte er nun ja rechtsdrehen, aber er dreht erneut links. Wo liegt nun hier das Problem?

Und wie soll ich das mit dem If-Else machen? versteh ich leider nicht ganz, vllt. kannst du mir das noch etwas genauer erklären.

______

Ja genau, er sollte geradeaus fahren, dann, wenn er das Hindernis erkennt nach links drehen. Nun soll er soweit nach links fahren, bis der Boden wieder eine bestimmte Farbe annimmt(etwa Wert 185, gemessen in der Schule), sich nun wieder rechts drehen und geradeaus auf das nächste Hindernis fahren. Dort nun das ganze in umgekehrter Richtung wieder durchführen. Verstanden? Leider scheitere ich schon an der ersten Rechtsdrehung mit Infrarot.

Wäre euch sau dankbar, wenn ich mir da noch den ein oder anderen Tipp geben könntet, wie ich das weiter lösen könnte.


#include "qfixMiniBoard.h"
#include "qfixLCD.h"


const int SENSOR3 = 3;
int SENSOR1 = 1;
int SENSOR2 = 2;
int SENSOR = 0;

MiniBoard robot;
LCD lcd;

#define geradeaus 0
#define linksDrehung 1
#define rechtsDrehung 2

#define hindernis 85
#define freieSicht 150 // Wenn der Robo etwas nach links fährt, aber dann gegen das Hindernis, ist dieser Wert zu klein

#define True 1
#define False 0

int main()
{

unsigned char drehrichtung = geradeaus; // unsigned char = 8bit integer von 0 bis 255, braucht weniger Platz im RAM
unsigned char schonNachLinksAusgewichen = False;

while(1)
{
int abstand = robot.analog(1);
int infrarot = robot.analog(3);

if( drehrichtung == geradeaus)
{
robot.motors(100,100); //geradeaus fahren
if( abstand < 85)
{
if(schonNachLinksAusgewichen == False)
drehrichtung = linksDrehung;
else
drehrichtung = rechtsDrehung;
}
}
if( drehrichtung == linksDrehung )
{
robot.motors(-100, 100); // nach links drehen
msleep(300);
if( abstand >= 120)
{
robot.motors(100,100);
msleep(280);
schonNachLinksAusgewichen = True;

msleep(1500);
if( infrarot > 185){
robot.motors(100,-100);


}
}
if( drehrichtung == rechtsDrehung )
{
robot.motors(200, -200); // nach rechts drehen
if( abstand >= 120 )
{
robot.motors(100,100);
msleep(280);
schonNachLinksAusgewichen = False;

int infrarot = robot.analog(3);

msleep(1500);
if( infrarot > 185){
robot.motors(-100,100);



// Er ist zwar schon mal nach links ausgewichen, aber inzwischen auch schon rechtsrum, also wieder von vorne





}
}
}

}
}
}

021aet04
05.01.2014, 00:45
Du prüfst in deinem Programm auf geradeaus, linksdrehung und rechtsdrehung. Ich würde aber zuerst einmal nur prüfen ob du geradeausfährst oder ausweichen musst.

Also nur die while Schleife. Die Variable musst du vorher initialisieren. Vor der While Schleife "int abstand",... Dann brauchst du die Variable nur verwenden.


while(1)
{
abstand = robot.analog (1);

if (abstand < 85)
{

Hindernis = true;

}

if (Hindernis == false)
{

robot.motors (-250, -250);

}
else
{

if (Drehrichtung == links)
{

robot.motors (200, -200);
Drehrichtung = rechts;

}
else
{

robot.motors (-200, 200);
Drehrichtung = links;

}

infrarot = robot.analog (3);

if ( infrarot < 85)
{

Hindernis = false;

}

}
msleep(500);
}

Das Programm sollte so funktionieren. Was hast du als Hindernis genommen. Je nach Objekt könnte es Probleme geben. Glatte Objekte (z.B. Bücher) 90° zum Sensor ist optimal, sollte auch nicht zu klein sein. Flaschen o.Ä. ist nicht optimal, da eigentlich nur die Fläche den Schall Richtung Sensor wirft der 90° zum Sensor steht.

Hast du Leds die du ansteuern kannst? So kannst du die Messwerte testen die vom Sensor kommen, du könntest auch die Motoren nehmen. Sensorwert direkt an den Motor geben.


i = robot.analog (1);
robot.motors (i, 0);
msleep(300);

Am Besten wäre es dann wenn du den Roboter anheben kannst und ein Objekt vom oder zum Sensor bewegst. Dann sollte sich die Motordrehzahl ändern.

MfG Hannes

timmy19
05.01.2014, 13:22
Klingt im Prinzip völlig verständlich. Nur hab ich nun dasselbe Problem wie am Anfang: Der Robo macht nichts außer 2 cm vor und dann wieder zurück zufahren(also so nen ruckeln). Nach einer kleinen Änderung macht er immerhin die linksdrehung. Also muss das am "Geradeausfahren" liegen. Aber wo ist da der fehler?

Letztes Mal lag es irgendwie an der Else-Steuerung. Wie kann es ich schaffen, dass ich die Else-Steuerung nutzen kann, ohne das dieser "Fehler" auftritt? Hast du da ne Ahnung?

Edit: Warum erkennt der Robo meine Hand als Hindernis und dreht sich dann perfekt, aber jede andere Sache erkennt er nicht oder zu spät? Ich verzweifle... :/

021aet04
05.01.2014, 14:03
Du könntest versuchen das msleep zu verlängern.

Ich vermute das das so abläuft:
Das Hindernis wird erkannt, der Roboter dreht, fährt nach vor und erkennt das Objekt erneut, weicht wieder aus, fährt wieder nach vor erkennt das Hindernis wieder,....

Somit würde sich das ruckeln erklären.

Wie ich oben schon gefragt habe was nutzt du als Hindernis?

Was du auch noch machen kannst das wäre das "abstand = robot.analog(1);" und die "if (abstand < 85)" Schleife in den "if (Hindernis == false)" Zweig geben.

Du kannst auch versuchen ein komplettes Ausweichmanöver ins Programm zu integrieren. Z.B. Wenn Hindernis erkannt Abstandsmessung abschalten, fahre zurück, drehe seitlich, fahre vor, wenn neben dem Hindernis Abstandsmessung einschalten.

MfG Hannes

timmy19
05.01.2014, 14:25
Der Ruckelt auch nur so rum, wenn gar kein Hindernis in Sicht ist.

_______

Meinst du es etwa so?(nur der if(Hindernis==false)-Pfad)


if (Hindernis == false)
{
Drehrichtung = geradeaus;
}
else
{
if (abstand < 85)
{
Hindernis = true;
Drehrichtung = links;
robot.motors (200, -200);
Drehrichtung = rechts;
}
else
{
robot.motors (-200, 200);
Drehrichtung = links;
}


Dann dreht der Robo sich nur nach links, auch wenn kein Hindernis in Sicht ist.

Zu den Hindernissen: Ich benutzte 2 glatte Schachteln, etwa 15 cm hoch und 30 cm lang, bei beiden die selbe Reaktion, jeweils erst kurz vorher wird das Hindernis erkannt. Bei meiner Hand ist das komplett anders, da dreht er sich früh genug

Wie meinst du das mit einem kompletten Ausweichmanöver? Kann mir gar nicht vorstellen, wie ich das schreiben sollte...(weiß z.B. gar nicht wie man die Messung ausschaltet, vllt. kannst mir ja kurz nen kleines Bsp. geben)

021aet04
05.01.2014, 15:11
Das Programm sieht nicht annähernd so aus wie das was ich gescchrieben habe. Bei dir steht im "if (Hindernis == false)" Zweig "Drehrichtung = geradeaus;" bei mir steht "robot.motors (-250, -250);". "Drehrichtung = geradeaus;" habe ich gar nicht.

Du hast das "if (abstand < 85)" in den else Zweig gegeben. Ich habe geschrieben das das in den "if (Hindernis == false)" Zweig soll.

Poste einmal das Programm als *.c Datei (Datei hochladen).

Einen Sensor ausschalten kannst du nicht, das war schlecht ausgedrückt. Du überprüfst den Sensor einfach nicht (du lässt das "abstand = robot.analog(1);" einfach weg.

Das Ausweichmanöver kannst du später hinzufügen. Hast du schon die Entfernung getestet so wie ich es im Post 18 geschrieben habe?

MfG Hannes

timmy19
05.01.2014, 15:36
Ach du meine Güte, sorry. Hab das komplett falsch verstanden und geändert. Aber auch nachdem ich es geändert habe, dreht sich der Robo einfach nur linksherum.
Tut mir leid, aber meine Datei ist ne cc und die kann man hier scheinbar nicht hochladen...

Ich habe leider kein LED, dementsprechend kann ich auch keine Werte messen, das hatten wir schon in der Schule gemacht.

____
Achso, jetzt versteh ich, soweit bin ich aber glaub noch nicht, dass ich das könnte. Wie man denke ich merkt, bin ich blutiger Anfänger.

Da ich es nicht hochladen kann, hier mal der Code so:


#include "qfixMiniBoard.h"
#include "qfixLCD.h"


const int SENSOR3 = 3;
int SENSOR1 = 1;
int SENSOR2 = 2;
int SENSOR = 0;

MiniBoard robot;
LCD lcd;

#define geradeaus 0
#define links 1
#define rechts 2

#define hindernis 85
#define freieSicht 150 // Wenn der Robo etwas nach links fährt, aber dann gegen das Hindernis, ist dieser Wert zu klein

#define True 1
#define False 0

int main()
{

unsigned char Drehrichtung = geradeaus; // unsigned char = 8bit integer von 0 bis 255, braucht weniger Platz im RAM
int abstand = robot.analog(1);
int infrarot = robot.analog(3);

while(1)
{
unsigned char Hindernis = false ;

if (Hindernis == false)
{
abstand = robot.analog (1);
robot.motors(250,250);
if(abstand < 85)
{
Hindernis = true;
}
}
else
{
if(Drehrichtung == links)
{

robot.motors (200, -200);
Drehrichtung = rechts;
}
else
{
robot.motors (-200, 200);
Drehrichtung = links;
}

infrarot = robot.analog (3);

if ( infrarot < 85)
{
Hindernis = false;
}
}
msleep(500);
}
}

021aet04
05.01.2014, 16:02
Was mir schon einmal auffällt ist das du in der while Schleife ("while(1)") "unsigned char Hindernis = false;" steht. Gehe einmal durch was das Programm macht. Normalerweise müsste sich der Roboter immer nach vorne bewegen. Du sagst vor der if Schleife immer das Hindernis falsch ist und somit wird nur der if... Zweig und nie der else Zweig ausgeführt.

Gleichzeitig gibts du das "#define geradeaus 0" weg. Stattdessen weißt du links 0 zu und rechts 1.

Wenn du vor dem links bzw rechtsdrehen noch zurückfahren willst kannst du so schreiben:

if (drehrichtung == links)
{
robot.motors (-100, -100);
msleep(100);
robot.motors (-200, 200);
drehrichtung = rechts;
}

MfG Hannes

timmy19
05.01.2014, 16:37
Leider löst das mein Hauptproblem nicht. Der Robo dreht sich immer noch nur im Kreis...

021aet04
05.01.2014, 16:57
Kannst du mit deiner IDE simulieren? Da könntest du genau sehen wie das Programm funktioniert. Wenn du nicht simulieren kannst könntest du den Else Zweig auskommentieren und sehen was passiert.

Das Programm sollte eigentlich passen (wenn die Limits passen).

MfG Hannes

timmy19
05.01.2014, 17:28
Komischerweise macht der Robo GAR nichts, wenn man den Else-Zweig auskommentiert. Das könnte das Problem sein, warum dem so ist, blick ich leider immer noch nicht. Weißt du vllt. woran es noch liegen könnte?

021aet04
05.01.2014, 17:46
Das ist ganz einfach. Wenn der else Zweig nicht auskommentiert ist und der Robo dreht sich und wenn der else Zweig auskommentiert ist dreht er sich nicht. Was bedeutet das? Der Else Zweig wird ausgeführt.

Ich weiß jedoch nicht warum. Das einzige was ich mir vorstellen kann ist das das Programm nicht dem entspricht das du gepostet hast.

Kannst du das Programm simulieren?

MfG Hannes

timmy19
05.01.2014, 18:01
Aber eigentlich sollte der Robo doch geradeaus fahren, denn kein Hindernis ist in Sicht. Zudem ist das komische ja, dass er sich nun wieder nur vor und rückwärts bewegt(vorher war das noch anders). Warum er das tut, versteh ich immer noch nicht. Er dreht sich ja nicht mal, nein, er bewegt sich kosequent vor und zurück. Alles bisschen seltsam.

Nein kann ich leider nicht...

EDIT: Wenn ich das Infrarot rausnehme, dann dreht er sich wieder.

Dieses Programm hab ich derzeit auf dem Robo:


#include "qfixMiniBoard.h"
#include "qfixLCD.h"


const int SENSOR3 = 3;
int SENSOR1 = 1;
int SENSOR2 = 2;
int SENSOR = 0;

MiniBoard robot;
LCD lcd;
#define links 0
#define rechts 1

#define hindernis 85
#define freieSicht 150 // Wenn der Robo etwas nach links fährt, aber dann gegen das Hindernis, ist dieser Wert zu klein

#define True 1
#define False 0

int main()
{

unsigned char Drehrichtung = links;
int abstand = robot.analog(1);
int infrarot = robot.analog(3);

while(1)
{
unsigned char Hindernis = true; // unsigned char = 8bit integer von 0 bis 255, braucht weniger Platz im RAM

if (Hindernis == false)
{
abstand = robot.analog (1);
robot.motors(250,250);
if(abstand < 85)
{
Hindernis = true;
}
}
else
{
if(Drehrichtung == links)
{

robot.motors (200, -200);
Drehrichtung = rechts;
}
else
{
robot.motors(-100,-100);
msleep(100);
robot.motors (-200, 200);
Drehrichtung = links;
}

infrarot = robot.analog (3);

if ( infrarot < 85)
{
Hindernis = false;
}
}
msleep(500);
}
}

021aet04
05.01.2014, 18:35
Liest du auch meine Posts genau durch? Ich habe im Post 6, 18, 24 geschrieben wo du die Variablen initialisieren musst.

Beim Programmieren geht es um das verstehen. Du verstehst es aber nicht, du schreibst einfach das hin was ich schreibe und das noch nichteinmal richtig (z.B. den Codeausschnitt in Post 24).

Das mit den Einrückungen ist auch extrem unübersichtlich. Schumi hat das schon geschrieben. Dann hat es funktioniert und seit Post 21 funktioniert es wieder nicht.

Versuche die Posts genau durchzulesen und umzusetzen. Wenn es dann nicht funktioniert poste nocheinmal das Programm.

MfG Hannes

timmy19
05.01.2014, 19:05
Keine Angst, ich lese mir die Beiträge schon genau durch. Ich habe die Anweisungen mit den Variablen auch so umgesetzt gehabt, nur zwischen drin klappte das dann nicht mehr... ist jetzt auch egal.

Und doch, Schumis Programm klappt bis auf die Tatsache, dass der Robo erst minimal vor dem Hindernis dreht und die Infrarotsteuerung(die klappt immer noch nicht...) Es klappt wahrscheinlich aber nur, weil da ohne Else-Steuerung gearbeitet wird. Um weiter zu kommen, wäre es vllt. sinnvoll, die Else-Steuerung(so leid es mir tut, sowohl um deine Arbeit, als auch darum da ich es gerne so gemacht hätte, da es schicker aussieht), weg zulassen und an dem anderen Programm weiterzuarbeiten.


#include "qfixMiniBoard.h"
#include "qfixLCD.h"


const int SENSOR3 = 3;
int SENSOR1 = 1;
int SENSOR2 = 2;
int SENSOR = 0;

MiniBoard robot;
LCD lcd;

#define geradeaus 0
#define linksDrehung 1
#define rechtsDrehung 2

#define hindernis 85
#define freieSicht 150 // Wenn der Robo etwas nach links fährt, aber dann gegen das Hindernis, ist dieser Wert zu klein

#define True 1
#define False 0

int main()
{

unsigned char drehrichtung = geradeaus; // unsigned char = 8bit integer von 0 bis 255, braucht weniger Platz im RAM
unsigned char schonNachLinksAusgewichen = False;
int abstand = robot.analog(1);
int infrarot = robot.analog(3);

while(1)
{


if( drehrichtung == geradeaus)
{
robot.motors(100,100); //geradeaus fahren
if( abstand < 150)
{
if(schonNachLinksAusgewichen == False)
drehrichtung = linksDrehung;
else
drehrichtung = rechtsDrehung;
}
}
if( drehrichtung == linksDrehung )
{
robot.motors(-100,-100);
msleep(100);
robot.motors(-150, 150); // nach links drehen
msleep(300);
if( abstand >= 150 )
{
robot.motors(100,100);
msleep(500);
schonNachLinksAusgewichen = True;


if( infrarot < 150){
robot.motors(100,-100);
msleep(500);

}
}
if( drehrichtung == rechtsDrehung )
{
robot.motors(150, -150); // nach rechts drehen
msleep(300);
if( abstand >= 150 )
{
robot.motors(-100, -100);
msleep(100);
robot.motors(100,100);
msleep(500);
schonNachLinksAusgewichen = False;

int infrarot = robot.analog(3);
if( infrarot < 150){
robot.motors(-100,100);
msleep(500);


// Er ist zwar schon mal nach links ausgewichen, aber inzwischen auch schon rechtsrum, also wieder von vorne





}
}
}

}
}
}

Wie gesagt: Das hier funktioniert soweit(arbeite sozusagen an zwei Versionen gleichzeitig), dass der Robo fährt, sich dann minimal vor dem Hindernis dreht. Die Rücksteuerung per Infrarot wäre jetzt das nächste, was ich gerne versuchen würde, vllt. klappt es dann ja. Würde mich extrem freuen. :)

Also, weißt du, was hier der Fehler an der Infrarotsteuerung sein könnte? Ich sehe keinen und weiß deshalb nicht was ändern.

_____

Bei dem mit der Else-Schleife bleibt das Problem, dass er sich nur dreht. Hab schon ein paar Dinge verändert, aber immer dasselbe Problem, er scheint den "If-Teil" einfach nicht auszuführen.

-schumi-
05.01.2014, 20:25
Irgendwie ist das alles etwas durcheinander.. Es ehrt mich zwar, dass das Grundgerüst deines Codes immer noch das von mir gepostete ist, aber mit dem Infrarot dazwischen wird das jetzt nicht mehr so funktionieren. Denn mein Code war so gedacht:

Kein Hindernis -> Roboter fährt vorwärts
kurz vor Hindernis -> so lange nach links drehen bis absolut kein Hindernis mehr
vorwärts bis zum nächsten Hindernis -> so lange nach links drehen bis absolut kein Hindernis mehr
vorwärts bzw. wieder von vorne

Aber jetzt soll er irgendwie über infrarot merken, dass er sich nicht mehr weiter nach links drehen soll oder so, so ganz habe ich das auch noch nicht verstanden. Und man kann jetzt nicht das Programm so ändern wie du es willst, indem man einfach Zeilen dazu schreibt, sondern man muss das Programm durch und durch verstehen (!) und dann abändern (Wie Hannes auch schon schrieb). Ich habe mich da bei meinem Code anscheinend etwas zu viel auf aussagekräftige Variablennamen verlassen und zu wenig erläutert..

An deiner Stelle würde ich jetzt folgendermaßen vorgehen:

Eine Skizze anfertigen (und hier posten. Entweder von Hand zeichnen und ein scharfes Foto machen, oder ein Foto von deinem Aufbau machen und genau erklären, oder auch am PC zeichnen wenn du passende Software hast)
Ganz genau Punkt für Punkt erläutern was der Robo machen soll. Worauf soll er reagieren, was spielt alles eine Rolle etc. (Der hat auch kein "Verständnis" und erkennt selbst was du tun möchtest, du musst alles haarklein definieren)
Herausfinden, wie die Sensoren des Roboters funktionieren, insbesondere bei welchen Werten du reagieren möchtest. Du schreibst z.B. dass er zu spät vor dem Hindernis stehen bleibt. Dann musst du zuerst einmal herausfinden bei welchem Abstandswert er reagieren soll. Um das zu tun schreibst du ein ganz einfaches Programm, das z.B. dass der Robo bis zu einem bestimmten Wert vorwärts fährt und dann stehen bleibt. Dann änderst du diesen Wert bis er dir passt, notierst ihn und postest ihn dann auch hier (das betrifft den Abstand und den Infrarot Wert)


Wenn du das hast, können wir dir helfen das Programm zu schreiben. Denn ich denke, dass du mit der bisherigen Vorgehensweise nicht mehr weiter kommst..

Viele Grüße
schumi

PS: Wie steht es eigentlich um deine Kenntnisse in Sachen C? Kannst du mit "#define" überhaupt was anfangen? Was ist der unterschied zu "const"? Und warum const' du deine SENSOR* Variablen?

021aet04
05.01.2014, 20:37
Schumi kann ich nur zustimmen.

Du könntest dich ins Thema C einlesen, wäre vielleicht nicht schlecht. Z.B. http://www.c-howto.de/ => dort findest du alles was du brauchst (Schleifen, Verzweigungen, Variablen,...)

MfG Hannes

timmy19
06.01.2014, 00:06
Also das mit dem Foto wird heute schwer(kann ich ev. morgen machen), aber ich kann es euch erklären:

- Unser Aufbau ist ein Untergrund, der sich farblich ändert - von dunkel zu hell(in der Mitte) zu dunkel.
- Darauf stehen mehrere Hindernisse, immer im Wechsel rechts links(etwa 4-6 Stück).
- Der Robo fährt also auf das erste Hindernis zu, dreht früh genug links, dann bis zu einer bestimmten Farbe wieder geradeaus(etwa 180), dann soll er sich wieder so drehen, dass er "gerade" steht.
- Dann fährt er auf das nächste Hindernis zu(diesmal auf der linken Seite), soll sich rechts drehen, wieder bis zu der selben Farbe auf der anderen Seite fahren, wieder links drehen. Und das eben zwei bis drei Mal.
- Wie gesagt, leider haben wir kein LED und daher kann ich mich nur auf die Werte beziehen, die wir in der Schule gemessen haben und bei welchen es bei den Hindernissen bestens geklappt hat. Warum es bei meinen Hindernissen nicht klappt versteh ich selber nicht...
- An den Seiten der Strecke links und rechts sind jeweils keine für den Roboter erkennbaren Hindernisse, deshalb muss das mit Infrarot gemacht werden und ein Sensor eingebaut werden.

Hilft das schon weiter?

PS: Meine Kenntnisse in C sind nicht besonders(wie ihr sicher bemerkt habt. ;) ), aber was define ist versteh ich grad so noch. Wenn du das meinst, warum ich das mit if(abstand < hindernis) in if(abstand < 85) umgebaut habe, dass liegt daran, dass der Robo irgendwie teilweise darauf nicht reagiert hat, es mit if(abstand < 85) aber besser geklappt hat.

Geistesblitz
06.01.2014, 00:45
Infrarotsensoren haben aber so die Eigenart, dass sie extrem unterschiedlich auf die Farbe und die Beschaffenheit des Untergrunds reagieren. Bei weißem, spiegelglatten Untergrund (oder Aluminium) löst der Sensor schon sehr früh aus, bei rauhem schwarzen Untergrund kaum. Da wäre Ultraschall vielleicht doch besser, aber darauf kannst du keinen Einfluss nehmen, wenn das die Aufgabenstellung nicht vorsieht. Das heißt, dass du jetzt wirklich überlegen musst, wie du die richtigen Werte für dich herausfinden kannst. Um zu sehen, welcher Wert vom Infrarotsensor am besten zu der gewünschten Weite passt, wo der Roboter sich drehen soll, kannst du zB. ein einfaches Programm schreiben, wo der Sensor einfach abgefragt wird und je nachdem, ob der Wert über einem bestimmten Wert ist, eine LED schaltet. Dann kannst du den Roboter näher an das Hindernis halten oder weiter weg und gucken, wann die LED an oder aus geht. Das probierst du dann mit mehreren Werten (und vielleicht auch mit verschiedenen Hindernissen), bis du einen Wert gefunden hast, der gut ist. Dass man auch einfach den Sensorwert auf die Motoren geben kann, ist auch eine gute Möglichkeit. Weißt du denn, was für ein Infrarotsensor verwendet wird und was für Werte man wann erwarten kann?
Kann mir gar nicht vorstellen, dass du keine LED oder ähnliches am Roboter hast, sowas ließe sich gut für Debuggingzwecke verwenden (zB., ob in bestimmte Verzweigungen gesprungen wird oder ähnliches).

timmy19
06.01.2014, 12:47
Da reden wir aneiander vor bei: Klar, ich hab 3 LEDs(2 grün, 1 rot), ich meinte so nen LED-Display an dem man Werte ablesen kann, das hab ich nämlich nicht...

Edit: Hab das jetzt getestet: Für meine Bahn ist infrarot < 120 perfekt.

Mein Code sieht nun so aus:


#include "qfixMiniBoard.h"
#include "qfixLCD.h"


const int SENSOR3 = 3;
int SENSOR1 = 1;
int SENSOR2 = 2;
int SENSOR = 0;

MiniBoard robot;
LCD lcd;

#define geradeaus 0
#define linksDrehung 1
#define rechtsDrehung 2

#define hindernis 85
#define freieSicht 150 // Wenn der Robo etwas nach links fährt, aber dann gegen das Hindernis, ist dieser Wert zu klein

#define True 1
#define False 0

int main()
{

unsigned char drehrichtung = geradeaus; // unsigned char = 8bit integer von 0 bis 255, braucht weniger Platz im RAM
unsigned char schonNachLinksAusgewichen = False;
int abstand = robot.analog(1);
int infrarot = robot.analog(3);

while(1)
{


if( drehrichtung == geradeaus)
{
robot.motors(200,200); //geradeaus fahren
if( abstand < 90)
{
if(schonNachLinksAusgewichen == False)
drehrichtung = linksDrehung;
else
drehrichtung = rechtsDrehung;
}
}
if( drehrichtung == linksDrehung )
{
robot.motors(-100,-100);
msleep(100);
robot.motors(-150, 150); // nach links drehen
msleep(300);
if( abstand >= 150 )
{
robot.motors(200,200);
msleep(500);
schonNachLinksAusgewichen = True;
robot.motors(150, -150);

if( infrarot < 120){
robot.motors(100,-100);
msleep(500);

}
}
if( drehrichtung == rechtsDrehung )
{
robot.motors(-100, -100);
msleep(100);
robot.motors(150, -150); // nach rechts drehen
msleep(300);
if( abstand >= 150 )
{
robot.motors(200,200);
msleep(500);
schonNachLinksAusgewichen = False;
robot.motors(-150, 150);

int infrarot = robot.analog(3);
if( infrarot < 120){
robot.motors(100,-100);
msleep(500);


// Er ist zwar schon mal nach links ausgewichen, aber inzwischen auch schon rechtsrum, also wieder von vorne





}
}
}

}
}
}

Trotzdem reagiert der Robo nicht auf den Boden. Ich weiß leider immer noch nicht woran das liegt. Kann das sein, dass er gar nicht soweit in seiner Schleife vorankommt?

Geistesblitz
06.01.2014, 16:04
Ich hab gerade mal versucht, deinen Code zu entziffern, aber die Einrückungen machen es wirklich sehr unleserlich. Wenn eine geschweifte Klammer aufgeht, sollte alles darunter eine Stufe weiter rechts stehen, wenn eine geschweifte Klammer zu geht, weiter nach links. Oder wird dein Code durch die Code-Tags übern Haufen geworfen?

Jedenfalls vermute ich auch mal, dass deine Probleme in der Verschachtelung liegen, hab mindestens eine Stelle gesehen, wo ein elseif oder zumindest ein else angebracht wäre.

Edit: warum wird eigentlich eine LCD_Bibliothek eingebunden, wenn kein LCD vorhanden ist? Muss ich das verstehen?

nochmal Edit: ist abstand der Wert, den du vom Entfernungssensor ausliest, um ein Hinternis zu detektieren? Der wird nämlich einmal am Anfang vor der while-Schleife ausgelesen und dann nie wieder...das heißt, der Wert ändert sich nie. Du musst den Sensor bei jedem Schleifendurchlauf auslesen mit


abstand = robot.analog(1);

sonst kann das gar nix werden...

021aet04
06.01.2014, 17:22
Und wieder "int infrarot = robot.analog(3);" in der while Schleife.

MfG Hannes

timmy19
06.01.2014, 18:56
Danke, hab dass aber schon irgedwann heute morgen reingeschrieben. Soweit passt das jetzt auch. Jetzt brauch ich nur noch dieses blöde Infrarot. Hier der Code der Linksdrehung:




if( drehrichtung == linksDrehung )
{
robot.motors(-255, 255); // nach links drehen


if( abstand >= freieSicht )
{
robot.motors(200,200);
schonNachLinksAusgewichen = True;
//if( infrarot > 180){
//robot.motors(100,-100);
//msleep(500);
//}

}



Das Infrarot ist grad noch auskommentiert, da es nicht klappt. Wie bekomm ich es hin, dass:

- Der Robo nach der Linksdrehung eben wieder geradeaus in waagrechte Richtung fährt, aber währenddessen per Infrarot den Boden prüft und bei > 180 (das ist der Wert, hab ich über die LEDs geprüft) sich wieder dreht (hier nach rechts)? Wenn ich das nicht habe, komm ich gar nicht weiter und ich weiß leider nicht, was ich da noch verändern könnte, so dass er das macht. Habt ihr ne Ahnung, wie ich das hinbekommen könnte?

021aet04
06.01.2014, 19:45
Was funktioniert nicht? Was macht der Roboter?
Mach einfach eine Skizze wie und wo der Roboter auf was reagieren soll. Das dein Roboter waagrechter Richtung fährt ist eigentlich logisch.

Du könntest dich auch weiter informieren (es gibt nicht nur if Schleifen) z.B. der Link den ich oben gepostet habe. Es gibt auch fußgesteuerte Schleifen, if und while sind kopfgesteuerte Schleifen da diese am Anfang überprüft werden.

Für die Skizze kannst du ein CAD Programm herunterladen oder du verwendest einfach Paint.

MfG Hannes

timmy19
06.01.2014, 20:07
Hab ich gemacht, zumindest so halbwegs.

Ich glaube es ist logisch: Am ersten weißen Kreis soll sich der Robo(das Quadrat) links drehen, dann ab dann per Infrarot den Boden scannen und sich am schwarzen Kreis(Wert >180) rechts drehen, damit er auf das nächste Hindernis zu fahren kann. Danach dasselbe in grün nur umgekehrt, also erst rechts drehen, dann links. Wie gesagt, ich hab was für das Infrarot geschrieben, nur will es nicht. Wie kann ich das anders machen?

Und noch eine Frage: Wie kann ich es machen, dass sich der Robo genau 90° dreht? Irgendwie macht der das nur manchmal...

So sieht das Programm derzeit aus:


while(1)
{
int abstand = robot.analog(1);
//int infrarot = robot.analog(3);
if( drehrichtung == geradeaus)
{
robot.motors(25,25); //geradeaus fahren
if( abstand < hindernis)
{
if(schonNachLinksAusgewichen == False)
drehrichtung = linksDrehung;
else
drehrichtung = rechtsDrehung;
}
}
if( drehrichtung == linksDrehung )
{

robot.motors(-255, 255); // nach links drehen

if( abstand >= freieSicht )
{
robot.motors(125,125);
schonNachLinksAusgewichen = True;
//if( infrarot > 180){
//robot.motors(100,-100);
//msleep(500);
//}

}
}
if( drehrichtung == rechtsDrehung )
{
robot.motors(200, -200); // nach rechts drehen
if( abstand >= freieSicht )
{
robot.motors(100,100);
schonNachLinksAusgewichen = False;
//msleep(500);
//if( infrarot > 180){
//robot.motors(-100,100);
//}

// Er ist zwar schon mal nach links ausgewichen, aber inzwischen auch schon rechtsrum, also wieder von vorne





}
}
}
}



____

Leider habe ich im Alltag nicht all zu viel Zeit dafür, mich einzulesen und jetzt ist zu spät, Ferienende. Zudem sollte das Ding eigentlich bis Mittwoch fertig sein, werd ich aber wohl nicht schaffen. Nun gut, kann man nix machen...

-schumi-
06.01.2014, 21:09
Gut, dass du endlich eine Skizze lieferst. Das mit den Hindernissen habe ich erst nicht so verstanden, erst wie du das Infrarot erklärt hast. Dafür habe ich dann das Infrarot nicht kapiert. So sieht man gleich was Sache ist, und es ist ganz klar, dass das vorherige Programm hierfür nicht geeignet ist.

Da du es zumindest versucht hast gibts auch als Belohnung (auch im Anhang nochmal als tmp.c, damit die Einrückungen korrekt erhalten bleiben):


#include "qfixMiniBoard.h"
#include "qfixLCD.h"
MiniBoard robot;


// Müssen evtl. angepasst werden:
#define HindernisAbstand 85
#define Schwarzwert 180
#define Drehgeschwindigkeit 25
#define Drehzeit 3000 // in ms
#define Fahrgeschwindigkeit 25


// Feste Konstanten:
#define SensorAbstand 1
#define SensorInfrarot 3

#define Links 1
#define Rechts 2

int main()
{
// Es wird davon ausgegangen, dass der Robo so los fährt wie auf deiner Skizze, also auf der rechten Seite (und somit als erstes nach links muss):
unsigned char naechsteAbbiegungNach = Links

while(1)
{

robot.motors(Fahrgeschwindigkeit,Fahrgeschwindigke it); // Zuerst mal geradeaus fahren
while(robot.analog(SensorAbstand)>HindernisAbstand); // Und so lange kein Hindernis in sicht nichts anderes tun
robot.motors(0,0); // Jetzt muss ein Hindernis da sein, also erst mal stehen bleiben

if(naechsteAbbiegungNach == Links) // Wenn wir jetzt als nächstes nach links müssen...
robot.motors(-Drehgeschwindigkeit, Drehgeschwindigkeit); // ..drehen wir mal nach links
else if(naechsteAbbiegungNach == Rechts)
robot.motors(Drehgeschwindigkeit, -Drehgeschwindigkeit);

msleep(Drehzeit); // Da es keinen Anhaltspunkt gibt, wie weit nach links, einfach mal eine bestimmte Zeit lang...
robot.motors(Fahrgeschwindigkeit,Fahrgeschwindigke it); // Und wenn fertig gedreht wieder geradeaus fahren (jetzt bewegt sich der Robo von einer Seite zur anderen)
while(robot.analog(SensorInfrarot)<Schwarzwert); // Solange der Infrarotwert nicht "schwarz" bedeuted, nichts weiter machen
robot.motors(0,0); // Jetzt muss der schwarze Punkt da sein, also erst mal stehen bleiben

// Bsp. für Linksabbiegung: Um die Linksabbiegung abzuschließen muss der Robo sich jetzt wieder nach rechts drehen, damit er wieder gerade steht.
if(naechsteAbbiegungNach == Links)
robot.motors(Drehgeschwindigkeit, -Drehgeschwindigkeit);
else if(naechsteAbbiegungNach == Rechts) // Und um die Rechtsabbiegung abzuschließen nach links drehen
robot.motors(-Drehgeschwindigkeit, Drehgeschwindigkeit);
msleep(Drehzeit); // Da es keinen Anhaltspunkt gibt, wie weit nach links, einfach mal eine bestimmte Zeit lang...
robot.motors(0,0); // fertig gedreht

// So, jetzt hat der Roboter entweder von der rechten auf die linke Seite gewechselt (Linksabbiegung) oder anders herum. Da er durch das zweite Drehen in die andere Richtung
// jetzt auch wieder gerade steht und auf das nächste Hindernis zufahren kann, geht das ganze wieder von vorne losgehen. Nur müssen wir vorher noch die nächste Abbiegung bestimmen,
// die logischerweise genau das Gegenteil von der letzten Abbiegung ist:
if(naechsteAbbiegungNach == Links)
naechsteAbbiegungNach == Rechts;
else if(naechsteAbbiegungNach == Rechts)
naechsteAbbiegungNach == Links;
}

return 0; // Keine Relevanz für den Programmablauf, gehört sich aber für ein sauberes C-Programm
}

Auch wenn du deine Hausaufgabe jetz (zumindest zum Großteil hast), musst du noch an deinen Fähigkeiten in Sachen Programmierung arbeiten. Denn wenn ihr darüber auch Prüfungen schreibt, wirst du da mit Ach und Krach durchrasseln.. (Ich würde vorschlagen, du übst weiter mit dem Robo, aber mit einfacheren Aufgabenstellungen)

Viele Grüße
schumi

PS: das #define ist einfach nur Textersetzung, die vom sogenannten Preprozessor durchgeführt wird. Der entfernt auch alle Kommentare usw. und bereitet so den Quellcode zum kompilieren (übersetzen in Maschinensprache) vor. Wie das Programm mit den Ersetzungen aussieht kannst du auch im Anhang sehen (ich habe nur die #include weggelassen, weil die auch der Preprozessor behandelt, die aber nicht auf meinem Computer installiert sind)

[EDIT]
Habe noch Fehler gefunden:
Bei den msleep muss es natürlich nicht Drehgeschwindigkeit sondern Drehzeit heißen! Kann ich aber in den Anhängen anscheinend nicht mehr ändern.. Und das #define True/False ist jetzt auch überflüssig

Geistesblitz
06.01.2014, 21:13
Für koordiniertes Drehen bräuchtest du entweder Schrittmotore oder eine Winkelrückmeldung von den Rädern, ansonsten wirst du immer Abweichungen drin haben.

Was funktioniert an den schwarzen Kreisen nicht?
Hab ich das richtig verstanden, dass der Roboter an der Unterseite irgendwo (?) einen Infrarotsensor hat, der Schwarz von nicht-Schwarz unterscheiden kann? Das wär dann doch genauso zu lösen, wie die Detektion vom Hindernis, nur, dass er sich nicht zwingend nochmal zurück bewegen muss.

Um den schwarzen Kreis sicher zu treffen, wäre wirklich gut, wenn der Roboter seine Orientierung bestimmen könne. Das Einfachste wäre wohl ein Kompasssensor, ansonsten lässt sich das wohl nur über die Radstellungen gewinnen. Gibt auch noch andere Verfahren, die dann aber meist mit zusätzlichen Raumpunkten, zB. Infrarotmarkern, arbeiten, aber das wird eben immer aufwändiger. Wenn sowas nicht zur Verfügung steht, musst du wohl oder übel hoffen, dass er beim Drehen nicht zu weit von den 90° abweicht. Gegebenenfalls die Wartezeit beim Drehen noch anpassen, sind ja noch ziemlich runde Werte. Vielleicht bringt es ja schon was, beim Drehen mit der Geschwindigkeit ein wenig runter zu gehen.

timmy19
06.01.2014, 22:54
Soviel hab ich jetzt gar nicht erwartet. ;)
Aber danke! :)

Nun, es gibt dennoch nen kleinen Fehler:
Er dreht sich ständig im Kreis(hatte das Problem schonmal, als ich den Infrarotsensor einsetzte). Könnt mir also vorstellen, dass das wieder am Infrarotsensor(?!) liegt. Er fährt nämlich solange geradeaus, bis er die Stelle gefunden hat, die über 180 ist. Wie kann man das ändern, dass der den Infrarotsensor erst nach dem ersten Drehen benutzt, also erstmal ganz normal auf das Hindernis zu fährt, sich dann dreht und dann die Stelle sucht, die über dem Wert 180 liegt? Vielleicht kann man den Infrarotsensor ja "schlafen" lassen bis zu ner bestimmten Zeit.

-schumi-
06.01.2014, 23:03
Kannst du noch mal ganz genau Schritt für Schritt erklären, was passiert wenn du ihn so wie in deiner Skizze hinsetzt und einschaltest? Du musst immer so präzise wie möglich beschreiben, sonst weis man nicht an welcher Stelle des Codes es hapert..

timmy19
07.01.2014, 13:45
Also: Wenn ich ihn so hinsetzte wie bei der Skizze macht er nichts anderes als die dunkle Farbe suchen(Wert 180) und sich darüber im Kreis zu drehen... weiß gar nicht warum, schätze aber das das am Infrarot liegt.

Wie gesagt: Hatte das Problem schonmal, konnte es aber damals schon nicht lösen... ihr vllt.?

Geistesblitz
07.01.2014, 13:58
Kann es sein, dass er direkt danach wieder eine schwarze Fläche sucht, und da er ja immer noch auf ihr drauf steht, findet er sie auch gleich wieder und dreht sich nochmal etc.
Müsstest wohl so umprogrammieren, dass er danach nur wieder nach einem Hindernis sucht und die schwarze Fläche ignoriert.

timmy19
07.01.2014, 14:41
Er soll die schwarze Fläche ja erst suchen, wenn er schon einmal links gedreht hat... Von daher wäre meine Frage: Wie kann ich es so programmieren, dass er das Infrarot erst dann einschaltet, wenn er sich schonmal gedreht hat? Geht das überhaupt? Das ist mein Grundproblem von anfang an gewesen und ich hab es nie lösen können. Sobald das Infrarot ins Programm geschrieben wurde, drehte er sich nur noch.

-schumi-
07.01.2014, 16:54
Wie kann ich es so programmieren, dass er das Infrarot erst dann einschaltet, wenn er sich schonmal gedreht hat?
Also ich habe schon mehreren Leuten (im echten Leben ;)) C beigebracht. Und diese Frage bestätigt einen Verdacht den ich schon vorher hatte, nämlich dass du noch nicht ganz verstanden hast wie ein Programm abläuft. Komischerweise scheint das aber vielen Leuten zuerst nicht in den Kopf zu gehen, nur die wenigsten checken es sofort..

Desshalb erkläre ich noch bevor irgend ein Code gezeigt wird folgendes:
Stell dir vor du liest eine Bedienungsanleitung. Wie machst du das? Na klar, Schritt für Schritt, und nebenbei machst du immer das was in diesem Schritt zu tun ist. Das was du vorher gemacht hast und was du später machen musst spielt in diesem Moment keine Rolle.

Was du machst wenn du programmierst ist eine Bedienungsanleitung für den Mikrocontroller schreiben. Und der ließt die auch nicht irgendwie durcheinander oder macht alles gleichzeitig, sonder auch streng Schritt für Schritt. Und zwar Zeile für Zeile von oben nach unten. Beispiel:


int main (void)
{
int zahl = 5;

if( zahl>100)
{
Alarm_Einschalten();
}

zahl = 5000;

return 0; // Programmende
}

Ganz einfach: Eine Variable "zahl" wird mit dem Inhalt 5 erstellt. Wenn die zahl größer 100 ist wird Alarm ausgelöst, und dann wird 5000 in zahl geschrieben.

Was ich denke dass du vermutest dass passiert: sobald das "zahl = 5000;" ausgeführt wird, wird Alarm ausgelöst. :!: DAS IST NICHT SO :!:

Denk dir du bist ein Mikrocontroller und liest das Programm, was du tust ist:

int zahl = 5; -> Arbeitsspeicher für die Variable "zahl" reservieren und 5 reinspeichern
if( zahl>100) -> Ist denn zahl > 100? NEIN, denn zahl ist 5. Also kann der nächste Befehl (also die { blabla } ) übersprungen werden
zahl = 5000; -> Gut, dann speichern wir 5000 in den Arbeitsspeicher der für "zahl" reserviert ist
return 0; -> Programmende. Habe fertig.


Du wirst jetzt warscheinlich sagen: "Ja, aber bei Schritt 3 speichere ich ja 5000 in Zahl, da muss ich doch den Alarm einschalten!". NEIN. Der Mikrocontroller merkt sich nicht was vorher war, er macht folgt strikt Zeile für Zeile den Befehlen. (wie ich schrieb: "Das was du vorher gemacht hast und was du später machen musst spielt in diesem Moment keine Rolle.").

Zurück zu deiner Frage:

Wie kann ich es so programmieren, dass er das Infrarot erst dann einschaltet, wenn er sich schonmal gedreht hat?

Und dann den Code:


#include "qfixMiniBoard.h"
#include "qfixLCD.h"
MiniBoard robot;


// Müssen evtl. angepasst werden:
#define HindernisAbstand 85
#define Schwarzwert 180
#define Drehgeschwindigkeit 25
#define Drehzeit 3000 // in ms
#define Fahrgeschwindigkeit 25


// Feste Konstanten:
#define SensorAbstand 1
#define SensorInfrarot 3

#define Links 1
#define Rechts 2

int main()
{
// Es wird davon ausgegangen, dass der Robo so los fährt wie auf deiner Skizze, also auf der rechten Seite (und somit als erstes nach links muss):
unsigned char naechsteAbbiegungNach = Links

while(1)
{

robot.motors(Fahrgeschwindigkeit,Fahrgeschwindigke it); // Zuerst mal geradeaus fahren
while(robot.analog(SensorAbstand)>HindernisAbstand); // Und so lange kein Hindernis in sicht nichts anderes tun
robot.motors(0,0); // Jetzt muss ein Hindernis da sein, also erst mal stehen bleiben

if(naechsteAbbiegungNach == Links) // Wenn wir jetzt als nächstes nach links müssen...
robot.motors(-Drehgeschwindigkeit, Drehgeschwindigkeit); // ..drehen wir mal nach links
else if(naechsteAbbiegungNach == Rechts)
robot.motors(Drehgeschwindigkeit, -Drehgeschwindigkeit);

msleep(Drehzeit); // Da es keinen Anhaltspunkt gibt, wie weit nach links, einfach mal eine bestimmte Zeit lang...
robot.motors(Fahrgeschwindigkeit,Fahrgeschwindigke it); // Und wenn fertig gedreht wieder geradeaus fahren (jetzt bewegt sich der Robo von einer Seite zur anderen)
while(robot.analog(SensorInfrarot)<Schwarzwert); // Solange der Infrarotwert nicht "schwarz" bedeuted, nichts weiter machen
robot.motors(0,0); // Jetzt muss der schwarze Punkt da sein, also erst mal stehen bleiben

// Bsp. für Linksabbiegung: Um die Linksabbiegung abzuschließen muss der Robo sich jetzt wieder nach rechts drehen, damit er wieder gerade steht.
if(naechsteAbbiegungNach == Links)
robot.motors(Drehgeschwindigkeit, -Drehgeschwindigkeit);
else if(naechsteAbbiegungNach == Rechts) // Und um die Rechtsabbiegung abzuschließen nach links drehen
robot.motors(-Drehgeschwindigkeit, Drehgeschwindigkeit);
msleep(Drehzeit); // Da es keinen Anhaltspunkt gibt, wie weit nach links, einfach mal eine bestimmte Zeit lang...
robot.motors(0,0); // fertig gedreht

// So, jetzt hat der Roboter entweder von der rechten auf die linke Seite gewechselt (Linksabbiegung) oder anders herum. Da er durch das zweite Drehen in die andere Richtung
// jetzt auch wieder gerade steht und auf das nächste Hindernis zufahren kann, geht das ganze wieder von vorne losgehen. Nur müssen wir vorher noch die nächste Abbiegung bestimmen,
// die logischerweise genau das Gegenteil von der letzten Abbiegung ist:
if(naechsteAbbiegungNach == Links)
naechsteAbbiegungNach == Rechts;
else if(naechsteAbbiegungNach == Rechts)
naechsteAbbiegungNach == Links;
}

return 0; // Keine Relevanz für den Programmablauf, gehört sich aber für ein sauberes C-Programm
}

Wenn du jetzt nach dem auslesen des Infrarotsensors suchst, wirst du feststellen, dass er nur in der rot markierten Zeile eine vorkommt. In allen anderen Zeilen ist der Infrarotsensore absolut piepschnurzegal! (<- Nicht möchte es nur deutlich genug sagen ;)) Jetzt merkst du hoffentlich, dass deine Frage keinen Sinn ergibt..



Also: Wenn ich ihn so hinsetzte wie bei der Skizze macht er nichts anderes als die dunkle Farbe suchen(Wert 180) und sich darüber im Kreis zu drehen...
Analyse (Versuche es im Quelltext nachzuvollziehen, das grüne entspricht deiner Frage):

Über der roten Zeile fährt er geradeaus

In der roten Zeile macht er nichts, solange er den schwarzen Punkt noch nicht gefunden hat

Dann bleibt er stehen (er hat den Punkt gefunden)

Dann dreht er je nach Drehrichtung (mit den if's)
wartet für 3 Sekunden
Er bleibt stehen
Dann wechselt er die "nächsteAbbiegungNach" und springt an den Anfang de while-Schleife
Dann fährt er geradeaus, ändert nichts bis er das Hindernis gefunden hat, bleibt dann stehen
Er dreht sich wieder für 3 Sekunden
Fährt dann wieder geradeaus, bzw erster Punkt dieser Aufzählung

Man könnte jetzt also zur Annahme kommen dass deine Entfernungsmessung nicht funktioniert und immer ein Hindernis sieht (rote Zeile).
(Und im übrigen wird man das stehenbleiben auch nicht sehen könne, weil er sofort danach auf eine andere Bewegung umschaltet)

ABER: Dann müsste sich der Robo 3+3 Sekunden in die eine und dann 3+3 Sekunden in die andere Richtung drehen. Du hast aber nicht präzise genug geantwortet, so dass man nicht weis, was der Robo genau tut. Eine richtige Antwort wäre gewesen:

Wenn ich den Robo wie in der Skizze auf seine Startposition setze, ihn dann einschalte fährt er nur geradeaus. Außer er findet einen schwarzen Punkt, dann dreht er sich auf ihm nach links und hört auch nach ca. 20 Sekunden nicht damit auf
Ich habe das was du nicht gesagt hast rot markiert:

Einschalten: Nur so kann man davon ausgehen, dass der Roboter sein Programm auch von vorne an abarbeitet, und nicht "irgendwo mitten in der Bedienungsanleitung drin steckt" wenn du ihn auf seine Startposition setzt
links: Wenn er sich nur in eine Richtung dreht, stimmt jedenfalls noch mehr nicht als eine nichtfunktionierende Abstandsmessung
20 Sekunden: Wenn nur die Abstandsmessung nicht funktioniert, wechselt er alle 3+3 = 6 Sekunden die Drehrichtung. Man weis jetzt nicht; vielleicht hast du den Robo nur für 5 Sekunden drehen lassen?



Ich hoffe deinem Grundverständnis für Programmcode ein wenig auf die Sprünge geholfen zu haben. Nur leider ist es sehr schwer das jemandem übers Internet beizubringen.. Und wenn du ganz ganz genaue Angaben machst was ganz genau der Robo tut und ihn auch sicher erst einschaltest wenn er auf seiner Startposition sitzt, dann bekommen wir das Ding vielleicht noch zum laufen..

timmy19
07.01.2014, 17:33
Es scheint tatsächlich noch bisschen mehr falsch zu sein. Der Robo zeigt nämlich unterschiedliche Reaktionen beim selben Startpunkt:

ERSTENS: Beim ersten Starten drehte er sich nur nach links( bis ich nach etwa 20 sec abgeschalten habe)
ZWEITENS: Er fuhr einmal kurz vor, dann wieder zurück, dann drehte er sich wieder paar mal nach links und fuhr dann ständig nur noch vor und zurück (wieder so nen Ruckeln)

Hab das dann paar mal ausprobiert, mal kam das eine mal das andere.

Das kann meiner Meinung nach trotzdem an nichts anderem liegen, als am Infrarot...


Edit: Nein er fährt definitiv nur nach links, jetzt grade schon mindestens 40 sec.

-schumi-
07.01.2014, 17:47
ZWEITENS: Er fuhr einmal kurz vor, dann wieder zurück, dann drehte er sich wieder paar mal nach links und fuhr dann ständig nur noch vor und zurück (wieder so nen Ruckeln)

Irgendetwas kann einfach nicht stimmen. Im gesammten Programm gibt es keine einzige Anweisung, die den Roboter rückwärts fahren lässt (das kann man auch in der tmp_preprozessor.c sehen, kein robot.motors mit zwei negativen Zahlen). Wenn du das Programm fehlerfrei kopiert und auf den Roboter übertragen hast, kann ich in keinster Weise nachvollziehen woher das kommen soll. Bleibt nur noch irgendwelche Softwarespezialitäten von denen man als Außenstehender nichts ahnen kann oder ein Hardwaredefekt.

Leider kann ich dir hier nicht mehr weiterhelfen :(

timmy19
07.01.2014, 18:22
Hab zwischen drin auch schon an sowas gedacht, aber irgendwie kann das doch nicht sein. :(

Wie könnte man denn in das vorherige Programm nen Infrarot reinbekommen?


#include "qfixMiniBoard.h"
#include "qfixLCD.h"


const int SENSOR3 = 3;
int SENSOR1 = 1;
int SENSOR2 = 2;
int SENSOR = 0;

MiniBoard robot;
LCD lcd;

#define geradeaus 0
#define linksDrehung 1
#define rechtsDrehung 2

#define hindernis 95
#define freieSicht 120 // Wenn der Robo etwas nach links fährt, aber dann gegen das Hindernis, ist dieser Wert zu klein

#define True 1
#define False 0

int main()
{
unsigned char drehrichtung = geradeaus; // unsigned char = 8bit integer von 0 bis 255, braucht weniger Platz im RAM
unsigned char schonNachLinksAusgewichen = False;

while(1)
{
int abstand = robot.analog(1);
//int infrarot = robot.analog(3);
if( drehrichtung == geradeaus)
{
robot.motors(25,25); //geradeaus fahren
if( abstand < hindernis)
{
if(schonNachLinksAusgewichen == False)
drehrichtung = linksDrehung;
else
drehrichtung = rechtsDrehung;
}
}
if( drehrichtung == linksDrehung )
{

robot.motors(-255, 255); // nach links drehen

if( abstand >= freieSicht )
{
robot.motors(125,125);
schonNachLinksAusgewichen = True;
//if( infrarot > 180){
//robot.motors(100,-100);
//msleep(500);
//}

}
}
if( drehrichtung == rechtsDrehung )
{
robot.motors(200, -200); // nach rechts drehen
if( abstand >= freieSicht )
{
robot.motors(100,100);
schonNachLinksAusgewichen = False;
//msleep(500);
//if( infrarot > 180){
//robot.motors(-100,100);
//}

// Er ist zwar schon mal nach links ausgewichen, aber inzwischen auch schon rechtsrum, also wieder von vorne





}
}
}
}



Im Prinzip müsste das Infrarot doch richtig sein oder nicht? Weil darauf reagiert er schlichtweg nicht...

Edit: Auch da ist sowas seltsam: Wenn ich bei der geradeaus-Schleife die Motoren auf 0 stelle fährt der trotzdem...was ist da los?
Und der dreht sich, egal was ich einstelle einfach nicht weit genug(der Abstandssensor reagiert nur bis 100, das FreieSicht geht nur bis 170). Was könnte ich da tun?

Denn irgendein Programm brauch ich, auch wenn es nur halb geht.