Moin,
LOL
Bin wohl in nen Anfängerfehler getappt....
Hab den Fehler selber gefunden
#include "RP6RobotBaseLib.h"
int main(void)
fehlte..... *peinlich**peinlich*
MfG
BacaBej
Moin,
LOL
Bin wohl in nen Anfängerfehler getappt....
Hab den Fehler selber gefunden
#include "RP6RobotBaseLib.h"
int main(void)
fehlte..... *peinlich**peinlich*
MfG
BacaBej
Folgendes Problem: Ich hab nen Code geschrieben( seeeeeehr einfachen), wo der Roboter einfach nur woanders hinfährt, wenn ein bumper gedrückt wird... Hab den RP6 noch nicht so lange....
Wird der Bumper gedrückt, dreht sich der Roboter im Kreis und fährt nicht weiter...
Nun zum Code: ( wie gesagt,.... anfängercode, und dann noch ein Fehler...)
Code:#include "RP6RobotBaseLib.h" void bumpersStateChanged(void) { if(bumper_left) {setLEDs(0b111111); move(50, BWD, DIST_MM(100), true); setLEDs(0b001111); rotate(90, RIGHT, 70, true); setLEDs(0b001001); } else if(bumper_right) {setLEDs(0b111111); move(50, BWD, DIST_MM(100), true); setLEDs(0b111001); rotate(90, LEFT, 70, true); setLEDs(0b001001); } } int main(void) { initRobotBase(); BUMPERS_setStateChangedHandler(bumpersStateChanged); powerON(); setLEDs(0b001001); while(true) { moveAtSpeed(100,100); task_RP6System(); } return 0;}
Gibts ne andere Möglichkeit, oder muss moveAtSpeed in der schleife stehn ? und kann man die If schleifen auch erst nach dem PowerOn schreiben?
MfG
BacaBej
Hallo
Keine Sorge wegen deines Codes, jeder hier hat mal klein angefangen.![]()
Zu deinem Problem:
Möglicherweise verhindert die blockierende Ausführung von Move und Rotate, dass die Bumber neu eingelesen werden können. Wenn man das Task-System verwendet, sollte man blockierende Funktionen vermeiden.
Anstelle des "true" verwendet man dann besser diese Funktion:
uint8_t isMovementComplete(void)
und der Code würde dann etwa so aussehen:
So ist gewährleistet, dass alle Task-Funktionen weiterhin ausgeführt werden.Code:... if(bumper_left) {setLEDs(0b111111); move(50, BWD, DIST_MM(100), false); while (!isMovementComplete()) task_RP6System(); setLEDs(0b001111); rotate(90, RIGHT, 70, false); while (!isMovementComplete()) task_RP6System(); setLEDs(0b001001); } ...
Gruß
mic
Bild hier
Atmel’s products are not intended, authorized, or warranted for use
as components in applications intended to support or sustain life!
Hallo :
Nicht verzweifeln, ich hab mein rp6 schon 2 wochen und hab noch kein progr. zum standen gebracht , bin aber am kämpfen , und am rumprobieren
,
Ich brauche noch ein experimentier steckboard , und ein paar elektronische komponente , weisst jemand wo ich so was kriege in österreich zum bestellen ?, bei Reichelt muss ich mindestens 150 euro bestellen als export kunde , und conrad hat nicht was ich will , danke in voraus
gruss Carlos
Tach,
Erstma danke für die Antworten...
In der Anleitung steht doch ein Programm wo auch das mit dem move und rotate drin steht oder ?? ? Kann mich auch irren... Und in der Anleitung steht auch nichts davon, das dat blockieren könnte.... Hätte man ja schreiben können... Oder ich hab das überlesen..
Jedenfalls versteh ich nicht ganz warum das blockiert...(ich will alles ganz genau wissen um das besser zu verstehn^^) Es müsste doch erst die Move Funktion ausgeführt werden UND erst dann das rotate... Und während dem Move und Rotate müssen die Bumber ja auch net ausgelesen werden...oder ? hehe Fragen über Fragen.....
Mfg
BacaBej
Hallo
Zitat aus Kapitel 4.6.9 (Seite 101) der Anleitung:
Das Task-System des RP6 verwaltet im Hintergrund mit einer Mischung aus Polling (regelmässiges Aufrufen aus dem Hauptprogramm) und Interupts (unterbrechen des Hauptprogramms) die Funktionen des Roboters. Mit den Funktionen der Bibliothek steuert man quasi nicht selbst den Roboter, man übergibt dem Task-System den Befehl und dieses organisiert dann das Zusammenspiel der einzelnen Funktionen. Dabei unterscheiden sich zwei Möglichkeiten:Der letzte Parameter der Funktion, „blocking“ ist eine kleine Besonderheit, die wir etwas
genauer erklären müssen.
Die Funktion setzt normalerweise nur ein paar Variablen und es würde dann sofort mit
dem normalen Programmablauf weitergemacht. Die Fahrt würde „im Hintergrund“ automatisch
von der motionControl Funktion gesteuert. Das ist sinnvoll, wenn der Roboter
nebenbei noch andere Dinge tun muss, wie z.B. auf Hindernisse reagieren.
- Es muss schnell auf ein Ereigniss reagieren (z.B. auf einen Feldwechsel der Odometry-Sensoren) oder periodisch immer wiederkehrend auf ein Ereigniss reagieren (z.B. Stopwatches oder Rampen bei setMotorPower). Dann verwendet das Task-System einen Interrupt und unterbricht für seine Aufgaben das Hauptprogramm (um z.B. den Impulszähler des Antriebs oder die Werte der Stopuhren zu akualisieren). Diese Unterbrechungen sind sehr kurz, weil sie nur aus ein paar Befehlen bestehen und nur das nötigste erledigen. Das Hauptprogramm wird dadurch fast nicht gebremst. (Tiefer mag ich an dieser Stelle nicht auf die Interupts eingehen)
- Es muss regelmässig umfangreiche Berechnungen anstellen (Fahrwege überwachen, Geschwindigkeiten regeln, IR und ACS-Signale auswerten..), die analogen Eingänge einlesen (Bumper, LDRs, Motorströme...) und andere, weniger zeitkritische Dinge erledigen. Es reicht vollkommen, wenn man dazu das Hauptprogramm an einer Stelle unterbricht und diese Tätigkeiten durch den Aufruf der jeweiligen Task-Funktion ausführen läßt. Im Gegensatz zum Interrupt, der ja für das Hauptprogramm zu einem willkührlichen Zeitpunkt auftreten kann, spricht man hier vom Polling. Allerdings werden nicht alle Aktionen bei nur einem Aufruf erledigt, es dauert einige Aufrufe, bis alle arbeiten erledigt sind und die Abarbeitung erneut startet. In der Anleitung steht dazu:
"Blockierend" bedeutet nun, das Hauptprogramm pollt nicht (oder zu langsam). Ursachen sind z.B. zu lange Schleifen ohne Task-Aufruf, mSleep()s oder das Senden von vielen Zeichen. Und beim blockierenden Move() werden alle Tasks außer dem motionControll blockiert.Ständig aus dem Hauptprogramm
aufrufen heisst hier nichts anderes, als dass man diese Funktion in der
Hauptschleife des Programms bei jedem Schleifendurchlauf einmal aufrufen muss. Es
reicht, wenn die Funktion alle 10 bis 50 Millisekunden einmal aufgerufen wird. Besser
ist es allerdings, die Funktion noch sehr viel öfter aufzurufen. Es schadet nicht, wenn
man die Funktion noch schneller aufruft, denn das Timing wird von einem der Hardwaretimer
gesteuert. Daher ist es auch egal ob man die Funktion in gleichbleibenden
Intervallen aufruft, oder ob man mal 1ms und mal 10ms zwischen den einzelnen Aufrufen
benötigt. Es kostet auch nur unwesentlich mehr Rechenzeit, die Funktion oft
aufzurufen. Sie wird nur komplett ausgeführt, wenn auch etwas zu tun ist.
Nach soviel Text und Erklärungen bleibt mir leider nur noch zu sagen, dass dies alles nichts mit der Fehlfunktion deines Programms zu tun hat. Das ist mir zwar peinlich, aber es fehlt wohl nur der setMotorDir(FWD,FWD); vor dem moveAtSpeed(100,100); deshalb drehen die Motoren mit den Richtungen weiter, die sie beim Rotate() hatten.
Gruß
mic
Bild hier
Atmel’s products are not intended, authorized, or warranted for use
as components in applications intended to support or sustain life!
Abend,
Danke Danke.... Jetzt hab ich das auch kapiert warum das net funzt.... In der schleife steht zwat moveAtSpeed(100,100) aber net in welche richtung... und da die letzte Richtung das Rotieren ist, dreht der halt weiter... *Peinlicher Fehler*. Aber naja.. Ich werde mich schon noch verbessern. Auf jedenfall nochmal Danke für die schnelle Antwort.
MfG
BacaBej
Hallo,
genau genommen gehört das moveAtSpeed() nicht mit in die Hauptschleife rein. Das braucht man nur dann aufzurufen, wenn sich die Geschwindigkeit ändern soll.
Genauso ist es mit changeDirection()!
setMotorDir sollte man nur dann verwenden, wenn man das task System NICHT benutzt![]()
Also bitte nicht mit der Funktion beim ASURO verwechseln - das funktioniert beim RP6 ein wenig anders.
Hier sollte man eigentlich immer changeDirection verwenden.
MfG,
SlyD
Hallo!
Ich bin auch gerade dabei, den Robo über die serielle zu steuern, bekomme es aber nicht wirklich hin.
ich habe die RX und TX Leitungen mit meinem PC verbunden und eben noch GND. Leider bekomme ich keine Ausgabe mit Hyperterminal hin (Keine Angst, beides läuft mit 5V). Ist es grundsätzlich nicht möglich, mit Hyperterminal eine verbindung hinzubekommen? Ich kann leider kein anderes Programm benutzen, da die Software in OpenWRT auf einem fonera router läuft.aber ich habe das gerade selbst mal ausprobiert - anscheinend setzt Hyper Terminal die Leitung RTS auf low --> das hält den MEGA32 im Reset Modus!
Ziel soll es ja sein, die Verbindung über ein eigenes Programm zu steuern. Hat jemand von euch schon mal so was gemacht? Also in C direkt auf die serielle Konsole zugegriffen? Man muss das Rad ja nicht mehrmals erfinden.
Vielen Dank für eure Antworten!
MfG
andieh
Ich habe mier einen RP6 gekauft und des program wo dabei war kapier ich net wie man des insterliert köntet ihr mier einen link schiken wo man das Program umsonst Downlouden kan ?
danke im foraus
Lesezeichen