%% 创建模糊控制器
fis = newfis('desk_lamp_control');
%% 添加输入变量 - 光照偏差 e (单位: lux)
fis = addvar(fis, 'input', 'e', [-200 200]);
fis = addmf(fis, 'input', 1, 'NB', 'zmf', [-200, -100]); % 负大
fis = addmf(fis, 'input', 1, 'NM', 'trimf', [-200, -150, -50]); % 负中
fis = addmf(fis, 'input', 1, 'NS', 'trimf', [-150, -50, 0]); % 负小
fis = addmf(fis, 'input', 1, 'ZO', 'trimf', [-50, 0, 50]); % 零
fis = addmf(fis, 'input', 1, 'PS', 'trimf', [0, 50, 150]); % 正小
fis = addmf(fis, 'input', 1, 'PM', 'trimf', [50, 150, 200]); % 正中
fis = addmf(fis, 'input', 1, 'PB', 'smf', [100, 200]); % 正大
%% 添加输入变量 - 偏差变化率 ec (单位: lux/s)
fis = addvar(fis, 'input', 'ec', [-50 50]);
fis = addmf(fis, 'input', 2, 'NB', 'zmf', [-50, -25]); % 负大
fis = addmf(fis, 'input', 2, 'NM', 'trimf', [-50, -30, -10]); % 负中
fis = addmf(fis, 'input', 2, 'NS', 'trimf', [-30, -10, 0]); % 负小
fis = addmf(fis, 'input', 2, 'ZO', 'trimf', [-10, 0, 10]); % 零
fis = addmf(fis, 'input', 2, 'PS', 'trimf', [0, 10, 30]); % 正小
fis = addmf(fis, 'input', 2, 'PM', 'trimf', [10, 30, 50]); % 正中
fis = addmf(fis, 'input', 2, 'PB', 'smf', [25, 50]); % 正大
%% 添加输出变量 - 亮度控制信号 u (单位: %)
fis = addvar(fis, 'output', 'u', [0 100]); % 0-100%亮度
fis = addmf(fis, 'output', 1, 'NB', 'zmf', [0, 20]); % 低亮度
fis = addmf(fis, 'output', 1, 'NM', 'trimf', [0, 20, 40]); % 中低亮度
fis = addmf(fis, 'output', 1, 'NS', 'trimf', [20, 40, 60]); % 偏低亮度
fis = addmf(fis, 'output', 1, 'ZO', 'trimf', [40, 50, 60]); % 适中亮度
fis = addmf(fis, 'output', 1, 'PS', 'trimf', [40, 60, 80]); % 偏高亮度
fis = addmf(fis, 'output', 1, 'PM', 'trimf', [60, 80, 100]);% 中高亮度
fis = addmf(fis, 'output', 1, 'PB', 'smf', [80, 100]); % 高亮度
%% 模糊规则表 - 49条规则
% 规则格式: [输入1 输入2 输出 权重 运算符(1=AND)]
ruleList = [
% e\ec | NB NM NS ZO PS PM PB
% --------------------------------
1 1 7 1 1; % 如果 光照偏差「负大」且 偏差变化率「负大」→ 亮度控制「正大」
1 2 7 1 1; % 如果 光照偏差「负大」且 偏差变化率「负中」→ 亮度控制「正大」
1 3 7 1 1; % 如果 光照偏差「负大」且 偏差变化率「负小」→ 亮度控制「正大」
1 4 6 1 1; % 如果 光照偏差「负大」且 偏差变化率「零」→ 亮度控制「正中」
1 5 6 1 1; % 如果 光照偏差「负大」且 偏差变化率「正小」→ 亮度控制「正中」
1 6 5 1 1; % 如果 光照偏差「负大」且 偏差变化率「正中」→ 亮度控制「正小」
1 7 5 1 1; % 如果 光照偏差「负大」且 偏差变化率「正大」→ 亮度控制「正小」
2 1 7 1 1; % 如果 光照偏差「负中」且 偏差变化率「负大」→ 亮度控制「正大」
2 2 7 1 1; % 如果 光照偏差「负中」且 偏差变化率「负中」→ 亮度控制「正大」
2 3 6 1 1; % 如果 光照偏差「负中」且 偏差变化率「负小」→ 亮度控制「正中」
2 4 6 1 1; % 如果 光照偏差「负中」且 偏差变化率「零」→ 亮度控制「正中」
2 5 5 1 1; % 如果 光照偏差「负中」且 偏差变化率「正小」→ 亮度控制「正小」
2 6 4 1 1; % 如果 光照偏差「负中」且 偏差变化率「正中」→ 亮度控制「适中」
2 7 4 1 1; % 如果 光照偏差「负中」且 偏差变化率「正大」→ 亮度控制「适中」
3 1 7 1 1; % 如果 光照偏差「负小」且 偏差变化率「负大」→ 亮度控制「正大」
3 2 6 1 1; % 如果 光照偏差「负小」且 偏差变化率「负中」→ 亮度控制「正中」
3 3 6 1 1; % 如果 光照偏差「负小」且 偏差变化率「负小」→ 亮度控制「正中」
3 4 5 1 1; % 如果 光照偏差「负小」且 偏差变化率「零」→ 亮度控制「正小」
3 5 4 1 1; % 如果 光照偏差「负小」且 偏差变化率「正小」→ 亮度控制「适中」
3 6 4 1 1; % 如果 光照偏差「负小」且 偏差变化率「正中」→ 亮度控制「适中」
3 7 3 1 1; % 如果 光照偏差「负小」且 偏差变化率「正大」→ 亮度控制「偏低」
4 1 6 1 1; % 如果 光照偏差「零」且 偏差变化率「负大」→ 亮度控制「正中」
4 2 5 1 1; % 如果 光照偏差「零」且 偏差变化率「负中」→ 亮度控制「正小」
4 3 5 1 1; % 如果 光照偏差「零」且 偏差变化率「负小」→ 亮度控制「正小」
4 4 4 1 1; % 如果 光照偏差「零」且 偏差变化率「零」→ 亮度控制「适中」
4 5 3 1 1; % 如果 光照偏差「零」且 偏差变化率「正小」→ 亮度控制「偏低」
4 6 3 1 1; % 如果 光照偏差「零」且 偏差变化率「正中」→ 亮度控制「偏低」
4 7 2 1 1; % 如果 光照偏差「零」且 偏差变化率「正大」→ 亮度控制「中低」
5 1 5 1 1; % 如果 光照偏差「正小」且 偏差变化率「负大」→ 亮度控制「正小」
5 2 4 1 1; % 如果 光照偏差「正小」且 偏差变化率「负中」→ 亮度控制「适中」
5 3 4 1 1; % 如果 光照偏差「正小」且 偏差变化率「负小」→ 亮度控制「适中」
5 4 3 1 1; % 如果 光照偏差「正小」且 偏差变化率「零」→ 亮度控制「偏低」
5 5 3 1 1; % 如果 光照偏差「正小」且 偏差变化率「正小」→ 亮度控制「偏低」
5 6 2 1 1; % 如果 光照偏差「正小」且 偏差变化率「正中」→ 亮度控制「中低」
5 7 2 1 1; % 如果 光照偏差「正小」且 偏差变化率「正大」→ 亮度控制「中低」
6 1 4 1 1; % 如果 光照偏差「正中」且 偏差变化率「负大」→ 亮度控制「适中」
6 2 4 1 1; % 如果 光照偏差「正中」且 偏差变化率「负中」→ 亮度控制「适中」
6 3 3 1 1; % 如果 光照偏差「正中」且 偏差变化率「负小」→ 亮度控制「偏低」
6 4 3 1 1; % 如果 光照偏差「正中」且 偏差变化率「零」→ 亮度控制「偏低」
6 5 2 1 1; % 如果 光照偏差「正中」且 偏差变化率「正小」→ 亮度控制「中低」
6 6 2 1 1; % 如果 光照偏差「正中」且 偏差变化率「正中」→ 亮度控制「中低」
6 7 1 1 1; % 如果 光照偏差「正中」且 偏差变化率「正大」→ 亮度控制「低」
7 1 3 1 1; % 如果 光照偏差「正大」且 偏差变化率「负大」→ 亮度控制「偏低」
7 2 3 1 1; % 如果 光照偏差「正大」且 偏差变化率「负中」→ 亮度控制「偏低」
7 3 2 1 1; % 如果 光照偏差「正大」且 偏差变化率「负小」→ 亮度控制「中低」
7 4 2 1 1; % 如果 光照偏差「正大」且 偏差变化率「零」→ 亮度控制「中低」
7 5 1 1 1; % 如果 光照偏差「正大」且 偏差变化率「正小」→ 亮度控制「低」
7 6 1 1 1; % 如果 光照偏差「正大」且 偏差变化率「正中」→ 亮度控制「低」
7 7 1 1 1; % 如果 光照偏差「正大」且 偏差变化率「正大」→ 亮度控制「低」
];
%% 添加规则并设置解模糊方法
fis = addrule(fis, ruleList);
fis = setfis(fis, 'DefuzzMethod', 'centroid');
%% 保存模糊控制器
writefis(fis, 'desk_lamp_fis.fis');
%% 可视化模糊系统
figure('Name', '台灯光照控制系统结构', 'Position', [100, 100, 800, 600]);
plotfis(fis);
title('台灯光照模糊控制系统结构图');
%% 可视化隶属度函数
figure('Name', '隶属度函数', 'Position', [100, 100, 1200, 800]);
% 光照偏差 e 的隶属度函数
subplot(3,1,1);
plotmf(fis, 'input', 1);
title('光照偏差 (e) 的隶属度函数');
xlabel('偏差 (lux)');
ylabel('隶属度');
grid on;
% 偏差变化率 ec 的隶属度函数
subplot(3,1,2);
plotmf(fis, 'input', 2);
title('偏差变化率 (ec) 的隶属度函数');
xlabel('变化率 (lux/s)');
ylabel('隶属度');
grid on;
% 控制信号 u 的隶属度函数
subplot(3,1,3);
plotmf(fis, 'output', 1);
title('亮度控制信号 (u) 的隶属度函数');
xlabel('控制量 (%)');
ylabel('隶属度');
grid on;
%% 仿真测试
fis = readfis('desk_lamp_fis.fis');
% 仿真参数
t = 0:0.1:60; % 60秒仿真时间
e = zeros(size(t));
ec = zeros(size(t));
u = zeros(size(t));
brightness = zeros(size(t)); % 台灯亮度
illuminance = zeros(size(t)); % 工作区域照度
% 设定值变化 (标准工作照度500lux)
setpoint = 500 * ones(size(t));
setpoint(t>=10 & t<20) = 600; % 阅读模式
setpoint(t>=30 & t<40) = 400; % 休息模式
% 环境光照变化 (模拟外部光线变化)
ambient_light = 100 * ones(size(t));
ambient_light(t>15 & t<=25) = 300; % 15-25秒: 外部强光
ambient_light(t>35 & t<=45) = 50; % 35-45秒: 外部弱光
% 系统初始状态
illuminance(1) = 300; % 初始照度
brightness(1) = 50; % 初始亮度50%
% 系统参数
K = 0.8; % 系统增益
tau = 0.5; % 响应时间常数
min_brightness = 10; % 最小亮度限制
max_brightness = 100;% 最大亮度限制
% 仿真循环
for i = 2:length(t)
% 计算光照偏差和变化率
e(i) = setpoint(i) - illuminance(i-1);
ec(i) = (e(i) - e(i-1)) / 0.1; % 采样时间0.1秒
% 模糊推理
u(i) = evalfis(fis, [e(i), ec(i)]);
% 确保控制信号在合理范围内
u(i) = max(min(u(i), max_brightness), min_brightness);
% 更新台灯亮度 (一阶惯性)
brightness(i) = brightness(i-1) + 0.1 * (u(i) - brightness(i-1)) / tau;
% 计算工作区域照度 (台灯贡献 + 环境光)
illuminance(i) = brightness(i) * 5 + ambient_light(i);
% 添加测量噪声
illuminance(i) = illuminance(i) + randn() * 2;
end
%% 绘制仿真结果(带位置跟踪图)
figure('Position', [100, 100, 1200, 1000]); % 调整窗口尺寸
% 1. 主位置跟踪图(设定值与实际值对比)
subplot(4,1,1);
hold on;
% 绘制设定照度(红色虚线)
plot(t, setpoint, 'r--', 'LineWidth', 2, 'DisplayName', '设定照度');
% 绘制实际照度(蓝色实线)
plot(t, illuminance, 'b-', 'LineWidth', 1.5, 'DisplayName', '实际照度');
% 添加图例和标题
title('光照设定值与实际值位置跟踪图');
xlabel('时间 (秒)');
ylabel('照度 (lux)');
legend('Location', 'best');
grid on;
ylim([0, 700]);
% 2. 光照强度细节图(含环境光)
subplot(4,1,2);
hold on;
plot(t, setpoint, 'r--', 'LineWidth', 2, 'DisplayName', '设定照度');
plot(t, illuminance, 'b-', 'LineWidth', 1.5, 'DisplayName', '实际照度');
plot(t, ambient_light, 'g-.', 'LineWidth', 1.2, 'DisplayName', '环境光照');
title('工作区域光照强度分析');
xlabel('时间 (秒)');
ylabel('照度 (lux)');
legend('Location', 'best');
grid on;
ylim([0, 700]);
% 3. 台灯亮度控制图
subplot(4,1,3);
plot(t, brightness, 'm-', 'LineWidth', 1.5);
title('台灯亮度控制信号');
xlabel('时间 (秒)');
ylabel('亮度 (%)');
grid on;
ylim([0, 100]);
% 4. 偏差及变化率图
subplot(4,1,4);
yyaxis left;
plot(t, e, 'g-', 'LineWidth', 1.5);
ylabel('光照偏差 (lux)');
yyaxis right;
plot(t, ec, 'c-', 'LineWidth', 1.5);
ylabel('偏差变化率 (lux/s)');
title('偏差及变化率动态响应');
xlabel('时间 (秒)');
grid on;
%% 性能指标计算
% 计算10秒处阶跃响应指标
idx_step = find(t >= 10, 1);
response = illuminance(idx_step:end);
time_step = t(idx_step:end) - t(idx_step);
% 稳态值
steady_state = mean(response(end-50:end));
% 上升时间 (10% 到 90%)
target_change = 100; % 500→600的阶跃幅度
rise_time_low = 500 + 0.1 * target_change;
rise_time_high = 500 + 0.9 * target_change;
idx_10 = find(response >= rise_time_low, 1);
idx_90 = find(response >= rise_time_high, 1);
if ~isempty(idx_10) && ~isempty(idx_90)
rise_time = time_step(idx_90) - time_step(idx_10);
else
rise_time = NaN;
end
% 超调量计算
if ~isempty(idx_90)
overshoot = max(response(idx_90:end)) - 600;
overshoot_percent = (overshoot / target_change) * 100;
else
overshoot_percent = NaN;
end
% 稳态误差
steady_error = abs(600 - mean(response(end-50:end)));
% 显示性能指标
fprintf('【控制系统性能指标】\n');
fprintf('上升时间: %.2f 秒\n', rise_time);
fprintf('超调量: %.2f%%\n', overshoot_percent);
fprintf('稳态误差: %.2f lux\n', steady_error);
%% 能耗分析
power_consumption = brightness.^2 * 0.1; % 假设功率与亮度平方成正比
avg_power = mean(power_consumption);
power_variation = std(power_consumption(t>20 & t<30)); % 稳态波动
fprintf('\n【能耗分析】\n');
fprintf('平均功率: %.2f W\n', avg_power);
fprintf('稳态功率波动: %.2f%%\n', (power_variation/avg_power)*100);
%% 保存模糊控制器并绘制功率消耗图
writefis(fis, 'bedside_light_fis.fis');
figure;
plot(t, power_consumption, 'LineWidth', 1.5);
title('台灯功率消耗曲线');
xlabel('时间 (秒)');
ylabel('功率 (W)');
grid on;优化一下使实际线条与设定值跟踪更近一些并且实际线条更直一些
最新发布