R2014a或更新版本中Simulink中嵌入matlab函数的图形对象句柄数组
为了调试,我在Simulink的嵌入式matlab函数中绘制了一些向量图。在Matlab R2013b之前,通过以下最小示例代码,一切工作正常:R2014a或更新版本中Simulink中嵌入matlab函数的图形对象句柄数组,matlab,function,graphics,simulink,handle,Matlab,Function,Graphics,Simulink,Handle,为了调试,我在Simulink的嵌入式matlab函数中绘制了一些向量图。在Matlab R2013b之前,通过以下最小示例代码,一切工作正常: function fcn %#minimum example for plot within for-loop of embedded matlab function coder.extrinsic('delete'); coder.extrinsic('quiver'); coder.extrinsic('gobjects'); numSteps=
function fcn
%#minimum example for plot within for-loop of embedded matlab function
coder.extrinsic('delete');
coder.extrinsic('quiver');
coder.extrinsic('gobjects');
numSteps=4;
persistent hFig;
persistent hVector;
if isempty(hFig)
hFig = figure;
hold on;
hVector=zeros(numSteps,1);
hVector=gobjects(numSteps,1);
for i=1:numSteps
hVector(i) = quiver(0,0,0,0);
end
end
set(0, 'CurrentFigure', hFig);
delete(hVector);
for i=1:numSteps
startInc=[1 1;1 1].*i;
endInc=[2 3;2 -3].*i;
hVector(i) = quiver(startInc(1,:),startInc(2,:),endInc(1,:),endInc(2,:));
end
对于句柄数组hVector
,由于在For
-循环中使用,因此需要进行初始化。但是,对于图形句柄对象的初始化,需要函数gobjects
,反过来,由于matlab无法正确确定外部函数输出的数据类型,因此需要初始化为带零的双精度(numSteps,1)
。
正如我所说,如果将此代码片段复制到simulink中的嵌入式matlab函数块中,而不在模型中添加任何其他内容,则该代码片段可以正常工作
我的问题是:Mathworks改变了R2014a中的许多绘图函数,其中一个变化是图形句柄的数据类型,对于我的quiver绘图,它不是类型quiver
。因此,使用零(numSteps,1)
初始化句柄数组的数据类型是错误的。然而,由于上述问题,忽略它仍然不起作用。init循环或任何类似的编译都不会出错
我非常感谢您在这个问题上提供的任何帮助。您可以尝试删除
gobject
初始化,并使用double()
来包装对任何matlab图形对象的调用。例:
hVector(i) = double( quiver(startInc(1,:),startInc(2,:),endInc(1,:),endInc(2,:)) ) ;
我建议阅读有关切换到Matlab的HG2版本时可能出现的兼容性问题
一个更适用于您的问题的it快速报价:
图形函数返回对象,而不是数字句柄
在R2014b之前,可以为图形对象存储一组句柄
然后向该数组中添加一些数字数据。在R2014b中,
这将导致错误。[…]
若你们发现自己真的被卡住了,那个么你们可以投射这个物体 使用
double
函数将句柄转换为数字句柄。那么你可以
使用handle
函数将数字转换回对象句柄。我们
不要建议将此作为长期解决方案。请注意,我们可能
选择在未来版本的MATLAB中删除此功能。如果我们这样做,
我们会提前通知你的
现在,如果您真的必须使用此解决方案,请注意这两个函数都适用于单个元素,但也适用于数组。所以
hVector_HG = handle( hVector_Num ) ; %// works if "hVector_Num" is an array of numeric handles
%// and ...
hVector_Num = double( hVector_HG ) ; %// works if "hVector_HG" is an array of HG2 graphic handles
这可能会简化一种或另一种格式之间的往返,如果它们经常成为必要的话
编辑: 我把这个放在帖子的底部,因为开头的答案已经被接受了,但是请尝试下面的方法,让我知道它是否有效。它可能会以更好(更能证明未来)的方式解决您的问题 初始化给定图形对象句柄数组的另一种方法是创建一个句柄数组(空就足够了)并复制它。例如:
hqNaN = quiver(NaN,NaN) ; %// create an empty quiver
hVector = repmat( hqNaN , numSteps , 1 ) ; %// replicate it in an array
将为您提供一个数组hVector
,其中包含numSteps
HG2图形对象句柄。此时,它们都指向同一个对象,但使用相同类型的句柄覆盖每个元素是完全合法的。因此,稍后:
hVector(i) = quiver( ... , etc ... ) ; %// overwrite handle "i" with a new quiver plot handle
将(应该)毫无问题地工作
这种方法需要注意以下几点:
- 将在何处创建空震颤?
你可能已经有了一个“当前”的数字,你不想把它搞砸。如果没有,将创建一个新的空绘图。因此,为了确保空震颤不会引起问题(只是屏幕上的闪烁),您可以这样包装:图形;hqNaN=颤动(NaN,NaN);关闭(gcf)代码>
hqNaN
变量仍然存在,但它不再是同一类型的句柄(因此,如果您想要完全复制这种类型,那么复制就没有用了)
- 如果不覆盖所有初始句柄数组怎么办?
记住数组的所有初始句柄都指向同一图形对象。因此,如果数组包含12个元素,但如果您错误地只覆盖了其中的10个,那么2个元素将是指向同一对象的句柄(您可能已经删除了该对象)。这意味着呼叫:
删除(hVector)
会给你带来麻烦:
使用handle.handle/delete时出错。无效或已删除的对象。
gna gna gna。。。幸运的是,通过防御性编程并改用:
删除(hVector(ishandle(hVector))
Matlab将自动执行检查,并且只删除正确的句柄
delete(hVector)
并没有删除句柄,而是删除对象(即箭图)。这是需要的,因为我只需要图中一个模拟步骤的绘图,而不是所有的旧绘图。该修复程序有效,谢谢!它必须围绕每个quivel
调用,显然会导致返回句柄对象的double
类型,而不是新的数据类型。作为外部函数的quiver
数据类型(和其他绘图函数)的初始化可能性将是完美的,特别是考虑到可能删除Loren上面提到的double()
函数。@Bazi,我知道,这真是一个肮脏的黑客(恢复到旧版本以使某些功能正常工作),这不是最方便的,将来可能会中断。同时,如果这是您唯一的选择,并且您有