Wir, de Equalizer-Gruppe, wollen hier eine Zusammenfassung unserer Präsentation im Wissenschaftsfenster hochladen. ** Die Präsentationsfolien:** {{:mechatronik:wise21:ml_theequalizor_2.pdf|}} **Der Bauplan:** {{ :mechatronik:wise21:thequalizer_schema.png?300 |}} **Der Schaltplan:** {{:mechatronik:wise21:schaltplan_3_ebene_1_schaltplan.jpg?200|}} **PID-Regler** Zum Balancieren der Kugel benutzen wir einen PID-Regler. Dieser versucht, einen Eingabewert einem gesetzten Punkt anzugleichen, indem er einen Ausgabewert verändert. PID-Regler benötigen außerdem drei festgelegte Werte, die sein Verhalten bestimmen. Das tun sie, indem sie unterschiedliche Gewichtung auf die momentane Position, Geschwindigkeit und die Änderung der Geschwindigkeit der Kugel zur Findung des Ausgabewertes legen. Zum Finden der korrekten PID-Werte haben wir ein zweites Programm geschrieben, das Variationen dieser Werte für jeweils 20 Sekunden ausprobiert und dann speichert, wie gut der jeweilige Versuch lief. Die besten Ergebnisse wurden danach noch einmal per Hand ausprobiert und verglichen. Jedes der drei Parameter konnte einen Wert von 0,01 bis 0,1 in Schritten von 0,005 annehmen. Das sind 18 Werte Pro Parameter, also insgesamt 18^3 = 5832 Tests über einen Zeitraum von 1 Tag, 8 Stunden und 24 Minuten. {{ :mechatronik:wise21:wertfindung.mp4? |}} Zeitraffer des Wertfindungs-Programms {{ :mechatronik:wise21:pidendwerte.png?300 |}} Auswertung der besten Werte **Der Arduino-Sketch:** //=============================================================================================================================Includes und Definitionen #include "Adafruit_VL53L0X.h" //Bibliothek zur Verwendung des TOF-Sensors (Entfernungsmessung) #include //Bibliothek zur Steuerung des Servomotors #include //Bibliothek zur Verwendung eines PID-Controllers #include //Bibliothek zur Steuerung der LED-Kette #define POTI_PIN A0 //Pin zum Auslesen des Slider-Potentiometers #define SERVO_OUT 8 //Pin für die Motorsteuerung #define LED_PIN 7 //Ansteuerungspin für die LED-Kette #define NUM_LEDS 12 //Anzahl der LEDs in der Kette #define POS_MAX 195 //höchste Entfernung, die die Kugel annehmen kann #define POS_MIN 20 //niedrigste Entfernung, die die Kugel annehmen kann //---------------------------------------------------------------------------------Deklarierung aller benötigten Objekte|| CRGB leds[NUM_LEDS]; //das Objekt, das den LED-Streifen steuert // Adafruit_VL53L0X lox = Adafruit_VL53L0X(); //das Objekt, das Messwerte vom TOF-Sensor ausliest // Servo myservo; //das Objekt, das den Servomotor steuert // // //Es werden zwei PID-Werte benutzt, zwischen denen je nach Entfernung gewechselt wird // double aggKp = 0.075, aggKi = 0.07, aggKd = 0.055; //agressive Werte // double consKp = 0.09, consKi = 0.025, consKd = 0.055; //feine Werte // PID_v2 myPID(consKp, consKi, consKd, PID::Direct); //Der PID-Controller, kriegt vorerst die feinen Parameter übergeben // //----------------------------------------------------------------------------------------------------------------------|| //---------------------------------------------------------------------------------------------------------Variablen|| int e1, e2, entfernung = 125; //Die beiden vorherigen und die durchschnittliche gemessene Entfernung // int s1, s2, s3, s4, sollwert = 130; //Die vier vorherigen und der durchschnittliche gemessene Sollwert // int motorwert = 90; //Der Winkel, zu dem sich der Motor drehen soll // int gap; //Entfernung, die zum gesetzten Punkt besteht // int zeit = 0; //Variable zur Messung der Zeit, die der Ball schon nahe am Sollwert liegt // //Misst aber nicht genau die Zeit, ist eher zur ungefähren Abschätzung der vergangenen Zeit // //------------------------------------------------------------------------------------------------------------------|| //=================================================================================================================================================Setup void setup() { FastLED.addLeds(leds, NUM_LEDS); //Setup des LED-Controllers lox.begin(); VL53L0X_RangingMeasurementData_t measure; //Erste Messung für die Initialisierung des PID-Controllers myPID.Start( //Initialisierung des PID-Controllers Dabei werden drei Variablen übergeben: measure.RangeMilliMeter, //Die gemessene entfernung 105, //der momentane Motorwinkel (wird erst einmal auf die Mitte des nutzbaren Bereiches gesetzt) 130); //der Sollwert myservo.attach(SERVO_OUT); //Der Motorsteuerung wird der Ansteuerungspin für den Servo übrgeben myPID.SetOutputLimits(70, 140); //Minimal- und Maximalwert für den PID-Ausgabewert werden beschränkt, da der Servo bei Winkeln unter 70° oder über 140° die Konstruktion beschädigt. } //======================================================================================================================================Programmschleife void loop() { //----------------------------------------------------------------wiederholendes Setup|| VL53L0X_RangingMeasurementData_t measure; //Die Entfernung des Balls wird gemessen // lox.rangingTest(&measure, false); //konstantes Debuggen des TOF-Sensors // //------------------------------------------------------------------------------------|| //------------Berechnung des Mittelwertes der letzten TOF-Messwerte|| e1 = e2; //Aktualisierung der Messwerte // e2 = measure.RangeMilliMeter; // entfernung = int((e1 + e2)/2); //Berechnung des Durchschnitts // //-----------------------------------------------------------------|| //---------------------------------------------------------------------------------------Setzen der neuen gewünschten Entfernung|| if(map(analogRead(POTI_PIN), 0, 1023, 50, 200) - sollwert > 5 || map(analogRead(POTI_PIN), 0, 1023, 50, 200) - sollwert < -5) // { // //Geschieht zur Vermeidung von Messpitzen nur, wenn sie sich um mehr als 5 bewegt // s1 = 2; //Zusätliche Glättung der Messwerte, Verfährt wie in Zeilen 59-61 // s2 = s3; // s3 = s4; // s4 = map(analogRead(POTI_PIN), 0, 1023, 70, 180); // sollwert = int((s1 + s2 + s3 + s4)/4); // myPID.Setpoint(sollwert); //Neuer Sollwert wird an den PID-Controller übergeben // } // //------------------------------------------------------------------------------------------------------------------------------|| //----------------------------------------------------------------------------------------------------------Setzen der PID-Parameter|| gap = abs(myPID.GetSetpoint() - measure.RangeMilliMeter); //Berechnet die Entfernung vom gewünschten Punkt // if (gap < 40) // { // myPID.SetTunings(consKp, consKi, consKd); //Benutzt schwache PID-Werte, da der Ball nahe am gewünschten Punkt ist // } else { // myPID.SetTunings(aggKp, aggKi, aggKd); //Benutzt aggressive PID-Werte, da der Ball weit vom gewünschten Punkt entfernt ist // } // //----------------------------------------------------------------------------------------------------------------------------------|| //------------------------------------------------------------------------------------------------------------Setzen der Punkte auf dem LED-Streifen|| for(int i = 0; i Das fertige Projekt in Aktion: {{ :mechatronik:wise21:thequalizerdemo.mp4?300 |}} {{ :mechatronik:wise21:pid_2.png?300 |}}