Es ist ein bisschen vorangegangen. Die Speicherung möglichst vieler Parameter ist auch beim mega328 ein Platzproblem. Immerhin sind jetzt die wichtigsten sichtbar geworden. Beobachtet werden derzeit die ersten hundert Encoderticks, also rund 70 mm der ersten Teilstrecke von 150 mm. Wer will, kann das Video, siehe Link oben, dazu ansehen - es ist die erste Teilstrecke bis zum Multiturn. Anmerkung: der besseren Anschauung wegen wurden die Parameterwerte yp, yi und yd - jeweils nur für dem Motor 12 - mit einem offset dargestellt. Der ist im Diagramm genannt (z.B. ist die Nulllinie für yp12 die 30-er Linie). Anmerkung2: eine Unachtsamkeit bei der Programmierung hatte dazu geführt, dass uint16- und int16-Werte in der Regelungroutine gemischt waren. Dabei hatte ich feststellen müssen, dass die Typwandlung offenbar drastisch viel Zeit braucht. Derzeit können in jeder INTx-ISR alle drei Reglerparamterwerte erfasst werden - davor, mit Typumwandlung - ging das nur mit einem Parameter. Den übersetzten Code hatte ich aber aus Bequemlichkeit nicht durchgesehen.
Deutlich zu sehen ist der hohe Einfluss des integralen Regleranteils. Der führt dazu, dass noch in der Vorwärtsphase - eindeutig ohne irgendeinem vorgegebenen Bremsvorgang - der P-Anteil deutlich negativ werden muss (liegt also weit unter der 30er-Linie), weil der integrale Anteil so hoch geworden ist (35 - weil er mit offset 10 dargestellt wird). Eine geringere Verstärkung im integralen Anteil - schon z.B. bei Ki = 20 - führt zu deutlicherem Schwingen. Derzeit fahre ich mit Ki=22 bei einem Minimum an Schwingen. Dies wird festgestellt nach der Methode des genauen Hinsehens auf den Verlauf von diff0 - sprich: auf die inverse Geschwindigkeit. Der Wert diff0 ist die Zeit vom vorherigen Encoderinterrupt bis zum Beobachtungszeitpunkt, also bis zum aktuellen Interrupt.
................Bild hier
Der Lohn der Arbeit ist die ausführliche Vorstellung, wie die Regleranteile verlaufen und die Möglichkeit, besser gegen schnelle, kleine Schwingungen im Lauf vorgehen zu können. Bei den derzeitigen Testfahrten habe ich keine Verbesserung der Reproduzierbarkeit der unterschiedlichen Läufe gesehen. Aber das will ich noch in mehreren Fahrten mit derselben Einstellung testen.
Nachtrag 26Aug09-11:11
Das Diagramm nutzt einem Interessenten nur dann, wenn der Berechnungsgang der Regelungsroutine bekannt ist. Daher folgt hier der Code mit der kompletten Regelungsroutine, ergänzt um eine Legende zum Diagramm. Die Messdaten werden in den ISR des extINT0 übernommen und in einer Inforoutine dargestellt. In dieser Info-/Ausgaberoutine wird auch der offset für die Achsenkorrektur der Regelungswerte (+10, +30 und +40) eingerechnet und der Wert Izeit_1 in Millisekunden umgerechnet. Das Ergebnis wird seriell ans Terminal ausgegeben.
Code:
/* >>
Sicherung 25Aug09 1800 ..C2\D01-3_40\D01-3_40_mot_x02.c ###>>> noch nicht
===================================================================================
Target MCU : m328p
Target Hardware : MiniD0
Target cpu-frequ. : In der Quelle wählbar
===================================================================================
Enthaltene Routinen: Auszugsweise nur rgl_mo_12
===================================================================================
*** Versionsgeschichte:
====================
x02 24Aug09 1500 Messdatensatz ändern zum möglichst kompletten Messen EINES Motors
x01 04Aug09 1450 Übernahme, erste Anpassungen+Änderungen für Messwerterfassung
===================================================================================
*** Aufgabenstellung : Software für R3D01
Original: ....C2\D01_20test328\D01_20_mot_x50.c 07Jul09 1630
================================================================================ */
// =================================================================================
// === Regelungsroutine für Motor 12 =============================================
// Die gemessene Zeitdifferenz Iz_diff0 zwischen zwei Encoderinterrupts
// wird zur Regelung verwendet
// Erläuterungen/Legende für die Diagrammdarstellung der Regelungswerte
//
// Izeit_1 Die Bordzeit, erzeugt aus einem Zähler für 50µs-Interrupts
// diff0 Abstand vom letzten zum aktuellen Interrupt in 50µs-Einheiten
// iyP12 P-Anteil der Regelung, im Code unten iyp12, in der Darstellung um
// 30 nach oben versetzt (Linie 30 ist Nulllinie)
// iyI12 I-Anteil der Regelung, sonst sinngemäß wie P-Anteil
// iyD12 D-Anteil der Regelung, sonst sinngemäß wie P-Anteil
// iy12 Gesamter Regelungsanteil, eingegrenzt auf [0, 255];
// damit wird die PWM/OCR=B angesteuert
// ncx0 bzw. Lncgs0 Anzahl der gefahreren Interruptticks der Odometrie
// 1 nxc0 sind theoretisch 0,83 gefahrene Millimeter
//
void rgl_mo_12(void) // Regelung für Motor 12 mit 2 Interr pro Umdr.
{
if (sspeed12 <= 15) // Soll überhaupt gefahren werden?
{
OCR0B = 0; // Unter x mm/s soll nicht gefahren werden
return;
}
tupsi12 = Iz_diff0; // Übernahme Interruptabstand in Regelung
ndrz12 = sspeed12; // Nenn = Solldrehzahl = Soll-speed
sei(); // Erlaube Interrupts ##### nested Interrupts
ix12 = 8300 / tupsi12; // => Ist-Geschwindigkeit in mm/s
ie_mot12 = ndrz12 - ix12; // Vergleich => Regelabweichung
if (tupsi12 > 500) {tupsi12 = 500;} // 22apr09-0847 Begrenze auf 500 statt 250
isum12 += ie_mot12;
if (isum12 < -1000 ) { isum12 = -1000; }
if (isum12 > 1000 ) { isum12 = 1000; }
iyp12 = ie_mot12 / Kp12; // P-Anteil berechnen, Kptheor = 0,25 !!
iyi12 = isum12 / Ki12; // I-Anteil berechnen
iyd12 = (ie_mot12 - ie_alt12) / Kd12; // D-Anteil berechnen
iy12 = iyp12 + iyi12 + iyd12; // Gesamtkorrektur berechnet
ie_alt12 = ie_mot12; // Merke Regelabweichung für D-Anteil
if ( iy12 < 0 ) { iy12 = 0;} // Stellwert (PWM) begrenzen
if ( iy12 > 255 ) { iy12 = 255;}
OCR0B = iy12; // Ansteuerung der PWM direkt statt "setPWMlinks"
return;
}
// =================================================================================
// =================================================================================
// ===== ENDE Subroutinen =====================================================
// =================================================================================
Lesezeichen