PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Nibo2 Test Seitensensoren



HJBB49
11.12.2010, 14:51
Im Gegensatz zu den hier im Forum beschriebenen Tests mit Bodensensoren, habe ich mich mit den Seitensensoren beschäftig.

Als Hindernisse benutze ich leere Zigarettenschachteln (bin leider Raucher!).
Diese kann ich flexibel aufstellen und so einfach die SensorRohdaten ermitteln.

Ich möchte zunächst mit dem Nibo2 in geringem Abstand (ca. 7 cm) vom Hindernis einen Parcour abfahren.

Ich definiere 3 Zustände:
- kritischer Bereich < 7 cm vom Hindernis
- normaler Bereich 9 cm < Hindernis > 7 cm
- undefiniert Hindernis > 9 cm

Die Werte werden als Vektoren für rechts, halbrechts; links, halblinks berechnet.

zur Zeit benutze ich nur das HighByte der Sensordaten.


Algorithmus (Hindernis rechts): -> zurück in den normalen Bereich:

Hindernis < 7 cm: -> Drehen Links ca. 15 Grad, vorwärts ca. 1 cm, Drehen rechts ca. 15 Grad, Sensordaten auswerten.

tld, trd Drehen Ticks links, rechts; tl, tr Ticks vor links, rechts
CodeUmsetzung: copro_setTargetRel(-tld, trd, speed);
copro_setTargetRel(tl, tr, speed);
copro_setTargetRel(tld, -tlr, speed);


Leider funktioniert das nicht!

Hauptprozessor schickt Daten an Coprozessor und wartet nicht ab, ob Aktion beendet ist.
Es fehlt eine Rückmeldung vom Coprozessor: Aktion beendet!
Dies führt dazu, das während der Coproz noch beschäftigt ist, bereits die nächste Aktion vom Hauptproz gestartet wird,
was nicht zum gewünschten Erfolg führt.

Bitte um Rückmeldung oder Lösungsvorschläge

hjbb

Achim S.
11.12.2010, 17:30
Hallo
bin leider noch nicht so weit um dir direkt helfen zu können. Ich habe auf Henke-Soft (google) ein ähnliches Prg wie deines gesehen. Er gibt ebenfalls Parameter vor, leht durch vorgaben bestimmte Bereiche fest und berechnet daraus entsprechende frei Richtungen. Habe es auch irgendwo. Problem ist nur, das es auf den Nibo 2 geschrieben ist und damit noch viele alte Befehle drin hat. Bin noch nicht zum übersetzen gekommen. Sieh es dir mal an.
Achim

workwind
11.12.2010, 19:00
Im C Tutorial Kapitel 8 wird gezeigt wie man die Werte der Hindernissensoren ausliest. Nach dem Aufruf von copro_update() stehen die aktuellen Werte im copro_distance Array zur Verfügung:



char text[20]="-- -- -- -- --";
// Co-Prozessor
if (copro_update()) {
sprintf(text, "%02x %02x %02x %02x %02x",
(uint16_t)copro_distance[0]/256,
(uint16_t)copro_distance[1]/256,
(uint16_t)copro_distance[2]/256,
(uint16_t)copro_distance[3]/256,
(uint16_t)copro_distance[4]/256);
}
gfx_move(10, 55);
gfx_print_text(text);


Komplettes Beispiel: http://www.roboter.cc/index.php?option=com_nicaiwci&view=project&projectid=53

Hero_123
11.12.2010, 21:01
Hi HJBB49

lies - wie von workwind vorgeschlagen - mittels copro_update() die Distanzdaten aus und entscheide dann, in welche Richtung der NIBO fahren soll; da gibt's ein ganz gutes (aber leider nicht dokumentiertes) Beispiel in der NIBOLIB V2.7 (hab ich mir mal als *.tar runtergeladen) im directory obstacle2 ein "main.c" file, mit dem NIBO2 einen Hindernisparcour abfahren kann; hab es dann an meine Belange angepasst...

mfg

Hero_123

HJBB49
12.12.2010, 08:06
Das Problem ist nicht Sensordaten auszulesen oder die entsprechenden Vektoren zu berechnen, sondern die Motorsteuerung

copro_setTargetRel(-tld, trd, speed);
copro_setTargetRel(tl, tr, speed);
copro_setTargetRel(tld, -tlr, speed);

funktioniert so nicht, weil keine Rückmeldung "Aktion abgeschlossen" vom Coproz kommt. Also zB Flag abfragen bevor die nächste Aktion ausgeführt werden kann.

1. Möglichkeit:
Wenn ich zwischen den Befehlen ein Delay 100 msec einfüge, funktioniert es. Ist aber keine schöne Lösung.

2. Möglichkeit (Vorschlag von Hr. Springob)
Ticks-Ist mit Ticks-Soll in einer Schleife vergleichen und weiter wenn (Ticks-Ist + delta) = Ticks-Soll
delta ist notwendig, weil ansonsten evtl. der Sollwert niemals erreicht wird.

Ist schon besser, aber noch nicht optimal. Es dauert evtl. ziemlich lange bis Sollwert erreicht wird.

Hängt vielleicht auch mit den Reglerdaten zusammen (PID)?

Hero_123
12.12.2010, 10:11
Hi

das mit dem Delay von 100ms sehe ich genauso, ist nur ein Pflaster und keine Lösung des Problems....

die 2te Möglichlichkeit klingt gut

Reglerdaten - welches kp, ki, kd hast Du beim Regler eingestellt? Es ist schon so, daß der Regler bei größerem kp schneller reagiert; da muß man "iterativ" rangehen (ausprobieren), der Regler soll aber nicht ins Schwingen kommen; leider gibt es da keine großartigen Möglichkeiten, das Regelverhalten des NIBO auszutesten bzw eine Sprungantwort aufzunehmen und dann die optimalen Reglerparameter rauszufinden und einzustellen.

mfg

Hero_123

workwind
12.12.2010, 14:49
Die zweite Möglichkeit ist der bessere Weg...

Du kannst das Problem lösen indem Du eine gewisse Unschärfe zulässt: Wenn der Abstand zum aktuellen Zielpunkt kleiner als X Ticks ist, berechnest Du einfach den nächsten Zielpunkt. Dadurch bekommst Du dann relativ weiche Übergänge zwischen den Wegpunkten.

Lisbeth2010
12.12.2010, 15:31
motco_resetOdometry(0,0); // copro_resetOdometry(0,0);
delay(10); // evtl.nicht nötig
motco_setPosition(-40, -40, 20); // copro_setTargetRel(-40, -40, 20);
while (motco_ticks_l > -40) { // copro_ticks_l > -40
motco_update(); //copro_update();
}

Funktioniert bei Nibo (fährt eine bestimmte Strecke rückwärts). Auskommentiertes sollte für Nibo2 gehen. Allerdings macht er ab und zu unmotivierte "Denkpausen". Hat vielleicht was mit dem PID-Regler zu tun.
MfG
Lisbeth2010

Hero_123
12.12.2010, 19:16
@workwind

passiert beim Aufruf von"uint8_t copro_resetOdometry(int16_t left, int16_t right)" überhaupt was?

Source-Code der aktuellen NIBOLIB V2.9 -> copro.c:

uint8_t copro_resetOdometry(int16_t left, int16_t right) {
return 1;
}

mfg

Hero_123

workwind
13.12.2010, 11:38
@Hero_123
Nein, Du hast Recht, da passiert nichts....
Ich werde das für die V2.10 beheben! Der Befehl ist jedoch nicht unbedingt nötig, da der NIBO2 über den copro_setTargetRel() Befehl vefügt.

Hero_123
13.12.2010, 19:05
@workwind

Source-Code der aktuellen NIBOLIB V2.9 -> copro.c: das selbe gilt auch für


uint8_t copro_setPositionParameters(int8_t ki, int8_t kp, int8_t kd) {
return 1;
}

mfg

Hero_123

HJBB49
15.12.2010, 11:15
Hallo
Erstmal vielen Dank für das rege Interesse.

Alle copro_xyz Aufrufe, die die Regler Parameter (ki, kp, kp) betreffen halte ich für akademisch (hier hat sich wohl ein Regelungstechniker ausgetobt!).
Für den normalen Anwender total überzogen. Hier würde vielleicht ein Set von evtl 12 Parameter , die der normale Anwender ausprobieren kann, völlig ausreichend.
Alle Möglichkeiten (2^10 * 2^10 * 2^10) auszuprobieren ist völlig unsinnig, auch wenn etliche Werte total unsinnig sind, aber schon der Rest würde einen enormen Zeitaufwand bedeuten!

Für mein Vorhaben habe ich folgende Daten ermittelt:

Drehung 15 Grad: ticks_links: 5; ticks_rechts: 4
Drehung 30 Grad: ticks_links: 8; ticks_rechts: 7

Vor 4,5 cm: ticks_links: 13; ticks_rechts: 10

Programmcode:

int8_t gotoPositionRel(int16_t left, int16_t right, uint16_t speed, int8_t deltaL, int8_t deltaR)

{
int16_t ctl, ctr;
int16_t i=0;

char text [20];

copro_setTargetRel(left, right, speed);

left += copro_ticks_l;
right += copro_ticks_r;

while(1)
{
copro_update();
i+=1;
ctl = copro_ticks_l;
ctr = copro_ticks_r;

if (i < 200)
{
if ((abs(left - ctl) <= deltaL) && (abs(right - ctr) <= deltaR))
{
// textout (0,56," ",0); // Zeile löschen
// sprintf (text,"i%d TL%d TR%d", i, ctl, ctr);
// textout (0,56, text,0);
return 0;

}
delay(5);
}
else
{
// textout (0,56," ",0); // Zeile löschen
// sprintf (text,"i%d TL%d TR%d", i, ctl, ctr);
// textout (0,56, text,0);
return 1;

}
}

}

....

main ()
....
// DrehLi, Vor, DrehRe
j = gotoPositionRel(-tld, trd, vl,dL,dR);
GetXY ();
j = gotoPositionRel(tl, tr, vl,dL,dR);
GetXY ();
j = gotoPositionRel(tld, -trd, vl,dL,dR);

Die "Unschärfe" wird über deltaL, deltaR vorgegeben.
Bei zu kleinen Werten wird ein EndlosLoop erzeugt. Darum die AbbruchVar i.

Wahrscheinlich sind aber meine Ansprüche zu hoch. Ich muß nochmal testen, wenn ich meine Anforderungen etwas zurückdrehe und dann das Verhalten im Parcour teste.

Die Variablen tl, tr, tld, trd können über eine IR-Fernbedienungen leicht eingestellt werden (so ist nicht jedesmal eine Neuprogrammierung notwendig!)

mfg