【问题标题】:matlab dymola connection fails after a while一段时间后matlab dymola连接失败
【发布时间】:2014-02-03 19:27:11
【问题描述】:

我有一个 .mat 文件中的实验数据和一个用 dymola 编写的模型。我使用 dymolaM.m 文件将命令从 matlab 发送到 dymola。这样我就可以使用 matlab 来优化我的模型的参数。 Matlab从.mat文件中读取数据,以正确的方式初始化dymola,让dymola模拟模型,读取dymola的输出并与实验数据进行比较。

这一切都可以正常工作,但如果我重复 matlab dymola 连接太多,我总是会收到以下错误:

    ??? Error using ==> ddeexec
    The first argument 'channel' is not valid.

    Error in ==> dymolaM at 59
    status = ddeexec(DymolaChannel, deblank(command(i,:)), '', timeout);

我尝试重复完全相同的命令 200 次。我总是在第 26 次迭代时遇到错误。

我该怎么办?这是dymolaM.m文件的代码

    function res=dymolaM(command, value)
    % Executes a command optionally followed by a value in Dymola.
    % Dymola is started if not already running.

    % Version 1.0, 1997-11-14
    % Version 1.1, 1999-06-12

    %    Copyright (C) 1997-2001 Dynasim AB.
    %    All rights reserved.

      DymolaChannel = ddeinit('dymola', ' ');
      if DymolaChannel == 0,
         pause(1);
         DymolaChannel = ddeinit('dymola', ' ');
         if DymolaChannel == 0,
           dymola    = getenv('DYMOLA');
           v=version;
            if (isempty(dymola) & v(1,1)>='5') 
                if v(1,1)>='7'
         [st,I]=dbstack('-completenames');
       else
         [st,I]=dbstack;
       end
       if v(1,1)>='7'
          currentfile=st(I).file;
       else
         currentfile=st(I).name;
       end
             I=find(currentfile=='\' | currentfile=='/');
             currentfile=currentfile(1:(max([1,I(1:end-1)])-1));
             dymola=currentfile;
           end
           if ~isempty(dymola)
              dymola=[dymola,'\bin\'];
           end
           disp('Starting Dymola - Wait');
           fquote    = '';
           if strcmp(computer, 'PCWIN') | strcmp(computer, 'PCWIN64')
            fquote = '"';
           end;
           dos([fquote,dymola,'Dymola',fquote,' &']);
           pause(10);
           DymolaChannel = ddeinit('dymola', ' ');
           disp('Dymola started');
        else
           disp('Worked around problem communicating with Dymola');
        end
      end
      if nargout>0
         res=zeros(size(command,1),1);
      end

      if DymolaChannel == 0,
         disp('Error starting Dymola');
      elseif nargin > 0,
         for i=1:size(command,1)
              timeout=4000*1000; % Can always kill dymola
              if nargin == 1, 
                 status = ddeexec(DymolaChannel, deblank(command(i,:)), '', timeout);
              elseif nargin == 2,
                 status = ddeexec(DymolaChannel, [deblank(command(i,:)), num2str(value(i))], '', timeout);
              end
              if nargout==0 
                 if status == 0,
                    error('Invalid Dymola command.');
                 end
              else
                 res(i)=status;
              end;
            end
            ddeterm(DymolaChannel);
      end

【问题讨论】:

  • 我对 DDE 连接的体验也有好有坏。如果您愿意投入一些时间,您可以尝试一种不同的(可能更稳定的)方法并将您的模型导出为 FMU。然后,您可以从 Python(使用例如开源工具 pyFMI,JModelica.org 的一部分)或 Matlab(使用商业 FMI 工具箱)或许多其他工具与 FMU 进行交互,请参阅fmi-standard.org/tools
  • 本文描述了 FMI/FMU 的想法:dx.doi.org/10.3384/ecp11063105 也可以在 SO 上查看 FMI 相关问题:stackoverflow.com/questions/tagged/fmi

标签: matlab dymola


【解决方案1】:

好的,这个问题已经存在四年了,但是我在最后两周使用了一些不令人满意的解决方法,然后才最终找到了这个解决方案。

我用以下策略解决了这个问题:

我用自己的修改版本重载了函数 dymolaM.m。 我把命令注释掉了:

DymolaChannel = ddeinit('dymola', ' ');

并将其替换为:

% DymolaChannel = ddeinit('dymola', ' ');
DymolaChannel = get_dymola_channel();

我将函数get_dymola_channel();定义如下:

function DymolaChannel = get_dymola_channel()
    persistent dymola_channel_persistent
    if isempty(dymola_channel_persistent)
        dymola_channel_persistent = ddeinit('dymola', ' ');
    end
    DymolaChannel = dymola_channel_persistent;
end

这意味着函数ddeinit(只能创建有限数量的通道)只被调用一次。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-08-23
    • 2022-06-13
    • 1970-01-01
    • 2015-07-17
    • 1970-01-01
    • 2013-08-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多