LINUX.ORG.RU

История изменений

Исправление WRG, (текущая версия) :

последний вариант фукнции вот такой

int16_t pid_compute(int measured, int setpoint, uint16_t *prev_error, float *integral)
{
	int16_t error = setpoint - measured;
	int16_t output;
	float derivate;
	
	*integral = *integral + (error * kI);
	derivate = (error - *prev_error) / (float)PID_INTERVAL;
	output = (kP * error) + (kI * (*integral)) + (kD * derivate);
	*prev_error = error;
	
	if(output > MOTOR_MAX_SPEED) output = MOTOR_MAX_SPEED;
	if(output < MOTOR_MIN_SPEED) output = MOTOR_MIN_SPEED;
	
	return output;
}
пробовал настроить по методу Зиглера-Никольса, он либо секунд за 20 работы разгоняется до максимума при значениях Ku от 9 и выше, или едет заметно медленнее чем задано и даже не может тронуться с места, если Ku меньше 9. Уже не знаю как поступить даже. С одной стороны можно захардкодить несколько экспериментально определенных «скоростей», и как только обороты упали ниже определенных для данной скорости, то включить следующую скорость. Но с другой стороны это не Ъ, надо бы чтобы все автоматически работало.

Исходная версия WRG, :

последний вариант фукнции вот такой

int16_t pid_compute(int measured, int setpoint, uint16_t *prev_error, float *integral)
{
	int16_t error = setpoint - measured;
	int16_t output;
	float derivate;
	
	*integral = *integral + (error * kI);
	derivate = (error - *prev_error) / (float)PID_INTERVAL;
	output = (kP * error) + (kI * (*integral)) + (kD * derivate);
	*prev_error = error;
	
	if(output > MOTOR_MAX_SPEED) output = MOTOR_MAX_SPEED;
	if(output < MOTOR_MIN_SPEED) output = MOTOR_MIN_SPEED;
	
	return output;
}
пробовал настроить по методу Зиглера-Никольса, он либо секунд за 20 работы разгоняется до максимума при значениях Ku от 9 и выше, или едет заметно медленнее чем задано и даже не может тронуться с места, если Ku меньше 9.