🎯 Цель: Изучаем как роботы движутся плавно и точно
⭐ Результат: Создаем блок-схему умного регулятора скорости
👨🏫 Учитель: Ахметов Рустам
🏫 Школа: ГБОУ № 1362
📅 Дата: 2025-06-14
⏰ Время: 85 минут
Наблюдаем:
Наблюдаем:
В чем секрет плавного движения?
🎯 Сегодня раскрываем тайну умного управления скоростью!
Простейший способ:
void setSpeed(int speed) {
motorPower = speed; // Просто задаем мощность
}
Что происходит:
1. Инерция системы:
2. Внешние помехи:
3. Неточность:
Идея: Постоянно проверяем результат и корректируем управление
🎯 Заданная скорость
↓
⚖️ Сравнение ← 📊 Измеренная скорость
↓ ↑
📈 Ошибка ↑
↓ ↑
🔧 Регулятор ↑
↓ ↑
⚡ Управление ↑
↓ ↑
🤖 Робот → 📏 Датчик ------┘
Основные величины:
Формула ошибки:
\[e(t) = r(t) - y(t)\]Цель регулятора: Свести ошибку e(t) к нулю!
Передаточная функция системы:
Для простого мотора с инерцией:
\[H(s) = \frac{K}{Ts + 1}\]где:
Характеристическое уравнение замкнутой системы:
\[1 + G_c(s) \cdot G_p(s) = 0\]где $G_c(s)$ - передаточная функция регулятора, $G_p(s)$ - передаточная функция объекта
Критерии устойчивости:
Качественные показатели:
Принцип: Управление пропорционально ошибке
Формула:
\[u(t) = K_p \cdot e(t)\]где $K_p$ - коэффициент пропорциональности
Алгоритм:
float pController(float setpoint, float measured) {
float error = setpoint - measured;
float output = Kp * error;
return output;
}
Свойства:
Принцип: Учитывает накопленную ошибку за все время
Формула:
\[u(t) = K_i \int_0^t e(\tau) d\tau\]Дискретная реализация:
class IController {
private:
float integral = 0;
float Ki = 0.1;
public:
float calculate(float error, float dt) {
integral += error * dt;
return Ki * integral;
}
};
Свойства:
Принцип: Реагирует на скорость изменения ошибки
Формула:
\[u(t) = K_d \frac{de(t)}{dt}\]Дискретная реализация:
class DController {
private:
float lastError = 0;
float Kd = 0.01;
public:
float calculate(float error, float dt) {
float derivative = (error - lastError) / dt;
lastError = error;
return Kd * derivative;
}
};
Свойства:
Нечеткий (Fuzzy) регулятор:
class FuzzyController {
private:
struct FuzzyRule {
float errorLow, errorHigh;
float outputLow, outputHigh;
};
vector<FuzzyRule> rules;
public:
float calculate(float error) {
float totalWeight = 0;
float weightedSum = 0;
for (auto& rule : rules) {
float membership = getMembership(error, rule.errorLow, rule.errorHigh);
if (membership > 0) {
float output = interpolate(rule.outputLow, rule.outputHigh, membership);
weightedSum += output * membership;
totalWeight += membership;
}
}
return (totalWeight > 0) ? weightedSum / totalWeight : 0;
}
};
Адаптивный регулятор с самонастройкой:
class AdaptivePID {
private:
float Kp, Ki, Kd;
float learningRate = 0.01;
public:
void adaptParameters(float error, float errorRate) {
// Самонастройка на основе поведения системы
if (abs(error) > threshold) {
Kp += learningRate * sign(error * errorRate);
}
if (hasOscillations()) {
Kd += learningRate * 0.1;
}
if (hasSteadyStateError()) {
Ki += learningRate * 0.01;
}
}
};
Формула ПИД-регулятора:
\[u(t) = K_p e(t) + K_i \int_0^t e(\tau)d\tau + K_d \frac{de(t)}{dt}\]Каждый компонент отвечает за свое:
class PIDController {
private:
float Kp, Ki, Kd;
float integral = 0;
float lastError = 0;
unsigned long lastTime = 0;
public:
PIDController(float kp, float ki, float kd) : Kp(kp), Ki(ki), Kd(kd) {}
float calculate(float setpoint, float measured) {
unsigned long now = millis();
float dt = (now - lastTime) / 1000.0; // секунды
if (dt == 0) return 0; // Избегаем деления на ноль
float error = setpoint - measured;
// Пропорциональная составляющая
float P = Kp * error;
// Интегральная составляющая
integral += error * dt;
float I = Ki * integral;
// Дифференциальная составляющая
float derivative = (error - lastError) / dt;
float D = Kd * derivative;
// Итоговое управление
float output = P + I + D;
// Ограничиваем выход
output = constrain(output, -255, 255);
// Запоминаем для следующего раза
lastError = error;
lastTime = now;
return output;
}
void reset() {
integral = 0;
lastError = 0;
lastTime = millis();
}
};
Влияние каждого коэффициента:
| Параметр | Увеличение приводит к: | Побочные эффекты |
|---|---|---|
| Kp | Faster response, Higher overshoot | Instability, Oscillations |
| Ki | Eliminates steady-state error | Slower response, Overshoot |
| Kd | Reduced overshoot, Improved stability | Noise amplification |
Метод настройки Зиглера-Никольса:
ПИД с защитой от wind-up:
class AdvancedPID {
private:
float Kp, Ki, Kd;
float integral = 0;
float lastError = 0;
float maxIntegral = 1000; // Ограничение интеграла
float outputMin = -255, outputMax = 255;
public:
float calculate(float setpoint, float measured, float dt) {
float error = setpoint - measured;
// P-компонент
float P = Kp * error;
// I-компонент с защитой от wind-up
float potentialIntegral = integral + error * dt;
float potentialOutput = P + Ki * potentialIntegral;
if (potentialOutput >= outputMin && potentialOutput <= outputMax) {
integral = potentialIntegral; // Обновляем только если не насыщение
}
integral = constrain(integral, -maxIntegral, maxIntegral);
float I = Ki * integral;
// D-компонент с фильтрацией
float rawDerivative = (error - lastError) / dt;
static float filteredDerivative = 0;
filteredDerivative = 0.8 * filteredDerivative + 0.2 * rawDerivative; // Низкочастотный фильтр
float D = Kd * filteredDerivative;
lastError = error;
float output = P + I + D;
return constrain(output, outputMin, outputMax);
}
};
flowchart TD
A[🎯 Задать целевую скорость] --> B[📏 Измерить текущую скорость]
B --> C[⚖️ Вычислить ошибку<br/>e = target - current]
C --> D[📈 Вычислить управление<br/>u = Kp × e]
D --> E[⚡ Применить к моторам<br/>motor.setPower(u)]
E --> F[⏱️ Ждать интервал Δt]
F --> B
G[🛑 Стоп-условие?] --> H[⏹️ Остановить моторы]
F --> G
G -->|Нет| BВходные данные:
targetSpeed - желаемая скорость (0-100%)Kp - коэффициент пропорциональностиdt - интервал обновления (мс)Выходные данные:
motorPower - мощность мотора (-255 до +255)Алгоритм в коде:
void proportionalSpeedControl() {
// Шаг 1: Инициализация
float targetSpeed = 50.0; // Целевая скорость %
float Kp = 2.0; // Коэффициент
while (true) {
// Шаг 2: Измерение
float currentSpeed = measureSpeed();
// Шаг 3: Вычисление ошибки
float error = targetSpeed - currentSpeed;
// Шаг 4: Регулирование
float motorPower = Kp * error;
// Шаг 5: Ограничение
motorPower = constrain(motorPower, -255, 255);
// Шаг 6: Применение
setMotorPower(motorPower);
// Шаг 7: Ожидание
delay(20); // 50 Hz
// Шаг 8: Проверка условий выхода
if (shouldStop()) break;
}
}
Разработайте блок-схему регулятора скорости для одной из ситуаций:
Группа 1: “Робот-доставщик”
Группа 2: “Робот-пылесос”
Группа 3: “Гоночный робот”
1. [НАЧАЛО]
↓
2. [Инициализация параметров]
↓
3. [Чтение датчиков]
↓
4. [Вычисление ошибки]
↓
5. [Применение алгоритма регулирования]
↓
6. [Ограничение выходного сигнала]
↓
7. [Управление моторами]
↓
8. [Проверка условий]
↓
9. [КОНЕЦ или возврат к п.3]
График 1: Только P-регулятор
Скорость
↑
100%| ╭──── Цель
| ╱
80%| ╱ ╲
| ╱ ╲
60%| ╱ ╲╱╲╱╲ ← Колебания
|╱ ╲
0%└─────────────────→ Время
0 1 2 3 4 5 сек
График 2: P + I регулятор
Скорость
↑
100%| ╭────── Точное достижение цели
| ╱
80%| ╱
| ╱
60%| ╱
| ╱
0%└───╱─────────────→ Время
0 1 2 3 4 5 сек
График 3: ПИД-регулятор
Скорость
↑
100%| ╭──── Быстро и точно
| ╱
80%| ╱
| ╱
60%| ╱
| ╱
0%└╱────────────────→ Время
0 1 2 3 4 5 сек
Ситуация: Робот едет в горку
Плохой регулятор:
Скорость падает и долго восстанавливается
50% → 30% → медленно → 50%
Хороший ПИД-регулятор:
Скорость быстро компенсируется
50% → 45% → быстро → 50%
Код для тестирования:
void testDisturbanceRejection() {
PIDController pid(2.0, 0.1, 0.5);
float targetSpeed = 50.0;
for (int t = 0; t < 100; t++) {
float measuredSpeed = simulateRobot(t);
// Имитируем возмущение на t=50
if (t == 50) {
measuredSpeed -= 20; // Резкое снижение скорости
}
float control = pid.calculate(targetSpeed, measuredSpeed);
Serial.print(t); Serial.print(","); Serial.println(measuredSpeed);
delay(100);
}
}
Характеристический полином замкнутой системы:
Для системы 2-го порядка с ПИД-регулятором:
\[s^3 + (1+K_d)s^2 + K_p s + K_i = 0\]Критерий устойчивости Рауса:
Система устойчива, если все коэффициенты положительны и:
\[(1+K_d) \cdot K_p > K_i\]Оптимальные настройки (метод LQR):
Минимизируем функционал:
\[J = \int_0^{\infty} (x^T Q x + u^T R u) dt\]где Q - матрица весов состояний, R - матрица весов управления
Эксперимент 1: P-регулятор
Эксперимент 2: ПИД-регулятор
Эксперимент 3: “Робот и оператор”
Круиз-контроль:
Код круиз-контроля:
class CruiseControl {
private:
PIDController speedPID;
float targetSpeed;
public:
void update() {
float currentSpeed = getVehicleSpeed();
float throttleCommand = speedPID.calculate(targetSpeed, currentSpeed);
if (throttleCommand > 0) {
setThrottle(throttleCommand);
setBrake(0);
} else {
setThrottle(0);
setBrake(-throttleCommand);
}
}
};
Автопилот:
Манипуляторы:
Системы ориентации:
Основы управления скоростью:
Практические навыки:
Что делает регулятор “умным”:
Тренды в управлении роботами:
1. Блок-схема регулятора Создайте детальную блок-схему пропорционального регулятора для робота, поддерживающего заданную скорость при движении на подъем.
2. Анализ ситуаций Опишите, в каких ситуациях лучше использовать:
3. Блок-схема ПИД-регулятора Разработайте полную блок-схему ПИД-регулятора с учетом всех трех компонентов и их взаимодействия.
4. Исследование применений Найдите примеры использования регуляторов скорости в реальных технических системах (автомобили, дроны, промышленные роботы) и подготовьте краткий обзор.
5. Программная реализация Напишите программу симуляции ПИД-регулятора с возможностью изменения коэффициентов и наблюдения за поведением системы.
6. Настройка параметров Исследуйте различные методы настройки ПИД-регуляторов (Зиглера-Никольса, эмпирические методы) и сравните их эффективность.
Теоретические знания:
Практические навыки:
“Умное управление скоростью - это не просто ‘газ-тормоз’. Это искусство создания системы, которая сама думает, анализирует и корректирует свое поведение для достижения идеального результата!”
Где используются регуляторы скорости:
🎯 Сегодня вы изучили одну из основ современной автоматики!
Теория управления:
Для школьников:
⭐ Для углубленного изучения:
Симуляторы систем управления:
Онлайн-симуляторы:
Успехов в изучении умного управления роботами! ⚙️🤖✨