PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Bitte erkärt mir diesen Text



DerNeuling
15.04.2010, 17:37
Hi Com,

hier ist das Beispiel, in dem der RP6 in Richtung Licht fährt:


// Includes:

#include "RP6RobotBaseLib.h"

/************************************************** ***************************/
// Behaviour command type:

#define IDLE 0

// The behaviour command data type:
typedef struct {
uint8_t speed_left; // left speed (is used for rotation and
// move distance commands - if these commands are
// active, speed_right is ignored!)
uint8_t speed_right; // right speed
unsigned dir:2; // direction (FWD, BWD, LEFT, RIGHT)
unsigned move:1; // move flag
unsigned rotate:1; // rotate flag
uint16_t move_value; // move value is used for distance and angle values
uint8_t state; // state of the behaviour
} behaviour_command_t;

behaviour_command_t STOP = {0, 0, FWD, false, false, 0, IDLE};

/************************************************** ***************************/
// Cruise Behaviour:

#define CRUISE_SPEED_FWD 80 // Default speed

#define MOVE_FORWARDS 1
behaviour_command_t cruise = {CRUISE_SPEED_FWD, CRUISE_SPEED_FWD, FWD,
false, false, 0, MOVE_FORWARDS};

/**
* Cruise Behaviour
*/
void behaviour_cruise(void)
{
}

/************************************************** ***************************/
// Escape Behaviour:

#define ESCAPE_SPEED_BWD 80
#define ESCAPE_SPEED_ROTATE 60

#define ESCAPE_FRONT 1
#define ESCAPE_FRONT_WAIT 2
#define ESCAPE_LEFT 3
#define ESCAPE_LEFT_WAIT 4
#define ESCAPE_RIGHT 5
#define ESCAPE_RIGHT_WAIT 6
#define ESCAPE_WAIT_END 7
behaviour_command_t escape = {0, 0, FWD, false, false, 0, IDLE};

/**
* This is the Escape behaviour for the Bumpers.
*/
void behaviour_escape(void)
{
static uint8_t bump_count = 0;

switch(escape.state)
{
case IDLE:
break;
case ESCAPE_FRONT:
escape.speed_left = ESCAPE_SPEED_BWD;
escape.dir = BWD;
escape.move = true;
if(bump_count > 3)
escape.move_value = 200;
else
escape.move_value = 140;
escape.state = ESCAPE_FRONT_WAIT;
bump_count+=2;
break;
case ESCAPE_FRONT_WAIT:
if(!escape.move) // Wait for movement to be completed
{
escape.speed_left = ESCAPE_SPEED_ROTATE;
if(bump_count > 3)
{
escape.move_value = 110;
escape.dir = RIGHT;
bump_count = 0;
}
else
{
escape.dir = LEFT;
escape.move_value = 75;
}
escape.rotate = true;
escape.state = ESCAPE_WAIT_END;
}
break;
case ESCAPE_LEFT:
escape.speed_left = ESCAPE_SPEED_BWD;
escape.dir = BWD;
escape.move = true;
if(bump_count > 3)
escape.move_value = 160;
else
escape.move_value = 100;
escape.state = ESCAPE_LEFT_WAIT;
bump_count++;
break;
case ESCAPE_LEFT_WAIT:
if(!escape.move) // Wait for movement to be completed
{
escape.speed_left = ESCAPE_SPEED_ROTATE;
escape.dir = RIGHT;
escape.rotate = true;
if(bump_count > 3)
{
escape.move_value = 100;
bump_count = 0;
}
else
escape.move_value = 65;
escape.state = ESCAPE_WAIT_END;
}
break;
case ESCAPE_RIGHT:
escape.speed_left = ESCAPE_SPEED_BWD ;
escape.dir = BWD;
escape.move = true;
if(bump_count > 3)
escape.move_value = 160;
else
escape.move_value = 100;
escape.state = ESCAPE_RIGHT_WAIT;
bump_count++;
break;
case ESCAPE_RIGHT_WAIT:
if(!escape.move) // Wait for movement to be completed
{
escape.speed_left = ESCAPE_SPEED_ROTATE;
escape.dir = LEFT;
escape.rotate = true;
if(bump_count > 3)
{
escape.move_value = 100;
bump_count = 0;
}
else
escape.move_value = 65;
escape.state = ESCAPE_WAIT_END;
}
break;
case ESCAPE_WAIT_END:
if(!(escape.move || escape.rotate)) // Wait for movement/rotation to be completed
escape.state = IDLE;
break;
}
}

/**
* Bumpers Event handler
*/
void bumpersStateChanged(void)
{
if(bumper_left && bumper_right) // Both Bumpers were hit
{
escape.state = ESCAPE_FRONT;
}
else if(bumper_left) // Left Bumper was hit
{
if(escape.state != ESCAPE_FRONT_WAIT)
escape.state = ESCAPE_LEFT;
}
else if(bumper_right) // Right Bumper was hit
{
if(escape.state != ESCAPE_FRONT_WAIT)
escape.state = ESCAPE_RIGHT;
}
}

/************************************************** ***************************/
// Avoid Behaviour:

#define AVOID_SPEED_L_ARC_LEFT 20
#define AVOID_SPEED_L_ARC_RIGHT 80
#define AVOID_SPEED_R_ARC_LEFT 80
#define AVOID_SPEED_R_ARC_RIGHT 20

#define AVOID_SPEED_ROTATE 60

#define AVOID_OBSTACLE_RIGHT 1
#define AVOID_OBSTACLE_LEFT 2
#define AVOID_OBSTACLE_MIDDLE 3
#define AVOID_OBSTACLE_MIDDLE_WAIT 4
#define AVOID_END 5
behaviour_command_t avoid = {0, 0, FWD, false, false, 0, IDLE};

/**
* Avoid behaviour with ACS IR Sensors.
*/
void behaviour_avoid(void)
{
static uint8_t last_obstacle = LEFT;
static uint8_t obstacle_counter = 0;
switch(avoid.state)
{
case IDLE:
if(obstacle_right && obstacle_left) // left AND right sensor have detected something...
avoid.state = AVOID_OBSTACLE_MIDDLE;
else if(obstacle_left) // Left "sensor" has detected something
avoid.state = AVOID_OBSTACLE_LEFT;
else if(obstacle_right) // Right "sensor" has detected something
avoid.state = AVOID_OBSTACLE_RIGHT;
break;
case AVOID_OBSTACLE_MIDDLE:
avoid.dir = last_obstacle;
avoid.speed_left = AVOID_SPEED_ROTATE;
avoid.speed_right = AVOID_SPEED_ROTATE;
if(!(obstacle_left || obstacle_right))
{
if(obstacle_counter > 3)
{
obstacle_counter = 0;
setStopwatch4(0);
}
else
setStopwatch4(400);
startStopwatch4();
avoid.state = AVOID_END;
}
break;
case AVOID_OBSTACLE_RIGHT:
avoid.dir = FWD;
avoid.speed_left = AVOID_SPEED_L_ARC_LEFT;
avoid.speed_right = AVOID_SPEED_L_ARC_RIGHT;
if(obstacle_right && obstacle_left)
avoid.state = AVOID_OBSTACLE_MIDDLE;
if(!obstacle_right)
{
setStopwatch4(500);
startStopwatch4();
avoid.state = AVOID_END;
}
last_obstacle = RIGHT;
obstacle_counter++;
break;
case AVOID_OBSTACLE_LEFT:
avoid.dir = FWD;
avoid.speed_left = AVOID_SPEED_R_ARC_LEFT;
avoid.speed_right = AVOID_SPEED_R_ARC_RIGHT;
if(obstacle_right && obstacle_left)
avoid.state = AVOID_OBSTACLE_MIDDLE;
if(!obstacle_left)
{
setStopwatch4(500);
startStopwatch4();
avoid.state = AVOID_END;
}
last_obstacle = LEFT;
obstacle_counter++;
break;
case AVOID_END:
if(getStopwatch4() > 1000)
{
stopStopwatch4();
setStopwatch4(0);
avoid.state = IDLE;
}
break;
}
}

/**
* ACS Event Handler
*/
void acsStateChanged(void)
{
if(avoid.state != IDLE)
{
if(obstacle_left && obstacle_right)
statusLEDs.byte = 0b100100;
else
statusLEDs.byte = 0b000000;
statusLEDs.LED5 = obstacle_left;
statusLEDs.LED4 = (!obstacle_left);
statusLEDs.LED2 = obstacle_right;
statusLEDs.LED1 = (!obstacle_right);
updateStatusLEDs();
}
}

/************************************************** ***************************/
// Follow Behaviour:

#define FOLLOW 3

#define LIGHT_MIN 100

behaviour_command_t follow = {0, 0, FWD, false, false, 0, IDLE};

/**
* The new Light following behaviour.
*/
void behaviour_follow(void)
{
switch(follow.state)
{
case IDLE:
if(adcLSL >= LIGHT_MIN || adcLSR >= LIGHT_MIN) // Is the light bright enough?
{
setStopwatch6(0);
startStopwatch6();
follow.state = FOLLOW;
}
break;
case FOLLOW:
if(getStopwatch6() > 100)
{
if(adcLSL >= LIGHT_MIN || adcLSR >= LIGHT_MIN) // Is the light bright enough?
{
int16_t dif = ((int16_t)(adcLSL - adcLSR))>>1;
if(dif > 40) dif = 40;
if(dif < -40) dif = -40;
follow.speed_left = 60 - dif;
follow.speed_right = 60 + dif;

// Set LEDs - a small bargraph display that shows which sensor has detected
// brighter light - and how much brighter it is:
if(dif > 30)
setLEDs(0b111000);
else if(dif > 25)
setLEDs(0b011000);
else if(dif > 5)
setLEDs(0b001000);
else if(dif > -5)
setLEDs(0b001001);
else if(dif > -25)
setLEDs(0b000001);
else if(dif > -30)
setLEDs(0b000011);
else
setLEDs(0b000111);
}
else // The light is not bright enough - it is very dark!
{
stopStopwatch6();
follow.state = IDLE;
}
if((avoid.state || escape.state)) // Update LEDs with ACS values if there is an
{ // Obstacle...
if(obstacle_left && obstacle_right)
statusLEDs.byte = 0b100100;
else
statusLEDs.byte = 0b000000;
statusLEDs.LED5 = obstacle_left;
statusLEDs.LED4 = (!obstacle_left);
statusLEDs.LED2 = obstacle_right;
statusLEDs.LED1 = (!obstacle_right);
updateStatusLEDs();
}
setStopwatch6(0);
}
break;
}
}

/************************************************** ***************************/
// Behaviour control:

/**
* This function processes the movement commands that the behaviours generate.
* Depending on the values in the behaviour_command_t struct, it sets motor
* speed, moves a given distance or rotates.
*/
void moveCommand(behaviour_command_t * cmd)
{
if(cmd->move_value > 0) // move or rotate?
{
if(cmd->rotate)
rotate(cmd->speed_left, cmd->dir, cmd->move_value, false);
else if(cmd->move)
move(cmd->speed_left, cmd->dir, DIST_MM(cmd->move_value), false);
cmd->move_value = 0; // clear move value - the move commands are only
// given once and then runs in background.
}
else if(!(cmd->move || cmd->rotate)) // just move forwards?
{
changeDirection(cmd->dir);
moveAtSpeed(cmd->speed_left,cmd->speed_right);
}
else if(isMovementComplete()) // movement complete? --> clear flags!
{
cmd->rotate = false;
cmd->move = false;
}
}

/**
* The behaviourController task controls the subsumption architechture.
* It implements the priority levels of the different behaviours.
*/
void behaviourController(void)
{
// Call all the behaviour tasks:
behaviour_cruise();
behaviour_follow();
behaviour_avoid();
behaviour_escape();

// Execute the commands depending on priority levels:
if(escape.state != IDLE) // Highest priority - 4
moveCommand(&escape);
else if(avoid.state != IDLE) // Priority - 3
moveCommand(&avoid);
else if(follow.state != IDLE) // Priority - 2
moveCommand(&follow);
else if(cruise.state != IDLE) // Priority - 1
moveCommand(&cruise);
else // Lowest priority - 0
moveCommand(&STOP); // Default command - do nothing!
// In the current implementation this never
// happens.
}

/************************************************** ***************************/
// Main:

int main(void)
{
initRobotBase();
setLEDs(0b111111);
mSleep(2500);
setLEDs(0b001001);

// Set Bumpers state changed event handler:
BUMPERS_setStateChangedHandler(bumpersStateChanged );

// Set ACS state changed event handler:
ACS_setStateChangedHandler(acsStateChanged);

powerON(); // Turn on Encoders, Current sensing, ACS and Power LED.
setACSPwrMed();

// Main loop
while(true)
{
behaviourController();
task_RP6System();
}
return 0;
}


Mein Englisch ist nicht perfekt, deshalb verstehe ich einige Sachen nicht.
Wäre einfach toll, wenn mir jemand der Reihe nach sagt, wozu man was schreiben muss bzw. wofür das ist.

Und erklärt mir bitte auch mal jemand wie man diese Kästen für den Programmiertext hier macht.

Edit von radbruch: Die Kästen macht man mit (code) ... (/code), die runden Klammern () aber mit Eckigen [] ersetzen.

Martinius11
15.04.2010, 17:58
also alles zu erlären ist ein bischen viel aber das prinzip ist das man die Motorsteuerungwerte durch variablen ersetzt werden und diese je nach
den Bedingungen angepasst werden.

Del
15.04.2010, 17:59
Du glaubst doch nicht wirklich das dir hier jemand eine Komplettübersetzung ins Deuschte macht...
http://www.google.de/language_tools?hl=de

SlyD
15.04.2010, 18:21
Das Prinzip ist in der RP6 Anleitung beschrieben.
Ja sogar auf Deutsch ;)

DerNeuling
16.04.2010, 16:50
Erstmal danke an radbruch.
Also dann mal genauer:
Was ich vorhabe ist,dass der RP6 geradeaus fährt und mit dem ACS Hindernisse erkennt und diesen dann ausweicht.Wäre nett wenn ihr mir diesen Teil aus dem Text rauskopiert(den ACS-Teil).Ich verstehe das wie gesagt nämlich nicht ganz.

Martinius11
16.04.2010, 17:37
Hier ist mal ein Programm von mir da reagiert er auch auf den Bumper:




#include "RP6RobotBaseLib.h"
int main(void)
{
initRobotBase();
powerON();
setLEDs(0b001001);
int a;
setACSPwrMed();
moveAtSpeed(160,160);

while(true)
{
if(getBumperLeft())
{
move(85, BWD, DIST_MM(70), true);
rotate(70, RIGHT, 50, true);
changeDirection(FWD);
moveAtSpeed(160,160);
}
if(getBumperRight())
{
move(85, BWD, DIST_MM(70), true);
rotate(70, LEFT, 50, true);
changeDirection(FWD);
moveAtSpeed(160,160);
}
if(obstacle_left)
{
move(85, BWD, DIST_MM(70), true);
rotate(70, RIGHT, 60, true);
changeDirection(FWD);
moveAtSpeed(160,160);
}
if(obstacle_right)
{
move(85, BWD, DIST_MM(70), true);
rotate(70, LEFT, 60, true);
changeDirection(FWD);
moveAtSpeed(160,160);
}
if(adcBat<600)
{
for(a = 0;a>10s00;a++)
{
setLEDs(0b010101);
mSleep(150);
setLEDs(0b101010);
}
}
task_RP6System();
task_motionControl();
task_ADC();

}
return 0;
}

DerNeuling
16.04.2010, 18:11
Danke martinus.
So,das nächste Problem^^.Ich speichere das in einem neuen Ordner.Da habe ich die Datei make_all und make_clean aus nem andren Ordner reinkopiert.Dann das makefile reinkopiert und dann noch irgendwas gemacht,damit da noch andre Dateien reinkommen bzw. geöffnet werden(das war in nem andrem Thread beschrieben.).Das dient ja dazu,dass der auf die RP6 Libraries zugreifen kann oder so.Dort stand auch noch,dass man in der makefiledatei oder so den Namen des alten Programms(wo man die herkopiert hat)auf den Namen des Programms,das man in diesen Ordner speichert,ändert.Das alles habe ich wei man sehen kann nicht wirklich verstanden.Wäre toll,wenn mir das jemand für dieses Programm von martinus nochmal erklären kann.Ich mache dann nen neuen Ordner.

Edit:
Ich hänge jetzt bei dieser Anweisung aus nem andren Thread fest:
3. Von einem ähnlichen Demo-Programm (was also ähnliches macht wie dein Programm) kopierst du makefile in den neuen Ordner.
Es gibt doch eigentlich kein ähnliches Beispielprogramm,von dem ich die makefiledatei in meinen neuen Ordner kopieren kann.Wenn doch,welche?
Und gibt es keine möglichkeit,dass ich immer,wenn ich einen neuen Ordner mache,diese files reinkopieren muss?

Martinius11
16.04.2010, 18:37
gut, aber als Notiz es gibt google und eine Suchfunktion für dieses Forum, als erstes öffnest du die Text datei (nicht Funktion) mit dem Notepad2 dann gehst du soweit runter bis das blau geschriebene Target = kommt du kannst somit den bezug ändern (=name des Programmes) dann alles in ein einen Ordner(Programm.c Make- u.Clean-funktionen und den textmakefile) und in
den Examples speichern

DerNeuling
16.04.2010, 18:44
Habe ich jetzt alles gemacht,aber trotzdem kommt das raus:
> Process Exit Code: 2 . also 2 Fehler.Aus welchem Beispielprogramm soll ich denn die makefiledatei kopieren bzw. welches ist ähnlich?Ich habe bei diesem Programm die makefiledatei aus dem Beispiel LightFollow genommen,aber es funktioniert ja nicht wie man sieht.

Martinius11
16.04.2010, 23:16
Am besten ist du nimmst ein Beispielprogramm änderst den namen und fügst da den code ein

DerNeuling
17.04.2010, 09:40
Ich hab jetzt einen neuen Ordner gemacht und dort einfach alle Datein aus einem Beispielprogramm reinkopiert.Dann habe ich bei der makefile-Datei bei Target den Namen meines Programmes hingeschrieben.Hat dann aber immernochnicht funktioniert.Was ist mit diesen Dateien?Soll ich die auch umbenennen?


RP6Base_Move_01.eep
RP6Base_Move_01.elf
RP6Base_Move_01.hex
.....
...

Was soll ich mit denen machen?

Martinius11
17.04.2010, 10:04
du kannst alle löschen ausser die die mit make oder clean oder dem Programm zutun haben.

DerNeuling
17.04.2010, 15:23
funktioniert nicht-.- :

Compiling: MeinProg01.c
avr-gcc -c -mmcu=atmega32 -I. -gdwarf-2 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=MeinProg01.lst -I../../RP6lib -I../../RP6lib/RP6base -I../../RP6lib/RP6common -std=gnu99 -MD -MP -MF .dep/MeinProg01.o.d MeinProg01.c -o MeinProg01.o
MeinProg01.c:43:13: error: invalid suffix "s00" on integer constant
../../RP6lib/RP6base/RP6RobotBaseLib.h:180: warning: inline function 'isMovementComplete' declared but never defined
../../RP6lib/RP6base/RP6RobotBaseLib.h:67: warning: inline function 'setLEDs' declared but never defined
make.exe: *** [MeinProg01.o] Error 1

> Process Exit Code: 2
> Time Taken: 00:01

Hab jetzt in dem Ordner makefile,makeclean,makeall,MeinProg01.c .Mehr ist nicht drinne.Was jetzt?

SlyD
17.04.2010, 15:27
> inline function 'setLEDs'

Du verwendest vermutlich eine alte Version der RP6Lib - die funktioniert nicht mit neuen Compilern.
--> aktuelle Version von www.arexx.com/rp6 herunterladen!

(die Suchfunktion des Forum hätte auch hier geholfen ;) )

MfG,
SlyD

DerNeuling
17.04.2010, 16:42
Done.Jetzt dieses Problem:

Compiling: MeinProg01.c
avr-gcc -c -mmcu=atmega32 -I. -gdwarf-2 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=MeinProg01.lst -I../../RP6Lib -I../../RP6Lib/RP6base -I../../RP6Lib/RP6common -std=gnu99 -MD -MP -MF .dep/MeinProg01.o.d MeinProg01.c -o MeinProg01.o
MeinProg01.c:43:13: error: invalid suffix "s00" on integer constant
make.exe: *** [MeinProg01.o] Error 1

> Process Exit Code: 2
> Time Taken: 00:01

Beim Klicken auf MeinProg01.c:43:13: error: invalid suffix "s00" on integer constant wurde for(a = 0;a>1 aus dem obigen Text markiert.Da ist warscheinlich der Fehler,aber was ist da der Fehler?Ich hab den Text nicht wirklich verstanden,werde ihn mir aber noch genauer ansehen.Was ist jetzt falsch?

SlyD
17.04.2010, 16:47
Quelltext?
(nähere Umgebung von Zeile 43 reicht und bitte Zeile 43 markieren)

DerNeuling
17.04.2010, 18:16
Ich habe den Quelltext von martinus11 genommen(weiter oben).
Die ganze Zeile ist:



}
if(adcBat<600)
{
for(a = 0;a>10s00;a++)
{
setLEDs(0b010101);
mSleep(150);
setLEDs(0b101010);
}

SlyD
17.04.2010, 18:28
a>10s00

Ja ne ist klar ;)
Das s ist da natürlich fehl am Platz. Das sagt die Fehlermeldung ja auch.

Die Schleife ist aber sowieso fehlerhaft da sie niemals ausgeführt wird.

Orientier dich mal lieber an den normalen Beispielprogrammen da ist auch alles gut lesbar formatiert.

MfG,
SlyD

DerNeuling
17.04.2010, 18:36
Naja das hilft mir nicht wirklich weiter.Dann halt nicht [-( .Closed

Martinius11
17.04.2010, 18:58
du muss ich beim speichern von Strg abgeruscht sein nimm das s einfach raus dann gehts.

DerNeuling
17.04.2010, 19:42
Danke martinus.Hat jetzt geklappt.Das ACS erkennt Objekte sehr früh.Kann ich das verstellen?Also so,dass der RP6 erst so ca- 5 cm vor einem Hinderniss stoppt und dann dreht?

Martinius11
17.04.2010, 20:40
anstatt setACSPwrMed(); setACSPwrHigh();
aber alles zu lesen in der Anleitung

DerNeuling
17.04.2010, 21:54
Sorry hab erst grade bemerkt,dass ich mit der Anleitungn och nicht mal ganz durch bin.Hätte mir viele Fragen erspart.Aber du meinst doch void setACSPwrLow(void) nicht High.Sorry,dass du so viele Fragen beantworten musstest.Closed