PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Rechenkette? / Winkelberechnung mit Cosinus?



Bammel
07.05.2009, 16:29
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]

vohopri
07.05.2009, 16:52
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, 17:04
grundsätzlich geht das so in allen höheren Programmiersprachen
in Bascom leider aber nicht!

vohopri
07.05.2009, 17:11
in Bascom leider aber nicht!


Danke, Bascom scheint ja ein eigenartiges Ding zusein.

grüsse,
Hannes

Klingon77
07.05.2009, 17: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

Bammel
07.05.2009, 17:51
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

Vitis
08.05.2009, 13:40
oder halt auch temporäre variablen also
local in subroutinen / funktionen ... hält den code übersichtlich

Bammel
08.05.2009, 16:02
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?

vohopri
08.05.2009, 16:06
Du kannst ja im Eröffnungspost die Überschrift editieren. Dann wird das neue Thema auch hier gefunden.

Thomas$
08.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
mfg thomas

sechsrad
09.05.2009, 15: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

Thomas$
09.05.2009, 15:19
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.

Bammel
09.05.2009, 15:42
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!!!

Bammel
09.05.2009, 16:01
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, 16: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...

Bammel
09.05.2009, 16:25
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?

vohopri
09.05.2009, 16:28
@ 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

Thomas$
09.05.2009, 16:28
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

vohopri
09.05.2009, 16:49
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

Bammel
09.05.2009, 17:02
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

vohopri
09.05.2009, 17:08
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

Bammel
09.05.2009, 17:11
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!

Thomas$
09.05.2009, 17:29
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

vohopri
09.05.2009, 17:34
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

Bammel
09.05.2009, 17:55
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, 20: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.

vohopri
10.05.2009, 00:37
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, 09: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, 12:22
@Vohopri:
Natürlich hast Du recht, was hab ich bloß für einen Unsinn geschrieben.
Ich war echt mies drauf gestern -.-

Richard
10.05.2009, 12:41
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

vohopri
10.05.2009, 15:32
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, 17:18
Es ist eben äußerst reizend, einen Weg ohne Sinus zu finden. Den Fehler hab ich auch gemacht.

vohopri
10.05.2009, 17:43
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

Bammel
11.05.2009, 17:08
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

vohopri
11.05.2009, 17:27
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

Bammel
11.05.2009, 17:30
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

vohopri
11.05.2009, 17:32
Schau dir mein letztes Posting an: ich habe nocht die Erklärung rein editiert, gerade bevor du gefragt hast. Das hat sich dann überschnitten.

Bammel
11.05.2009, 17:35
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?

vohopri
11.05.2009, 17:40
Jap, treffend formuliert.

grüsse,
Hannes

Bammel
11.05.2009, 18:43
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?

vohopri
11.05.2009, 19:22
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

Bammel
11.05.2009, 20:51
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

vohopri
12.05.2009, 08:01
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

Bammel
12.05.2009, 15:26
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

vohopri
12.05.2009, 16:45
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

Bammel
12.05.2009, 16:58
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°

vohopri
12.05.2009, 17:12
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

Bammel
12.05.2009, 17:17
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.

vohopri
12.05.2009, 17:30
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

Bammel
12.05.2009, 18:02
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

Bammel
13.05.2009, 20:29
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