Hab ich gerade weitgehend erledigt. Als Controller ein babyorangutan - lag rum aus ner Reparatur mit nem neuen m328/20MHz/MLF und hat schon nen 2x1,2A/3,2Apeak Motortreiber drauf - TB6612FNG. Motor ist ein Getriebemotor von Pololu mit zugehörigem Encoder. Die Hauptarbeit lag an etlichen Testroutinen z.B. für Sprungantwort, Test der Positioniergenauigkeit, Geschwindigkeitsmessung etc. Die Lageregelung habe ich als PD ausgeführt weil "alle" davon sprechen/schreiben dass der i-Anteil unnötig ist. Regelung per Timerinterrupt, Regelfrequenz 200 Hz, Abtastung des Servopulses mit 16 bit/uint_16. Allerdings vermisse ich den I-Anteil, weil das Ding jetzt naturgemäß, lastlos, um die angesteuerte Position pendelt, ± 2 Encoderticks, also weniger als 1 ° an der Abtriebswelle - das geht ausschließlich ins Getriebespiel; unter Last praktisch kein Pendeln. Ein Umbau der Software steht noch bevor: beim zweispurigen Encoder beide Spuren zur Positionsbestimmung hernehmen und evtl. nen i-Anteil, zumindest nen Freischnitt um die Sollposition. Was ich nicht habe ist ein Absolutencoder; der lag halt nicht rum und ein Teil aus nem geschlachteten Servo wollt ich nicht nehmen. Der zentrale Programmcode ist läppisch, die Regelgüte und Steifigkeit ist mit den geschätzten Regelfaktoren Kp = KD = 10 bestens. Regelabweichung ca. 3° bei max. Last ca. 30 Ncm/5V/360mA... Open-Servo .. nach seinen eigenen Anforderungen .. werde ich mich demnächst .. mit der Regelung eines Servomotors beschäftigen ..
Code:// - - - - - - - - - - - - - - - - // Der regelungsinterne Sollwert ist SollPo, wird aus SollPos genommen SollPo = SollPos; // Nenndrehzahl = Solldrz = Soll-Upm ## in Upm IstPo = IencB0; // IstPosition eRA = SollPo - IstPo; // Sollposition-IstPos, "e" => Regelabweichung // // - - - - - - - - - - - - - - - - // Regleranteile berechnen iyp12 = eRA * Kp12; // P-Anteil berechnen eRAalt = eRA; // iyd12 = (eRA - eRAalt) * Kd12; // D-Anteil berechnen iy12 = iyp12 + iyd12; // Gesamtkorrektur berechnen // // - - - - - - - - - - - - - - - - if ( iy12 < -250 ) { iy12 = -250; } // Begrenzen auf { -250 bis if ( iy12 > 250 ) { iy12 = 250; } // +250 } // // ------------------------------------------------------------------------------- // Ansteuerung der PWM direkt fuer babyorangutan if ( iy12 <= 0 ) // { OCR0A = 0; OCR0B = (0 - iy12); } // if ( iy12 > 0 ) // { OCR0A = iy12; OCR0B = 0; } // // // - - - - - - - - - - - - - - - -
Lesezeichen