Files
UPP/MATLAB/upp_demo.m
Razvalyaev 19ce761264 Первый запуск в реале. Всякие фиксы
Тесты происходили на двух двигателях и трансе через ЛАТР
2026-02-12 17:29:52 +03:00

450 lines
19 KiB
Matlab
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
%% Скрипт визуализации тиристорного устройства плавного пуска
% Автоматически создает графики входных и выходных напряжений
% с возможностью изменения угла открытия тиристоров
%% Основные параметры системы
clear; close all; clc;
% Параметры сети
f = 50; % Частота, Гц
T = 1/f; % Период, с
U_phase = 220; % Фазное напряжение (действующее), В
U_line = U_phase*sqrt(3); % Линейное напряжение (действующее), В
% Временной вектор
t = linspace(0, 3*T, 1000); % 3 периода
% Начальный угол открытия (градусы)
alpha_deg = 30;
alpha_rad = deg2rad(alpha_deg);
%% Создание графического интерфейса
fig = figure('Name', 'Тиристорное устройство плавного пуска', ...
'Position', [100, 100, 1200, 800], ...
'NumberTitle', 'off');
% Создание панели для ползунка
control_panel = uipanel('Title', 'Управление', ...
'Position', [0.75, 0.85, 0.23, 0.14]);
% Текст с текущим значением угла
angle_text = uicontrol('Parent', control_panel, ... % Добавляем Parent
'Style', 'text', ...
'String', sprintf('Угол α = %d°', alpha_deg), ...
'Units', 'normalized', ...
'Position', [0.05, 0.6, 0.9, 0.3], ... % Относительно панели
'FontSize', 12, 'FontWeight', 'bold');
% Ползунок для управления углом
slider = uicontrol('Parent', control_panel, ... % Добавляем Parent
'Style', 'slider', ...
'Min', -30, 'Max', 180, 'Value', alpha_deg, ...
'Units', 'normalized', ...
'Position', [0.05, 0.1, 0.9, 0.4], ... % Относительно панели
'Callback', @set_alpha);
%% Создание осей для графиков
% Входные напряжения (фазные и линейные на одном графике)
ax1 = subplot(3, 1, 1); % Было (3, 2, 1)
title('Входные напряжения');
xlabel('Время, с');
ylabel('Напряжение, В');
grid on; hold on;
% Выходные линейные напряжения
ax3 = subplot(3, 1, 3); % Было (3, 2, [3, 4])
title('Выходные линейные напряжения (после тиристоров)');
xlabel('Время, с');
ylabel('Напряжение, В');
grid on; hold on;
% Визуализация открытия тиристоров
ax4 = subplot(3, 1, 2); % Было (3, 2, [5, 6])
title('Состояние тиристоров');
xlabel('Время, с');
ylabel('Тиристор');
grid on; hold on;
ylim([0.5, 6.5]);
yticks(1:6);
yticklabels({'VS1+', 'VS1-', 'VS2+', 'VS2-', 'VS3+', 'VS3-'});
%% Инициализация графиков
% Обновляем графики с начальными значениями
update_plots(alpha_deg, alpha_rad, t, f, U_phase, U_line, angle_text);
%% Пояснительная информация
disp('===============================================');
disp('ТИРИСТОРНОЕ УСТРОЙСТВО ПЛАВНОГО ПУСКА');
disp('===============================================');
disp('Управление:');
disp(' - Используйте ползунок для изменения угла α от 0° до 180°');
disp(' - α = 0° - полное напряжение на выходе');
disp(' - α = 90° - половина напряжения на выходе');
disp(' - α = 180° - напряжение отключено');
disp(' ');
disp('Обозначения тиристоров:');
disp(' VS1+ - тиристор положительной полуволны фазы A');
disp(' VS1- - тиристор отрицательной полуволны фазы A');
disp(' VS2+ - тиристор положительной полуволны фазы B');
disp(' VS2- - тиристор отрицательной полуволны фазы B');
disp(' VS3+ - тиристор положительной полуволны фазы C');
disp(' VS3- - тиристор отрицательной полуволны фазы C');
%% Функция обновления графиков
function update_plots(alpha_deg, alpha_rad, t, f, U_phase, U_line, angle_text)
% Расчет синусоидальных напряжений
omega = 2*pi*f;
% Входные фазные напряжения
Ua = U_phase*sqrt(2)*sin(omega*t);
Ub = U_phase*sqrt(2)*sin(omega*t - 2*pi/3);
Uc = U_phase*sqrt(2)*sin(omega*t + 2*pi/3);
% Входные линейные напряжения
Uab_in = Ua - Ub;
Ubc_in = Ub - Uc;
Uca_in = Uc - Ua;
% Выходные линейные напряжения (после тиристоров)
Uab_out = zeros(size(t));
Ubc_out = zeros(size(t));
Uca_out = zeros(size(t));
% Состояния тиристоров (1 - открыт, 0 - закрыт)
thyristor_state = zeros(6, length(t));
% Физическое состояние тиристоров (1 - открыт, 0 - закрыт)
thyristor_conducting = zeros(6, length(t));
% Для каждого момента времени определяем состояние тиристоров
for i = 1:length(t)
% Фазовый угол для каждой фазы
theta = omega*t(i);
theta_a = theta;
theta_b = theta - 2*pi/3;
theta_c = theta + 2*pi/3;
% Модулированные углы (для определения полуволны)
theta_a_mod = mod(theta_a, 2*pi);
theta_b_mod = mod(theta_b, 2*pi);
theta_c_mod = mod(theta_c, 2*pi);
%% 1. Определяем, когда ПОДАНЫ управляющие импульсы
% Исправление для поддержки отрицательных углов
% VS1+ (положительная полуволна фазы A)
% Нормализуем угол: если alpha_rad < 0, добавляем 2π для корректной работы
alpha_norm = mod(alpha_rad, 2*pi);
pulse_start = alpha_norm;
pulse_end = pulse_start + 3*pi/4;
% Проверяем два случая: импульс в пределах одного периода
% и импульс, пересекающий границу 2π
if pulse_end <= 2*pi
% Импульс не пересекает границу периода
if theta_a_mod >= pulse_start && theta_a_mod <= pulse_end
thyristor_state(1, i) = 1;
end
else
% Импульс пересекает границу периода (pulse_end > 2π)
% Импульс состоит из двух частей: [pulse_start, 2π) и [0, pulse_end-2π]
if theta_a_mod >= pulse_start || theta_a_mod <= pulse_end - 2*pi
thyristor_state(1, i) = 1;
end
end
% VS1- (отрицательная полуволна фазы A)
pulse_start_neg = pi + alpha_norm;
pulse_end_neg = pulse_start_neg + 3*pi/4;
% Нормализуем start_neg и end_neg к диапазону [0, 4π)
if pulse_start_neg >= 2*pi
pulse_start_neg = pulse_start_neg - 2*pi;
pulse_end_neg = pulse_end_neg - 2*pi;
end
if pulse_end_neg <= 2*pi
if theta_a_mod >= pulse_start_neg && theta_a_mod <= pulse_end_neg
thyristor_state(2, i) = 1;
end
else
% Импульс пересекает границу периода
if theta_a_mod >= pulse_start_neg || theta_a_mod <= pulse_end_neg - 2*pi
thyristor_state(2, i) = 1;
end
end
% VS2+ (положительная полуволна фазы B)
pulse_start = alpha_norm;
pulse_end = pulse_start + 3*pi/4;
if pulse_end <= 2*pi
if theta_b_mod >= pulse_start && theta_b_mod <= pulse_end
thyristor_state(3, i) = 1;
end
else
if theta_b_mod >= pulse_start || theta_b_mod <= pulse_end - 2*pi
thyristor_state(3, i) = 1;
end
end
% VS2- (отрицательная полуволна фазы B)
pulse_start_neg = pi + alpha_norm;
pulse_end_neg = pulse_start_neg + 3*pi/4;
% Нормализуем start_neg и end_neg к диапазону [0, 4π)
if pulse_start_neg >= 2*pi
pulse_start_neg = pulse_start_neg - 2*pi;
pulse_end_neg = pulse_end_neg - 2*pi;
end
if pulse_end_neg <= 2*pi
if theta_b_mod >= pulse_start_neg && theta_b_mod <= pulse_end_neg
thyristor_state(4, i) = 1;
end
else
if theta_b_mod >= pulse_start_neg || theta_b_mod <= pulse_end_neg - 2*pi
thyristor_state(4, i) = 1;
end
end
% VS3+ (положительная полуволна фазы C)
pulse_start = alpha_norm;
pulse_end = pulse_start + 3*pi/4;
if pulse_end <= 2*pi
if theta_c_mod >= pulse_start && theta_c_mod <= pulse_end
thyristor_state(5, i) = 1;
end
else
if theta_c_mod >= pulse_start || theta_c_mod <= pulse_end - 2*pi
thyristor_state(5, i) = 1;
end
end
% VS3- (отрицательная полуволна фазы C)
pulse_start_neg = pi + alpha_norm;
pulse_end_neg = pulse_start_neg + 3*pi/4;
% Нормализуем start_neg и end_neg к диапазону [0, 4π)
if pulse_start_neg >= 2*pi
pulse_start_neg = pulse_start_neg - 2*pi;
pulse_end_neg = pulse_end_neg - 2*pi;
end
if pulse_end_neg <= 2*pi
if theta_c_mod >= pulse_start_neg && theta_c_mod <= pulse_end_neg
thyristor_state(6, i) = 1;
end
else
if theta_c_mod >= pulse_start_neg || theta_c_mod <= pulse_end_neg - 2*pi
thyristor_state(6, i) = 1;
end
end
%% 2. Определяем, когда тиристоры ФИЗИЧЕСКИ открыты
% В схеме без нейтрали тиристоры открываются парами (фаза-фаза)
% Пары тиристоров для линейных напряжений:
% Uab: VS1+ (A+) и VS4- (B-)
% Uba: VS3+ (B+) и VS2- (A-)
% Ubc: VS3+ (B+) и VS6- (C-)
% Ucb: VS5+ (C+) и VS4- (B-)
% Uca: VS5+ (C+) и VS2- (A-)
% Uac: VS1+ (A+) и VS6- (C-)
% Проверяем каждую пару
% Пара A+ и B- (Uab)
if thyristor_state(1, i) == 1 && thyristor_state(4, i) == 1 && Ua(i) > Ub(i)
thyristor_conducting(1, i) = 1;
thyristor_conducting(4, i) = 1;
elseif i > 1 && thyristor_conducting(1, i-1) == 1 && thyristor_conducting(4, i-1) == 1
if Ua(i) > Ub(i)
thyristor_conducting(1, i) = 1;
thyristor_conducting(4, i) = 1;
end
end
% Пара B+ и A- (Uba)
if thyristor_state(3, i) == 1 && thyristor_state(2, i) == 1 && Ub(i) > Ua(i)
thyristor_conducting(3, i) = 1;
thyristor_conducting(2, i) = 1;
elseif i > 1 && thyristor_conducting(3, i-1) == 1 && thyristor_conducting(2, i-1) == 1
if Ub(i) > Ua(i)
thyristor_conducting(3, i) = 1;
thyristor_conducting(2, i) = 1;
end
end
% Пара B+ и C- (Ubc)
if thyristor_state(3, i) == 1 && thyristor_state(6, i) == 1 && Ub(i) > Uc(i)
thyristor_conducting(3, i) = 1;
thyristor_conducting(6, i) = 1;
elseif i > 1 && thyristor_conducting(3, i-1) == 1 && thyristor_conducting(6, i-1) == 1
if Ub(i) > Uc(i)
thyristor_conducting(3, i) = 1;
thyristor_conducting(6, i) = 1;
end
end
% Пара C+ и B- (Ucb)
if thyristor_state(5, i) == 1 && thyristor_state(4, i) == 1 && Uc(i) > Ub(i)
thyristor_conducting(5, i) = 1;
thyristor_conducting(4, i) = 1;
elseif i > 1 && thyristor_conducting(5, i-1) == 1 && thyristor_conducting(4, i-1) == 1
if Uc(i) > Ub(i)
thyristor_conducting(5, i) = 1;
thyristor_conducting(4, i) = 1;
end
end
% Пара C+ и A- (Uca)
if thyristor_state(5, i) == 1 && thyristor_state(2, i) == 1 && Uc(i) > Ua(i)
thyristor_conducting(5, i) = 1;
thyristor_conducting(2, i) = 1;
elseif i > 1 && thyristor_conducting(5, i-1) == 1 && thyristor_conducting(2, i-1) == 1
if Uc(i) > Ua(i)
thyristor_conducting(5, i) = 1;
thyristor_conducting(2, i) = 1;
end
end
% Пара A+ и C- (Uac)
if thyristor_state(1, i) == 1 && thyristor_state(6, i) == 1 && Ua(i) > Uc(i)
thyristor_conducting(1, i) = 1;
thyristor_conducting(6, i) = 1;
elseif i > 1 && thyristor_conducting(1, i-1) == 1 && thyristor_conducting(6, i-1) == 1
if Ua(i) > Uc(i)
thyristor_conducting(1, i) = 1;
thyristor_conducting(6, i) = 1;
end
end
%% 3. Расчет выходных напряжений
% Фазные выходные напряжения
Ua_out = 0;
if thyristor_conducting(1, i) || thyristor_conducting(2, i)
Ua_out = Ua(i);
end
Ub_out = 0;
if thyristor_conducting(3, i) || thyristor_conducting(4, i)
Ub_out = Ub(i);
end
Uc_out = 0;
if thyristor_conducting(5, i) || thyristor_conducting(6, i)
Uc_out = Uc(i);
end
% Линейные выходные напряжения
Uab_out(i) = Ua_out - Ub_out;
Ubc_out(i) = Ub_out - Uc_out;
Uca_out(i) = Uc_out - Ua_out;
end
%% Обновление графиков (ВАЖНО: без изменений!)
% Входные фазные напряжения
subplot(3, 1, 1);
cla; grid on; hold on;
plot(t, zeros(size(t)), 'k', 'LineWidth', 0.5);
plot(t, Ua, 'r', 'LineWidth', 2, 'DisplayName', 'Фаза A');
plot(t, Ub, 'g', 'LineWidth', 2, 'DisplayName', 'Фаза B');
plot(t, Uc, 'b', 'LineWidth', 2, 'DisplayName', 'Фаза C');
plot(t, Uab_in, 'r--', 'LineWidth', 0.5, 'DisplayName', 'Uab');
plot(t, Ubc_in, 'g--', 'LineWidth', 0.5, 'DisplayName', 'Ubc');
plot(t, Uca_in, 'b--', 'LineWidth', 0.5, 'DisplayName', 'Uca');
title('Входные напряжения (сплошные - фазные, пунктир - линейные)');
xlabel('Время, с');
ylabel('Напряжение, В');
legend('Location', 'west');
xlim([0, max(t)]);
ylim([-700, 700]);
% Выходные линейные напряжения
subplot(3, 1, 3);
cla; grid on; hold on;
plot(t, zeros(size(t)), 'k', 'LineWidth', 0.5);
plot(t, Uab_out, 'r', 'LineWidth', 1.5, 'DisplayName', 'Uab вых');
plot(t, Ubc_out, 'g', 'LineWidth', 1.5, 'DisplayName', 'Ubc вых');
plot(t, Uca_out, 'b', 'LineWidth', 1.5, 'DisplayName', 'Uca вых');
title(sprintf('Выходные линейные напряжения (α = %d°)', alpha_deg));
xlabel('Время, с');
ylabel('Напряжение, В');
legend('Location', 'west');
xlim([0, max(t)]);
ylim([-700, 700]);
% Визуализация состояния тиристоров - показываем управляющие импульсы
subplot(3, 1, 2);
cla; grid on; hold on;
% Цвета для тиристоров
colors = {'r', 'r', 'g', 'g', 'b', 'b'};
line_styles = {'-', '--', '-', '--', '-', '--'};
names = {'VS1+', 'VS1-', 'VS2+', 'VS2-', 'VS3+', 'VS3-'};
% Измененный порядок отрисовки: VS1+, VS1-, VS2+, VS2-, VS3+, VS3-
order = [6, 5, 4, 3, 2, 1];
for idx = 1:6
k = order(idx); % Берем тиристор в нужном порядке
% Находим интервалы, где подан управляющий импульс
state = thyristor_state(k, :);
diff_state = diff([0, state, 0]);
start_idx = find(diff_state == 1);
end_idx = find(diff_state == -1) - 1;
% Рисуем горизонтальные линии для каждого интервала
for m = 1:length(start_idx)
plot(t(start_idx(m):end_idx(m)), idx*ones(1, length(start_idx(m):end_idx(m))), ...
'Color', colors{k}, 'LineStyle', line_styles{k}, 'LineWidth', 1);
end
% Находим интервалы, где тиристор открыт
state = thyristor_conducting(k, :);
diff_state = diff([0, state, 0]);
start_idx = find(diff_state == 1);
end_idx = find(diff_state == -1) - 1;
% Рисуем горизонтальные линии для каждого интервала
for m = 1:length(start_idx)
plot(t(start_idx(m):end_idx(m)), idx*ones(1, length(start_idx(m):end_idx(m))), ...
'Color', colors{k}, 'LineStyle', line_styles{k}, 'LineWidth', 2);
end
end
title(sprintf('Управляющие импульсы тиристоров (α = %d°)', alpha_deg));
xlabel('Время, с');
ylabel('Тиристор');
ylim([0.5, 6.5]);
yticks(1:6);
yticklabels(names(order));
xlim([0, max(t)]);
% Обновление текста с текущим углом
set(angle_text, 'String', sprintf('Угол α = %d°', alpha_deg));
end
%% Функция обратного вызова для ползунка
function set_alpha(source, ~)
% Получаем значение из ползунка
alpha_deg = round(get(source, 'Value'));
% Обновляем глобальные переменные
evalin('base', sprintf('alpha_deg = %d;', alpha_deg));
evalin('base', 'alpha_rad = deg2rad(alpha_deg);');
% Получаем ссылки на переменные из базового рабочего пространства
t = evalin('base', 't');
f = evalin('base', 'f');
U_phase = evalin('base', 'U_phase');
U_line = evalin('base', 'U_line');
angle_text = evalin('base', 'angle_text');
% Обновляем графики
update_plots(alpha_deg, deg2rad(alpha_deg), t, f, U_phase, U_line, angle_text);
end