Hallo,
ich habe hier meinen Roby 2.0 schon gut ans laufen gebracht. Alle Sensoren funktionieren. Ziel soll es sein, das er das Zimmer meiner Tochter aufräumt (wenigstens ein paar Objekte erkennt und wegbringt). Darum ist vorne eine Ultraschallsensor für die Objekterkennung vorhanden und hinten eine zwei Finger Gripper mit Sensoren um das Objekt zu greifen. Mit absoluten Werten (hier meine ich fahre x steps vor und drehe x steps usw.) funktioniert das eigendich schon ganz gut.
Bilderlink: http://www.schilly.net/index.php?id=22
Bild hier
Bild hier
Um ganz genaue Positionen anfahren zu können, soll eine PID Regler die beiden Motoren regeln. Hier habe ich mein Problem zum Code.
Der Code ist aus dem Buch "Roboter Selbst bauen" Cybot Pimp.
Ich steuere meine Motoren über PWM in einem Bereich zwischen 300 und 511. Das gebe ich über pwm an....
Ich verstehe in dem Code von Uli Sommer die PID-Regler Steuerung nicht. Der PID Regler ist in einem Timer_IRQ untergebracht. Soweit alles gut.
Frage: Was bedeutet die 512 ?? Siehe Code
Hier die If-Abfrage:
Code:'>>> vorwärts If Motor_l > 512 And Motor_r > 512 Then If Rad_l_save > Rad_r_save Then Motor_l = Motor_l + PID End If If Rad_l_save < Rad_r_save Then Motor_r = Motor_r + PID End If End If
Hier alles:
Hier wird der Motor_L (links) in einer If-Abfrage abgefragt > oder < usw.Code:'############################################################################### '# Projekt : Cybot Pimp # '# Controller: Mega32 RN-Control Board # '# Autor : Sommer Ulli # '# Homepage : www.sommer-robotics.de # '# # '# Funktionen: 1. PID-Regler # '# Taster 1 = Start # '# Taster 2 = Stop # '############################################################################### '=============================================================================== '***| Mikrocontroller Config |************************************************** '=============================================================================== 'Microcontroller '================ $regfile = "m32def.dat" $crystal = 16000000 $baud = 19200 $hwstack = 100 $swstack = 100 $framesize = 100 'ADC einstellen '=============== Config Adc = Single , Prescaler = Auto , Reference = Internal Start Adc 'I/O '====== 'Port A als Eingang und Pullup on Config Porta.7 = Input Porta.7 = 1 'Zähler '====== Dim X As Word 'Taster abfrage und Auswetung '============================= Declare Function Tastenabfrage() As Byte Declare Sub _tastenauswertung() Dim Ton As Integer Dim Taste As Byte Dim Tastelast As Byte Dim Start_flag As Bit Dim Int_flag As Bit 'Drehzahlmessung '================ 'Timer0 = 100Hz Config Timer0 = Timer , Prescale = 1024 Const Timervorgabe = 100 On Timer0 Timer_irq Enable Timer0 'Antrieb '======== Declare Sub Fast_forward() Declare Sub Middle_forward() Declare Sub Slow_forward() Declare Sub Fast_backward() Declare Sub Middle_backward() Declare Sub Slow_backward() Declare Sub Fast_left() Declare Sub Middle_left() Declare Sub Slow_left() Declare Sub Fast_right() Declare Sub Middle_right() Declare Sub Slow_right() Dim Speed_l_soll As Word Dim Speed_r_soll As Word Dim Motor_l As Word Dim Motor_r As Word Dim Speed_l As Word Dim Speed_r As Word Dim Dir_l As Bit Dim Dir_r As Bit Config Pinc.6 = Output 'linker Motor Kanal 1 Config Pinc.7 = Output 'linker Motor Kanal 2 Config Pind.4 = Output 'linker Motor PWM Config Pinb.0 = Output 'rechter Motor Kanal 1 Config Pinb.1 = Output 'rechter Motor Kanal 2 Config Pind.5 = Output 'rechter Motor PWM Config Timer1 = Pwm , Pwm = 10 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down Pwm1a = 0 Pwm1b = 0 Tccr1b = Tccr1b Or &H02 'Endcoder '========= Config Pind.2 = Input Config Pind.3 = Input Dim Rad_l As Long Dim Rad_r As Long Dim Rad_l_save As Long Dim Rad_r_save As Long Config Int0 = Falling Config Int1 = Falling On Int0 Int0_int On Int1 Int1_int Enable Int0 Enable Int1 'Sonar Servo '============ Config Porta.2 = Output Declare Sub _servo() Dim Servo_pos As Word Dim Servo_pos_save As Word Dim Multiplikator_servo As Byte Dim Setup As Word Multiplikator_servo = 15 Setup = 3900 'PID Regler '=========== Dim P As Integer Dim I As Integer Dim D As Integer Dim Kp As Integer Dim Ki As Integer Dim Kd As Integer Dim PID As Integer Dim Error As Integer Dim Error_last As Integer 'je niedriger die Geschwindigkeit desto höher die Werte Kp = 100 Ki = 50 Kd = 10 'Odometrie '========== Declare Sub _stop() Declare Sub _odo_reset() Dim Odo_l As Long Dim Odo_r As Long Const Pi = 3.14159265 Const Tick_l = 2297 'pro Radumdrehung Const Tick_r = 2291 Const Wheel_base = 10.7 Enable Interrupts '=============================================================================== '***| Initzialisierung|********************************************************* '=============================================================================== Akku_leer = 0 Dir_l = 1 Dir_r = 1 Int_flag = 0 Rad_l_save = 0 Rad_r_save = 0 Rad_l = 0 Rad_r = 0 Motor_r = 512 Motor_l = 512 Odo_l = 0 Odo_r = 0 Lcd_counter = 0 For X = 1 To 50 Servo_pos = 128 Call _servo() Next X X = 0 'LCD Start Bildschirm '===================== Locate 1 , 1 : Lcd "# Cybot - Pimp #" Locate 2 , 1 : Lcd "#--------------#" Locate 3 , 1 : Lcd " PID-Regler " Locate 4 , 1 : Lcd "Sommer Robotics" '############################################################################### '*** Haubtprogramm ************************************************************* '############################################################################### Main: Do ' Tasterabfrage und Auswertung '=============================================================================== Call _tastenauswertung() ' Sensor Abfrage '=============================================================================== Call _betriebsspannung() Call _srf02_entfernung() ' LCD Ausgabe '=============================================================================== Incr Lcd_counter If Lcd_counter > 10 Then 'Locate 1 , 1 : Lcd "SRF02: " ; Entfernung ; " cm " 'Locate 2 , 1 : Lcd "Bat: " ; Fusing(volt , "##.##") ; " Volt " 'Locate 3 , 1 : Lcd "Odo-l: " ; Odo_l ; " " 'Locate 4 , 1 : Lcd "Odo-r: " ; Odo_r ; " " Lcd_counter = 0 End If ' Jetzt gehts los '=============================================================================== If Start_flag = 1 Then Do Call _srf02_entfernung() If Entfernung < 30 Then Call _stop() Start_flag = 0 Exit Do End If Call Slow_forward() Call _tastenauswertung() If Taste = 2 Then Call _stop() Exit Do End If Loop End If Loop End '############################################################################### '*** Haubtprogramm Ende ******************************************************** '############################################################################### '=============================================================================== '***| Fahrbefehle |************************************************************* '=============================================================================== '>>> vorwärts Sub Fast_forward() Motor_l = 1000 Motor_r = 1000 End Sub Sub Middle_forward() Motor_l = 800 Motor_r = 800 End Sub Sub Slow_forward() Motor_l = 650 Motor_r = 650 End Sub '>>> rückwärts Sub Fast_backward() Motor_l = 50 Motor_r = 50 End Sub Sub Middle_backward() Motor_l = 300 Motor_r = 300 End Sub Sub Slow_backward() Motor_l = 450 Motor_r = 450 End Sub '>>> links drehen Sub Fast_left() Motor_l = 300 Motor_r = 850 End Sub Sub Middle_left() Motor_l = 400 Motor_r = 800 End Sub Sub Slow_left() Motor_l = 450 Motor_r = 700 End Sub '>>> rechts drehen Sub Fast_right() Motor_l = 850 Motor_r = 300 End Sub Sub Middle_right() Motor_l = 800 Motor_r = 400 End Sub Sub Slow_right() Motor_l = 700 Motor_r = 450 End Sub '=============================================================================== '***| Stop |******************************************************************** '=============================================================================== Sub _stop() '>>> Motor_l Stop! Portd.4 = 0 Pwm1a = 0 '>>> Motor_r Stop! Portd.5 = 0 Pwm1b = 0 End Sub '=============================================================================== '***| Odometer Reset |********************************************************** '=============================================================================== Sub _odo_reset() Odo_l = 0 Odo_r = 0 End Sub '=============================================================================== '***| Tastenabfrage |*********************************************************** '=============================================================================== Function Tastenabfrage() As Byte Local Ws As Word Tastenabfrage = 0 Ws = Getadc(7) If Ws < 1010 Then Waitms 10 If Ws < 1000 Then 'T1 = 404 'T2 = 336 'T3 = 265 'T4 = 188 'T5 = 106 Select Case Ws Case 390 To 420 Tastenabfrage = 1 Case 320 To 350 Tastenabfrage = 2 Case 250 To 280 Tastenabfrage = 3 Case 170 To 200 Tastenabfrage = 4 Case 90 To 130 Tastenabfrage = 5 End Select End If End If End Function '=============================================================================== '***| Tastenabfrage |*********************************************************** '=============================================================================== Sub _tastenauswertung() '>>> Tastenfeld abfragen Taste = Tastenabfrage() If Taste <> Tastelast And Taste <> 0 Then Sound Beep , 400 , 500 End If Tastelast = Taste '>>> START If Taste = 1 Then Start_flag = 1 Odo_l = 0 Odo_r = 0 End If '>>> STOP If Taste = 2 Then Call _stop() Start_flag = 0 End If End Sub '=============================================================================== '***| SRF02 Entfernung |******************************************************** '=============================================================================== Sub _srf02_entfernung() Local Lob As Byte Local Hib As Byte Local Firmware As Byte Local Temp As Byte Local Slaveid_read As Byte Slaveid_read = Slaveid + 1 'Messvorgang in starten Incr Srf02_counter If Srf02_counter = 100 Then I2cstart I2cwbyte Slaveid I2cwbyte 0 I2cwbyte 81 'in Zentimetern messen I2cstop End If If Srf02_counter => 200 Then I2cstart I2cwbyte Slaveid I2cwbyte 2 I2cstop I2cstart I2cwbyte Slaveid_read I2crbyte Hib , Ack I2crbyte Lob , Nack I2cstop Entfernung = Makeint(lob , Hib) Srf02_counter = 0 End If End Sub '=============================================================================== '***| Servo |******************************************************************* '=============================================================================== Sub _servo() Servo_pos_save = Servo_pos * Multiplikator_servo Servo_pos_save = Setup + Servo_pos_save Pulseout Porta , 2 , Servo_pos_save Waitms 10 End Sub '=============================================================================== '***| Interrupt Encoder |******************************************************* '=============================================================================== Int0_int: Incr Rad_l Incr Odo_l Return Int1_int: Incr Rad_r Incr Odo_r Return '=============================================================================== '***| Interrupt Timer0 |******************************************************** '=============================================================================== Timer_irq: Timer0 = Timervorgabe Rad_l_save = Rad_l Rad_r_save = Rad_r Rad_l = 0 Rad_r = 0 '>>> Akku leer Warnung If Akku_leer = 1 Then Incr Akku_beep If Akku_beep > 50 Then Sound Beep , 400 , 500 Akku_beep = 0 End If End If 'Start ? '======== If Start_flag = 1 Then If Motor_l <> 512 Or Motor_r <> 512 Then '***| PID Regler |************************************************************** '>>> Error differenz Error = Rad_l_save - Rad_r_save Error = Abs(error) '>>> P - Anteil P = Error P = P * Kp '>>> I - Anteil I = I + Ki I = Error - Error_last '>>> D - Anteil D = Error - Error_last D = D * Kd '>>> Error last Error_last = Error '>>> PID PID = P + I PID = PID + D '>>> rückwärts If Motor_l < 512 And Motor_r < 512 Then If Rad_l_save > Rad_r_save Then Motor_l = Motor_l - PID End If If Rad_l_save < Rad_r_save Then Motor_r = Motor_r - PID End If End If '>>> vorwärts If Motor_l > 512 And Motor_r > 512 Then If Rad_l_save > Rad_r_save Then Motor_l = Motor_l + PID End If If Rad_l_save < Rad_r_save Then Motor_r = Motor_r + PID End If End If '>>> links drehen If Motor_l < 512 And Motor_r > 512 Then If Rad_l_save > Rad_r_save Then Motor_l = Motor_l - PID End If If Rad_l_save < Rad_r_save Then Motor_r = Motor_r + PID End If End If '>>> rechts drehen If Motor_l > 512 And Motor_r < 512 Then If Rad_l_save > Rad_r_save Then Motor_l = Motor_l + PID End If If Rad_l_save < Rad_r_save Then Motor_r = Motor_r - PID End If End If '>>> Begrenzung If Motor_l > 1023 Then Motor_l = 1023 If Motor_l < 1 Then Motor_l = 0 If Motor_r > 1023 Then Motor_r = 1023 If Motor_r < 1 Then Motor_r = 0 '***| Antrieb |***************************************************************** '>>> Motor_l rückwärts If Motor_l < 512 Then Dir_l = 0 Portc.6 = 1 Portc.7 = 0 Portd.4 = 1 Speed_l = Motor_l * 2 Speed_l = 1023 - Speed_l Pwm1a = Speed_l End If '>>> Motor_l vorwärts If Motor_l > 512 Then Dir_l = 1 Portc.6 = 0 Portc.7 = 1 Portd.4 = 1 Speed_l = Motor_l * 2 Pwm1a = Speed_l End If '>>> Motor_r rückwärts If Motor_r < 512 Then Dir_r = 0 Portb.0 = 1 Portb.1 = 0 Portd.5 = 1 Speed_r = Motor_r * 2 Speed_r = 1023 - Speed_r Pwm1b = Speed_r End If '>>> Motor_r vorwärts If Motor_r > 512 Then Dir_r = 1 Portb.0 = 0 Portb.1 = 1 Portd.5 = 1 Speed_r = Motor_r * 2 Pwm1b = Speed_r End If '>>> Motor_l Stop! If Motor_l = 512 Then Portd.4 = 0 Pwm1a = 0 End If '>>> Motor_r Stop! If Motor_r = 512 Then Portd.5 = 0 Pwm1b = 0 End If End If End If Return
Waum 512?
Ich habe mir das ein paar Tage angeschaut und komme nicht dahinter. Servos sind es ja nicht...
Das ist mein eigendliches Problem...
Gruß Schilly







Zitieren

Lesezeichen