PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Gyros aus Wii MP real winkel ?



Thalhammer
02.10.2011, 16:42
Hallo,
ich hab nach längerer zeit mal wieder zeit gehabt um ein wenig mit meinem Atmega8 zu basteln als ich gelesen hab das die Wii extensions per I2C ausgelesen werden.
Das hab ich dann auch gleich gemacht und war überrascht welche daten ich bekam.
Und zwar ist das Problem, das ich vorher noch nie erfahrung mit gyros hatte und dachte immer die würden eine spannung relativ zur !!absoluten!! position im raum zurück geben.
Heute hab ich festgestellt, das der wert vom Wii motion plus bei einer drehung nach links rechts oder sonst wo hin nur solange verändert wird wie die bewegung anhält.
hört man auf es zu bewegen so normalisiert sich der wert immer auf den gleichen wert, völlig egal in welcher lage.

Nun meine frage:
wie kann ich aus der änderung den absoluten winkel berechen ?

MFG Thalhammer

Che Guevara
02.10.2011, 16:55
Hallo,

ja, Gyros geben nur die WinkelGESCHWINDIGKEIT aus. Um von dieser auf die absolute Winkelposition zu kommen musst du integrieren, sprich du addierst die einzelnen Werte immer auf. Somit erhältst du mehr oder weniger genau die Winkelposition. Allerdings musst du den Sensor oft auslesen, damit dir keine Werte verloren gehen! Da aber ein Gyro prinzipbedingt einen Drift aufweist, solltest du, falls es so genau gewünscht wird, noch einen acc auslesen und dann die Werte von ACC und Gyro kombinieren, entweder über einen Komplementärfilter oder einen Kalmanfilter. Am besten, du liest dich mal in die Thematik ein, es gibt sehr viel im Netz ;)

Gruß
Chris

Thalhammer
02.10.2011, 17:17
nun ja so wie ich bisher gelesen hab sind die Wii gyros relativ drift frei.
Wie sähe den das in Bascom aus ?
Nunja ein ACC währe ja kein problem, der ist ja im nunjuck drin.
So genau muss es ja nicht sein, +- 5° währen verkraftbar.
Das ganze soll später eine steuerung für einen modell flieger werden.
Heist wenn sich eine ungenauigkeit nur über längere Zeit entwickelt ist das kein problem, da spätestens nach 20 minuten der akku leer ist.
Ich poste mal den Code den ich bisher habe.
Dieser Code liest alle 25ms die werte aus und schickt sie an den PC.

MFG Thalhammer

Che Guevara
02.10.2011, 18:55
Hm, ich habe selbst eine WMP auf meinem Quadrocopter und habe anfangs auch ein paar Tests gemacht und dabei hat sich herausgestellt, dass die untersten 7 (bin mir nicht mehr ganz sicher) Bit rauschen sind. Aber durch shiften bekommst du das Rauschen weg, allerdings hast du dann aber auch eine geringere Auflösung. Der Drift hält sich in Grenzen, er sollte kein Problem darstellen ;)
Das Ganze in Bascom auszulesen, ist kein Problem. Hier im Forum gibts genug Codes (auch von mir), sieh sie dir doch mal an :) WMP und Nunchuk sollen ja grundsätzlich miteinander funktionieren (im Passthrough Mode), in C wurde es auch schon geschafft! Ich selbst hätte es mal in Bascom probiert, bin allerdings gescheitert. Habe damals den C Code 1:1 nach Bascom übersetzt und hatte auch die gleiche Belegung, aber nach ein paar Abfragen (noch während der Initialisierung) bekam ich einen Error.... Kannst ja mal hier im Forum suchen, ich hatte es gepostet.
Also auf meinem Quadrocopter kann ich keinen Drift beobachten, mein Akku hält ca. 17mins. Alle 25ms ist imho zu langsam, du wirst nicht alle Drehungen korrekt und ferlustfrei aufzeichnen können. Bei mir wird das WMP ca. alle 2ms ausgelesen, das reicht und sollte für dich auch kein Problem darstellen ;) Je schneller / öfter, desto besser und genauer.

Gruß
Chris

Thalhammer
02.10.2011, 23:18
ne die 25ms sind ja nur für die Tests am PC, in der endanwendung ist das natürlich nicht geeignet.
Ich muss also quasi nur hergehen und einen Wert der festgelegt ist zu nehmen und bei jedem abfragen den wert den der abgefragte wert von der ruheposition abweicht zum vorherigen wert zu addieren ?

Könnt ich da mal ein beispiel haben ?
Tut mir leid, wenn ich so blöd frage aber ich hab grade keinen Plan wie das gehen soll.

MFG Thalhammer

Che Guevara
03.10.2011, 00:04
Hier mal ein Beispiel (ungetestet), wie du den Sensor auslesen kannst. Der Offset wird hier auch gleich abgezogen:


$regfile = "m328pdef.dat"
$crystal = 16000000
$framesize = 250
$hwstack = 250
$swstack = 250
$baud = 19200


Declare Sub Filter_gyro_data()
Declare Sub Wmp_init()
Declare Sub Send_zero()
Declare Sub Read_wmp_data()
Declare Sub Set_wmp_offset()




$lib "I2C_TWI.LBX"
Config Scl = Portc.5
Config Sda = Portc.4
Config Twi = 100000
I2cinit



Dim I As Byte


'###################################
'###########I2C-Inputs##############
'###################################
Dim Wmplus_buffer(6) As Byte
'###################################
'###################################
'###################################


'###################################
'#########GYRO######################
'###################################
Dim Yaw As Word
Dim Yaw0 As Byte At Yaw + 1 Overlay
Dim Yaw1 As Byte At Yaw Overlay

Dim Roll As Word
Dim Roll0 As Byte At Roll + 1 Overlay
Dim Roll1 As Byte At Roll Overlay

Dim Pitch As Word
Dim Pitch0 As Byte At Pitch + 1 Overlay
Dim Pitch1 As Byte At Pitch Overlay

Dim _yawoffset As Long
Dim _rolloffset As Long
Dim _pitchoffset As Long

Dim _yawoffset_int As Integer
Dim _rolloffset_int As Integer
Dim _pitchoffset_int As Integer

Dim _yawnow As Integer
Dim _rollnow As Integer
Dim _pitchnow As Integer
'###################################
'###################################
'###################################


Call Wmp_init()
Waitms 100
Call Set_wmp_offset() 'nicht bewegen!!!
Waitms 100



Do


Call Filter_gyro_data()
Print "YAW: " ; _yawnow ; " ROLL: " ; _rollnow ; " PITCH: " ; _pitchnow


Loop


Sub Filter_gyro_data()
Call Read_wmp_data()

_yawnow = Yaw - _yawoffset_int
_rollnow = Roll - _rolloffset_int
_pitchnow = Pitch - _pitchoffset_int
End Sub


Sub Wmp_init()
I2cstart
I2cwbyte &HA6
I2cwbyte &HFE
I2cwbyte &H04
I2cstop
End Sub


Sub Send_zero()
I2cstart
I2cwbyte &HA4
I2cwbyte &H00
I2cstop
End Sub


Sub Read_wmp_data()
Gosub Send_zero
I2creceive &HA4 , Wmplus_buffer(1) , 0 , 6
Yaw1 = Wmplus_buffer(1)
Roll1 = Wmplus_buffer(2)
Pitch1 = Wmplus_buffer(3)
Shift Wmplus_buffer(4) , Right , 2 : Yaw0 = Wmplus_buffer(4)
Shift Wmplus_buffer(5) , Right , 2 : Roll0 = Wmplus_buffer(5)
Shift Wmplus_buffer(6) , Right , 2 : Pitch0 = Wmplus_buffer(6)
Shift Yaw , Right , 4
Shift Roll , Right , 4
Shift Pitch , Right , 4
End Sub


Sub Set_wmp_offset()
_yawoffset = 0
_rolloffset = 0
_pitchoffset = 0
For I = 1 To 100
Call Read_wmp_data()
_yawoffset = _yawoffset + Yaw
_rolloffset = _rolloffset + Roll
_pitchoffset = _pitchoffset + Pitch
Next I
_yawoffset = _yawoffset / 100
_rolloffset = _rolloffset / 100
_pitchoffset = _pitchoffset / 100
_yawoffset_int = _yawoffset
_rolloffset_int = _rolloffset
_pitchoffset_int = _pitchoffset
End Sub


End

Jetzt musst du zum integrieren nur noch drei Variablen definieren, zb.


Dim Yaw_integral As Integer
Dim Roll_integral As Integer
Dim Pitch_integeral As Integer
...
Yaw_integral = Yaw_integral + _yawnow
....

Falls du noch Fragen hast, stell sie einfach :D

Gruß
Chris

Thalhammer
03.10.2011, 09:14
Hallo,
leider kann ich es momentan nicht testen, den das Wii motion plus, das ich vorher hatte darf aus bestimmten gründen nicht kaputt werden.
Daher muss ich erstmal bis morgen warten und mir ein anderes und eine 3.3V versorgung/Pegelwandler zulegen.
Aber sobald ich deinen code gestestet habe melde ich mich.

Du hast im Code kommentierd das das Wii MP während der offset erkennung nicht bewegt werden darf, was auch logisch ist.
Aber die NULL Position der ° berechnung ist immer die die das Wii motion plus zum zeitpunkt der offset erkennung hatte oder ?

MFG Thalhammer

Che Guevara
03.10.2011, 09:37
Also als Versorgung könntest du entweder zwei Dioden in Reihe nehmen und das dann an 5V anschließen oder mittels einem LM317. Pegelwandler brauchst du eigentlich nicht, es reichen Pullups (4,7k) nach 3V3.
Ja, die Offsetausrichtung entspricht dann der Nullposition. Du könntest ja z.b. auf Knopfdruck die Offset-Funktion erneut aufrufen, somit kannst du jederzeit die Nulllage verändern ;)

Gruß
Chris