@ Tim Hansen
Wenn dein Summer nur ein paar mA (Strom) braucht, kannst du ihn direkt anschliessen (ohne Transistor, wie LED, aber ohne Vorwiderstand).![]()
@ Tim Hansen
Wenn dein Summer nur ein paar mA (Strom) braucht, kannst du ihn direkt anschliessen (ohne Transistor, wie LED, aber ohne Vorwiderstand).![]()
Geändert von PICture (25.01.2012 um 17:25 Uhr)
MfG (Mit feinem Grübeln) Wir unterstützen dich bei deinen Projekten, aber wir entwickeln sie nicht für dich. (radbruch) "Irgendwas" geht "irgendwie" immer...(Rabenauge) Machs - und berichte.(oberallgeier) Man weißt wie, aber nie warum. Gut zu wissen, was man nicht weiß. Zuerst messen, danach fragen. Was heute geht, wurde gestern gebastelt. http://www.youtube.com/watch?v=qOAnVO3y2u8 Danke!
Mit Bumper ist das sicher einfacher und billiger zu lösen als mit Ultraschall, aber eleganter sieht es natürlich mit Ultraschall aus, weil der Roboter dann nicht gegen eine Wand fährt wenn er in eine Sackgasse fährt.
Aber man kann es ja zuerst mit Bumper und später als Erweiterung vielleicht mit Ultraschall realisieren.
Also, meine Überlegung ist jetzt momentan, ihn das ganze mit dem ACS machen zu lassen. Er soll sich auf jedem Feldchen einmal nach links umschauen und bei Möglichkeit abbiegen. Wenn vorne, links und rechts blockiert ist, soll er umdrehen.
Jetzt habe ich aber ein Problem mit meinem Code.
Wieso wird immer das aus "ELSE {}" gemacht?
Das verstehe ich nicht :OCode:// Includes: #include "RP6RobotBaseLib.h" uint8_t acs_bool = 0; // Main: void acsStateChanged(void) { //Nix. } int main(void) { initRobotBase(); setLEDs(0b111111); mSleep(2500); powerON(); // Strom für alle Systeme wie ACS, Bumper und die LEDs ACS_setStateChangedHandler(acsStateChanged); // Main loop while(true) { setLEDs(0b100100); //LEDs setzen setLEDs(0b111001); updateStatusLEDs(); // Prüfe, ob links eine Öffnung ist if (obstacle_left && obstacle_right) { // LEDs setzen setLEDs(0b001111); updateStatusLEDs(); // Rotiere wieder zurück in gerade Position rotate(40, RIGHT, 90, BLOCKING); //LEDs setzen setLEDs(0b001001); updateStatusLEDs(); // Prüfe, ob vorne ein Hindernis ist if (obstacle_left && obstacle_right) { // LEDs setzen setLEDs(0b001111); updateStatusLEDs(); // Rotiere rechts rotate(40, RIGHT, 90, BLOCKING); //LEDs setzen setLEDs(0b111001); updateStatusLEDs(); // Prüfe, ob rechts ein Hindernis ist if (obstacle_left && obstacle_right) { // LEDs setzen setLEDs(0b001111); updateStatusLEDs(); // Rotiere rechts rotate(40, RIGHT, 90, BLOCKING); //LEDs setzen setLEDs(0b111001); updateStatusLEDs(); } else { move(50, FWD, DIST_MM(250), BLOCKING);} } else { move(50, FWD, DIST_MM(250), BLOCKING);} } else { move(50, FWD, DIST_MM(250), BLOCKING);} } return 0; }
Danke schonmal!
Geändert von radbruch (26.01.2012 um 16:32 Uhr)
Was genau meinst du? Was soll aus dem else gemacht werden?Wieso wird immer das aus "ELSE {}" gemacht?
Das else sieht doch ganz normal aus.
Edit: Ah jetzt verstehe ich, du hast gemeint, dass immer der else-Block ausgeführt wird.
Sorry war ein missverständnis![]()
Geändert von masasibe (26.01.2012 um 16:45 Uhr)
Die IF Abfrage scheint immer "false" zu sein, da immer das ELSE durchgeführt wird. Ich hab da meine Hand, 'ne Zeitung, etc. vorgehalten, aber der Roboter fährt ungeniert weiter. Der erkennt offensichtlich das Hindernis nicht.
Hallo
Es wird immer der else-Zweig ausgeführt, weil obstacle_left und obstacle_right vom Tasksystem gesetzt werden, wenn etwas im Blickfeld erscheint:
(ungetestet)Code:// Prüfe, ob xxxx eine Öffnung ist task_ACS(); if (obstacle_left && obstacle_right)
Tasksystem direkt vor der Abfrage der Variablen könnte funktionieren. Das ACS muss man auch noch initialisieren:
Das sollte noch irgendwo vor der While()-Schleife erledigt werden.Code:enableACS(); //setACSPwrLow(); setACSPwrMed(); //setACSPwrHigh();
Gruß
mic
[Edit]
Das wird so auch nicht funktionieren, weil der ACS-Task mehrere Aufrufe benötigt. Der Task funktioniert wie eine Schrittkette:
#define ACS_STATE_IDLE 0
#define ACS_STATE_IRCOMM_DELAY 1
#define ACS_STATE_SEND_LEFT 2
#define ACS_STATE_WAIT_LEFT 3
#define ACS_STATE_SEND_RIGHT 5
#define ACS_STATE_WAIT_RIGHT 6
Vermutlich mußt du auf das Blocking verzichten und die Bewegungen mit dem Tasksystem ausführen:
https://www.roboternetz.de/community...eAtSpee-Befehl
Geändert von radbruch (26.01.2012 um 17:01 Uhr)
Bild hier
Atmel’s products are not intended, authorized, or warranted for use
as components in applications intended to support or sustain life!
Also, ich habe jetzt etwas mit Tasksystem, was erstmal die Basisbewegung darstellt.
In meinem Beispiel wird Bumper links für "Hindernis" und Bumper rechts für "Kein Hindernis" verwendet. Da sollen dann irgendwann mal die ACS-Tasks hin, da ich da aber ja im Moment hänge habe ich das erstmal mit den Bumpern gemacht, damit ich die in der Testumgebung eben fix drücken kann.
Code:#include "RP6RobotBaseLib.h" #define STATE_START 0 #define STATE_LEFT_OBSTACLE 1 #define STATE_FRONT_OBSTACLE 2 #define STATE_RIGHT_OBSTACLE 3 #define STATE_ALL_OBSTACLE 4 #define STATE_MOVE_FORWARD 5 uint8_t move_state = STATE_START; void move_stateMachine(void) { switch(move_state) { case STATE_START: setLEDs(0b010000); move_state = STATE_LEFT_OBSTACLE; rotate(50, LEFT, 90, true); break; case STATE_LEFT_OBSTACLE: if(isMovementComplete()) { if(getStopwatch1() > 500) { writeString_P("Blinke links"); statusLEDs.LED5 = !statusLEDs.LED5; updateStatusLEDs(); setStopwatch1(0); } if(bumper_left) { writeString_P("Bumper links getroffen"); writeString_P("HINDERNIS"); setLEDs(0b011001); rotate(50, RIGHT, 90, true); move_state = STATE_FRONT_OBSTACLE; } if(bumper_right) { writeString_P("Bumper rechts getroffen"); writeString_P("KEIN HINDERNIS"); setLEDs(0b011001); move_state = STATE_MOVE_FORWARD; } } break; case STATE_FRONT_OBSTACLE: if(isMovementComplete()) { if(getStopwatch1() > 500) { writeString_P("Blinke links"); statusLEDs.LED5 = !statusLEDs.LED5; updateStatusLEDs(); setStopwatch1(0); } if(bumper_left) { writeString_P("Bumper links getroffen"); writeString_P("HINDERNIS"); setLEDs(0b011001); rotate(50, RIGHT, 90, true); move_state = STATE_RIGHT_OBSTACLE; } if(bumper_right) { writeString_P("Bumper rechts getroffen"); writeString_P("KEIN HINDERNIS"); setLEDs(0b011001); move_state = STATE_MOVE_FORWARD; } } break; case STATE_RIGHT_OBSTACLE: if(isMovementComplete()) { if(getStopwatch1() > 500) { writeString_P("Blinke links"); statusLEDs.LED5 = !statusLEDs.LED5; updateStatusLEDs(); setStopwatch1(0); } if(bumper_left) { writeString_P("Bumper links getroffen"); writeString_P("HINDERNIS"); setLEDs(0b011001); rotate(50, RIGHT, 90, true); move_state = STATE_ALL_OBSTACLE; } if(bumper_right) { writeString_P("Bumper rechts getroffen"); writeString_P("KEIN HINDERNIS"); setLEDs(0b011001); move_state = STATE_MOVE_FORWARD; } } break; case STATE_ALL_OBSTACLE: if(isMovementComplete()) { if(getStopwatch1() > 500) { writeString_P("Blinke links"); statusLEDs.LED5 = !statusLEDs.LED5; updateStatusLEDs(); setStopwatch1(0); } if(bumper_left) { writeString_P("Bumper links getroffen"); writeString_P("ERROR! GEFANGEN!"); setLEDs(0b011001); rotate(50, RIGHT, 90, true); } if(bumper_right) { writeString_P("Bumper rechts getroffen"); writeString_P("KEIN HINDERNIS"); setLEDs(0b011001); move_state = STATE_MOVE_FORWARD; } } break; case STATE_MOVE_FORWARD: if(isMovementComplete()) { move(50, FWD, DIST_MM(250), true); move_state = STATE_START; } break; } } int main(void) { initRobotBase(); setLEDs(0b111111); mSleep(1000); powerON(); startStopwatch1(); while(true) { move_stateMachine(); task_RP6System(); } return 0; }
Meine Frage ist nun, wie spreche ich denn nun die ACS-Tasks an. Geht das nicht einfach so wie die Bumper!?
Und noch etwas zu meiner Peinlichkeit: Was genau meint eigentlich das Blocking? Habe es mir einfach so zusammengeschnipselt.
Lesezeichen