Matlab使用m文件调用simulink(附matlab代码)

本文介绍如何使用Matlab的遗传算法来优化Simulink模型中的参数,通过反复迭代找到最优参数组合,使得模型输出与目标值之间的误差最小。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

B站讲解视频
我就是按这个视频写的代码
我用simulink打了一个简单地模型,希望用遗传算法识别模型中的参数。
实现这个目的得流程是将simulink模型中的参数设为变量,每运行一次模型就将结果和对应的参数值读取到matlab中,然后通过遗传算法计算更优参数值,再将参数值赋给模型重新计算,得到结果开始循环。
在这里插入图片描述假如不想自己搭模型可以直接用我的,
链接:https://pan.baidu.com/s/1di1_5vJIZXUdWTOsw_EPvA
提取码:7788
–来自百度网盘超级会员V5的分享
如果要自己搭模型的话记得按视频里的操作进行设置。

我真的好心烦csdn传资源这个事,这不是一个分享平台吗,我把我的学习资源传上来供大家学习,结果其他人想下载还要充会员,甚至有的充了会员还要花钱下载。有时候看一篇博客,博主说欢迎大家下载他的文件,大家一起学习交流,结果一点开需要花钱才能下,博主自己知道自己的资源需要别人花钱才能下载吗,给博主分成是多少啊。
要是博主自己要收钱那无可厚非,可我的资源是想无偿给大家的啊,而且我一个资源分享者都无法评论我的资源,要下载后才能评论,真是离谱,一个好端端的分享平台竟然干这事。
所以我把资源放在百度网盘里了,大家可以免费下载。

评论说链接挂掉了,很奇怪我明明选的是永久有效,我再放一个新的
链接:https://pan.baidu.com/s/1Bx5lbmHrHxEBMFJTySp7TQ
提取码:qtyt
–来自百度网盘超级会员V6的分享

然后这是使用的matlab代码

clc
close all
clear
mdlName = 'model';
%参数标准值
b1_ref = 1;
b2_ref = 1;
a11_ref = 0.4;
a12_ref = 0.4;
a21_ref = 0.2;
a22_ref = 0.2;

b1_test = 0;
b2_test = 0;
a11_test = 0;
a12_test = 0;
a21_test = 0;
a22_test = 0;


% 参数范围,按照b1,b2,a11,a12,a21,a22的顺序
lb = [0,0,0,0,0,0];
ub = [2,2,1,1,0.5,0.5];

% 种群数量
popSize = 50;

% 迭代次数
maxGen = 100;

% 交叉率
crossRate = 0.9;

% 变异率
mutationRate = 0.1;

% 初始化种群
pop = rand(popSize,6).*(ub-lb)+lb;
fitness = zeros(popSize,maxGen+1);
n = 0;%记录最优适应度相同的次数
fitnessmax = 0;%记录最优适应度
% 迭代
for i = 1:maxGen
    mutationRate = 0.1;
    
    
    for j = 1:popSize
        b1 = pop(j,1);
        b2 = pop(j,2);
        a11 = pop(j,3);
        a12 = pop(j,4);
        a21 = pop(j,5);
        a22 = pop(j,6);

        % 评估适应度
        load_system(mdlName);
        cs = getActiveConfigSet(mdlName);
        model_cs = cs.copy;
        simOut = sim(mdlName,model_cs);
        x1 = simOut.logsout{1}.Values.Data;
        x2 = simOut.logsout{2}.Values.Data;
        x1_ref = simOut.logsout{3}.Values.Data;
        x2_ref = simOut.logsout{4}.Values.Data;
        fitness(j,i) = fun(x1,x1_ref,x2,x2_ref);
    end
    
    % 选择操作
    [~,index] = sort(fitness(:,i));
    if fitnessmax == fitness(index(1))
        n = n+1;
    else
        n = 0;
    end
    fitnessmax = fitness(index(1));%更新最佳适应度
    parents = pop(index(1:popSize/2),:);
    
    % 交叉操作
    offsprings = zeros(popSize/2,6);
    for j = 1:popSize/2
        if rand < crossRate
            parent1 = parents(randi(popSize/2),:);
            parent2 = parents(randi(popSize/2),:);
            nums = randperm(6, 3);
            %将两个亲代的三个随机基因进行交换
            for m = 1:length(nums)
                parent1(nums(m)) = parent2(nums(m));
            end
            offsprings(j,:) = parent1;
        else
            offsprings(j,:) = parents(randi(popSize/2),:);
        end
    end
    
    % 变异操作
    if fitnessmax >20 && n == 7%n=7设为阈值
        mutationRate = 0.9;%增大变异概率,进入物种大爆发阶段
        n = 0;
        for k = 5:popSize/2-5
            c = ceil(rand(1,1)*6);
            parents(k,c) = rand(1,1).*(ub(c)-lb(c))+lb(c);
        end
        for k = popSize/2-5:popSize/2
            parents(k,:) = rand(1,6).*(ub-lb)+lb;
        end
    end
    for j = 1:popSize/2
        if rand < mutationRate
            c = ceil(rand(1,1)*6);
            offsprings(j,c) = rand(1,1).*(ub(c)-lb(c))+lb(c);
        end
    end
    offsprings(end,:) = rand(1,6).*(ub-lb)+lb;
    % 合并新一代种群
    pop = [parents;offsprings]; 
%     fitness(:,i)
     i
%     n
end

% 返回最优解

 for j = 1:popSize
        b1 = pop(j,1);
        b2 = pop(j,2);
        a11 = pop(j,3);
        a12 = pop(j,4);
        a21 = pop(j,5);
        a22 = pop(j,6);

        % 评估适应度
        load_system(mdlName);
        cs = getActiveConfigSet(mdlName);
        model_cs = cs.copy;
        simOut = sim(mdlName,model_cs);
        x1 = simOut.logsout{1}.Values.Data;
        x2 = simOut.logsout{2}.Values.Data;
        x1_ref = simOut.logsout{3}.Values.Data;
        x2_ref = simOut.logsout{4}.Values.Data;
        fitness(j,end) = fun(x1,x1_ref,x2,x2_ref);
end

[~,index] = min(fitness(:,end));
x = pop(index,:);
b1_test = x(1);
b2_test = x(2);
a11_test = x(3);
a12_test = x(4);
a21_test = x(5);
a22_test = x(6);
load_system(mdlName);
cs = getActiveConfigSet(mdlName);
model_cs = cs.copy;
simOut = sim(mdlName,model_cs);


plot(fitness(1,:),'LineWidth',3)
xlabel('迭代次数')
ylabel('适应度值')

不好意思忘记放里面适应度的计算函数了,其实就是误差啦。这是fun函数的写法。

function e =fun(x1,x1_ref,x2,x2_ref)
    e1 = (sum((x1-x1_ref).*(x1-x1_ref)))^(0.5);
    e2 = (sum((x2-x2_ref).*(x2-x2_ref)))^(0.5);
    e = (e1+e2);
end




<think>嗯,用户遇到了在MATLAB中运行仿真后无法识别getElement方法的问题。首先,我需要回想一下MATLABSimulink数据记录的结构。根据经验,Simulink的日志数据通常是通过Dataset格式存储的,而Dataset对象的方法可能在不同版本中有所变化。比如,旧版本可能使用getElementByName,而新版本则推荐find方法或者直接通过名称索引访问。 用户代码中的getElement('Vout')报错,说明在当前MATLAB版本中这个方法不存在。可能的原因是用户使用的是较新的版本,比如R2016a之后,这时Dataset对象不再支持getElement方法,而是改用find或直接索引。需要检查用户代码中如何访问logsout中的元素。 接下来,我应该考虑替代方法。比如,使用find函数来按名称查找元素,或者直接通过大括号和名称索引访问。例如,simOut.logsout.find('Vout')或者simOut.logsout.getElement('Vout').Values.Data。此外,还要确认信号是否确实被正确记录,名称是否正确,是否有空格或特殊字符需要处理。 另外,可能还需要检查模型的配置,确保信号日志记录已启用,并且Vout和Iinductor信号被标记为记录。如果信号名称在模型中包含空格,可能需要使用getElementByName或者在名称周围加引号。 总结解决步骤:首先确认MATLAB版本,然后替换getElement为find或直接索引。如果名称有特殊字符,可能需要转义或使用不同的方法。最后,确保信号正确记录,必要时调整代码中的访问方式。</think>在Simulink仿真数据采集中出现"无法识别getElement"错误,通常是因为MATLAB版本差异或数据格式不匹配造成的。以下是解决方案和详细解释: 解决方案: ```matlab % 方法1:使用find方法(推荐) Vout = simOut.logsout.find('Vout').Values.Data; Iinductor = simOut.logsout.find('Iinductor').Values.Data; % 方法2:直接索引访问 Vout = simOut.logsout{1}.Values.Data; % 索引号取决于信号记录顺序 Iinductor = simOut.logsout{2}.Values.Data; % 方法3:使用getElementByName(需要确认名称完全匹配) Vout = simOut.logsout.getElementByName('Vout').Values.Data; % 方法4:转换为结构体数组 logData = struct(simOut.logsout); index = find(strcmp({logData.Name}, 'Vout')); Vout = logData(index).Values.Data; ``` 原因解释: 1. **版本差异**:从MATLAB R2016a开始,Dataset对象的访问方法有所改变,旧版本使用的getElement可能已被弃用 2. **数据格式**:logsout默认返回Simulink.SimulationData.Dataset对象,需要使用特定方法访问元素 3. **名称匹配**:信号名称必须严格匹配(包括大小写),建议使用find方法进行模糊查找 4. **记录设置**:需要确保模型中对应信号已启用"Log signals to workspace"选项 建议补充检查: ```matlab % 查看所有记录信号的名称 simOut.logsout.getElementNames % 验证信号是否存在 if simOut.logsout.exists('Vout') Vout = simOut.logsout.get('Vout').Values.Data; end ```
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值