Liste der Anhänge anzeigen (Anzahl: 1)
erweiterte ASURO Bibliothek
Hallo,
mir ist aufgefallen, daß mit den mitgelieferten Funktionen in asuro.h es schwer ist, gerade für Anfänger, gute Programme zu schreiben. Eine erweiterte Bibliothek kann da hilfreich sein. Natürlich muss dabei auf den kleinen Speicher geachtet werden. Ich würde mich freuen, wenn hier Verbesserungen zusammengetragen werden. Ich hab schon mal einen Anfang gemacht und 3 hilfreiche Funktionen in der angefügten Datei zusammengestellt.
1. Encoder_Init()
initialisiert einen Hintergrund Odometrie-Zähler
2. Encoder Signal(Interrupt) routine
setzt ständig die neuen Werte.
In der globolen Variable encoder(LEFT) und encoder(RIGHT) steht immer der aktuelle Zählerwert. Zurückgesetz wird mit z.B. encoder(LEFT)=0
3. Msleep(int Dauer) wartet die angegebene Zeit in ms.
als weitere Funktionen wünsche ich mr z.B. eine einfache formatierte Ausgabe und ein simples Multitasking oder watchdog-handling. Eine Verbesserung von PollSwitch() mit einer Rückgabe als BitFeld.......
Übrigens: Kann mir jemand StartSwitch(), StopSwitch() aus asuro.c erklären ?
Ich hoffe auf rege Beteiligung (was hälst Du davon Henk?)
Gruß
Weja
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo Leute,
nun habe ich es doch noch hinbekommen die "wichtigsten" Funktionen zum einfachen Programmieren für den Asuro in eine neue Bibliothek einzubinden.
Ich musste dabei die Dateien asuro.h und asuro.c vollständig ersetzen, weil auch viele Änderungen an den vorhandenen Funktionen nötig waren.
Diese Dateien und eine Kurzbeschreibung, sowie ein Beispielprogramm mit dem Namen test.c sind in dem begefügtem Archiv.
Sinn des ganzen Projektes ist es ja, dass sich der asuro-Programmierer um Lösungsstrategien für bestimmte Aufgaben kümmen kann, und sich nicht mit dem Setzen von irgendwelchen Registerwerten herumschlagen muss., die man in evt. nur kiloschweren Handbüchern findet.
Zum Beispielprogramm ( das gerade mal aus 30 Codezeilen besteht !!) :
Stell Dir vor, Du befindest Dich aus mir unbekannten Gründen, in einem Labyrinth mit Wänden, die unter Hochspannung stehen. Es ist stockdunkel, Du kannst nichts sehen. Bevor man Dich in dieses Labyrint verfrachtete hattest Du noch einen Wunsch frei. " Lasst mir den ASURO" war Dein Wunsch. Als Zugabe durftest Du den Asuro auch noch einige Minuten programmieren.
Das Ergebnis steht in test.c
Wenn der asuro startet fährt er eine Zeitlang (8 Sekunden) geradeaus. Triffte er dabei auf kein Hindernis, dreht er um und kommt zum Ausgangpunkt zurück. Er signalisiert die freie Strecke mit einer grünen LED. Wird vor Ablauf der 8 Sekunden auf ein Hindernis (schlimme Wand) getroffen, kommt asuro auch zum Ausgangspunkt zurück und signalisiert mit roter Status LED wenn diese Wand sehr nahe ist, oder mit gelber, wenn sie etwas weiter weg ist. So hast Du die Möglichkeit den Ausgang zu finden ( wenn denn einer da ist ) .
Ich hoffe, Ihr habt Spaß mit den neuen Programmiermöglichkeiten und würde mich über eine Rückmeldung sehr freuen.
Gruß
Weja
Schwierigkeiten mit den Interrupts
Hallo zusammen,
ich verwende ebenfalls die erweiterte Lib (an dieser Stelle einmal vielen Dank dafür, dass ihr die zur Verfügung stellt) und habe dabei folgendes Problem:
Da ich zur sauberen Geradeausfahrt den Encoder nutze, muss ich auch die Kollisionsabfrage über Interrupts durchführen (mit einefachen PollSwitch()-Aufrufen gehen mir Encoderticks verloren und der Asuro fährt unkontrollierte Kurven).
Daher prüfe ich bei der Geradeausfahrt, ob switched gesetzt ist. Ist dies der Fall, so kann ich einfach zurücksetzen, drehen und weiterfahren (nach dem Zurücksetzen setze ich auch switched wieder auf 0 und führe StartSwitch() aus, damit es beim nächsten Mal wieder funktioniert). Soweit so gut - bis dahin läuft alles wie gewünscht.
Kritisch wird es, wenn ich die Drehrichtung anhand der Taster auswählen möchte. Da die Interruptbehandlung nur das switched Flag setzt, muss ich den gedrückten Taster also explizit herausfinden. Dazu nutze ich der Einfachheit halber PollSwitch() - wenn der Asuro ohnehin angehalten hat, ist diese Funktion ja nicht mehr zeitkritisch und ich kann bequem die langsame AD-Konversion ausführen.
Leider tritt hierbei das Problem auf, dass ab diesem Moment permanent Interrupts bei den Schaltern auftreten - sprich: sobald der Asuro fertig gedreht hat, stellt er fest, dass er schon wieder kollidiert ist (auch wenn das nicht der Fall ist).
Ich habe zu diesem Problem schon eine ganze Weile im Datenblatt geblättert, muss aber etwas übersehen haben. Vielleicht hat ja jemand von euch dieselben Schwierigkeiten und einen Tipp parat, woran das liegen könnte (?). Wenn ja, würde ich mich über eine Antwort hier freuen.
Gruß
Ole
P.S.: Zum Besseren Verständnis (und vielleicht selbst ausprobieren), füge ich hier mal meinen Code an.
Code:
/*******************************************************************************
* File: drive.c
* Project: Asuro
*
* ------------
* Description:
* ------------
* Implements a simple drive-behavior.
*
* Features: - Move straight forward.
* - Step back, if we bump against an obstacle.
* - Turn left or right to aviod the obstacle.
* -----------------------------------------------------------------------------
*
* --------
* History:
* --------
* Version | Author | Date | Comments
* --------+----------------+------------+--------------------------------------
* 0.1 | Jan Ole Berndt | 11.12.2005 | Initial version.
*
******************************************************************************/
#include "asuro.h"
#define FORWARD 1
#define STEP_BACK 2
#define TURN_LEFT 4
#define TURN_RIGHT 8
#define BASE_SPEED 150
int driveState = FORWARD;
int turnDirection = TURN_LEFT;
/*
* Determines whether we have to stop the current move.
*/
int Interrupted(void)
{
return switched;
}
/*
* Moves the robot straight forward.
* This function is based on the Go()-function from the extended
* asuro-library.
*/
char Forward(int distance, int speed)
{
int enc_count = 0;
int tot_count = 0;
int diff = 0;
int l_speed = speed, r_speed = speed;
enc_count=abs(distance);
Encoder_Set(0,0); // reset encoder
MotorSpeed(l_speed,r_speed);
MotorDir(FWD,FWD);
//As long, as we haven't moved as far as we should and are not forced
//to stop:
while(tot_count<enc_count && !Interrupted()) {
tot_count += encoder[LEFT];
diff = encoder[LEFT] - encoder[RIGHT];
if (diff > 0) { //Left faster than right
if ((l_speed > speed) || (r_speed > 244)) l_speed -= 10;
else r_speed += 10;
}
if (diff < 0) { //Right faster than left
if ((r_speed > speed) || (l_speed > 244)) r_speed -= 10;
else l_speed += 10;
}
Encoder_Set(0,0); // reset encoder
MotorSpeed(l_speed,r_speed);
Msleep(1);
}
//If we are forced to stop:
if(Interrupted()){
MotorDir(BREAK,BREAK);
Msleep(200);
}
return 0;
}
/*
* Moves the robot in backward direction.
*/
char StepBack()
{
unsigned char switches = PollSwitch();
switches &= PollSwitch();
switches &= PollSwitch();
switches &= PollSwitch();
switches &= PollSwitch();
switches &= PollSwitch();
switches &= PollSwitch();
switches &= PollSwitch();
if(switches & 0x07)
turnDirection = TURN_LEFT;
else
turnDirection = TURN_RIGHT;
Encoder_Init();
Go(-50,150);
switched = 0;
StartSwitch();
return 0;
}
/*
* Turns the robot to the left.
*/
char TurnLeft()
{
Turn(-100,BASE_SPEED);
return 0;
}
/*
* Turns the robot to the right.
*/
char TurnRight()
{
Turn(100,BASE_SPEED);
return 0;
}
/*
* Returns the next state of the robot.
*/
int NextState()
{
if(driveState & STEP_BACK)
return turnDirection;
else if(Interrupted())
return STEP_BACK;
else
return FORWARD;
}
/*
* Main function.
* Determines the next state of the robot and calls the corresponding function.
*/
int main(void)
{
Init();
driveState = FORWARD;
Encoder_Init(); //Start Interrupt-handling for odometry.
StartSwitch(); //Start Interrupt-handling for switches.
while(1){
driveState = NextState();
switch(driveState){
case FORWARD:
Forward(500,BASE_SPEED);
break;
case STEP_BACK:
StepBack();
break;
case TURN_LEFT:
TurnLeft();
break;
case TURN_RIGHT:
TurnRight();
break;
}
}
//if any error occures and we leave the loop above,
//stop the motors and enter stable state (do nothing).
MotorSpeed(0,0);
MotorDir(BREAK,BREAK);
StopSwitch();
Encoder_Stop();
while(1);
return 0;
}
Liste der Anhänge anzeigen (Anzahl: 1)
Asuro interuptfähige PollSwitch() fnk
Ich habe mich ausgiebig mit der PollSwitch fnk auseinander gesetzt. Das Ergebnis ist eine interuptfähige PollSwitch() fnk. Meine Frage nun, wer ist der Maintainer dieser lib, gibt es einen Subversion/cvs Server?
Weitere Anfrage: Warum habt ihr den TimerCounter von 72 auf 36 KHZ umgestellt?
Ich bin zuerst von der orginal asuro lib ausgegangen und habe diverse änderungen selbst angebracht.