Почему этот класс повторно инициализируется каждый раз? - PullRequest
2 голосов
/ 07 мая 2010

У меня есть 4 файла, и код «работает», как и ожидалось.

Я пытаюсь все очистить, поместить код в функции и т. Д. ... и все выглядит хорошо ... и это не такРабота.Может кто-нибудь объяснить, почему MatLab такой странный ... или я просто тупой?

Обычно я печатаю

terminator = simulation(100,20,0,0,0,1);
terminator.animate();

, и он должен создать карту деревьев с терминатором, бродящим по лесу.Все вращается в его ракурсе.

Когда я разбиваю его на функции ... все перестает работать.

Я действительно изменил только несколько строк кода, показанных в комментариях.

Код, который работает:

classdef simulation
properties
    landmarks
    robot
end

methods
    function obj = simulation(mapSize, trees, x,y,heading,velocity)
        obj.landmarks = landmarks(mapSize, trees);
        obj.robot = robot(x,y,heading,velocity);
    end
    function animate(obj)
        %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=scatter([0],[0],'bo');
        axis([xymin xymax xymin xymax]);
        obj.landmarks.apparentPositions
        %Simulation Loop  THIS WAS ORGANIZED
        for n = 1:720,
            %Calculate and Set Heading/Location
            obj.robot.headingChange = navigate(n);

            %Update Position
            obj.robot.heading = obj.robot.heading + obj.robot.headingChange;
            obj.landmarks.heading = obj.robot.heading;
            y = cosd(obj.robot.heading);
            x = sind(obj.robot.heading);     
            obj.robot.x = obj.robot.x + (x*obj.robot.velocity);
            obj.robot.y = obj.robot.y + (y*obj.robot.velocity);
            obj.landmarks.x = obj.robot.x;
            obj.landmarks.y = obj.robot.y;

            %Animate
            set(l,'XData',obj.landmarks.apparentPositions(:,1),'YData',obj.landmarks.apparentPositions(:,2));
            rectangle('Position',[-2,-2,4,4]);
            drawnow
        end
    end
end
end

-----------
classdef landmarks
properties
    fixedPositions  %# positions in a fixed coordinate system. [ x, y ]
    mapSize = 10;  %Map Size.  Value is side of square
    x=0;
    y=0;
    heading=0;
    headingChange=0;
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)
        %-STILL ROTATES AROUND ORIGINAL ORIGIN
        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
end
end

----------
classdef robot

properties
    x
    y
    heading
    velocity
    headingChange
end

methods
    function obj = robot(x,y,heading,velocity)
        obj.x = x;
        obj.y = y;
        obj.heading = heading;
        obj.velocity = velocity;
    end
end
end

----------
function headingChange = navigate(n)
%steeringChange = 5 * rand(1) * sign(rand(1) - 0.5); Most chaotic shit
%Draw an S
if n <270
    headingChange=1;
elseif n<540
    headingChange=-1;
elseif n<720
    headingChange=1;
else
    headingChange=1;
end
end

Код, который не работает ...

classdef simulation
properties
    landmarks
    robot
end

methods
    function obj = simulation(mapSize, trees, x,y,heading,velocity)
        obj.landmarks = landmarks(mapSize, trees);
        obj.robot = robot(x,y,heading,velocity);
    end
    function animate(obj)
        %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=scatter([0],[0],'bo');
        axis([xymin xymax xymin xymax]);
        obj.landmarks.apparentPositions
        %Simulation Loop
        for n = 1:720,
            %Calculate and Set Heading/Location

            %Update Position
            headingChange = navigate(n); 
            obj.robot.updatePosition(headingChange); 
            obj.landmarks.updatePerspective(obj.robot.heading, obj.robot.x, obj.robot.y);

            %Animate
            set(l,'XData',obj.landmarks.apparentPositions(:,1),'YData',obj.landmarks.apparentPositions(:,2));
            rectangle('Position',[-2,-2,4,4]);
            drawnow
        end
    end
end
end

-----------------
classdef landmarks
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 = createLandmarks(mapSize, numberOfTrees)
        obj.mapSize = mapSize;
        obj.fixedPositions = obj.mapSize * rand([numberOfTrees, 2]) .* sign(rand([numberOfTrees, 2]) - 0.5);
    end
    function apparent = get.apparentPositions(obj)
        %-STILL ROTATES AROUND ORIGINAL ORIGIN
        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

-----------------
classdef robot

properties
    x
    y
    heading
    velocity
end

methods
    function obj = robot(x,y,heading,velocity)
        obj.x = x;
        obj.y = y;
        obj.heading = heading;
        obj.velocity = velocity;
    end
    function updatePosition(obj,headingChange)
        obj.heading = obj.heading + headingChange;
        tempy = cosd(obj.heading);
        tempx = sind(obj.heading);     
        obj.x = obj.x + (tempx*obj.velocity);
        obj.y = obj.y + (tempy*obj.velocity);  
    end
end
end

Функция навигации такая же ...

Буду признателенлюбая помощь в отношении того, почему что-то не работает.

Все, что я сделал, это взял код из первого раздела из-под комментария:% Цикл моделирования, который был организован, и разбил его на 2 функции.Один в роботе и один в ориентирах.

Создается ли новый экземпляр каждый раз, потому что он постоянно печатает один и тот же заголовок для этой строки в классе робота obj.heading = obj.heading + headingChange;

Ответы [ 2 ]

1 голос
/ 10 мая 2010

Я дам вам объяснение.

По умолчанию, когда вы вызываете метод для объекта MATLAB, платформа создает копию объекта и вызывает метод для этой копии. Это совершенно другая парадигма C ++. В C ++, когда вы вызываете метод объекта, вы вызываете метод для ссылки на экземпляр этого объекта.

Итак, когда вы звоните

obj.robot.updatePosition(headingChange);

Создает новую копию объекта робота и вызывает updatePosition для этой копии. Состояние исходного робота остается неизменным.

Альтернативой использованию дескрипторов является код, подобный следующему:

obj.robot = obj.robot.updatePosition(headingChange);

Другой подход - сделать так, чтобы класс che наследовал от handle. В этом случае каждая операция копирования копирует ссылку на класс, а не на экземпляр, поэтому функции обновления изменяют фактическое состояние объектов.

1 голос
/ 08 мая 2010

Замените ваши определения на:

classdef landmarks <handle 
classdef robots <handle

Тогда взгляните на: http://www.mathworks.com/access/helpdesk/help/techdoc/matlab_oop/brfylq3.html

...