Ich stimme für izaseba. Sein Bild hat einfach den schöneren Hintergrund und mit einer Frau im Rücken,
die überwacht, dass er nicht auf den Fußboden malt, hatte er eindeutig erschwerte Bedingungen ;-)
Druckbare Version
Ich stimme für izaseba. Sein Bild hat einfach den schöneren Hintergrund und mit einer Frau im Rücken,
die überwacht, dass er nicht auf den Fußboden malt, hatte er eindeutig erschwerte Bedingungen ;-)
Tja, das ist ja sehr schön, wenn ich richtig gezählt habe, dann hat jeder von uns zwei Stimmen bekommen, die vom jeweils anderen und noch eine.
Damit steht es UNENTSCHIEDEN !!!!
Aber das es ging ja um den Spass bei der Sache.
Was mich noch rein programmtechnisch interessieren würde: izaseba, wie hast Du den Gleichlauf der Motoren und den korrekten Winkel hingekriegt? Bei meinem Programm sind es ja die Kallibrierroutinen.
Was mich mal interessieren würde: hat mal jemand das Programm von mir in seinen ASURO geladen und ausprobiert ? Mich würde interessieren ob man die Winkelroutine anpassen muss.
Schade das linux_80 nicht mitmachen konnte und ICH_ hat sich angemeldet, aber konnte wohl auch nicht teilnehmen ( war ja auch ein zu schönes Wochenende)
Gut, das Wetter macht einem im Moment nicht so an, um was zu programmieren.
Aber meine Frage: Sollen wir noch mal so einen Wettbewerb veranstalten ? Ich denke es ließen sich sogar ein paar Preise organisieren. Wäre das ein Anreiz ?
viele Gruesse,
stochri
Oh, halt, "unentschieden": Ich habe vergessen, dass die Bewertungsphase ja eigentlich erst morgen um Mitternacht endet;-)
Tschuldigung,
stochri
Hallo stochri,
Ich habe einfach alles über die Odometrie gemacht,
Geradefahren tut mein Asuro schon so, da habe ich gottseidank nichts machen brauchen
(hatte auch nicht viel Zeit um das auch noch zu programmieren)
und die Winkel, ich habe gezählt wieviele schwarz-weiß Übergänge bei 90 grad stattfinden (ich habe die scheiben mit 4 weißen und 4 schwarzen Feldern drauf) und das waren genau 50.
Na ja dann kamen noch 75 für 135 grad und Fertig.
Für die Strecke habe ich 100 Übergänge genommen und für die diagonale und das Dach habe ich den Herrn Pytagoras befragt, stimmte zwar nicht ganz genau, wegen dem Schlupf (Theorie und Praxis) also noch etwas angepasst und fertig.
Anbei mein Programm, da ich ein Purist bin und C an meinem Rechner schon immer benutze, habe ich das Programm im Assembler geschrieben.
Ist zwar nicht ganz perfekt, aber wie Du schon sagtest, schönes Wetter, noch Kirmes im Dorf, die Bruderschaft hat gerufen, naja nicht viel Zeit gehabt.
Code:;Version 1.0
;Odometrie nach dem Beispiel von Rechteck.c
.include "m8def.inc"
.equ fwd = PB5 ;vor
.equ rwd = PB4 ;zurück
.equ encodertrue = 7 ;Bit 7 von tooglereg für Odometrie an/aus
.equ kolisionflag = 6 ;Bit 6 von tooglereg für Kolisionerkennung
.equ toogleflagL = 2 ;Hat eine Änderung am Rad Links stattgefunden ?
.equ toogleflagR = 1 ;Hat eine Änderung am Rad Rechts stattgefunden?
.equ toogle = 0 ;Bit 0 von tooglereg für Rad R "0" und Rad L "1" umzuschalten
.equ geschwindigkeit = 0xA0
.equ encoderon = 0x80
.equ encoderoff = 0x7F
.equ rechterwinkel = 53 ; 90 grad rechts sind genau 53 schritte
.equ rechterwinkel2 = 54 ; 90 grad links sind genau 54 schritte
.equ halbrechterwinkel = 80 ;135 grad rechts
.equ weg = 100 ;soll 300 schritte fahren
.equ weglang = 150 ;Langer Weg diagonal
.equ wegkurz = 50 ;Kurzer Weg für das Dach
.def encoder_leftL = R1
.def encoder_leftH = R2
.def encoder_rightL = R3
.def encoder_rightH = R4
.def vergleicherL = R5
.def vergleicherH = R6
.def tmp = R16 ; Multipurose
.def tmpi = R17 ; Multipurose für Interrupts
.def tmpi2 = R19 ;Multipurose 2 für 16 Bit rechnen
.def tmp2 = R20 ;Multipurose für 16 Bit rechnen
.def geschlinks = R21 ;geschwindigkeit linkes Rad
.def geschrechts = R22 ;geschwindigkeit rechtes Rad
.def tooglereg = R18 ;Toogle Register
.org 0x00
rjmp reset ;ResetVector
.org ADCCaddr
rjmp ADCcomplete ; ADC Interrupt Vector Address
reset:
;Stack einrichten
ldi tmp,HIGH(RAMEND)
out SPH,tmp
ldi tmp,LOW(RAMEND)
out SPL,tmp
;Stack fertig
ldi tooglereg,0x00
ori tooglereg,encoderon
;PWM einstellen
ldi tmp,(1<<WGM10) | (1<<COM1A1) | (1<<COM1B1)
out TCCR1A,tmp
ldi tmp,(1<<CS11)
out TCCR1B,tmp
;DDR für Tastenabfrage
;A/D Conversion
ldi tmp,(1<< ADEN) | (1<<ADFR) | (1<<ADIE) | (1<<ADSC) | (1<<ADPS0) | (1<<ADPS1) | (1<<ADPS2)
out ADCSRA,tmp
ldi tmp,(1<<REFS0) | (1<<ADLAR) | (1<<MUX0)
out ADMUX,tmp
; DDR für Motor Rechts und Statusled green
ldi tmp,(1<<PB0) |(1<<PB1) | (1<<PB2) | (1<<PB5) | (1<<PB4)
out DDRB,tmp
;DDR für Motor Links,Statusled red, LED für Linienverfolgung und LEDs
;Odometrie und Backleds
ldi tmp,(1<<PD2) | (1<<PD4) | (1<<PD5) | (1<<PD6) | (1<<PD7)
out DDRD,tmp
cbi DDRD,PD3
cbi DDRC,PC0 ;schalte PC0 als eingang
cbi DDRC,PC1 ;schalte PC0 als eingang
sbi PORTD,PD7 ;schalte Odometrie LEDs ein
cbi PORTB,PB0 ;Status LED aus
cbi PORTD,PD2 ;Dito
;ldi tmp,LOW(weg)
;mov vergleicherL,tmp
;ldi tmp,HIGH(weg)
;mov vergleicherH,tmp
;sbi PORTD,PD6
ldi geschrechts,geschwindigkeit
ldi geschlinks,geschwindigkeit
sei
main:
rcall motorengesch
rcall ladeweg
rcall fahre
rcall drehe
rcall ladeweg
rcall fahre
rcall drehe
rcall ladeweg
rcall fahre
rcall drehe
rcall ladeweg
rcall fahre
rcall drehehalb
rcall ladeweglang
rcall fahre
rcall drehelinks
rcall ladewegkurz
rcall fahre
rcall drehelinks
rcall ladewegkurz
rcall fahre
rcall drehelinks
rcall ladeweglang
rcall fahre
rcall motorenloeschen
stop:
rjmp stop
ladeweg:
cli
ldi tmp,LOW(weg)
mov vergleicherL,tmp
ldi tmp,HIGH(weg)
mov vergleicherH,tmp
sei
rcall odozaehlernull
sbi PORTB,fwd
sbi PORTD,fwd
ret
ladeweglang:
cli
ldi tmp,LOW(weglang)
mov vergleicherL,tmp
ldi tmp,HIGH(weglang)
mov vergleicherH,tmp
sei
rcall odozaehlernull
sbi PORTB,fwd
sbi PORTD,fwd
ret
ladewegkurz:
cli
ldi tmp,LOW(wegkurz)
mov vergleicherL,tmp
ldi tmp,HIGH(wegkurz)
mov vergleicherH,tmp
sei
rcall odozaehlernull
sbi PORTB,fwd
sbi PORTD,fwd
ret
drehe:
rcall motorenloeschen ;motoren STOP
ldi tmp,rechterwinkel ;Lade 90 grad Drehung
mov vergleicherL,tmp
ldi tmp,0x00
mov vergleicherH,tmp
rcall odozaehlernull ;Wegezähler löschen
sbi PORTD,fwd ;Jetzt Drehen wir uns was
rcall fahre ;Jetzt warten bis wir uns um 90 grad gedreht haben
rcall motorenloeschen ;motoren STOP
ret
drehelinks:
rcall motorenloeschen ;motoren STOP
ldi tmp,rechterwinkel2 ;Lade 30 schritte für die 90 grad Drehung
mov vergleicherL,tmp
ldi tmp,0x00
mov vergleicherH,tmp
rcall odozaehlernull ;Wegezähler löschen
sbi PORTB,fwd ;Jetzt Drehen wir uns was
rcall fahrelinks ;Jetzt warten bis wir uns um 90 grad gedreht haben
rcall motorenloeschen ;motoren STOP
ret
drehehalb:
rcall motorenloeschen ;motoren STOP
ldi tmp,halbrechterwinkel ;135 grad Drehung
mov vergleicherL,tmp
ldi tmp,0x00
mov vergleicherH,tmp
rcall odozaehlernull ;Wegezähler löschen
sbi PORTD,fwd ;Jetzt Drehen wir uns was
rcall fahre
rcall motorenloeschen ;motoren STOP
ret
fahre:
cli
mov tmp,encoder_rightL
mov tmp2,encoder_rightH
cp vergleicherL,tmp ;Vergleiche gefahrenen Weg
cpc vergleicherH,tmp2
sei
in tmp,SREG
sbrs tmp,0
rjmp fahre
ret
fahrelinks:
cli
mov tmp,encoder_leftL
mov tmp2,encoder_leftH
cp vergleicherL,tmp ;Vergleiche gefahrenen Weg
cpc vergleicherH,tmp2
sei
in tmp,SREG
sbrs tmp,0
rjmp fahrelinks
ret
.include "motoren.asm"
.include "LED.asm"
ADCcomplete:
in tmpi,SREG
push tmpi
ldi tmpi2,0x00
in tmpi,ADCL
in tmpi,ADCH
sbrs tooglereg,toogle ;Wenn Bit toogle = 1 Weiter bei Rechtem Rad
rjmp radlinks
;Rad Rechts
sbrs tooglereg,toogleflagR
rjmp flagRfalse
;flagRtrue
cpi tmpi,0x8C
brsh ausR
ldi tmpi,0x01
add encoder_rightL,tmpi
adc encoder_rightH,tmpi2
;debug
cbi PORTD,PD2
sbi PORTB,PB0
;ende debug
andi tooglereg,0xFD
rjmp ausR
flagRfalse:
cpi tmpi,0xA0
brlo ausR
ldi tmpi,0x01
add encoder_rightL,tmpi
adc encoder_rightH,tmpi2
;debug
cbi PORTD,PD2
sbi PORTB,PB0
;ende debug
ori tooglereg,(1<<toogleflagR)
ausR:
sbi ADMUX,MUX0
andi tooglereg,0xFE
rjmp rausadc
radlinks:
sbrs tooglereg,toogleflagL ;ist toogleflagL gesetzt? wenn ja springe zu flagtrue
rjmp flagLfalse ;wenn nicht springe zu flagLfalse
;flagLtrue
cpi tmpi,0x8C ;vergleiche mit 0xA0
brsh ausL ;wenn größer oder gleich springe zu ausL
ldi tmpi,0x01
add encoder_leftL,tmpi ;encoder_left++
adc encoder_leftH,tmpi2
;Debug
sbi PORTD,PD2
cbi PORTB,PB0
;Ende Debug
andi tooglereg,0xFB ;Lösche flagL
rjmp ausL
flagLfalse:
cpi tmpi,0xA0
brlo ausL
ldi tmpi,0x01
add encoder_leftL,tmpi
adc encoder_leftH,tmpi2
;Debug
sbi PORTD,PD2
cbi PORTB,PB0
;ende debug
ori tooglereg,(1<<toogleflagL)
ausL:
cbi ADMUX,MUX0
ori tooglereg,(1<<toogle)
rjmp rausadc
rausadc:
pop tmpi
out SREG,tmpi
reti
Ok, ich bin jetzt etwas spät dran.
Trotzdem möchte ich meinen Nikolaus hier auch einbringen, da mich dieser Threat eigendlich dazu gebracht hat überhaupt mit dem Asuro weiterzumachen. (Natürlich verstehe ich es, wenn ich nicht mehr in die Wertung komme.)
Einmal vorweg:
Mein Asuro scheint eine echte Krücke zu sein. Wie ihr gleich am ersten Bild sehen könnt, hatte ich zwar keine Probleme mit dem Programm von stochri so halbwegs gerade Striche hinzubekommen, aber das gesamte Ergebnis war eher etwas für 'bildende Künste' als für den Nikolaus. Jedenfalls ist das mein bestes Ergenis, dass ich mit dem Program von stochri hinbekommen hatte.
Dann habe ich mich so ein paar Monate zurückgezogen und einige Infos hier aus dem Forum (waste sei Dank) und gründlichem Studium der Doku und einiger schlaflosen Nächte zusammengeschustert um meinem Asuro den Nikolaus zu entlocken.
Nachdem also der linienverfolgende PID-Regleger von waste zu einem Raddekoder-Regler umkonfiguriert war und alle Sensoren (außer der Empfangsschnittstelle) auf Interruptbetrieb umgestellt wurden, habe ich meine Willen durchsetzen können und dem vergammelten, verrosteten, und wahrscheinlich Vorgänger von R2D2 (soll heissen mein Asuro) doch noch einen Nikolaus so halbwegs malen lassen können.
So, nun der schlechteste Nikolaus in diesem Wettbewerb, und dann der nach monatelagen Versuchen entstanden 'Nachbau'.
So, damit ihr auch nachsehen könnt, was ich mir für eine Mühe gemacht habe, gibt es auch noch meinen Source dazu.
- asuro_st.c entspricht ca. der asuro.c mit 'kleinen' Umbauten
- asuro_st.h bringt auch 'ungefähr' das Gleiche mit
- asuro_hw.h enthält nur einen Hardwaredefine für meine unterschiedlichen (Krücken-)Motoren
- asuro_md.h enthält einige Defines zum sammeln von MessDaten
- test.c enthält den Nikolaus
Im Source asuro_st.c sind vor allem die Umbauten zum Interruptbetrieb und ich habe dort den PID-Regler von waste so eingebaut, dass sowohl eine Linienverfolgung als eben auch eine Nutzung für die Raddekoder möglich ist.
[Edit 30.04.2010] Eine angepasste Version (V10-2) hinzugefügt, da es bei neueren Compilern Probleme mit dem #include <string.h> gibt. Die scheint nicht mehr notwendig zu sein.
GRATULATION ZU DISEM ERGEBNIS !!
Hallo Sternthaler,
Dein Nikolaushaus ist wirklich das Beste im ganzen Wettbewerb.
Und das Ziel des Wettbewerbs war es ja eingentlich, gute Verfahren für die Asuorwegsteuerung zu finden.
Bei meinem Programm muss man erst ein paar mal die Kallibrierroutinen laufen lassen, bis der ASURO um den richtigen Winkel dreht und eine gerade Linie fährt. Erst wenn man das gemacht hat, kann man das Ergebnisbild erreichen, welches ich gepostet habe.
Beim Wettbewerb stand ich vor der Entscheidung, einen Regler zu entwerfen, oder einfach nur eine Steuerung zu implementieren. Da ein hoher Zeitdruck ( fast wie im richtigen Entwicklerleben ) vorhanden war, habe ich mich für die Steuerung entschieden, weil ich davon ausgegangen bin, dass für eine kurze Zeit die Batteriespannung einigermaßen konstant bleibt und die Motoren gliechbleibend laufen.
Bei diesem Verfahren ist natürlich die Kallibrierung etwas umständlich und für ein gutes NIkolaushaus bedarf es dann einiger Versuche.
Das Programm ist deshalb für eine Wegsteuerung nicht allgemein verwendbar, aber für den Wettbewerb durchaus ausreichend.
Bei der Implementation des Reglers hätte ich die Schwierigkeit erwartet, beim Zeichnen einer geraden Linie einen Einschwingvorgang auf der Linie zu sehen. Und wenn der ASURO einmal seine Position leicht verloren hat, wird es mit dem Nikolaushaus nichts.
Deshalb halte ich Dein Ergebnis für super, nur mit dem Zeitkriterium ist es halt etwas knapp. Aber Dein Ergebnis ist sicherlich allgemein verwendbar und deshalb ist das Ziel, für den ASURO eine vernünftige Motorsteuerung zu realisieren wohl erreicht.
Bin mal gespannt, was Waste zu Deinerm Ergebnis meint.
Beste Grüße,
stochri
@stochri
Danke für die Blumen.
Eigendlich kann ich dir nicht zustimmen, dass der Nicolaus von mir der Beste sein soll. Bei deinem passen die Ecken besser, und izaseba's Ansatz die Kringel beim Wenden durch eine Bogenfahrt zu vermeiden, ist zwar nicht der 'klassische' Nikolaus, aber alleine der Mut zu diesem Ansatz hatte mich damals schon überrascht. Da wäre ich nie im Leben selber drauf gekommen.
Da hast du vollkommen Recht. Wenn ihr euch mal die rechte, obere Ecke, bzw. die obere waagerechte Linie an der rechten Seite anseht (Ausschnitt siehe unten), dort ist das Schwingen sehr gut zu sehen.Zitat:
Zitat von stochri
Der Bogen geht erst nach unten, das heisst der Asuro fährt erst mit dem linken Motor los, die Linie pendelt dann tatsächlich erst etwas bis der Regler alles in den Griff bekommen hat. Eigendlich ist bei allen Linien dieser Effekt zu sehen. Klar, ich hatte ja schon davon gesprochen, das mein linker Motor wesentlich besser ist.
Was ich aber nicht feststellen konnte, ist deine Vermutung, das der Asuro dann komplett seine Positionen verliert. Wahrscheinlich liegt es hier aber am großen Verhältnis zwischen der gut geregelten Strecke und dem ersten Stück Weg, an dem der Asuro noch schwingt.
Ich hatte noch vergessen anzugeben, wie ich auf die Zahlen für die Wegliste (in test.c) gekommen bin.
Ich habe (mal wieder) ein EXCEL-Blättchen gemacht und dort ein bisschen die Geometrie von dieser 2-rädrigen Art der Fortbewegung hinterlegt.
Mittlerweile gibt es in der Zelle [P4] einen sehr wichtigen Prozentwert, der angibt wie viele der Farbwechsel auf der Dekoderscheibe tatsächlich vom Asuro registriert werden. Ich komme mit den dann berechneten Tick-Werten am besten an das gewünschte Ergebnis, wenn ich nur 96% der eigendlich zu erwartenden Tick's in den Berechnungen berücksichtige.
Meine Vermutung ist, dass trotz konstantem, nächtlichem Licht über dem Küchentisch, die leider immer noch festen Schwellwerte zur Hell-/Dunkelübergangsbestimmung die Ursache sind.
Jetzt also auch noch das EXCEL als Tick-(Trick- und Track)-Berechner.
Nochmals vielen Dank für das große Lob. Bekommt mir sehr gut. :-)
Ist ja lustig, dass der ASURO trotz des Einschwingvorgangs seine Richung beibeihaelt.
Woher kommen eigentlich die leicht verdelten Kreise? Ist es moeglich, dass der Stift ein wenig in seiner Halterung wackelt ? O:)
Bei einem der Versuche habe ich einen 1.5mm Kupferdraht genommen und damit eine Halterung zurecht gebogen. Wenn man den Draht an den Enden abisoliert, kann man ihn in die Loecher der Batteriehalterung einhaengen:
https://www.roboternetz.de/phpBB2/ze...ht=servo+asuro
Das Servo braucht man natuerlich nicht unbedingt.
Dass die Encoderscheiben immer ungenaue Werte liefern, ist irgendwie seltsam. Vielleicht liegt es ja gar nicht unbedingt am Stoerlicht, sondern aus irgendwelchen Gruenden koennte der AD-Wandler ja auch ab und zu mal einen elektrischen Stoerpeak abkriegen.
Oder es ist ein Konflikt im Timing des Programms. Ich verwende AVR-Studio und mir ist aufgefallen, dass die 72kHz Interruptroutine relativ viel Rechenkapazitaet des Atmega auffrisst. Vielleicht koennte es ja bisweilen auch einen Konflikt mit der AD-Wandlung geben.
Deine Routinen scheinen sehr genau zu funktionieren. Da waere es doch lustig, mal etwas komplizierteres als ein Nikolaushaus zu malen. Oder wie waers, das Nikolaushaus einfach 4x in die 4 unterschielichen Himmelsrichtungen zu zeichnen. Sieht bestimmt auch gut aus.
Gruss,
stochri
Also ich habe mal irgendwo gelesen, dass einer um die Photdioden und die Scheibe irgendwie ein Gehäuse gebastelt hat (siehe Bild) und dann diese Probleme weg waren... Also liegt es wohl mit ziemlicher Sicherheit am Störlicht...Zitat:
Zitat von stochri
Hallo Nabla,
es ist richtig, dass starkes Stoerlicht ( z.B. Sonneneinstrahlung ) zur Fehlfunktion der Odometrie fuehren kann. Und es ist auch richtig, dass eine Abschirmung dieses Stoerlicht unterdrueckt.
Es ist allerdings keineswegs gesagt, dass es nicht noch andere Stoerquellen gibt. Und wenn man keine so hochpraezise Odometriefunktion wie fuer das Zeichnen des Nikolaushauses braucht, fallen statistisch wenige Ausreisser gar nicht auf. Ich vermute, dass dies beim DosenASURO der Fall ist.
Wenn man allerdings genauere Untersuchungen anstellt, wie Sternthaler in diesem Thread hier, dann fallen 4 Prozent Abweichung sehr wohl auf. Und dann stellt sich die Frage: woher kommen diese Ausreisser ?
Gruss,
stochri
Hallo zusammen,
Ne, die Halterung ist zwar nicht so stark wie deine Servo-Version, das liegt mal wieder an meinen schrottigen Motoren. P.S. Der Servo ist super stark! Alle Achtung!Zitat:
Zitat von stochri
Ich habe mal versucht den entstandenen 'Bogen' durch einen Film darzustellen. Da es leider nur ein paar Zeichnungen sind, hier noch eine Erklärung dazu:
Mein linker Motor ist einfach wesentlich besser. Jedesmal wenn der Asuro neu anfahren muss, bewegt sich fast immer der Linke zuerst. Irgendwann, kommt dann der Regler in's Spiel und reduziert die linke bzw. erhöht die rechte Motorleistung. Geregelt wird über die Abweichung der zu fahrenden Tik's gegenüber den tatsächlich gezählten Tik's.
Damit sind wir bei der Frage, warum das Zählen nicht so einfach ist. (siehe nächsten Eintrag, da ich nicht weiss wie man Bilder mitten in den Text setzen kann.)
Ok, ich habe euch verschwiegen, dass ich die schon lange habe. So richtig zufrieden bin ich nicht mit meiner Lösung, da ihr auf den Bildern gut sehen könnt mit welchem Spiel das Zahnrad mit der Dekoderscheibe hin und her wackeln kann. Im Moment seht ihr auf den Bildern nicht was ich dagegen getan habe, da die Lösung nicht besonders stabil ist. Ich habe meistens eine Unterlegscheibe mit Uhu an der Achse angeklebt um die Dekoderzahnradwichtigscheibe möglichst spielfrei zu haben. Da kann ich nabla nur Recht geben: Bei spielfreier Abdeckung ist das Tik-Zählen tatsächlich recht gut.Zitat:
Zitat von nabla
Ich bin der Meinung, dass Tik's durch wechselndes Umgebungslicht UND durch ein 'FLATTERN' der Dekoderscheibe verloren gehen. Das 'Flattern' ist mechanisch (Uhu hilft eine Zeit lang), aber das Umgebungslicht ist nur sehr schwer zu fassen. Ich habe da schon einige Versuche angestellt dies durch eine Messung ohne LED-Beleuchtung 'wegzurechnen'. Laut Schaltplan ist es eigendlich nicht möglich eine 'Dunkelmessung' zu machen. Es geht aber tatsächlich doch. Im Interrupt zum ADC ist die Messung auch schon vorhanden. Bis jetzt habe ich aber noch keine schnelle, kleine Berechnung hinbekommen so dass der Schwellwert zum Tik-Zählen beeinflusst werden kann. (Bei Bedarf kann ich endlose EXCEL-Daten für unterschiedliches Umgebungslicht posten)
Weiss nicht, wenn man mal 2 Extremfälle durchgeht: (in beiden Fällen sollen beide Räder 80 Tik's fahren. Eine Radumdrehung)Zitat:
Zitat von stochri
1:
- Links fährt 80; Rechts fährt 0
- Links fährt 0; Rechts fährt 80
---> gibt einen rechts- / links-Schlenker, aber der Asuro steht wieder in gleicher Richtung wie beim Start. Allerdings ist er mehr oder weniger diagonal nach rechts gefahren.
2:
- Links fährt 1; Rechts fährt 0
- Regler stopt Links; Vollgas Rechts
- Links fährt 0; Rechts fährt 1
- Regler ist zufrieden, da Zählergleichstand, aber rechter Motor 'brummt'
- Links fährt 0; Rechts fährt 2
- Regler sieht nun zu, dass Links wieder Speed aufnimmt.
- ...
---> Die Linie sieht gerade aus und niemandem fällt auf, dass der Asuro eigendlich wackelt.
Ich glaube, dass die von mir ermittelten Regler-PARAMETER nicht besonders optimal sind (siehe das Pendeln aus dem Ausschnitt), aber dass trotzdem die Abweichungen in Summe so klein bleiben, dass der Asuro eben nicht wie in Fall 1: geschildert "diagonal nach rechts" fährt. Aber wer weiss das schon ;-)
Genau, aber nicht in 4 verschiedene Richtungen, sondern immer wieder von der gleichen Stelle aus. Leider ergeben sich dann immer noch Abweichungen von einer zur nächsten Fahrt. (Ich bin sicher, du hast auf deinem geposteten Bild in den oberen Bildteilen solche Wiederholungen?)Zitat:
Zitat von stochri
Hallo Sternthaler,
poste doch einfach mal 4 uebereinandergezeichnete Haueser, mich wuerde mal interessieren, wie sie aufeinander zu liegen kommen.
Beste Gruesse,
stochri
Hallo stochri,
ich habe hier ein bisschen gemogelt und den Asuro nach jeder Fahrt wieder genau nach oben ausgerichtet. Ausserdem den Stift wieder etwas nach unten gedrückt (hab ja leider keinen Servo, heul, schnief), dadurch sieht man unten rechts die 'fetten' Startpositionen. Die erste Fahrt ging an der rechten Linie los.
Ich habe mal überlegt, ob man den Asuro nicht in einen 'Lernmodus' bringen kann. Die Idee, ist folgende:Zitat:
Zitat von stochri
- Taster 'Lernmodus' drücken
- Loop
- Asuro möglichst gerade SCHIEBEN (Asuro zählt die Tik's)
- Taster 'Speichern' drücken
- LoopENDE wenn Taster 'Ende' gedrückt wurde
- Taster 'Los gehts' drücken (Reproduktionen nummerieren und verkaufen?)
Frohes Bildermalen (lassen)
Einen sehr schoen kleinen Servo gaebe es im Modellbaugeschaeft fuer ca. 15 Euro. Oder ein klein wenig groesser beim Conrad fuer 5 Euro. Den Stifthalter kann man aber auch sehr shoen ohne Servo benutzen, den Draht kann man im Baumarkt kaufen. Der Stift muss lose in der Drahtspule haengen, dann drueckt er von selber mit der richtigen Kraft nach unten.Zitat:
hab ja leider keinen Servo, heul, schnief
Sehr interessante Idee. Eigentlich lassen sich die Motoren ja relativ schwer drehen, aber vielleicht koennte man sie schon mit eine wenig Strom beaufschlagen, sodass sie sich fast von selbst drehen. Man muss dann aber auf das Haftreibungsmoment aufpassen, sonst laeuft der ASURO weiter, wenn man ihn mal angeschoben hat.Zitat:
Ich habe mal überlegt, ob man den Asuro nicht in einen 'Lernmodus' bringen kann.
Gruss,
stochri
Irgendwie erinnert mich Dein Spruch an das hier:Zitat:
Schöne Grüße von Sternthaler
---
Lieber Asuro programieren als arbeiten gehen.
http://www.jrobot.net/Projects/AVRcam.html
Hallo stochri,
das mit einem Servo für meinen Asuro meine ich aktuell nicht ernst. Trotzdem danke für die Infos zu Bezugsquellen.
Deine Stifthalterung aber werde ich mal übernehmen, da der Aufwand ja auch für andere 'Zeichenkünstler' so gering ist, dass man das jedem Asuro-Besitzer zutrauen kann. Sonst habe ich im Moment keinesfalls vor irgendeine Änderung an der Hardware zu machen.
Zum Lernmodus:
Keine schlechte Idee von dir die Motoren schon mal 'vorzuspannen'.
Zu meiner Idee ist mir allerdings noch ein entscheidender Fehler aufgefallen: Wenn der Asuro GESCHOBEN wird, bekommt er ja nix davon mit, ob ich vorwärts oder rückwärts schiebe. Somit muss die von mir angesprochenen LOOP noch ein wenig überdacht werden.
Evl. hilft folgendes:
Lernmodus einschalten
LOOP
. Taste drücken
. WENN Taste = vorwärts, dann Richtung merken und Motoren 'leicht' vorwärts
. WENN Taste = rückwärts, dann Richtung merken und Motoren 'leicht' rückwärts
. WENN Taste = fertig, dann letzten Tic-Counter speichern;Loop abbrechen
. Asuro schieben, Tic's werden gezählt und gespeichert
ENDE LOOP
Taste WIEDERHOLE
Ist ja nicht schlecht der Spruch auf jrobot.net
"Building robots instead of sleeping..." Da kann ich mich auf alle Fälle wiederfinden. Mit der Arbeit ist das so eine Sache: schlafen nicht erwünscht, Asuro programieren leider auch nicht. Thead-Beiträge schreiben hoffentlich nicht entdeckt (so wie dieser)
P.S.: Schreibt man programieren eigendlich mit 2 'm'?
hmm schön schön :) (sehr aktuell)
den 1. code habe ich verstanden, der 2. über forderte mich ein wenig, doch wenn ich meinen asuro habe, versuch ichs auch mal
na wer weiss, vielleicht kann ichs noch toppen :)
Hallo dinoAG,Zitat:
Zitat von dinoAG
muss hier nicht aktuell sein, da der Wettbewerb zuende ist. ;-)
Wenn du zu zum 2.ten Fragen hast, helfe ich da sehr gerne weiter. Ich hatte gehofft durch die großzügig eingestreuten Kommentare im Code genuegend Infos zu geben.
Ich hoffe, dass du toppen kannst. Denn dann hast du das Problem mit den Raddekoder-Sensoren auf alle Fälle gelösst. Dieses Problem haben hier mehrere, und sind an einer funktionierenden Lösung bestimmt hochgradig interressiert. Ich jedenfalls suche/überlege/messe/programmiere da immer noch.
Mein nächster Versuch geht zu einem kleinen Umbau des Sensors. (Weiss aber noch nicht wann, da ich ja jetzt erst mal von der Arbeit nach Hause gehen muss.) Ich möcht die Empfindlichkeit RUNTER-schrauben, da die Probleme immer nur bei zu starkem Umgebungslicht auftreten. Ist allerdings nicht meine favorierte Lösung, da dies einen Umbau am ASURO bedeuten würde, den ich eigendlich vermeiden will, damit nicht alle anderen ASURO-Besitzer auch zum Lötkolben greifen müssen um meinen Programmcode laufen lassen zu können.
P.S.: Schön, dass sich hier nochmal einer meldet.
Hallo Zusammen,
ist ja witzig, dass das Thema nach so langer Zeit wieder aufgewärmt wird. Aber jetzt, so um die Weihnachtszeit ist "das Haus vom Nikolaus" ja durchaus ein passendes Thema.
Aber Vorsicht ! Das Ganze mag sich zwar einfach anhören, ist aber ganz schön schwierig, wenn man es wirklich gut lösen will.
Also viel Glück bei euere Weihnachtferien/ Urlaubs- Programmier-Roboter-Mal-Aktion.
Viele Grüße,
stochri
Guten Abend,
kann mir jemand sagen, was dieser Befehl in Storchi Source macht?
z.B.
#define links45 { turn(180); Msleep(500);turn(135);Msleep(500);}
Vielen Dank schonmal..
das bedeutet, dass überall im quelltext wo "links45" steht,
turn(180); Msleep(500);turn(135);Msleep(500);
ausgeführt wird.
der befehl define sagt aus das das erste wort nach define (turn45) vor dem kompilieren dur das ersetzt wird, as dahinter steht (alles zwischen den {}).
das ist gut, wenn man nur ein paar befehle hat, für die es sich nicht lohnt, eine ganze funktion zu schreiben.
wird diese befehlsfolge allerdings öfter benutzt, sollte man eine funktion schreiben, um speicher zu sparen.
Hätte ich nicht besser erklären können.
Kleine Fehlerteufel-Anmerkung noch zu den { } Klammern. Auch die werden zum Glück beim kompilieren mitgenommen und übersetzt.
Warum zum Glück?
Tipp: #define Name { IMMER mit Klammern schreiben. }Code:if (x == y)
links45;
else
was_anderes;
würde sonst folgenden Code ergeben:
if (x == y)
turn(180);
Msleep(500);
turn(135);
msleep(500);
else
was_anderes;
Jetzt wäre nur noch das 'turn(180)' hinter dem if x==y gültig und wir würden wegen des noch folgenden 'else' einen Compiler-FEHLER bekommen. Im schlimmsten Fall würde der logische Ablauf in unserem Programm falsch sein wenn wir z.B. nur folgendes programmieren:
if (x == y)
links45;
mache_hier_weiter;
Jetzt bekommen wir KEINEN Fehler, aber hinter dem if ist wiederum nur das turn(180) und der Rest vom define (Msleep(500); turn(135); Msleep(500);) wird IMMER ausgeführt.
Edit: 18.12.2006 Sternthaler. Wenn ich schon pingelich bin, dann gehören natürlich auch Klammern zum if.
Hallo,
brauch nochmal Hilfe.
Also das sind 2 Schleifen, soweit ist mir klar, aber was macht sie ganz genau in Storchi programm?
Verzögerung in zehntel sekunden ausrechnen?
Code://delay in 1/10 sec
void wait(int zehntel)
{
int i,temp2;
for(i=0;i<zehntel;i++)
for(temp2=0;temp2<100;temp2++) Sleep(72);
}
Nein, du gibts einfach die Zeit die du warten möchtest in Zehntel Sekunden ein und dann macht der Asuro so lange gar ncihts.
Andun
Nachdem ich das jetzt schon eine Weile beobachte, muss ich jetzt doch mal antworten:
#define links45 { turn(180); Msleep(500);turn(135);Msleep(500);}
Eine Rechtsdrehung um 180°+135° = 315° ist wie eine Linksdrehung um 45° ( 360°-45° = 315° ).
Mein ASURO hat die Eigenschaft, dass er je nach Richtung unterschiedlich weit dreht. Die Kallibrierroutine ist aber nur für die Rechtsdrehung ( glaub ich mich zu erinnern ). Deshalb habe ich die Linksdrehung über eine Rechtsdrehung realisiert.
Ein weiteres Problem der Turn ( und Go ) Routine ist, dass man die Bewegungen eigentlich mit einer programmgesteuerten Bremsphase versehen müsste. Schaltet man die Motoren schnell ab, bewegt sich der Roboter noch ein Stückchen weiter, was zu einem Fehler in der Sollposition führt.
Das ist eine Unsauberkeit der Routinen, die man irgendwan mal beheben könnte. Damals im Wettberwerb ging es aber darum, möglichst schnell das Ziel zu erreichen, deshalb sind solche Feinheiten unter den Tisch gefallen.
Gruss,
sto - chri
Hier mal ein kleines Video meines Asuros: http://www.zippyvideos.com/5870203996486466/video3/
Die main-Funktion ist nicht besonders interessant, da nur eine Aneinanderreihung von Go und Turn...
Und hier poste ich mal die modifizierten Go und Turn Funktionen der asuro.c. Im Großen und Ganzen entsprechen diese den originalen aus der erweiterten Asuro-Lib auf Sourceforge. Aber vor allem bei der Turn habe ich einiges an den Parametern geändert (mit Abbremsfunktion). Ansonsten habe ich meist noch die Variablentypen und die Reihenfolge angepasst.
Ist zwar noch immer nicht ganz 100%, aber das liegt wohl an der Ungenauigkeit der Odometrie. Ich werde versuchen es noch etwas zu verbessern; mal schauen, was ich noch erreichen kann.Code:void Go(int distance, unsigned char speed)
{
unsigned int enc_count = abs(distance);
unsigned int tot_count = 0;
signed char diff = 0;
unsigned char l_speed = speed, r_speed = speed;
// mm -> ticks
enc_count /= 2; // only for 12 fields gearwheel
// set direction
if(distance < 0) MotorDir(RWD,RWD);
else MotorDir(FWD,FWD);
// reset encoder
Encoder_Set(0,0);
// set speed
MotorSpeed(l_speed,r_speed);
// do until destination reached
while(tot_count < enc_count)
{
tot_count += encoder[LEFT];
// calculate speed difference
diff = encoder[LEFT] - encoder[RIGHT];
// reset encoder
Encoder_Set(0,0);
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;
}
// set new speeds
MotorSpeed(l_speed,r_speed);
Sleep(36);
}
// Stop
MotorSpeed(0,0);
MotorDir(BREAK,BREAK);
Msleep(200);
}
void Turn(int degree, unsigned char speed)
{
unsigned int enc_count;
unsigned int tot_count = 0;
int diff = 0;
unsigned char l_speed = speed, r_speed = speed;
// degree -> tick
enc_count = (unsigned int) (((long)abs(degree) * (long)4080) / (long)10000);
// set direction
if(degree < 0) MotorDir(RWD,FWD);
else MotorDir(FWD,RWD);
// reset encoder
Encoder_Set(0,0);
// set speed
MotorSpeed(l_speed,r_speed);
// do until angel reached
while(tot_count < enc_count)
{
tot_count += encoder[LEFT];
// calculate speed difference
diff = encoder[LEFT] - encoder[RIGHT];
// reset encoder
Encoder_Set(0,0);
// calculate new speed
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;
}
// set new speed, with slow down
MotorSpeed(l_speed - (unsigned char) ((unsigned int)(l_speed) / enc_count),r_speed - (unsigned char) ((unsigned int)(r_speed) / enc_count));
Sleep(36);
}
// stop
MotorSpeed(0,0);
MotorDir(BREAK,BREAK);
Msleep(200);
}
Klasse. Ich hoffe, mein 1. Versuch wird auch bald hier zu sehen sein.
Hallo Stallion,
Glückwunsch zum Nikolaushaus. :Weihnacht
Der ASURO fährt ganz gut in dem Video. Interresanterweise fährt er rückwärts.
Im Video kann man die Striche nicht so gut erkennen, vielleicht kannst Du so ein Bild mit mehreren hintereinandergezeichneten ASUROs wie Sternthaler posten, dann kann man erkennen, wie gut der ASURO seine Position hält.
Wenn's gut funktioniert, wären ja vielleicht sogar kompliziertere Gemälde denkbar. O:)
Gruss,
stochri
Ja, ist dieser Bug, den alle neueren Asuros haben. Und ich war bisher zu faul die Kabel der Motoren umzulöten, damit er in die richtige Richtung fährt. Sollte aber eigentlich keinen großen Unterschied machen.Zitat:
Zitat von stochri
naja... einen unterschied machts. wenn du fremde hex-files flasht, dann macht dein asuro nicht was er soll. und andere können mit deinen hexfiles nicht viel anfangen...
aber ansonsten ist es nicht so schlimm.
so nun hab ich mich auch am Haus probiert.
dabei musste ich folgendes beachten:
mein asuro macht sehr ungenaue Turn und ich habe nur die 8er scheiben drauf
--> ich habe eine MyTurn geschrieben die alle winkel in 60grad häppchen zerlegt
-->in Stallions Turn habe ich enc_count um 2/3 redziert
mein kleiner macht nun die kurven ganz gut bis auf....Code://falls 8er Scheibe
enc_count =(unsigned int) ((((long)abs(degree) * (long)4080) / (long)10000) * (long)2 / (long)3);
.. er rechnet müll.
ich gebe die Seite (iSeite) und den Dachwinkel (iWinkel_Dach1) vor und berechen nun die Diagonale und die Dachseiten.
für iSeite = 100 geht das auch super idiagonale = 141 :)Code:int iDiagonale= sqrt(2*iSeite*iSeite);
int iDach=(iSeite/2)/cos(iWinkel_Dach1/180*3.1415926535);
für iSeite = 150 ist iDiagonale 28672 --<<<<<<<WARUM?
für iSeite = 200 ist iDiagonale 120 --<<<<<<<<WARUM?
pythagoras 150*150+150*150 = 2* 150*150 daraus die Wurzel->212
und bei iSeite 200 wäre 282 das richtige
gruß
downad
Dann rechnen wir mal:Zitat:
Zitat von Downad
für 100:
sqrt(2*100*100) = sqrt(20000) = 141
für 150:
sqrt(2*150*150) = sqrt(45000)
signed int geht aber nur bis +32767 -> overflow -> sqrt(-20535)...
Also kannst eigentlich froh sein, dass dir der Prozessor überhaupt etwas ausspuckt. Also sollte man in dem Fall (long) verwenden um sinnvolle Ergebnisse zu bekommen.
Zweitens kann man die Formel vereinfachen in iSeite*sqrt(2) = iSeite*1,414... (float verwenden nicht vergessen!)
Und drittens hab ich es vorher ausgerechnet und direkt in Programm geschrieben, damit sich der Asuro die Arbeit sparen kann.
Hallo Stallion,Zitat:
Zitat von Stallion
gratuliere, das ist ja wirklich auch eine sehr schöne Nikolaus-Fahrt.
Ich habe mal gezählt, wie häufig du bei deinem Nikolaus mal nach rechts bzw. nach links drehst. Du drehst 6 mal links und nur ein mal rechts. (oder anders rum)
Bei meinem Asuro hatte ich festgestellt, dass sich die Fahrfehler beim Drehen am besten aufheben, wenn man möglichst gleich viele Drehungen in beide Richtungen macht. Bei dir sieht aber das Ergebniss trotzdem recht gut aus.
Deshalb fände ich es auch gut, so wie stochri vorgeschlagen hat, die Fahrt mal öfters hintereinander zu zeigen um zu sehen wie die Wiederholgenauigkeit ist.
Weiter so.
Hallo Zusammen,
gerade eben habe ich im Netz einen Zeichenroboter gefunden:
http://www.hobbyrobotik.de/Kritzler.htm
Er unterscheidet sich in der Größenordnung nicht so sehr vom ASURO. Die Bilder sind allerdings doch um einiges komplexer. Das gibt mir doch etwas Hoffnung, dass bei Verbesserung der Odometrie aus dem ASURO doch noch etwas mehr herauszuholen ist.
Gruss,
stochri
schrittmotoren sind natürlich eine feine sache für sowas... leider hat der asuro sowas nicht. da müsste man dann irgendwie die odometrie sehr exakt ansprechen.
Es bleibt nicht aus, dass man immer mal wieder hier vorbei kommt.
Der Grund meines Besuchs hier ist der Code von Stallion, da ich mich erinnert habe, dass er eine Abbremsfunktion in Turn() eingebaut hatte.
Mein Problem: Ich verstehe nicht wie das gehen soll.
Ich habe mal (hoffentlich korrekt) den gekürzten code von Stallion nochmal wiedergegeben und meine Frage da reingeschrieben:
War es so gewollt, und ich habe falsch verstanden, das am Ende der Fahrstrecke abgebremst werden sollte? Oder habe ich den Code nicht verstanden?Code:---> enc_count wird einmal berechnet.
---> Bei degree = 90 wird enc_count also 36,72 (36 oder 37 ist aber egal)
enc_count = (unsigned int) (((long)abs(degree) * (long)4080) / (long)10000);
// set direction
// reset encoder
// set speed
// do until angel reached
while(tot_count < enc_count)
{
tot_count += encoder[LEFT];
// calculate speed difference
// reset encoder
// calculate new speed
if (diff > 0) //Left faster than right
{
}
if (diff < 0) //Right faster than left
{
}
// set new speed, with slow down
---> Hier den nur einmal berechneten Wert von enc_count eingesetzt, ergibt fuer
---> mich keinen Sinn, da doch dann eigendlich nur [l|r]_speed durch diese
---> 'Konstante' geteilt und abgezogen wird.
---> Wenn Speed als so um 200 (plus/minus "calculate new speed") ist, und dann durch
---> 36 oder 37 geteilt wird, kommt da bei mir ein Wert um 200/36 = 5 raus.
---> Diese 5 werden nun aber einfach nur von den 200 abgezogen und wir fahren doch
---> 'nur' die gesamte Strecke etwas langsamer.
MotorSpeed (l_speed - (unsigned char) ((unsigned int)(l_speed) / enc_count),
r_speed - (unsigned char) ((unsigned int)(r_speed) / enc_count));
Sleep(36);
}
Mag hier noch einer Antworten?
hat das evtl den zweck dass die ganze kurve in der mitt etwas langsamer gefahren wird? quasi schnell rein in die kurve, auf der ideallinie lang, etwas bremsen, und dann mit gas wieder raus? =)
Hallo Sternthaler,
Bei menen Experimenten hat sich gezeigt, dass die Motordrehzahl relativ unabhängig vom Untergrund ist. Ich hatte den Eindruck, dass der Schlupf auch nicht so stark Untergrund abhängig ist.
Allerdings treten in den Phasen der Geschwindikeitsänderung die größten Kräfte auf und deshalb ist in den Brems- und Beschleunigungsphasen der Schlupf auch am größten. Treten diese Phasen gehäuft auf, wird der Odometriefehler größter ( kann man einfach testen: eine Wegstrecke in kleinen Stücken und in einem großen Stück auf verschiedenen Untergründen fahren ).
Es ist also von sehr großem Vorteil für eine genaue Odometrie, sanft zu beschleunigen und zu bremsen ( besonders wenn man ein Nikolaushaus zeichnen will ).
Bei meinen Versuchen mit der Bluetoothübertragung konnte ich einen Fehler feststellen: Manchmal haben die Encoder ohne Bewegung hochgezählt. Da müsste also ein Fehler in den Odometrie-Interruptroutinen sein ( Das könnte man auch mit der Funktion PrintInt und der IR-Schnittstelle nachprüfen: einfach den Encoderwert zyklich auf der IR ausgeben und schauen, ob es eine Radstellung gibt, bei der die Encoder hochlaufen.
Gruss,
robo
Der Verdacht wurde schon mehrfach geäußert, aber bisher noch nicht bewiesen. Ich hatte auch schon solche Effekte bemerkt obwohl ich eine ältere Version der Libary verwende. Möglicherweise ist das eine "Altlast" die immer wieder in die neuen Releases mitkopiert wird.Zitat:
Da müsste also ein Fehler in den Odometrie-Interruptroutinen sein