Archiv verlassen und diese Seite im Standarddesign anzeigen : Rechenkette? / Winkelberechnung mit Cosinus?
Hallo,
ich schreibe mir gerade eine rechnung und die sieht grade so aus:
Hoehe_q = Hoehe * Hoehe
Abstand_q = Abstand * Abstand
Dis_q = Hoehe_q + Abstand_q
Dis = Sqr(dis_q)
Ist der Satz des Pytagoras.
nun würde ich das gerner vereinfachen!
in etwa so:
Dis_q = Hoehe * Hoehe + Abstand * Abstand
Dis = Sqr(dis_q)
oder sogar so:
Dis = Sqr(Hoehe * Hoehe + Abstand * Abstand)
dieses funktioniert so aber leider nicht! nur meine ganz oben gepostete version läuft. dort sind mir aber zu viele variabeln drinne die ich garnicht bräuchte.
also wäre das ganze möglich? wenn ja wie?
mfg Bammel[/code]
Hallo Bammel,
grundsätzlich geht das so in allen höheren Programmiersprachen, die ich kenne. Ohne jetzt deinen Compiler zu kennen, würd ich zunaächst prüfen ob Hoehe und Abstand Integer sind, Sqr abar einen real typ braucht, und ob deine Programmiersprache es erfordert, dass du die Typumwandlung explizit machst.
grüsse,
Hannes
ikarus_177
07.05.2009, 18:04
grundsätzlich geht das so in allen höheren Programmiersprachen
in Bascom leider aber nicht!
in Bascom leider aber nicht!
Danke, Bascom scheint ja ein eigenartiges Ding zusein.
grüsse,
Hannes
Klingon77
07.05.2009, 18:28
hi,
habe ich auch schon versucht und bin darüber gestolpert.
Ist wohl so; muß man hinnehmen.
Du könntest zu Programmbeginn ein paar Variablen definieren welche Du immer für Zwischenergebnisse verwendest.
Die kann man dann ja mehrfach verwenden.
z.B:
DIM ER01 as XXX
DIM ER02 as XXX
usw.
in die Kopfzeile des entsprechenden Berechnungs-Unterprogramm vermerkst Du dann wofür die einzelnen Variablen in der Berechnung stehen.
Dann bleibt es auch halbwegs übersichtlich.
liebe Grüße,
Klingon77
Hallo,
danke für die antworten.
ja klingon, genauso mache ich das auch. aber gerade das wollte ich ja eigentlich umgehen. gerade wegen der übersicht. aber was solls. funktionieren tut es
schönen dank,
Bammel
oder halt auch temporäre variablen also
local in subroutinen / funktionen ... hält den code übersichtlich
aha das ist interesant... programmier noch net so lange in bascom. wobei qbasic hatte ich mal gelernt und eine andere sprache die dem sehr ähnlich war konnte ich auch recht gut.
aber die temp. variabeln muss ich mir mal anschauen!
im moment habe ich nen anderes problem.
ich will nen winkel in einem dreieck berechnen. ich habe alle seitenlängen! und ich hbae ausgerechnet bzw. über internet-tools das der winkel 92° sein müsste nur errechnet der µC mir immer 99°
soll ich meinen code hier mal posten? oder lieber nen neuen thread?
Du kannst ja im Eröffnungspost die Überschrift editieren. Dann wird das neue Thema auch hier gefunden.
ein rechner kan nur einwas machen z.B. 2+1=3 um 2+1+2= 5 zurechnen muss man 2+1= 3 3+2= 5 ansonsten kann er das nicht um 2+1+2=5 in einem schritt zu machen rechnet der Rechner erst 2+1= 3 3+2= 5 das problem ist bascom kann das nicht da muss der programierer das machen vieleicht wird das mal irgendwann in bascom geändert bascom ist zwar basic aber trotzdem relativ low lewel
im einfachten falle nennst du ne varible tmp die immer als zwischen ergebniss gut ist
mfg thomas
sechsrad
09.05.2009, 16:11
ein rechner kan nur einwas machen z.B. 2+1=3 um 2+1+2= 5 zurechnen muss man 2+1= 3 3+2= 5 ansonsten kann er das nicht um 2+1+2=5 in einem schritt zu machen rechnet der Rechner erst 2+1= 3 3+2= 5 das problem ist bascom kann das nicht da muss der programierer das machen vieleicht wird das mal irgendwann in bascom geändert bascom ist zwar basic aber trotzdem relativ low lewel
im einfachten falle nennst du ne varible tmp die immer als zwischen ergebniss gut ist
Sag mal ist das Pisadeutsch oder bis du noch am lernen als Ausländer.
mfg
ich komme aus deutschland und ich hoffd du hast das "oder bis du noch am lernen als Ausländer. " nicht rassistisch gemeint ich bin bloß kein sprachlich begabter mensch und werde es nie sein soll ich es noch mal ander formulieren und kanst du es auch so verstehen. was ich auch gern weg lass sind kommas bzw algemin satzzeichen.
also ich habs verstanden auch wenn ich es zweimal lesen musste. aber kenne das problem! schriftlich habe ihc auhc oft probleme was zu erklären.. ich amche lieber dabei skizzen oder zeige was.
und solche aussagen wie von sechrad find ich echt unverschämt!!!
So sry für doppelpost aber ich wollte nicht beides in einem packen!
Erstmal hab ich nen bild angehangen das ihr euch erstmal ein eindruck machen könnt was ich genau will.
So der code sieht so aus:
Declare Sub Berechnung
Dim Hoehe As Byte
Dim Abstand As Byte
Dim Hoehe_q As Word
Dim Abstand_q As Word
Dim Dis_q As Word
Dim Dis As Byte
Dim Knie_wi As Byte
Dim Kniea As Word
Dim Knieb As Word
Dim Knie_zw_a As Word
Dim Knie_zw_b As Word
Dim Knie_zw_c As Word
Dim Knie_zw_d As Integer
Dim Knie_zw_e As Single
Dim Knie_zw_wi As Single
Const Oberschenkel = 67
Const Unterschenkel = 87
Const Oberschenkel_q = 4489
Const Unterschenkel_q = 7569
Hoehe = 50
Abstand = 100
...
Sub Berechnung
If Hoehe > 110 Then Hoehe = 110
If Abstand < 37 Then Abstand = 37
Hoehe_q = Hoehe * Hoehe
Abstand_q = Abstand * Abstand
Dis_q = Hoehe_q + Abstand_q
Dis = Sqr(dis_q)
'-------------- Knie ----------------------
Knie_zw_a = Dis_q - Unterschenkel_q
Knie_zw_b = Knie_zw_a - Oberschenkel_q
Knie_zw_c = Unterschenkel * Oberschenkel
Knie_zw_d = -2 * Knie_zw_c
Knie_zw_e = Knie_zw_b / Knie_zw_d
Knie_zw_wi = Cos(knie_zw_e)
Knie_wi = Knie_zw_wi * 100
If Knie_wi < 45 Then Knie_wi = 45
If Knie_wi > 180 Then Knie_wi = 180
Kniea = 6400 / 180
Knieb = Kniea * Knie_wi
Servo(2) = 63200 - Knieb
Hab den code ein wenig verkürzt hoffe das okay so!?
formel hab ich diese verwendet: gamma = cos((c² - a² - b²) / (-2 * a * b))
a ist Unterschenkel
b ist Oberschenkel
c ist Dis
(siehe auch angehängte zeichnung)
danke schonmal fürs anschauen!
MfG Bammel
stefan_Z
09.05.2009, 17:11
Temporäre Variablen gehen ja nur in Funktionen und Subs. Der Sprung dahin dauert aber glaube ich recht "lange" - wenn der AVR diese Rechnung sehr oft ausführen muss, bremst es das Programm dann schon sehr.
Die Einschränkung auf eine Operation pro Zeile nervt im Vergleich zu C schon, man darf hoffen, dass es mit der neuen Version von Bascom besser wird...
ok. aber mein problem jezze ist das der µC "falsch" rechnet!
normalerweis muss der winkel 92° betragen der µC errechnet aber 99°
da war nun meine frage die ich weiter oben gestellt hatte warum? was amch ich falsch?
@ sechsrad:
Sag mal ist das Pisadeutsch oder bis du noch am lernen als Ausländer.
Für einen Sprachkritiker schreibst du aber ein erbärmliches Deutsch.
@ Bammel:
Nur zur Bestätigung: 92° und ~112mm sind einmal richtig, bei den hier stehendenn Angaben. Ich habs im CAD durchgezeichnet. Als müssen wir uns das verborgene Treiben des mc näher ansehen.
Hannes
Was ist wenn höhe was anderes ist bleibt der winkel da auch 99 ?
Edit: kanst du bitte den code ausführ bar machen das ich ihn in bascom mit der simulation überprüfen kann das ich nach fehlernsuchen kann
Hallo nochmal,
gamma = cos((c² - a² - b²) / (-2 * a * b))
Das hast du anscheinend im Code auch so umgesetzt (hab noch nicht näher rein geschaut), aber es ist falsch.
Muss heissen: gamma = arccos((c² - a² - b²) / (-2 * a * b))
- weil du ja vom Cosinuswert auf den Winkel zurückrechnest.
hoffe, das bringt dich weiter,
und grüsse,
Hannes
hallo,
in bascom heist der befehl dan einfach acos(var)
aber das führt zum selben ergebnis!
$regfile = "m8def.dat"
$crystal = 3686400
$baud = 19200
$framesize = 64
$swstack = 64
$hwstack = 64
Config Timer1 = Timer , Prescale = 1 'timer für servos
Enable Timer1
Timer1 = 56320
Config Portc = Output
Portc.0 = 0 'hier hängt servo1
Portc.1 = 0 'hier hängt servo2
Portc.2 = 0 'hier hängt servo3
Portc.3 = 0 'hier hängt servo4
On Timer1 Servoirq 'servo
Enable Interrupts
Declare Sub Berechnung
Dim Kanal As Byte
Dim Servo(4) As Word 'links: 63200, mitte 60000, rechts 56800
Dim Hoehe As Byte
Dim Abstand As Byte
Dim Hoehe_q As Word
Dim Abstand_q As Word
Dim Dis_q As Word
Dim Dis As Byte
Dim Knie_wi As Byte
Dim Kniea As Word
Dim Knieb As Word
Dim Knie_zw_a As Word
Dim Knie_zw_b As Word
Dim Knie_zw_c As Word
Dim Knie_zw_d As Integer
Dim Knie_zw_e As Single
Dim Knie_zw_wi As Single
Dim Huft_wi As Byte
Dim Hufta As Word
Dim Huftb As Word
Const Oberschenkel = 67
Const Unterschenkel = 87
Const Oberschenkel_q = 4489
Const Unterschenkel_q = 7569
Hoehe = 50
Abstand = 100
Call Berechnung
Servo(3) = 60000
Servo(4) = 60000
Wait 3
Do
Hoehe = 50
Abstand = 100
Call Berechnung
Wait 2
Loop
Servoirq:
If Kanal = 0 Then
If Portc.0 = 0 Then 'wenn port low
Timer1 = Servo(1) 'dann timer auf entsprechende verzögerung
Portc.0 = 1 'und port anschalten
Else 'das hier passiert erst bei dem darauf folgenden interrupt
Portc.0 = 0 'dann port wieder ausschalten
Incr Kanal 'und den nächsten kanal bearbeiten
End If
End If
If Kanal = 1 Then
If Portc.1 = 0 Then
Timer1 = Servo(2)
Portc.1 = 1
Else
Portc.1 = 0
Incr Kanal
End If
End If
If Kanal = 2 Then
If Portc.2 = 0 Then
Timer1 = Servo(3)
Portc.2 = 1
Else
Portc.2 = 0
Incr Kanal
End If
End If
If Kanal = 3 Then
If Portc.3 = 0 Then
Timer1 = Servo(4)
Portc.3 = 1
Else
Portc.3 = 0
Incr Kanal
End If
End If
If Kanal = 4 Then
Timer1 = 21300 '54016 eine pause von ca. 12ms bis zum nächsten interrupt. Bei guten Servos oder Brushlessreglern kann man hier bis auf 65530 gehen ==> ansteuerfrequenz von ~ 200Hz
Kanal = 0
End If
Return
'------------------------------------------
Sub Berechnung
If Hoehe > 110 Then Hoehe = 110
If Abstand < 37 Then Abstand = 37
Hoehe_q = Hoehe * Hoehe
Abstand_q = Abstand * Abstand
Dis_q = Hoehe_q + Abstand_q
Dis = Sqr(dis_q)
'-------------- Knie ----------------------
Knie_zw_a = Dis_q - Unterschenkel_q
Knie_zw_b = Knie_zw_a - Oberschenkel_q
Knie_zw_c = Unterschenkel * Oberschenkel
Knie_zw_d = -2 * Knie_zw_c
Knie_zw_e = Knie_zw_b / Knie_zw_d
Knie_zw_wi = Cos(knie_zw_e)
Knie_wi = Knie_zw_wi * 100
If Knie_wi < 45 Then Knie_wi = 45
If Knie_wi > 180 Then Knie_wi = 180
Kniea = 6400 / 180
Knieb = Kniea * Knie_wi
Servo(2) = 63200 - Knieb
'-------------- Hüfte ---------------------
If Huft_wi < 55 Then Huft_wi = 55
If Huft_wi > 180 Then Huft_wi = 180
Hufta = 6400 / 180
Huftb = Hufta * Huft_wi
Servo(1) = 56800 + Huftb
Print "----------------------------------"
Print
Print "Knie_zw_a " ; Knie_zw_a
Print "Knie_zw_b " ; Knie_zw_b
Print
Print "Knie_zw_c " ; Knie_zw_c
Print "Knie_zw_d " ; Knie_zw_d
Print
Print "Knie_zw_e " ; Knie_zw_e
Print "Knie_zw_wi " ; Knie_zw_wi
Print
Print "Knie_wi " ; Knie_wi
Print
End Sub
End
das ist der vollständige code!
wenn nohc verbessungsvorschläge da sind imemr her damit. fange erst an mit der programmierung. vorherige projekte waren kleiner. nen glcd mit touchscreen angesteuert. und kleinere sensoren ausgewertet.
dies ist bislang mein erstes richtiges projekt.
den mein traum ist es iwann mal ein hexabot zu bauen ;-D ich weis das wollen viele aber iwann wil ich das verwirklichen und da mich die IK sehr interessiert und reizt wollt ihc mal erste versuche machen.
vohopri weis was ich meine. den er/du machst es ja auch so. viele kleinere projekt die zum schluss zusammengesetzt werden ;-) (dein auton. fahrzeug fand bzw. find ich genial)
mfg bammel
Hallo,
das glaub ich gerne, dass das acos(..) heisst, in deinem Code steht aber cos(...). acos und cos ergeben mit Sicherheit nicht das Selbe.
Acos ergibt den Winkel in rad, und die müssen mit / pi und * 180 in Grad umgewandelt werden, ich seh da nur * 100.
Hannes
das werde ich mal eben testen!
das war mir net bekannt!
das * 100 kommt daher das der wert aus cos(var) bzw acos(var) 0,99... ergab
edit:
boar danke!!!! jezze gehts endlich!!! hab schon 2 abende dran gehangen :D
woher hast du die infos genommen? hatte schon etliche versuche bei google unternommen gehabt!
wenn du in vb dir die hilfe anguckst stehen solche sachen drin. da hab ich viel gelernt ansonsten kann es sein das vohopri die infos vileicht auch noch von wikipädia hat da steht zu dem thema auch viel
Hallo Bammel, Ha, das freut mich.
Woher die Info? Naja ich ich hab in den letzten Jahre sehr viel solche Trigonometrieaufgaben programmiert, vor allem für CAD Systeme. Wiki ist da eine recht ergiebiege Quelle, wenn man mal was neues braucht. Ich mach das in anderen Programmiersprachen, aber mit google hab ich mich dann schnell versichert, dass das in Bascom gleich funktioniert.
Aber glaub mir, ich bin auch an manchen Programmzeilen mehrere Abende gesessen.
http://www.google.at/images?q=tbn:1rxd7eiY_NOeGM::i272.photobucket.com/albums/jj183/singaporepersonaltrainer/beer-smiley.gifhttp://www.google.at/images?q=tbn:1rxd7eiY_NOeGM::i272.photobucket.com/albums/jj183/singaporepersonaltrainer/beer-smiley.gif
grüsse und wünsche schönes Wochenende,
Hannes
jup, danke nochmal. nun hänger ihc schonwieder an nem anderem problem. aber denke da hab ich einfach nen kleinen denkfehler! auhc weider winkelberechnung aber jetzt hab ich ja die richtige formel ;)
schönes wochenende wünsche ich
thewulf00
09.05.2009, 21:57
Nochwas:
Wenn Du alle Seiten des Dreiecks gegeben hast, brauchst Du keine Cosinus/Sinusfunktion zu verwenden.
Edit: Was für ein Schwachsinn, natürlich brauchst Du sie. Entschuldigt diesen Thread.
Hallo Wulf,
U/A = 180°/a
U - Dreiecksumfang
A - Seite A
a - Winkel Alpha
Das ist nicht richtig. Zeichene dir Dreiecke auf, wo Alpha 90° beträgt und sieh nach, ob a gleich dem halben Umfang ist: Du wirst sehen, dass das fast nie der Fall ist.
vohopri
ikarus_177
10.05.2009, 10:02
Hi Bammel,
du musst nicht unbedingt die rad "umständlich" mit 180/pi multiplizieren, um aufs Gradmaß zu kommen. Bascom bietet da auch eine eigene Funktion an, nennt sich "Rad2deg()".
Viele Grüße
thewulf00
10.05.2009, 13:22
@Vohopri:
Natürlich hast Du recht, was hab ich bloß für einen Unsinn geschrieben.
Ich war echt mies drauf gestern -.-
das werde ich mal eben testen!
das war mir net bekannt!
das * 100 kommt daher das der wert aus cos(var) bzw acos(var) 0,99... ergab
edit:
boar danke!!!! jezze gehts endlich!!! hab schon 2 abende dran gehangen :D
woher hast du die infos genommen? hatte schon etliche versuche bei google unternommen gehabt!
Moin moin Bammel.
Ich habe auch lange gesucht, schau mal diese Site an.....
http://www.mathe-online.at/mathint/wfun/i.html#bogenmass
Gruß Richard
a²+b²+c² 180°
-------- = ---- usw.
a² α
Und das ist immer noch billiger zu berechnen als die Winkelfunktionen.
Hallo Rolf,
was hilft der günstige Preis der Rechnung, wenn sie falsch ist? Ist auch kein Schwachsinn, aber eine ungeprüft geäusserte Vermutung, die der näheren Überprüfung nicht standhält.
Ein Gegenbeispiel reicht bekanntlich zum Widerlegen:
Dreieck mit Winkeln 30,120,30°, Winkelsumme 180.
Seiten: 1,sqrt(3),1
Quadrierte Seiten: 1,3,1 Quadratsumme 5.
30° ist 1/6 von 180°
1 ist 1/5 von 5
Es verhält sich der Winkel zur Winkelsumme also NICHT so wie die quadrierte Seite zur Quadratsumme.
grüsse,
Hannes
thewulf00
10.05.2009, 18:18
Es ist eben äußerst reizend, einen Weg ohne Sinus zu finden. Den Fehler hab ich auch gemacht.
Ja leider hat man da im allgemeinen Dreieck keine Chance auf eine Lösung ohne Winkelfunktion. Nur im rechtwinkeligen bleibt es einem manchmal erspart.
Hannes
Hallo,
ich hab schonwieder ein problem! man, dabei bin ich eigentlich recht gut in mathe.
ertsmal danke an ikarus, rad2deg() funzt bestens.
also ich habs nochmal im angehangen bild dargestellt suche diese beiden winkel um den servos dort auchnoch stellen zu können. aber iwie funktioniert das nicht. habs mit dem selben verfahren versucht wie den obersten winkel. nur halt die dementsprechende formal genommen. aber da hab ihc jeweils 180° bekommen dies kann ja nicht sein. dann dachte ich okay versuchst es mal von vorne formeln gelöscht und nochmal hab dann aber ist mir eingefallen da ich ja im grünen dreieck nen rechten winkel hab kann ich ja den einfachen kosinus verwenden.
cos(beta) = a / c
da bekomme ich aber 51° dachte okay ist ja richtig. aber nein! das ist ja das falsche dreieck?! zufall???
code sieht so aus:
Dim Hufta_zw_a As Single
Dim Hufta_zw_b As Single
Dim Hufta_wi As Byte
...
Hufta_zw_a = Hoehe / Dis
Hufta_zw_b = Cos(hufta_zw_a)
Hufta_wi = Rad2deg(hufta_zw_b)
mfg bammel
Hallo Bammel,
du hast im Programm wieder cos statt acos geschrieben.
acos(50/112)=63.49° Das ist OK
cos(50/112)=57.29° Das ist ein Unsinn, der nur zufällig richtig aussieht und für böse Überraschungen sorgen würde.
EDIT:
Vielleicht noch zur Erklärung:
cos(beta) = a / c
die cos Funktion auf die andere Seite ergibt
beta=acos(a /c)
grüsse,
Hannes
aber in der formel von wikipedia steht doch iemmr cos...!? das check ich nicht. leider bin ich auch schon zu lange raus aus den schulischen winkelberechnen. da konnte ich das wie eine eins.
edit: danke das funktioniert. nun nur mal schauen ob ich den anderen hinbekomme. sonst melde ich mich wieder :D
Schau dir mein letztes Posting an: ich habe nocht die Erklärung rein editiert, gerade bevor du gefragt hast. Das hat sich dann überschnitten.
ahhhhh... jetzt hab ich das endlich geschnallt! cos kann man nur verwenden wenn man den winkel hat. und mit acos "erstellt" man quasie den winkel. richtig?
Jap, treffend formuliert.
grüsse,
Hannes
jaaaa.. nun funzt es endlich!
ein problem hab ich dennoch :(
wenn ich werte nehme wie z.b.
hoehe = 30
abstand = 110
dann ist der obere winkel imemr größer als 180° ich hab es eh auf 180° begrenzt, damit mir die servos nicht an den endanschlag fahren.
also anstatt das die fussspitze 30mm tiefer als der körper ist und 110mm ragt die fussspitze diagona nach rechts oben!
weis da jemand rat?
Hallo Bammel,
1. freut mich und ich werd dann noch ein Bier auf das Wohl deines Roboters trinken.
2. versteh ich nicht, könntest du das vielleich aufmalen?
grüsse,
Hannes
bild...
könnte mir nur vorstellen das das ganze mit den katheten und hyputinosen zusammen hängt das sich das vllt verschiebt.
was ich nochmal testen wollte ein poti zum einstellen der abstände einzubinden. so kann ich sehen wann sich welcher winkel wie verhält.
edit: hab mal ein poti eingebaut. um den abstand verändern zu können und dann live zu beobachten was passiert. für die höhe soll auchnoch eins eingebaut werden. aber das kommt morgen. erstmal ist es schon sehr geil zu sehen das die idee hinter dem ganzen so funktioniert wie ich es mir erhofft habe.
zu dem problem: erste erkenntnis: bei einer höhe von 50 geht der knie-winkel nie kleiner als 90°. kann es daran liegen das dann die seitenbezeichnungen nicht mehr passen. den c ist ja immer die hypotinuse und die ist ja iemmr die längste seite im dreieck. oder irre ich mich? wenn das so ist wie kann ich das umsetzten das es mir keine probleme bereitet? erste idee von mir wäre ne abfrage zu machen wenn der winkel kleiner als 90° ist, die größenverhältnisse zu tauschen und neu zu berechnen so das es wieder hinkommt.
gute nacht
Ah,
das ist kein Problem, das macht der Hund vom Nachbarn auch immer. Das ist ein natürliches Bedürfnis.
Nein im Ernst: Dis wird dann 114 und der Kniewinkel 95°.
Welcher Code produziert denn diesen Fehler. Ich will nicht im alten Code von früher herumsuchen, du hast den ja inzwischen geändert.
Die veränderte Höhe ändert nichts daran, dass DIS die Hypothenuse im blauen Dreieck ist , und dass das Beindreieck ein allgemeines Dreieck ist. Es brauchen keine Bezeichnungen verändert werden.
grüsse,
Hannes
habs nochmal genau durchgeschaut bei folgenden daten geht das bein hoch:
Hoehe = 50
Abstand = 97
bei abstand = 98 bleibt es noch unten und verhält sich so wie es soll
code ist folgender:
$regfile = "m8def.dat"
$crystal = 3686400
$baud = 19200
$framesize = 64
$swstack = 64
$hwstack = 64
Config Timer1 = Timer , Prescale = 1 'timer für servos
Enable Timer1
Timer1 = 56320
Config Portc = Output
Portc.2 = 0 'hier hängt servo1
Portc.3 = 0 'hier hängt servo2
Portc.4 = 0 'hier hängt servo3
Portc.5 = 0 'hier hängt servo4
Config Pinc.0 = Input ' Port C.0 Ausgang
Config Pinc.1 = Input
On Timer1 Servoirq 'servo
Config Adc = Single , Prescaler = 64 , Reference = Avcc
Start Adc
Enable Interrupts
Declare Sub Berechnung
Dim Kanal As Byte
Dim Servo(4) As Word 'links: 63200, mitte 60000, rechts 56800
Dim Hoehe As Byte
Dim Abstand As Byte
Dim Wert1_a As Single
Dim Wert1_b As Word
Dim Hoehe_q As Word
Dim Abstand_q As Word
Dim Dis_q As Word
Dim Dis As Byte
Dim Knie_wi As Byte
Dim Kniea As Word
Dim Knieb As Word
Dim Knie_zw_a As Word
Dim Knie_zw_b As Word
Dim Knie_zw_c As Word
Dim Knie_zw_d As Integer
Dim Knie_zw_e As Single
Dim Knie_zw_wi As Single
Dim Hufta_zw_a As Single
Dim Hufta_zw_b As Single
Dim Hufta_wi As Byte
Dim Huftb_zw_a As Word
Dim Huftb_zw_b As Word
Dim Huftb_zw_c As Word
Dim Huftb_zw_d As Integer
Dim Huftb_zw_e As Single
Dim Huftb_zw_wi As Single
Dim Huftb_wi As Byte
Dim Huft_wi As Byte
Dim Hufta As Word
Dim Huftb As Word
Const Oberschenkel = 67
Const Unterschenkel = 87
Const Oberschenkel_q = 4489
Const Unterschenkel_q = 7569
Hoehe = 50
Abstand = 100
Call Berechnung
Servo(3) = 60000
Servo(4) = 60000
Wait 3
Do
Wert1_b = Getadc(0)
Waitus 50
Wert1_a = 150 / 1024
Abstand = Wert1_a * Wert1_b
Call Berechnung
Loop
Servoirq:
If Kanal = 0 Then
If Portc.2 = 0 Then 'wenn port low
Timer1 = Servo(1) 'dann timer auf entsprechende verzögerung
Portc.2 = 1 'und port anschalten
Else 'das hier passiert erst bei dem darauf folgenden interrupt
Portc.2 = 0 'dann port wieder ausschalten
Incr Kanal 'und den nächsten kanal bearbeiten
End If
End If
If Kanal = 1 Then
If Portc.3 = 0 Then
Timer1 = Servo(2)
Portc.3 = 1
Else
Portc.3 = 0
Incr Kanal
End If
End If
If Kanal = 2 Then
If Portc.4 = 0 Then
Timer1 = Servo(3)
Portc.4 = 1
Else
Portc.4 = 0
Incr Kanal
End If
End If
If Kanal = 3 Then
If Portc.5 = 0 Then
Timer1 = Servo(4)
Portc.5 = 1
Else
Portc.5 = 0
Incr Kanal
End If
End If
If Kanal = 4 Then
Timer1 = 21300 '54016 eine pause von ca. 12ms bis zum nächsten interrupt. Bei guten Servos oder Brushlessreglern kann man hier bis auf 65530 gehen ==> ansteuerfrequenz von ~ 200Hz
Kanal = 0
End If
Return
'------------------------------------------
Sub Berechnung
If Hoehe > 110 Then Hoehe = 110
If Abstand < 37 Then Abstand = 37
Hoehe_q = Hoehe * Hoehe
Abstand_q = Abstand * Abstand
Dis_q = Hoehe_q + Abstand_q
Dis = Sqr(dis_q)
'-------------- Knie ----------------------
Knie_zw_a = Dis_q - Unterschenkel_q
Knie_zw_b = Knie_zw_a - Oberschenkel_q
Knie_zw_c = Unterschenkel * Oberschenkel
Knie_zw_d = -2 * Knie_zw_c
Knie_zw_e = Knie_zw_b / Knie_zw_d
Knie_zw_wi = Acos(knie_zw_e)
Knie_wi = Rad2deg(knie_zw_wi)
If Knie_wi < 45 Then Knie_wi = 45
If Knie_wi > 180 Then Knie_wi = 180
Kniea = 6400 / 180
Knieb = Kniea * Knie_wi
Servo(2) = 63200 - Knieb
'-------------- Hüfte a ---------------------
Hufta_zw_a = Hoehe / Dis
Hufta_zw_b = Acos(hufta_zw_a)
Hufta_wi = Rad2deg(hufta_zw_b)
'-------------- Hüfte b --------------------- alpha = acos((ober² + dis² - unter²)/(2·ober·dis))
'alpha = acos((ober² - unter² - dis²) / (-2 * ober * dis))
Huftb_zw_a = Oberschenkel_q + Dis_q
Huftb_zw_b = Huftb_zw_a - Unterschenkel_q
Huftb_zw_c = Oberschenkel * Dis
Huftb_zw_d = 2 * Huftb_zw_c
Huftb_zw_e = Huftb_zw_b / Huftb_zw_d
Huftb_zw_wi = Acos(huftb_zw_e)
Huftb_wi = Rad2deg(huftb_zw_wi)
Huft_wi = Hufta_wi + Huftb_wi
If Huft_wi < 55 Then Huft_wi = 55
If Huft_wi > 180 Then Huft_wi = 180
Hufta = 6400 / 180
Huftb = Hufta * Huft_wi
Servo(1) = 56800 + Huftb
Print "----------------------------------"
Print
Print "Knie_wi " ; Knie_wi
Print
Print "Abstand " ; Abstand
Print "adc " ; Wert1_b
Print "huft_wi " ; Huft_wi
Print
End Sub
End
EDIT: hab gerade noch ein poti für die höhe eingebaut. und ich muss feststellen sobald der kniewinkel kleiner als 90° werden würde geht das bein in fehlstellung. aber ich glauber nur der unterschenkel. dieser stellt sich dann immer in den 180° winkel
mfg bammel
Hallo,
der Code, den du gepostet hast, hat der den Fehler produziert? Da ist ja hoehe 50, Abstand 100. Wenn das nicht exakt der Code ist, der den Fehler produziert hat, dann tu ich mit kein Kreuzkompilieren an.
Aber andere Frage: Was ist denn der Argumentbereich und der Wertebereich der Ergebnisse von Bascom acos?
Wenn ich mit hoehe 80 Abstand 97 rechne, dann ist das Ergebnis acos(+.015) = 89°. Teste doch in Bascom acos(+.015), ob das dort auch so ist.
grüsse,
Hannes
ja der code ist der!!! ja die hoehe und abstand sind erstaml an anfang gegeben dann wird nurnoch der abstand durch das poti (AD-Wandler) verändert!
EDIT:
änderunegn in der knieberechnung:
'-------------- Knie ----------------------
Knie_zw_e = 0.015
Knie_zw_wi = Acos(knie_zw_e)
Knie_wi = Rad2deg(knie_zw_wi)
If Knie_wi < 45 Then Knie_wi = 45
If Knie_wi > 180 Then Knie_wi = 180
Kniea = 6400 / 180
Knieb = Kniea * Knie_wi
Servo(2) = 63200 - Knieb
das ergebnis ist dann wie es sein sollte 89°
OK, das kann ich ohne Hardware nicht nachvollziehen. Macht nix.
Was ergibt in Bascom acos(+.015) ? Und was ergibt die Umrechnung genau davon in Grad?
Hannes
siehe edit im vorherigen post ;)
edit: was mir grade einfällt gibt es nicht ein programm (simulation??) in der ich das ganze auch virtuel machen könnte um es mal bildlich zu haben. sowas könnte ich mir dann leichter vorstellen. udn evtl so auch schneller fehler finden.
Aha,
da steht ja inzwischen was: und es liegt also nicht am Bascom.
Inzwischen hab ich deinen Code durchgesehen, und ich finde keinen Fehler. Da kann ich nur empfehlen, nach jeder Zeile einen Test - Print befehl zu schreiben, und mit dem Taschenrechner mitrechnen, bis es abweicht. Wahrscheinlich steht irgendwo etwas anderes als beabsichtigt und beim Lesen sehen wir immer das was beabsichtigt war.
wünsche viel Erfolg und
grüsse,
Hannes
okay werde also alles aml gründlich durchforsten.. nun geh ich aber erstmal ins kino. star trek schaun ;)
werde mich dann morgen mal dran machen.
mfg Bammel
WOOHOO!!! *runde bier ausgeb*
habs gefunden.. eigentlich recht simpel! die variable knie_zw_b war als word declariert. diese ging aber in den negativen bereich also schnell zum integer gemach und vola... funktioniert!
und ich muss mir ne lizens für bascom holen... bin ghrade an den 4kb angekommen
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.