Zitat Zitat von SlyD
Läuft los ja, aber hält er bei 46 auch wieder an?
Das ist nämlich meistens nicht der Fall
Wenns mal läuft dann läufts leichter...
Danke für den Hinweis, hab ich ganz vergessen, aber wär mir bestimmt bald aufgefallen
Mit der Hyterese sollte das dann auch kein Problem sein.

Zitat Zitat von SlyD
Einfacher wäre es natürlich, wenn man dem Motor der später losläuft beim Start direkt etwas mehr Power gibt.
(also nur beim Start z.B. dem Integrierer eine Konstante hinzuaddieren... )
Zitat Zitat von SlyD
Ich meinte damit die Integral Variablen left_i und right_i beim standard I Regler in der Lib.
Also da muss ich jetzt ein bissl was erzählen. Und zwar habe ich einen völlig eigenen Regler programmiert und den anderen Regler aus dem Code entfernt. Grund: Eingreifen in das Regelgeschehen war nicht einfach, wegen dem Soft-PWM etc. und ich wollte nicht Speed und Direction getrennt angeben. Ich habe jetzt die Funktion runSpeedController(int left, int right) und da kann ich die Geschwindigkeit in mm/s von -300mm/s bis +300mm/s eingeben. Was bei einer Positionsregelung dann auch von Vorteil ist, weil wenn die Dirfferenz negativ ist, ich nicht die Richtung ändern muss sondern der zweite Regler einfach mit Minus weiterrechnen kann.
Deshalb brauch ich auch eine Hyterese um den Nullpunkt, da happerts im Moment noch.

Ich stell mal den Code hier rein. Im Code siehst du auch den Grund, warum ich das mit einer Voreinstellung des I-Wertes nicht machen kann, weil mein Regler nicht einen I-Wert speichert sondern immer zur momentan eingestellten Stellgröße dazurechnet oder abzieht. Der Korrekturfaktor ist der Wert, wo ich die maximale Pulsweite(180, eigentlich 210 aber von meinem Programm begrenzt auf 180) durch die daraus resultierende Geschwindigkeit in [mm/s] dividiere.
Der Code läuft im Timer0 Interrupt ab:

Code:
if(speedController == 1)
	{
		if(speedControllCounter++ >= speedControllTimer)
		{
			//Linke Raupe
			speedControllCounter = 0;
			sclE = sclW - getLSpeed();
			
			if(speedKp > 0)
			delta_y = speedKp * (180/267.0) * ((sclE - sclE1) + speedKi * sclE * speedControllTimer/10000.0 + 
					  speedTv * (sclE - 2*sclE1 + sclE2)/(speedControllTimer/10000.0));
			else
			delta_y = (180.0/267.0) * (speedKi * sclE * speedControllTimer/10000.0 + 
					  speedTv * (sclE - 2*sclE1 + sclE2)/(speedControllTimer/10000.0));
			
			difE2 = difE1;
			difE1 = difE;

			if(delta_y > scMaxUp)
				delta_y = scMaxUp;
			
			if(delta_y < scMaxDown)
				delta_y = scMaxDown;

			
			if((PORTC & 0x04) >= 1) //BWD?
				y1 = OCR1BL * (-1);  //=>y ist dann eigentlich negativ
			else
				y1 = OCR1BL;		    //sonst positiv


			//Umwandeln von PW 46 bis 180 auf 0 bis 180 zur Kompatibilität zum Regler
			//bzw. bei Rückwärtlauf von PW -42 bis -180 auf 0 bis -180
			if(y1 >= 46)
				y1 = (y1-46) * (180.0/(180.0-46.0));
			else if(y1 <= (-42))
				y1 = (y1-(-42)) * ((-180.0)/((-180.0)-(-42.0)));
			else
				y1 = 0;

			//neues delta_y einfließen lassen und Signal in den vorgegebenen Grenzen halten
			y1 += delta_y;

			if(y1 > 180)
				y1 = 180;
			
			if(y1 < -180)
				y1 = -180;

			//Zurückrechnen auf Werte zwischen 46 und 180 bzw. -42 bis -180

			if(y1 > 0 || (y1 == 0 && delta_y >= 0))
				y1 = 46 + y1 * ((180.0-46.0)/180.0);
			else if(y1 < 0 || (y1 == 0 && delta_y < 0))
				y1 = -42 + y1 * (((-180.0)-(-42.0))/(-180.0));

			if(y1 < 0)
			{
				PORTC |= (1<<PORTC2); //BWD
				y1 *= (-1); //y muss wieder positive Zahl sein weils auf OCR geschrieben wird
			}
			else
			{
				PORTC &= ~(1<<PORTC2); //FWD
			}

			sclE2 = sclE1;
			sclE1 = sclE;

			OCR1BL = y1;







			//Rechte Raupe
			
			scrE = scrW - getRSpeed();
			
			if(speedKp > 0)
				delta_y = speedKp * (180.0/284.0) * ((scrE - scrE1) + speedKi * scrE * speedControllTimer/10000.0 + speedTv * (scrE - 2*scrE1 + scrE2)/(speedControllTimer/10000.0));
			else
					delta_y = (180.0/284.0) * (speedKi * scrE * speedControllTimer/10000.0 + speedTv * (scrE - 2*scrE1 + scrE2)/(speedControllTimer/10000.0));
			

			if(delta_y > scMaxUp)
				delta_y = scMaxUp;
			
			if(delta_y < scMaxDown)
				delta_y = scMaxDown;

			if((PORTC & 0x08) >= 1) //BWD?
				y2 = OCR1AL * (-1);  //=>y ist dann eigentlich negativ
			else
				y2 = OCR1AL;		    //sonst positiv

			//Umwandeln von PW 20 bis 180 auf 0 bis 180 zur Kompatibilität zum Regler
			//bzw. bei Rückwärtlauf von PW -18 bis -180 auf 0 bis -180
			if(y2 >= 20)
				y2 = (y2-20) * (180.0/(180.0-20.0));
			else if(y2 <= (-18))
				y2 = (y2-(-18)) * ((-180.0)/((-180.0)-(-18.0)));
			else
				y2 = 0;

			//neues delta_y einfließen lassen und Signal in den vorgegebenen Grenzen halten
			y2 += delta_y;

			if(y2 > 180)
				y2 = 180;
			
			if(y2 < -180)
				y2 = -180;

			//Zurückrechnen auf Werte zwischen 20 und 180 bzw. -18 bis -180

			if(y2 > 0 || (y2 == 0 && delta_y >= 0))
				y2 = 20 + y2 * ((180.0-20.0)/180.0);
			else if(y2 < 0 || (y2 == 0 && delta_y < 0))
				y2 = -18 + y2 * (((-180.0)-(-18.0))/(-180.0));

			if(y2 < 0)
			{
				PORTC |= (1<<PORTC3); //BWD
				y2 *= (-1); //y muss wieder positive Zahl sein weil auf OCR geschrieben wird
			}
			else
			{
				PORTC &= ~(1<<PORTC3); //FWD
			}

			scrE2 = scrE1;
			scrE1 = scrE;

			OCR1AL = y2;
		}	
	}
Mit freundlichen Grüßen

Schwammi