PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Programmierungs (C) Bewegungsproblem



TcH
01.06.2008, 10:54
Hallo

Ich habe mir jetzt vor paar Tagen den RP6 geholt (hatte anfänglich auch ein defektes USB Interface...) und bin jetzt fleißig am programmieren.

Momentan schreibe ich ein Programm mit einer Statemachine, was den Roboter durch den Raum manövrieren soll, ohne irgendwo anzuecken.



#include "RP6RobotBaseLib.h"

#define STATE_NONE 0
#define STATE_MOVE 1
#define STATE_ROTATE 2
#define STATE_HALT 3
#define STATE_CHANGE_DIRECTION 4
#define STATE_CHECK_FOR_OBSTACLE 5
#define STATE_INITIALIZE 6

uint8_t state;
uint8_t velocity;

void state_machine(void)
{
// Statusvariablen
int8_t is_moving = false;
int8_t is_rotating = false;

switch(state)
{
// Initialisieren
case STATE_INITIALIZE:
{
// Microcontroller initialisieren
initRobotBase();

// Motorencoder initialisieren
powerON();

// Entfernungssensoren aktivierencv
setACSPwrMed();

state = STATE_CHECK_FOR_OBSTACLE;

break;
}

// Fahren
case STATE_MOVE:
{
//move(velocity, FWD, DIST_MM(100), true);
//state = STATE_CHECK_FOR_OBSTACLE;

// Roboter fährt nicht
if(!is_moving)
{
move(velocity, FWD, DIST_MM(50), false);

is_moving = true;
state = STATE_MOVE;
}
// Roboter fährt bereits
else
{
// prüfen, ob Fahrvorgang abgeschlossen ist
if(isMovementComplete())
{
is_moving = false;
state = STATE_CHECK_FOR_OBSTACLE;
}
}


break;
}

// Rotieren
case STATE_ROTATE:
{
//rotate(velocity, LEFT, 45, true);
//state = STATE_CHECK_FOR_OBSTACLE;


// Roboter rotiert nicht
if(!is_rotating)
{
rotate(velocity, LEFT, 45, false);

is_rotating = true;
state = STATE_ROTATE;
}
// Roboter rotiert bereits
else
{
// Rotation ist abgeschlossen?
if(isMovementComplete())
{
is_rotating = false;
state = STATE_CHECK_FOR_OBSTACLE;
}
}


break;
}

// Kollision ermittlen
case STATE_CHECK_FOR_OBSTACLE:
{
// Hindernis gefunden?
if(obstacle_left || obstacle_right)
{
// rotieren...
setLEDs(0b111111);
state = STATE_ROTATE;

}
else
{
// fahren...
setLEDs(0b000000);
state = STATE_MOVE;

}

break;
}
}
}

int main(void)
{
// Anfangsstate festlegen...
state = STATE_INITIALIZE;

// Geschwindigkeit setzten
velocity = 200;

// Hauptschleife
while(true)
{
// gesamtes System updaten...
task_RP6System();

// State Machine durchlaufen
state_machine();
}

return 0;
}


Folgendes Problem habe ich: der Roboter soll, nachdem die Bewegungsroutine abgeschlossen ist prüfen, ob Hindernisse vor ihm liegen - er macht es aber nicht...
Warum kommt es in

case STATE_MOVE:
{
//move(velocity, FWD, DIST_MM(100), true);
//state = STATE_CHECK_FOR_OBSTACLE;

// Roboter fährt nicht
if(!is_moving)
{
move(velocity, FWD, DIST_MM(50), false);

is_moving = true;
state = STATE_MOVE;
}
// Roboter fährt bereits
else
{
// prüfen, ob Fahrvorgang abgeschlossen ist
if(isMovementComplete())
{
is_moving = false;
state = STATE_CHECK_FOR_OBSTACLE;
}
}


break;
}


nie zu


if(isMovementComplete())
{
is_moving = false;
state = STATE_CHECK_FOR_OBSTACLE;
}

Nochmal kurz die aktuelle (fehlerhafte VErhaltensbeschreibung des Roboters)
Er fährt einfach nur gerade durch, ohne Rücksicht auf Verluste ;)
(Die Sensoren vernachlässigt er (diese Funktionieren aber einwandfrei!))


mfG TcH

SlyD
01.06.2008, 13:21
Hallo TcH,

aus diesem State hier:



// Initialisieren
case STATE_INITIALIZE:
{
// Microcontroller initialisieren
initRobotBase();

// Motorencoder initialisieren
powerON();

// Entfernungssensoren aktivierencv
setACSPwrMed();

state = STATE_CHECK_FOR_OBSTACLE;

break;
}


sollte besser alles raus und wie in den Beispielprogrammen direkt am Anfang des Programms stehen - also ganz am Anfang der Main Funktion.
Mindestens initRobotBase(); MUSS ganz am Anfang stehen - sonst funktionieren einige Dinge nicht richtig.

Um den Fehler selbst besser eingrenzen zu können, kannst Du einfach in jeden Zustand der State Machine mal eine Textausgabe reinmachen. Dann siehst Du sofort wie sich die State Machine verhält wenn sich etwas ändert.
Also einfach ein paar writeString_P("State 12345 "); reinmachen und evtl. zusätzlich noch ein paar Sensorwerte per writeInteger mit ausgeben.

Also den Roboter dabei dann erstmal am Rechner angeschlossen lassen und die Ausgaben im Terminal ansehen.
Dabei den Roboter natürlich entweder mit der Hand hochheben oder irgendwas drunterstellen so dass er sich nicht bewegen kann.

MfG,
SlyD

KayH
02.06.2008, 00:43
Hi,

in der Methode state_machine() wird die Variable is_moving bei jedem Aufruf auf false gesetzt ... Das war wohl nicht der beabsichtigte Sinn. ;-)
Die sollte nur einmal initialisiert werden und spaeter ihren Wert in Abhaengigkeit anderer Ereignisse aendern.

hth
Kay

EDIT: hint: bitte informiere Dich ueber die Bedeutung von "static" im Zusammenhang mit einer "lokalen Variable"

TcH
03.06.2008, 11:43
Jop, dummer Fehler... den Zusammenhang mit static kenne ich, man hätte die Variablen alternativ auch Global deklarieren können.

TcH
03.06.2008, 18:10
Ich habe mal noch eine Frage: Ich habe bereits an meheren Stellen gelesen, dass es kein Problem sei, mit WinAVR C++ umzusetzten, leider kamen beim Compilieren einige Fehler.

Kann mir jemand sagen, welche Konfigurationen ich am Makefile/Compiler vornehmen muss?

schonmal Danke im Voraus