Gratulation zum Etappensieg,
ich bewundere Deine hartnäckigkeit bei diesem Projekt.
manchmal geht es schneller als man erhofft hat:
ich habe das beispiel "RP6Control_10_Move2.c" in der mainschleife mit dieser funktion ergänzt (spannungsabfrage über die multiIO)
dort kann ich direkt über die Vbat abfrage den wert festlegen bei dem die funktion "bake_suche" aufgerufen werden soll. Und es funktioniert!!!Code:void accuzustand(void) // accuspannung abfragen und signalisieren { LTC2990_measure(); if (vbat < 6) { buzzer(330); mSleep(200); buzzer(330); mSleep(200); bake_suche(); } }
Ich muss jetzt noch prüfen nach welcher funktion jetzt die reaktion auf die bumper erfolgt, ob das auf diese "behaviour_escape" oder auf die direkte abfrage in der "bake_suche" ist. Ich vermute es ist die "behaviour_escape" funktion...
weiter geht es dann mit der liniensuche: ich muss ja in einer bestimmten richtung (eigentlich senkrecht auf die wand) auf die ladestation zufahren...
gruß inka
Gratulation zum Etappensieg,
ich bewundere Deine hartnäckigkeit bei diesem Projekt.
Geändert von TrainMen (11.02.2014 um 13:22 Uhr)
Gruß TrainMen
Hi inka,
dem Glückwunsch zum "Etappensieg" schließe ich mich gern an.
Man kann so was machen, allerdings muss ...ich habe das beispiel "RP6Control_10_Move2.c" in der mainschleife mit dieser funktion ergänzt (spannungsabfrage über die multiIO)
a) die Hauptschleife ohne Verzögerungen (d.h. ohne mSleep) ablaufen und
b) man kann nicht auch noch eine längere Suche nach der Bake dort durchführen (bake_suche).
Grund: Die weiteren Programmfunktionen reagieren dann kaum noch.
Der "Bumpers Event handler" (bumpersStateChanged) wird angesprungen, wenn sich der Bumper-Zustand ändert.Ich muss jetzt noch prüfen nach welcher funktion jetzt die reaktion auf die bumper erfolgt,...
Wie du schon gesagt hast, passiert die Reaktion auf Bumper-Änderungen in der behaviour_escape Funktion.
Grundsätzlich zeigt die Demo "RP6Control_10_Move2.c", wie man "Verhalten" (behaviour) programmieren kann.
Die Demo:
1. Warte bis ein Geräusch gehört wird (behaviour_waitForStart).
2. Fahre dann herum (behaviour_cruise).
3. Weiche Hindernissen aus (behaviour_escape).
4. Vermeide Hindernisse (behaviour_avoid).
5. Achte auf leere Batterie (behaviour_checkLowBattery)
6. Gehe zu 2.
Die Demo ist eigentlich ideal für dein Vorhaben, das du ja auch in verschiedenes "Verhalten" aufteilen könntest:
1. Mache was (Herumfahren).
2. Achte auf leere Batterie.
3. Falls leer: Suche Bake
4. Fahre auf schwarzer Linie zur Ladestation
5. Lade Akku
6. Gehe zu 1.
Das bedeutet in der Demo:
Du müßtest eigene "Verhalten" (behaviours) nach dem Vorbild in der Demo schreiben. Dazu müßtest du z.B. auch die Rangfolge der Verhaltensweisen (siehe behaviourController) festlegen.
Das ist zwar nicht ganz einfach, aber es ist leider nicht damit getan, deine Funktionen (Akku überwachen, Bake suchen, auf der Linie zur Ladestation fahren ...) in die Hauptschleife dieser Demo zu packen.
Gruß
Dirk
Ja genau so habe ich das gemacht. In der Funktion Akku überprüfen habe ich eine Variable auf Aktiv gesetzt wenn der Akku zur Neige ging. In einer anderen Funktion habe ich dann diese Variable überprüft. Wenn dies dann Aktiv war habe ich nach der hellsten Stelle im Raum (Solar-Projekt) suchen lassen. Am Ende der Funktion habe ich die Variable wieder auf inAktiv gesetzt. So konnte mein BOT auch auf dem Weg zu hellsten Stelle auch wieder die anderen Verhalten beachten. Das müsste doch mit der Bake auch funktionieren ?. Jedenfalls zum auffinden der Bake.Du müßtest eigene "Verhalten" (behaviours) nach dem Vorbild in der Demo schreiben. Dazu müßtest du z.B. auch die Rangfolge der Verhaltensweisen (siehe behaviourController) festlegen.
Gruß TrainMen
hallo,
ich musste die links und rechts IR-sensoren des linienfolgemoduls (einbaubedingt) in der lib tauschen:
RP6Control_MultiIO.h:
das hat soweit gut funktioniert, verunsichert bin ich durch diese defines, was ist das?Code:// Other ADC channel definitions: // (Depending on jumper settings on the MultiIO Project Board!) // (The ADC-Mxxx plug is connected to the M32 ADC plug!) #define ADC_MULTIIO_LFS_L ADC_5 // ADC-Mxxx: ADC geändert von 3 in 5, (L=links in fahrtrichtung) #define ADC_MULTIIO_LFS_M ADC_4 // ADC-Mxxx: ADC #define ADC_MULTIIO_LFS_R ADC_3 // ADC-Mxxx: ADC geändert von 5 in 3 (R=rechts in fahrtrichtung)
RP6Control_LFSBumperLib.h:
Code:// Define the use of the LFS Board here! #define LFS // LFS Board is used // --------------------------------------------------------------------------- #define CH_LFS_L 1 #define CH_LFS_M 2 #define CH_LFS_R 3
gruß inka
Das sind die Nummern der ADC-Kanäle (CHannel). Die müssen so bleiben.... verunsichert bin ich durch diese defines, was ist das?
Gruß
Dirk
hallo,
wieder einmal eine anfängerfrage...
folgende funktion funktioniert, beim empfang eines signals der IR-bake wird 000 angezeigt, wenn kein signal 004:
diese aber nicht. Da kommt immer nur 000, egal ob IR-bake sendet oder nicht:Code:void read_Register_30(void) { I2CTWI_transmitByte(I2C_RP6_BASE_ADR, 0); // Start with register 0... I2CTWI_readBytes(I2C_RP6_BASE_ADR,RP6data, 31); // and read all 30 registers uint8_t i = 0; for(i = 0; i < 31; i++) { // mSleep(8); if (i == 30) IR_wert[0] = RP6data[30]; } }
ich verstehe einfach nicht warum, hab doch nur die schleife rausgenommen?Code:void read_Register_30(void) { I2CTWI_transmitByte(I2C_RP6_BASE_ADR, 30); // Start with register 30... I2CTWI_readBytes(I2C_RP6_BASE_ADR,RP6data, 1); // and read one register IR_wert[0] = RP6data[30]; }
gruß inka
Nur die Schleife rausgenommen? Ich vermute mal (Glaskugel) das ist ein Stück Code aus dem i2c-Slave der Base.
Du nimmst aber nicht nur die Schleife raus .. du nimmst dem System auch die benötigte Zeit um die Daten aufzuarbeiten.
Die I2C Datenverarbeitung ist zeitkritisch. Wie so vieles andere an den RP6 Libs auch.
Mach doch einfach mal:
und probiere mit Werten für x von 0 bis ... keine Ahnung.. 100 .. was die Funktion macht wenn du x bei sendender Bake erhöhst.Code:void read_Register_30(void) { I2CTWI_transmitByte(I2C_RP6_BASE_ADR, 30); // Start with register 30... I2CTWI_readBytes(I2C_RP6_BASE_ADR,RP6data, 1); // and read one register mSleep(x); IR_wert[0] = RP6data[30]; }
Eigentlich sollte sich experimentell ein Wert ermitteln lassen, ab wieviel x die bake gefunden bzw diese 004 übertragen wird.
Es würde mich auch nicht wundern, wenn Du bald die Erkenntnis hast, das sich die Motorsteuerung und die I2C slave lib jeweils als Zeitkritische Module sich im Prinzip gegenseitig in den Füßen stehen - weshalb es nicht ganz ist, das Base Slave Programm softwaremässig noch zu erweitern.
Gruß
Geändert von RolfD (12.03.2014 um 20:10 Uhr)
Sind Sie auch ambivalent?
Bei dem Code wird das über I2C gelesene Byte in "RP6data" gespeichert.Code:I2CTWI_readBytes(I2C_RP6_BASE_ADR,RP6data, 1); // and read one register IR_wert[0] = RP6data[30];
Du must also mit: IR_wert[0] = RP6data; ... auslesen.
Vorsicht mit den Namen von Variablen (Var) und Arrays (Var[n])!
Gruß
Dirk
@Dirk,
bei genauerem hinschauen wars dann doch recht einfach:
zum einen das "s", zum anderen das direkte auslesen in den IR-wert...Code:void read_Register_30(void) { I2CTWI_transmitByte(I2C_RP6_BASE_ADR, 30); // Start with register 30... I2CTWI_readBytes(I2C_RP6_BASE_ADR,RP6data, 1); // and read one register IR_wert[0] = RP6data[30]; }
Code:void read_Register_30(void) { I2CTWI_transmitByte(I2C_RP6_BASE_ADR, 30); IR_wert = I2CTWI_readByte(I2C_RP6_BASE_ADR); }
@RolfD,
der code hatte diesmal nichts mit code aus dem I2C-Slave der Base zu tun, war ein codeschnipsel aus einem der m32 beispiele...
mit dem mSleep (evtl. stopwatsches) geht es jetzt weiter zu angleichung der sende/empfangfrequenz. So weit war ich eigentlich schon mal...
danke Euch beiden...
gruß inka
Lesezeichen