PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Software für Roboter effizienter gestalten



Torrentula
10.06.2012, 20:16
Hallo RNler!

Im Moment bastle ich wieder an meinem Roboter rum auf Basis eines ATmega644.

Ich habe mehrere Probleme mit dem Code und hoffe, dass hier jemand helfen kann.

Das 1. Problem ist, der Roboter scheint garnicht zu vergleichen ob Links oder Rechts mehr Platz frei ist, sondern dreht immer nach Links. Ich habe das Gefühl, dass der Code so nicht wirklich effizient ist, wie könnte man dieses "Geradeausfahren bis ein Hindernis kommt" so gestalten, dass ich die main() frei bekomme und andere Sachen während des Fahrens machen kann?

Noch ein Problem ist die Kurskorrektur mittels dem HMC5883L Kompassmodul. Mir wurde ein P-Regler bzw. PI-Regler empfohlen jedoch habe ich diesbezüglich keinerlei Erfahrungen welchen Ansatz ich dafür verfolgen muss.

Hier einmal die main():



int main(void)
{
init_SRF05();
init_uart(9600);
init_Servo();
init_Timer1();

i2c_init();
// initialize compass
init_HMC5883L();

sei();

headingDegrees = getHeading();
heading_previous = headingDegrees;

distL = SRF05_getDistance(left);
distM = SRF05_getDistance(middle);
distR = SRF05_getDistance(right);

Mleftfwd();
Mrightfwd();
accelerate(1);

while(1)
{

while(distM > threshold){
distL = SRF05_getDistance(left);
distM = SRF05_getDistance(middle);
distR = SRF05_getDistance(right);
}

if(distM < threshold && distR > threshold){

while(distM < threshold){
setPWMleft(motor_values[maxspeed]);
setPWMright(motor_values[0]);
distM = SRF05_getDistance(middle);
}

setPWMleft(motor_values[maxspeed]);
setPWMright(motor_values[maxspeed]);
}
else if(distM < threshold && distL > threshold){

while(distM < threshold){
setPWMleft(motor_values[0]);
setPWMright(motor_values[maxspeed]);
distM = SRF05_getDistance(middle);
}

setPWMleft(motor_values[maxspeed]);
setPWMright(motor_values[maxspeed]);
}
}
}


Und hier habe ich nochmal eine Fahrschleife, nur dass anstatt dem Distanzsensor nun der Kompass abgefragt wird und der Kurs korrigiert wird. Ich scheitere an der Kombination von Hinderniserkennung & Vermeidung und der Kurskorrektur.



while( (headingDegrees < (heading_previous + max_course_deviation)) && (headingDegrees > heading_previous - max_course_deviation ) ){
getHeading();
_delay_ms(66);
}

if(headingDegrees > (heading_previous + max_course_deviation) ){

while(headingDegrees > (heading_previous + max_course_deviation) ){
setPWMlinks(maxspeed + 50);
setPWMrechts(maxspeed - 50);
getHeading();
_delay_ms(66);
}

setPWMlinks(maxspeed);
setPWMrechts(maxspeed);
}
else if(headingDegrees < (heading_previous - max_course_deviation) ){

while(headingDegrees < (heading_previous - max_course_deviation)){
setPWMlinks(maxspeed - 50);
setPWMrechts(maxspeed + 50);
getHeading();
_delay_ms(66);
}

setPWMlinks(maxspeed);
setPWMrechts(maxspeed);
}


Bin für Hilfe dankbar!

021aet04
16.06.2012, 14:56
Hast du schon den Code im Simulator angeschaut? Vielleicht weißt du dann besser wo der Fehler ist. Probleme gibt es mit dem Simulator nur wenn man Datenübertragungen simulieren will (z.B. SPI, I2C,...).

Um das Programm besser zu gestalten kann man mit Interrupts arbeiten. Man wählt z.B. eine Interrupt am Int0 Eingang und wenn sich der Pegel ändert springt er in die Interrupt Routine. Diese wird nur abgearbeitet wenn der Interrupt ausgelöst wird. Es gibt auch noch andere Interruptquellen wie z.B. Timer, ADC, UART,...

MfG Hannes