【问题标题】:Plotting the same figure in real time实时绘制相同的图形
【发布时间】:2017-11-09 10:04:25
【问题描述】:

所以,我是 Simulink 的新手,并且具备基本的 Matlab 技能。我正在尝试使用投影仪(作为第二台显示器连接)在地板上绘制障碍物。 无论如何,我想一直在同一个数字上绘图,但我遇到了问题。有时图形在开始模拟时打开,有时则不打开。我不能为我的生活,找出原因。

情节的基本思想是情节和障碍物在地板上以与跑步机移动相同的速度向用户移动,以使其感觉就像它真的在地板上。我已经删除了图中的所有元素,只显示一个红色条作为障碍物和黑色背景。

function plot_fcn(x)

persistent f 

    projectionArea=3; %3m - arbitrary, will change later
    barLength=0.35; %0.35m - arbitrary, will change later
    no_contact=true; % contact indicator
    treadmillSpeed=10/9; %4km/h = 10/9 m/s
    refreshRate= 100; % 100Hz
    obstacleIncrement=treadmillSpeed/refreshRate; % eye noticeable increment


if isempty(f)
        target=1; 
        beforeBar=1;
        p=[10;901;1680;1027.5];
        f = figure;
        set(f, 'MenuBar', 'none', 'ToolBar', 'none', 'Color','black');
        set(0, 'DefaultFigurePosition', p);
        % target=x;
        while (no_contact) 

            afterBar=projectionArea-barLength-beforeBar;

            Y = [beforeBar, barLength, afterBar;
                 beforeBar, barLength, afterBar;
                 beforeBar, barLength, afterBar];

            f=area(Y);

            set(f,'EdgeColor','red');
            f(1).FaceColor = [0 0 0];
            f(2).FaceColor = [1 0 0];
            f(3).FaceColor = [0 0 0];

            if beforeBar>=projectionArea-(target+barLength/2)
                no_contact=false
            else 
                beforeBar=beforeBar+treadmillSpeed*obstacleIncrement;
                pause(obstacleIncrement)
            end
        end

        end
end

【问题讨论】:

    标签: matlab simulink


    【解决方案1】:

    您第二次调用该函数时未执行模拟,并且在上一次调用中打开的持久图形保持打开状态。简而言之,if isempty(f) 包含太多代码。并且drawnow 有助于迭代更新窗口中的绘图。

    function plot_fcn()
    
    persistent f
    
    projectionArea=3; %3m - arbitrary, will change later
    barLength=0.35; %0.35m - arbitrary, will change later
    no_contact=true; % contact indicator
    treadmillSpeed=10/9; %4km/h = 10/9 m/s
    refreshRate= 100; % 100Hz
    obstacleIncrement=treadmillSpeed/refreshRate; % eye noticeable increment
    
    target=1;
    beforeBar=1;
    if isempty(f) || ~ishandle(f) || ~isa(f,'matlab.ui.Figure')
        f = figure;
        set(f, 'MenuBar', 'none', 'ToolBar', 'none', 'Color','black');
    else
        delete(findobj(f,'type','Area'))
    end
    figure(f); %focus window
    while (no_contact)
        afterBar=projectionArea-barLength-beforeBar;
    
        Y = [beforeBar, barLength, afterBar;
            beforeBar, barLength, afterBar;
            beforeBar, barLength, afterBar];
    
        aH=area(Y);
    
        set(aH,'EdgeColor','red');
        aH(1).FaceColor = [0 0 0];
        aH(2).FaceColor = [1 0 0];
        aH(3).FaceColor = [0 0 0];
    
        if beforeBar>=projectionArea-(target+barLength/2)
            no_contact=false;
        else
            beforeBar=beforeBar+treadmillSpeed*obstacleIncrement;
            pause(obstacleIncrement)
        end
    
        if isempty(f) || ~ishandle(f) || ~isa(f,'matlab.ui.Figure')
            f = figure;
            set(f, 'MenuBar', 'none', 'ToolBar', 'none', 'Color','black');
        else
            figure(f); %focus window
            drawnow
        end
    
    end
    

    【讨论】:

    • 我还要补充一点,重新使用 f 将 area 对象存储在 while 循环中可能会导致意外行为,这不是一个好主意。前任。第一次运行f 被覆盖为区域对象。关闭图然后重新运行代码。 f 不为空,也不是预期的图形句柄...没有创建具有给定属性的新图形等。
    • @AeroEngy 你是对的。以前我尝试使用isgraphics() 没有成功。我用try catch 更新了代码。不是一个干净的解决方案,但它有效。正如您所建议的,如果出于某种未知原因确实不需要,则应删除 persistent f
    • 也许ishandle(f) && isa(f,'matlab.ui.Figure') ...这将确保它是一个有效的句柄(没有死或删除)并且它是一个数字。此外,如果是我的代码 'f=area(Y)' 将变为 aH = area(Y),因此您不必担心 fanyway 中包含的内容。
    • 是的,现在好多了。
    • 谢谢你们。你一直很有帮助。我还是新手,所以这是一条崎岖不平的道路:)
    猜你喜欢
    • 1970-01-01
    • 2013-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-27
    • 2015-01-10
    • 1970-01-01
    • 2015-03-03
    相关资源
    最近更新 更多