- LiFePO4 Speicher Test         
Ergebnis 1 bis 10 von 14

Thema: Gyro-Signal (und RC-Empfänger) filtern

Baum-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    32
    Beiträge
    1.578

    Gyro-Signal (und RC-Empfänger) filtern

    Hallo,

    nachdem ich nun erfolgreich meinen PID-Regler implementiert habe, möchte ich nun die Gyro-Signale meiner WM+ filtern, um etwas bessere Werte zu erhalten. Aber ich weiß leider nicht so genau, wie ich die Signale filtern soll?!
    1. Mit einem Komplementärfilter (also Hochpass und Tiefpassfilter, oder?!)
    2. Mit einem Kalmanfilter (ist mir ehrlich gesagt zu kompliziert)
    3. Nur mit einem Hochpass bzw. nur mit einem Tiefpassfilter

    Was wäre eurer Meinung nach am besten geeignet? Der Tricopter soll jetzt nicht da minutelang in der Luft schweben, aber momentan ist es leider so, dass die Motoren vereinzelt schon im Stand anfangen, sich zu drehen, wegen dem Drift...
    Außerdem möchte ich noch einen Filter für den RC-Empfänger implementieren, da diese Werte auch geringfügig schwanken. Welchen Filter sollte ich den hier verwenden?
    Hier noch der jetztige Code:
    Code:
    $regfile = "m8def.dat"
    $crystal = 16000000
    $framesize = 140
    $hwstack = 120
    $swstack = 120
    $baud = 38400
    
    
    Declare Sub Wmp_init()
    Declare Sub Send_zero()
    Declare Sub Read_data()
    Declare Sub Set_offset()
    
    Declare Sub Filter_gyro_data()
    Declare Sub Pid_regulator()
    Declare Sub Filter_rx_data()
    Declare Sub Mixer()
    Declare Sub Send_data()
    
    
    
    $lib "I2C_TWI.LBX"                                          'Hardware I2C
    Config Scl = Portc.5                                        'Ports for I2C-Bus
    Config Sda = Portc.4
    Config Twi = 100000                                         '400000
    I2cinit
    
    
    Config Timer1 = Timer , Prescale = 1
    On Timer1 Pausedetect
    Enable Timer1
    
    Config Int1 = Falling
    On Int1 Measure
    Enable Int1
    
    
    Config Pind.3 = Input
    Portd.3 = 0
    
    
    Const Start_byte = 127
    Const _maxchannel = 4
    
    Const _bl1offset = 0
    Const _bl2offset = 0
    Const _bl3offset = 0
    Const _bl4offset = -600
    
    Const _yaw_kp = 4
    Const _roll_kp = 4
    Const _pitch_kp = 4
    
    Const _yaw_ki = 2
    Const _roll_ki = 2
    Const _pitch_ki = 2
    
    Const _yaw_kd = 5
    Const _roll_kd = 5
    Const _pitch_kd = 5
    
    
    
    Dim _yaw_kp_err As Integer
    Dim _roll_kp_err As Integer
    Dim _pitch_kp_err As Integer
    
    Dim _yaw_ki_err As Integer
    Dim _roll_ki_err As Integer
    Dim _pitch_ki_err As Integer
    
    Dim _yaw_ki_sum As Integer
    Dim _roll_ki_sum As Integer
    Dim _pitch_ki_sum As Integer
    
    Dim _yaw_kd_err As Integer
    Dim _roll_kd_err As Integer
    Dim _pitch_kd_err As Integer
    
    Dim _yaw_kd_old As Integer
    Dim _roll_kd_old As Integer
    Dim _pitch_kd_old As Integer
    
    Dim _yaw_pid As Integer
    Dim _roll_pid As Integer
    Dim _pitch_pid As Integer
    
    Dim _yaw_err As Integer
    Dim _roll_err As Integer
    Dim _pitch_err As Integer
    
    
    Dim Bufferbyte As Byte
    Dim Kanal(_maxchannel) As Word
    Dim Channel As Byte
    Dim _bl(_maxchannel) As Word
    Dim I As Byte
    Dim _crc As Word
    Dim _sbl(_maxchannel) As Integer
    
    Dim Buffer(6) As Byte
    
    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 _yawnow As Integer
    Dim _rollnow As Integer
    Dim _pitchnow As Integer
    
    Dim _empfmiddle(_maxchannel) As Word
    Dim _empfmin(_maxchannel) As Word
    Dim _empfmax(_maxchannel) As Word
    Dim _empfdiv(_maxchannel) As Word
    Dim _stick_sensitivy(_maxchannel) As Word
    
    _stick_sensitivy(1) = 2265
    _stick_sensitivy(2) = 1800
    _stick_sensitivy(3) = 1800
    _stick_sensitivy(4) = 1800
    
    _empfmiddle(1) = 26500
    _empfmiddle(2) = 23800
    _empfmiddle(3) = 25300
    _empfmiddle(4) = 22250
    
    _empfmin(1) = 14300
    _empfmin(2) = 14650
    _empfmin(3) = 17100
    _empfmin(4) = 14750
    
    _empfmax(1) = 32300
    _empfmax(2) = 32600
    _empfmax(3) = 32600
    _empfmax(4) = 30500
    
    For I = 1 To 4
     _empfdiv(i) = _empfmiddle(i) - _empfmin(i)
     _empfdiv(i) = _empfdiv(i) / _stick_sensitivy(i)            '2265
     _empfdiv(i) = _empfdiv(i) * 2
    Next I
    
    
    Call Wmp_init()
    Waitms 500
    Call Set_offset()
    
    Wait 2
    
    Enable Interrupts
    
    
    
    Do
    
    
    Call Filter_rx_data()
    Call Filter_gyro_data()
    Call Pid_regulator()
    Call Mixer()
    Call Send_data()
    
    
    Loop
    
    
    Measure:
    If Channel > 0 And Channel < 5 Then
      Kanal(channel) = Timer1
    End If
    Timer1 = 1536
    Incr Channel
    Return
    
    Pausedetect:
    Channel = 0
    Return
    
    
    Sub Wmp_init()
        I2cstart
        I2cwbyte &HA6                                           ' sends memory address
        I2cwbyte &HFE                                           ' WM+ activation
        I2cwbyte &H04 .                                         ' Now Adress changes to &HA4
        I2cstop
    End Sub
    
    Sub Send_zero()
       I2cstart
       I2cwbyte &HA4                                            ' sends memory address
       I2cwbyte &H00                                            ' sends zero before receiving
       I2cstop
       Waitms 1
    End Sub
    
    Sub Read_data()
       Gosub Send_zero                                          ' sends zero before receiving
       I2creceive &HA4 , Buffer(1) , 0 , 6                      ' receive 6 bytes
       Yaw1 = Buffer(1)
       Roll1 = Buffer(2)                                        '  Low Bytes
       Pitch1 = Buffer(3)
       Shift Buffer(4) , Right , 2 : Yaw0 = Buffer(4)
       Shift Buffer(5) , Right , 2 : Roll0 = Buffer(5)          '  High Bytes
       Shift Buffer(6) , Right , 2 : Pitch0 = Buffer(6)
    End Sub
    
    Sub Set_offset()
       _yawoffset = 0
       _rolloffset = 0
       _pitchoffset = 0
       For I = 1 To 100
          Call Read_data
          _yawoffset = _yawoffset + Yaw
          _rolloffset = _rolloffset + Roll
          _pitchoffset = _pitchoffset + Pitch
       Next I
       _yawoffset = _yawoffset / 100
       _rolloffset = _rolloffset / 100
       _pitchoffset = _pitchoffset / 100
    End Sub
    
    
    
    Sub Filter_gyro_data()
     Call Read_data()
     _yawnow = Yaw - _yawoffset
     _rollnow = Roll - _rolloffset
     _pitchnow = Pitch - _pitchoffset
    
     _yawnow = _yawnow / 2
     _rollnow = _rollnow / 2
     _pitchnow = _pitchnow / 2
    End Sub
    
    
    
    Sub Pid_regulator()
    _yaw_err = _sbl(4) / 1
     _yaw_err = _yaw_err - _yawnow
    
     _roll_err = _sbl(3) / 5
     _roll_err = _roll_err - _rollnow
    
     _pitch_err = _sbl(2) / 5
     _pitch_err = _pitch_err - _pitchnow
    
    
     _yaw_kp_err = _yaw_kp_err * _yaw_kp
     _yaw_kp_err = _yaw_err / 10
    
     _roll_kp_err = _roll_kp_err * _roll_kp
     _roll_kp_err = _roll_err / 10
    
     _pitch_kp_err = _pitch_kp_err * _pitch_kp
     _pitch_kp_err = _pitch_err / 10
    
    
     _yaw_ki_err = _yaw_ki_err * _yaw_ki
     _yaw_ki_err = _yaw_err / 50
     _yaw_ki_sum = _yaw_ki_sum + _yaw_ki_err
    
     _roll_ki_err = _roll_ki_err * _roll_ki
     _roll_ki_err = _roll_err / 50
     _roll_ki_sum = _roll_ki_sum + _roll_ki_err
    
     _pitch_ki_err = _pitch_ki_err * _pitch_ki
     _pitch_ki_err = _pitch_err / 50
     _pitch_ki_sum = _pitch_ki_sum + _pitch_ki_err
    
    
     _yaw_kd_err = _yaw_kd_err * _yaw_kd
     _yaw_kd_err = _yaw_err / 50
     _yaw_kd_err = _yaw_kd_old - _yaw_kd_err
     _yaw_kd_old = _yaw_kd_old
    
     _roll_kd_err = _roll_kd_err * _roll_kd
     _roll_kd_err = _roll_err / 50
     _roll_kd_err = _roll_kd_old - _roll_kd_err
     _roll_kd_old = _roll_kd_old
    
     _pitch_kd_err = _pitch_kd_err * _pitch_kd
     _pitch_kd_err = _pitch_err / 50
     _pitch_kd_err = _pitch_kd_old - _pitch_kd_err
     _pitch_kd_old = _pitch_kd_old
    
    
     _yaw_pid = _yaw_kp_err + _yaw_ki_sum
     _yaw_pid = _yaw_pid + _yaw_kd_err
    
     _roll_pid = _roll_kp_err + _roll_ki_sum
     _roll_pid = _roll_pid + _roll_kd_err
    
     _pitch_pid = _pitch_kp_err + _pitch_ki_sum
     _pitch_pid = _pitch_pid + _pitch_kd_err
    
    
     If _yaw_pid < -1000 Then _yaw_pid = -1000
     If _yaw_pid > 1000 Then _yaw_pid = 1000
     If _roll_pid < -1000 Then _roll_pid = -1000
     If _roll_pid > 1000 Then _roll_pid = 1000
     If _pitch_pid < -1000 Then _pitch_pid = -1000
     If _pitch_pid > 1000 Then _pitch_pid = 1000
    End Sub
    
    
    Sub Filter_rx_data()
     For I = 1 To 4
      _sbl(i) = Kanal(i) - _empfmiddle(i)
      _sbl(i) = _sbl(i) / _empfdiv(i)
     Next I
    
     _sbl(4) = _sbl(4) * -1
    
     _sbl(2) = _sbl(2) / 2
     _sbl(3) = _sbl(3) / 2
     _sbl(4) = _sbl(4) / 2
    End Sub
    
    
    Sub Mixer()
     _bl(1) = 62667 - _sbl(1)
     _bl(2) = _bl(1)
     _bl(3) = _bl(1)
     _bl(4) = 62667
    
     _bl(1) = _bl(1) + _bl1offset
     _bl(2) = _bl(2) + _bl2offset
     _bl(3) = _bl(3) + _bl3offset
     _bl(4) = _bl(4) + _bl4offset
    
     _bl(1) = _bl(1) + _pitch_pid
     _bl(2) = _bl(2) + _roll_pid
     _bl(3) = _bl(3) - _roll_pid
     _bl(4) = _bl(4) - _yaw_pid
    End Sub
    
    
    Sub Send_data()
     If Channel <= 11 Then
      _crc = Crc16(_bl(1) , 4)
      Printbin Start_byte ; _bl(1) ; _bl(2) ; _bl(3) ; _bl(4) ; _crc
     End If
    End Sub
    
    
    End
    Vielen Dank
    Gruß
    Chris

    EDIT:
    Wenn jemand einen Beispielcode oder eine Seite hätte, auf der man ein Beispiel einer Implementierung sieht, wäre ich nicht abgeneigt, da sich das Internet über solche Implementaitionen doch sehr ausschweigt :/
    Ein Tiefpass-Filter ist mir eigtl. klar, das ist im Prinzip nichts anderes als eine Durchschnittsbildung.
    Geändert von Che Guevara (22.05.2011 um 12:00 Uhr)

Ähnliche Themen

  1. GSM Anruf signal Empfänger selbst bauen
    Von mkRE im Forum Elektronik
    Antworten: 2
    Letzter Beitrag: 30.08.2009, 21:38
  2. Tonfrequenzen filtern
    Von MezzoMix im Forum Elektronik
    Antworten: 2
    Letzter Beitrag: 14.05.2008, 19:05
  3. C-Micro PWM-Spannung filtern
    Von -seppel- im Forum Controller- und Roboterboards von Conrad.de
    Antworten: 3
    Letzter Beitrag: 31.01.2008, 16:22
  4. PWM Signal von RC-Empfänger auswerten
    Von MartinFunk im Forum C - Programmierung (GCC u.a.)
    Antworten: 6
    Letzter Beitrag: 18.04.2007, 15:29
  5. 650nm Filtern mit Fotofiltern?
    Von Christian Sturm im Forum Sensoren / Sensorik
    Antworten: 20
    Letzter Beitrag: 14.02.2007, 16:17

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

fchao-Sinus-Wechselrichter AliExpress