2010-05-10 7 views
1

J'ai du mal à comprendre le paradigme des classes Matlab comparé à C++. J'ai écrit du code l'autre jour et j'ai pensé que ça devrait marcher. Il n'a pas ... jusqu'à ce que j'ajoute"Invalid Handle Object" lors du tracé de 2 chiffres Matlab

<handle 

après la classedef. J'ai donc deux classes, les points de repère et le robot, tous deux sont appelés depuis la classe de simulation. Ceci est la boucle principale de obj.simulation.animate() et cela fonctionne, jusqu'à ce que j'essaie de tracer deux choses à la fois. DATA.path est un enregistrement de tous les endroits où un robot a été sur la carte, et il est mis à jour chaque fois que la position est mise à jour.

Lorsque je tente de le tracer, en décommentant les deux lignes marquées ci-dessous, je reçois cette erreur:

??? Erreur lors de l'utilisation de ==> set Objet de poignée non valide.

erreur dans ==> simulation> simulation.animate à 45 ensemble (l.lm, 'XData', obj.landmarks.apparentPositions (:, 1), 'ydata', obj.landmarks.apparentPositions (:, 2));

%INITIALIZE GLOBALS 
global DATA XX 
XX = [obj.robot.x ; obj.robot.y]; 
DATA.i=1; 
DATA.path = XX; 

%Setup Plots 
fig=figure; 
xlabel('meters'), ylabel('meters') 
set(fig, 'name', 'Phil''s AWESOME 80''s Robot Simulator') 
xymax = obj.landmarks.mapSize*3; 
xymin = -(obj.landmarks.mapSize*3); 
l.lm=scatter([0],[0],'b+'); 
%"UNCOMMENT ME"l.pth= plot(0,0,'k.','markersize',2,'erasemode','background'); % vehicle path 
axis([xymin xymax xymin xymax]); 


%Simulation Loop 
for n = 1:720, 
    %Calculate and Set Heading/Location 
    XX = [obj.robot.x;obj.robot.y]; 
    store_data(XX); 
    if n == 120, 
     DATA.path 
    end 
    %Update Position 
    headingChange = navigate(n); 
    obj.robot.updatePosition(headingChange); 
    obj.landmarks.updatePerspective(obj.robot.heading, obj.robot.x, obj.robot.y); 

    %Animate 
    %"UNCOMMENT ME" set(l.pth, 'xdata', DATA.path(1,1:DATA.i), 'ydata', DATA.path(2,1:DATA.i)); 
    set(l.lm,'XData',obj.landmarks.apparentPositions(:,1),'YData',obj.landmarks.apparentPositions(:,2)); 
    rectangle('Position',[-2,-2,4,4]); 
    drawnow 

C'est le classdef de repères

classdef landmarks <handle 
properties 
    fixedPositions; %# positions in a fixed coordinate system. [ x, y ] 
    mapSize; %Map Size. Value is side of square 
    x; 
    y; 
    heading; 
    headingChange; 
end 
properties (Dependent) 
    apparentPositions 
end 
methods 
    function obj = landmarks(mapSize, numberOfTrees) 
     obj.mapSize = mapSize; 
     obj.fixedPositions = obj.mapSize * rand([numberOfTrees, 2]) .* sign(rand([numberOfTrees, 2]) - 0.5); 
    end 
    function apparent = get.apparentPositions(obj) 
     currentPosition = [obj.x ; obj.y]; 
     apparent = bsxfun(@minus,(obj.fixedPositions)',currentPosition)'; 
     apparent = ([cosd(obj.heading) -sind(obj.heading) ; sind(obj.heading) cosd(obj.heading)] * (apparent)')'; 
    end 
    function updatePerspective(obj,tempHeading,tempX,tempY) 
     obj.heading = tempHeading; 
     obj.x = tempX; 
     obj.y = tempY; 
    end 
end 
end 

Pour moi, voilà comment je comprends les choses. J'ai créé une figure l.lm qui a environ 100 points xy. Je peux tourner cette figure en utilisant

set(l.lm,'XData',obj.landmarks.apparentPositions(:,1),'YData',obj.landmarks.apparentPositions(:,2)); 

Lorsque je fais cela, les choses fonctionnent. Lorsque j'essaie de tracer un deuxième groupe de points XY, stocké dans DATA.path, cela craint et je n'arrive pas à comprendre pourquoi.

J'ai besoin de tracer le chemin du robot, stocké dans DATA.path, ET les positions des points de repère. Des idées sur comment faire ça? Je ne dis pas que vous avez tort, parce que je ne connais pas la réponse, mais j'ai le code d'une autre application qui trace ce chemin sans appeler les axes ('NextPlot', 'add');

if dtsum==0 & ~isempty(z) % plots related to observations 
    set(h.xf, 'xdata', XX(4:2:end), 'ydata', XX(5:2:end)) 
    plines= make_laser_lines (z,XX(1:3)); 
    set(h.obs, 'xdata', plines(1,:), 'ydata', plines(2,:)) 
    pfcov= make_feature_covariance_ellipses(XX,PX); 
    set(h.fcov, 'xdata', pfcov(1,:), 'ydata', pfcov(2,:)) 
end 
drawnow 

Ce qui précède fonctionne sur l'autre code, mais pas le mien. Je vais essayer de mettre en œuvre votre suggestion et vous le faire savoir.

Répondre

3

Lorsque vous appelez l'intrigue à plusieurs reprises sur la même figure, le tracé précédent est effacé par défaut et la poignée de l'intrigue précédente indique rien. Ainsi l'erreur.

Pour résoudre ce problème, vous devez définir la propriété NextPlot des axes sur add. Vous pouvez le faire en appelant hold on (c'est ce que vous feriez si vous complotaient de la ligne de commande), ou vous pouvez écrire

fig=figure; 
%# create a set of axes where additional plots will be added on top of each other 
%# without erasing 
axes('NextPlot','add'); 

Si vous le souhaitez, vous pouvez stocker les axes gérer aussi bien, et utiliser plot(ah,x,y,...) pour vous assurer que vous tracez dans le bon ensemble d'axes et non quelque part étrange si vous cliquez sur une fenêtre de chiffre différente entre le moment où le chiffre est ouvert et la commande de traçage est émise.

+0

Voir les modifications au bas de mon message. –

+0

Puis-je également définir «tenir» pour chaque axe ou est-ce pour l'ensemble de la figure ou rien. –

+0

Maintenir fonctionne pour les axes actuels. S'il n'y a pas d'axes courants, Matlab crée un ensemble d'axes et définit sa propriété 'NextPlot' sur' add'. «hold on» et «hold of» sont simplement des raccourcis pour 'set (gca, 'NextPlot', 'add')' et 'set (gca, 'NextPlot', 'replace')'. 'gca' obtient le handle des axes actuels, c'est-à-dire les axes sur lesquels vous avez cliqué en dernier ou les premiers axes du dernier chiffre sur lequel vous avez cliqué. – Jonas

Questions connexes