PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Ultraschallcode erweitert



pinsel120866
19.01.2008, 09:24
Hallo Zusammen,

da mein Asuro, wenn er zu schräg auf ein Hindernis zufährt, anstossen kann, habe ich versucht den US-Code um eine Art "Taster-Kollisions-Schutz" zu erweitern:


#include "asuro.h"
#include "ultrasonic.h"
#include "myasuro.h"
#define MAXDIFF 80

int main(void)
{
int abstand, abstand_alt, diff;
Init();
abstand = Chirp();

while(TRUE)
{
unsigned char i;
unsigned char taste=0;
abstand_alt = abstand;
abstand = Chirp();
diff = abstand - abstand_alt;
for(i=0;i<10;i++)
{
PollSwitch();
}
taste=PollSwitch();

if( (abstand>15) && (abs(diff)<MAXDIFF) && (taste==0))
{
StatusLED(GREEN);
MotorDir(FWD, FWD);
MotorSpeed(150, 150);
for(i=0;i<10;i++)
{
PollSwitch();
}
}
else
{
StatusLED(RED);
MotorDir(RWD, RWD);
MotorSpeed(100, 200);
Msleep(300);
}
}
return 0;
}


Jetzt aber eine Frage: Wie kann ich einen Zufallsgenerator einbauen, dass der ASURO nicht immer auf die gleiche Seite ausweicht?

inka
22.01.2008, 05:59
es macht ja nur dann einen sinn, wenn der asuro immer weg von der wand dreht, oder? Versuche doch die taster einzeln abzufragen, sodass er wenn er links anstösst nach rechts wegdreht und umgekehrt...

pinsel120866
22.01.2008, 09:36
Da hast du recht, wenn aber vom US ein Hindernis erkannt wird, geht's dann nicht. Ich meine dass sich der ASURO dann "natürlicher" verhält.

inka
22.01.2008, 09:59
verstehe ich nicht...
wenn also die abfrage <10cm positiv beantwortet wird funktioniert die abfrage der taster nicht?

pinsel120866
22.01.2008, 10:21
Bei meinem Programm dreht der Asuro weg, wenn der Abstand kleiner 15 cm wird, bzw. wenn ein Taster betätigt wird. Allerdings dreht er dann immer in die gleiche Richtung.

inka
22.01.2008, 12:09
meinst du sowas?

#include "asuro.h"
#include "ultrasonic.h"
#include "inka.h"


int main(void)
{
int abstand, sw, sw0, sw1, sw2;
Init();
WaitforStart();
// abstand = Chirp();

while(1)
{

sw0=PollSwitch(); // Schalter einlesen und für eine Runde speichern
sw1=PollSwitch();
sw2=PollSwitch();
if ((sw0==sw1) && (sw0==sw2)) sw=sw0; else sw=0;


MotorDir(FWD,FWD);
MotorSpeed(150, 150);

abstand = Chirp();
StatusLED(YELLOW);

if (sw==32)
{
StatusLED(RED);

MotorDir(RWD,RWD);
MotorSpeed(150, 150);
Msleep(600);

MotorDir(RWD,FWD);
MotorSpeed(150, 150);
Msleep(900);
}
if (sw==1)
{
StatusLED(RED);

MotorDir(RWD,RWD);
MotorSpeed(150, 150);
Msleep(600);

MotorDir(FWD,RWD);
MotorSpeed(150, 150);
Msleep(900);
}

else if(abstand<15)
{
StatusLED(RED);

MotorDir(RWD,RWD);
MotorSpeed(150, 150);
Msleep(600);

MotorDir(RWD,FWD);
MotorSpeed(150, 150);
Msleep(900);
}

else
{
StatusLED(GREEN);
MotorDir(FWD, FWD);
MotorSpeed(250, 250);
}
}
return 0;
}

pinsel120866
22.01.2008, 12:17
Ja, genau das. DANKE!
Wofür braucht man "WaitForStart()"?

inka
22.01.2008, 12:28
damit er wartet, bis er mit einem tastendruck "losgeschickt" wird und nicht sofort nach dem einschalten losrast...
ist einen ähnliche tastenabfrage wie oben, als funktion in "inka.c" und h abgelegt...

pinsel120866
22.01.2008, 12:32
Gut, danke dass du einer "Programmierpflaume" wie mir etwas unter die Arme greifst. Das willkürliche Wegdrehen (rechts ODER links) bei Abstand<15 habe ich leider noch nicht m Griff...

inka
22.01.2008, 12:46
das ist ein problem der hinderniserfassung, man hat halt nur einen sender und einen empfänger, nicht sechs taster :-( - daher schwierig.
Und was das "unter die arme greifen" betrifft, ich bin eigentlich eine nicht wesentlich bessere "pflaume", aber du kennst sicher die story mit den blinden hünhnern"?
im forum gibt es einen "zufallsgenerator", ich glaube von M.1.R, suche mal danach...

pinsel120866
22.01.2008, 13:58
Nur keine falsche Bescheidenheit, wenn ich so das Forum durchsuche, finde ich oft hilfreiche Threats von "inka" ;-)

Ich habe das gefunden:

//
// uint8_t zufall()
//
// Liefert eine 8Bit Pseudozufallszahl zurück,
// die Zahlenfolge wiederholt sich spätestens nach 65535 Aufrufen
//

uint8_t zufall()
{
static uint16_t startwert=0x0AA;

uint16_t temp;
uint8_t n;

for(n=1;n<8;n++)
{
temp = startwert;
startwert=startwert << 1;

temp ^= startwert;
if ( ( temp & 0x4000 ) == 0x4000 )
{
startwert |= 1;
}
}

return (startwert);
}

Muss ich mir jetzt eine "zufall.c" und eine "zufall.h" machen , damit ich das einbauen kann?

inka
22.01.2008, 14:25
ich würde es zunächstmal versuchen als funktion in deine datei, da wo du es brauchst aufzunehmen:

uint8_t zufall();
-----------------------
und weiter unten die funktion beschreiben:
-------------------
void uint8_t zufall(void)
{
static uint16_t startwert=0x0AA;
uint16_t temp;
uint8_t n;
for(n=1;n<8;n++)
{
temp = startwert;
startwert=startwert << 1;
temp ^= startwert;
if ( ( temp & 0x4000 ) == 0x4000 )
{
startwert |= 1;
}
}
return (startwert);
}
---------------

hoffe dass es so stimmt :-)

pinsel120866
22.01.2008, 15:10
Irgendwie wird mir die Sache zu kompliziert, ich frage mich ob ich mir da nicht zu viel vorgenommen habe...

Trotzdem DANKE für deine Hilfe!

MartinFunk
22.01.2008, 15:36
hi pinsel,
ich habe das bei meinem robby so gemacht das ich aus einem timer register(OCRx) den wert ausgelsen habe und überprüft ob die zahl gerade oder ungerade ist. Da der zeitpunkt an dem dein asuro ein hinderniss erkennt nicht immer gleich ist ensteht so eine einfache ufalls funktion.

MfG Martin

pinsel120866
22.01.2008, 15:41
Hallo Martin,

hört sich gut an, kannst du mir weitere Infos dazu geben?

MartinFunk
22.01.2008, 15:51
unsigned char ocr = 0;
unsigned char ocr1 = 0;
ocr = OCR0;
ocr1 =ocr/2;
ocr1 *=2;
if(ocr == ocr1){
//rechts
}
else{
//links
}

pinsel120866
22.01.2008, 16:17
OK, ich habs mal eingefügt, es kommt aber eine Fehlermeldung:

test.c:18: error: 'OCR0' undeclared (first use in this function)

MartinFunk
22.01.2008, 16:23
oh hab da das register verwechselt es muss heisen


TCNT0

pinsel120866
22.01.2008, 16:36
Jetzt hat's geklappt.

Nur weicht er bei Abstand<15 immer noch auf die gleiche Seite aus.
Hier der Code:

#include "asuro.h"
#include "ultrasonic.h"

int main(void)
{
int abstand, sw, sw0, sw1, sw2;
unsigned char ocr = 0;
unsigned char ocr1 = 0;

Init();

while(1)
{

sw0=PollSwitch();
sw1=PollSwitch();
sw2=PollSwitch();
ocr = TCNT0;
ocr1 =ocr/2;
ocr1 *=2;

if ((sw0==sw1) && (sw0==sw2)) sw=sw0; else sw=0;


MotorDir(FWD,FWD);
MotorSpeed(150, 150);

abstand = Chirp();
StatusLED(YELLOW);

if (sw==32)
{
StatusLED(RED);

MotorDir(RWD,RWD);
MotorSpeed(150, 150);
Msleep(600);

MotorDir(FWD,RWD);
MotorSpeed(150, 150);
Msleep(600);
}
if (sw==16)
{
StatusLED(RED);

MotorDir(RWD,RWD);
MotorSpeed(150, 150);
Msleep(600);

MotorDir(FWD,RWD);
MotorSpeed(150, 150);
Msleep(600);
}
if (sw==8)
{
StatusLED(RED);

MotorDir(RWD,RWD);
MotorSpeed(150, 150);
Msleep(600);

MotorDir(FWD,RWD);
MotorSpeed(150, 150);
Msleep(600);
}
if (sw==1)
{
StatusLED(RED);

MotorDir(RWD,RWD);
MotorSpeed(150, 150);
Msleep(600);

MotorDir(RWD,FWD);
MotorSpeed(150, 150);
Msleep(600);
}
if (sw==2)
{
StatusLED(RED);

MotorDir(RWD,RWD);
MotorSpeed(150, 150);
Msleep(600);

MotorDir(RWD,FWD);
MotorSpeed(150, 150);
Msleep(600);
}
if (sw==4)
{
StatusLED(RED);

MotorDir(RWD,RWD);
MotorSpeed(150, 150);
Msleep(600);

MotorDir(RWD,FWD);
MotorSpeed(150, 150);
Msleep(600);
}

else if (abstand<15)
{
if (ocr == ocr1){
StatusLED(RED);

MotorDir(RWD,RWD);
MotorSpeed(150, 150);
Msleep(600);

MotorDir(RWD,FWD);
MotorSpeed(150, 150);
Msleep(600);
}
else
{
StatusLED(RED);

MotorDir(RWD,RWD);
MotorSpeed(150, 150);
Msleep(600);

MotorDir(FWD,RWD);
MotorSpeed(150, 150);
Msleep(600);
}
}

else
{
StatusLED(GREEN);
MotorDir(FWD, FWD);
MotorSpeed(150, 150);
}
}
return 0;
}

MartinFunk
22.01.2008, 16:41
das sollte so aussehen:


#include "asuro.h"
#include "ultrasonic.h"

int main(void)
{
int abstand, sw, sw0, sw1, sw2;
unsigned char ocr = 0;
unsigned char ocr1 = 0;

Init();

while(1)
{

sw0=PollSwitch();
sw1=PollSwitch();
sw2=PollSwitch();

if ((sw0==sw1) && (sw0==sw2)) sw=sw0; else sw=0;


MotorDir(FWD,FWD);
MotorSpeed(150, 150);

abstand = Chirp();
StatusLED(YELLOW);

if (sw==32)
{
StatusLED(RED);

MotorDir(RWD,RWD);
MotorSpeed(150, 150);
Msleep(600);

MotorDir(FWD,RWD);
MotorSpeed(150, 150);
Msleep(600);
}
if (sw==16)
{
StatusLED(RED);

MotorDir(RWD,RWD);
MotorSpeed(150, 150);
Msleep(600);

MotorDir(FWD,RWD);
MotorSpeed(150, 150);
Msleep(600);
}
if (sw==8)
{
StatusLED(RED);

MotorDir(RWD,RWD);
MotorSpeed(150, 150);
Msleep(600);

MotorDir(FWD,RWD);
MotorSpeed(150, 150);
Msleep(600);
}
if (sw==1)
{
StatusLED(RED);

MotorDir(RWD,RWD);
MotorSpeed(150, 150);
Msleep(600);

MotorDir(RWD,FWD);
MotorSpeed(150, 150);
Msleep(600);
}
if (sw==2)
{
StatusLED(RED);

MotorDir(RWD,RWD);
MotorSpeed(150, 150);
Msleep(600);

MotorDir(RWD,FWD);
MotorSpeed(150, 150);
Msleep(600);
}
if (sw==4)
{
StatusLED(RED);

MotorDir(RWD,RWD);
MotorSpeed(150, 150);
Msleep(600);

MotorDir(RWD,FWD);
MotorSpeed(150, 150);
Msleep(600);
}

else if (abstand<15)
{
ocr = TCNT0;
ocr1 =ocr/2;
ocr1 *=2;
if (ocr == ocr1){
StatusLED(RED);

MotorDir(RWD,RWD);
MotorSpeed(150, 150);
Msleep(600);

MotorDir(RWD,FWD);
MotorSpeed(150, 150);
Msleep(600);
}
else
{
StatusLED(RED);

MotorDir(RWD,RWD);
MotorSpeed(150, 150);
Msleep(600);

MotorDir(FWD,RWD);
MotorSpeed(150, 150);
Msleep(600);
}
}

else
{
StatusLED(GREEN);
MotorDir(FWD, FWD);
MotorSpeed(150, 150);
}
}
return 0;
}

pinsel120866
22.01.2008, 16:45
Leider wie bei mir, er dreht immer nach links weg :-(

MartinFunk
22.01.2008, 16:49
oh ich seh grad beim asuro wird der timer 1 gar nicht benutzt
versuchs mal mit meinem code und TCNT2

pinsel120866
22.01.2008, 17:28
Jetzt hat's geklappt, danke für deine Hilfe!

pinsel120866
22.01.2008, 18:34
Projekt fertig: \:D/

US-Code für ASURO mit folgenden Extras:

- Geradeausfahrt mit Odometriezähler (Ausgleich Links, Rechts)
- Wegdrehen bei Tasterberührung von der Wand (T1,T2,T3 links - T4,T5,T6 rechts)
- bei Abstand < 15 cm wegdrehen von der Wand mittels Zufallsgenerator (Links oder Rechts mittels Timer TCNT2)




#include "asuro.h"
#include "ultrasonic.h"

#define TRIGGERLEVEL 600
#define HYSTERESIS 10
#define LOW 0
#define HIGH 1

int main(void)
{
int abstand, sw, sw0, sw1, sw2;
unsigned char ocr = 0;
unsigned char ocr1 = 0;
unsigned int data[2];
signed int status[2]={0,0};
signed int difference=0;

Init();

while(1)
{

sw0=PollSwitch();
sw1=PollSwitch();
sw2=PollSwitch();

if ((sw0==sw1) && (sw0==sw2)) sw=sw0; else sw=0;

{
StatusLED(GREEN);
MotorDir(FWD, FWD);
MotorSpeed(150, 150);
}

abstand = Chirp();
StatusLED(YELLOW);

if (sw==32)
{
StatusLED(RED);

MotorDir(RWD,RWD);
MotorSpeed(150, 150);
Msleep(600);

MotorDir(FWD,RWD);
MotorSpeed(150, 150);
Msleep(600);
}
if (sw==16)
{
StatusLED(RED);

MotorDir(RWD,RWD);
MotorSpeed(150, 150);
Msleep(600);

MotorDir(FWD,RWD);
MotorSpeed(150, 150);
Msleep(600);
}
if (sw==8)
{
StatusLED(RED);

MotorDir(RWD,RWD);
MotorSpeed(150, 150);
Msleep(600);

MotorDir(FWD,RWD);
MotorSpeed(150, 150);
Msleep(600);
}
if (sw==1)
{
StatusLED(RED);

MotorDir(RWD,RWD);
MotorSpeed(150, 150);
Msleep(600);

MotorDir(RWD,FWD);
MotorSpeed(150, 150);
Msleep(600);
}
if (sw==2)
{
StatusLED(RED);

MotorDir(RWD,RWD);
MotorSpeed(150, 150);
Msleep(600);

MotorDir(RWD,FWD);
MotorSpeed(150, 150);
Msleep(600);
}
if (sw==4)
{
StatusLED(RED);

MotorDir(RWD,RWD);
MotorSpeed(150, 150);
Msleep(600);

MotorDir(RWD,FWD);
MotorSpeed(150, 150);
Msleep(600);
}

else if (abstand<15)
{
ocr = TCNT2;
ocr1 =ocr/2;
ocr1 *=2;
if (ocr == ocr1){
StatusLED(RED);

MotorDir(RWD,RWD);
MotorSpeed(150, 150);
Msleep(600);

MotorDir(RWD,FWD);
MotorSpeed(150, 150);
Msleep(600);
}
else
{
StatusLED(RED);

MotorDir(RWD,RWD);
MotorSpeed(150, 150);
Msleep(600);

MotorDir(FWD,RWD);
MotorSpeed(150, 150);
Msleep(600);
}
}

else
{

OdometrieData(data);
if ((status[0]==LOW) && (data[0]>TRIGGERLEVEL+HYSTERESIS)) {
status[0]=HIGH;
difference++;
}
if ((status[0]==HIGH) && (data[0]<TRIGGERLEVEL-HYSTERESIS)) {
status[0]=LOW;
difference++;
}
if ((status[1]==LOW) && (data[1]>TRIGGERLEVEL+HYSTERESIS)) {
status[1]=HIGH;
difference--;
}
if ((status[1]==HIGH) && (data[1]<TRIGGERLEVEL-HYSTERESIS)) {
status[1]=LOW;
difference--;
}

if (difference<-155) difference=-155;
if (difference>155) difference=155;


StatusLED(status[0]+status[1]*2);

if (difference>0) MotorSpeed(155-difference,155);
else MotorSpeed(155,155+difference);


}



}
return 0;
}


Mein ASURO verhält sich jetzt viel natürlicher (wie ein Hamster) :-)

Kopieren erlaubt, Verbesserungsvorschläge willkommen!

Danke an inka und MartinFunk für die Unterstützung!

inka
22.01.2008, 18:44
hi pinsel,

gleich einen vereinfachungsvorschlag für die tasterabfrage:
abfrage für zusammengehörende taster zusammenfassen mit hilfe von:

if ((sw==1) || (sw==2) || (sw==3))

(k1, k2, k1+k2) - ich bin ziemlich sicher dass man die abfrage der innenliegenden taster nicht braucht...

JensK
23.01.2008, 19:36
wenn ich pinsles programm compilieren möchte, kommt diese Fehlermeldung:

J:\ASURO\Programme\asuro_libv271\examples\FirstTry/test.c:47: undefined reference to `Chirp'

das heißt doch, dass er "Chirp" nicht kennt oder? oder will er in den klammern ein wert haben?

mfg

pinsel120866
24.01.2008, 06:35
Hi JensK,

guckst du hier: https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=10907&postdays=0&postorder=asc&start=103

inka
24.01.2008, 07:04
oder in die ultrasonic.c aus der lib 2.7.1...

pinsel120866
24.01.2008, 07:14
Hi Inka,

mit deiner Vereinfachung habe ich den Code von 42 auf 36 Pages reduziert.

Noch was - hast du schon Erfahrungen mit der Triangulation gemacht?

inka
24.01.2008, 08:40
hi pinsel,
meinst du die sensoren aus dem asurobuch?

pinsel120866
24.01.2008, 08:42
Ja, genau die SHARP Sensoren.

inka
24.01.2008, 08:46
nein, das habe ich nur überflogen und mich dann auf ultraschall und IR (was ja auch dazu genutzt werden könnte) konzentriert...

JensK
25.01.2008, 21:42
okidoki klappt jetzt alles dankö

mfg