Реализация управления PI для Teensy Atmega 32u4 - PullRequest
0 голосов
/ 07 марта 2019

Я реализую ПИД-управление с использованием стандартных библиотек Teensy Atmega32u4. Моя переменная управления - это сигнал ШИМ. Моя переменная процесса - это текущее угловое положение двигателя постоянного тока, которое связано с потенциометром 10 кОм с кодом, который считывает входной сигнал АЦП положения по шкале от 0 до 270 градусов. Уставка - это джойстик с лазерной резкой, рукоятка которого также прикреплена к потенциометру 10 кОм, который считывает угловое положение таким же образом, как и переменная процесса.

У меня вопрос, как реализовать составную часть схемы управления. Интегральный термин задается как:

Error = Set Point – Process Variable

Integral = Integral + Error

Control Variable = (Kp * Error) + (Ki * Integral)

Но я не уверен, как рассчитать интегральную часть. Нужно ли нам учитывать количество времени, прошедшее между выборками, или просто накопленную ошибку и инициализировать интегральную часть нулем, чтобы она действительно была дискретизирована? Поскольку я использую C, термин Integral может быть просто глобальной переменной?

Я на правильном пути?

Ответы [ 2 ]

0 голосов
/ 07 марта 2019

Чтобы добавить к предыдущему ответу, также рассмотрите случай целочисленного завершения в вашем коде.Должен быть какой-то механизм для сброса интегрального члена, если произойдет откат.Также выберите наибольший доступный тип данных, чтобы сохранить член интеграма (суммы), чтобы избежать целочисленного переполнения (обычно long long).Также позаботьтесь о встроенном переполнении.

Если вы выбираете достаточно высокую частоту дискретизации, можно избежать деления, чтобы уменьшить количество вычислений.Однако, если вы хотите поэкспериментировать со временем выборки, оставьте время выборки кратным степеням двух, чтобы деление можно было выполнить с помощью операций сдвига.Например, предположим, что выбранное время выборки составляет 100 мс, 50 ​​мс, 25 мс, 12,5 мс.Тогда делительными коэффициентами могут быть 1, 1 << 1, 1 << 2, 1 << 4. </p>

Удобно хранить все связанные переменные ПИД-регулятора в одном struct, изатем используйте это struct в качестве параметров в функциях, работающих с этим PID.Таким образом, код будет модульным, и многие микропроцессорные циклы могут одновременно работать на микроконтроллере, используя один и тот же код и только разные экземпляры struct.Этот подход особенно полезен в больших робототехнических проектах, где у вас есть много циклов для управления с помощью одного процессора.

0 голосов
/ 07 марта 2019

Поскольку время выборки (время, после которого вычисляется PID) всегда одинаково, не имеет значения, делите ли вы интегральный член на время выборки, так как это время выборки будет просто действовать как постоянная Ки, но лучше разделить интеграл термин время выборки, так что если вы измените время выборки, PID изменяется со временем выборки, но это не обязательно.

Вот функция PID_Calc, которую я написал для моего конкурса Drone Robotics в python. Не обращайте внимания на «[index]», который был создан мной для создания общего кода.

def pid_calculator(self, index):

    #calculate current residual error, the drone will reach the desired point when this become zero
    self.Current_error[index] = self.setpoint[index] - self.drone_position[index]      

    #calculating values req for finding P,I,D terms. looptime is the time Sample_Time(dt).
    self.errors_sum[index] = self.errors_sum[index] + self.Current_error[index] * self.loop_time 
    self.errDiff = (self.Current_error[index] - self.previous_error[index]) / self.loop_time

    #calculating individual controller terms - P, I, D.
    self.Proportional_term = self.Kp[index] * self.Current_error[index]
    self.Derivative_term = self.Kd[index] * self.errDiff
    self.Intergral_term = self.Ki[index] * self.errors_sum[index] 

    #computing pid by adding all indiviual terms
    self.Computed_pid = self.Proportional_term + self.Derivative_term + self.Intergral_term 

    #storing current error in previous error after calculation so that it become previous error next time
    self.previous_error[index] = self.Current_error[index]

    #returning Computed pid
    return self.Computed_pid

Вот если ссылка на весь мой PID скрипт в git hub. Посмотри, поможет ли это тебе. Нажмите кнопку вверх ig = f u, чтобы получить ответ, и отметьте мой репозиторий Github. Мне нравится сценарий в github. Спасибо.

...