Why is this class being reinitialized every time?

I have 4 files and the code "works" as expected.

I'm trying to clean everything up, put the code in functions, etc ... and everything looks fine ... and it doesn't work. Can someone explain why MatLab is so quirky ... or am I just dumb?

I usually type

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

      

and he has to create a tree map with a terminator walking in the forest. Everything revolves in his direction.

When I break it down into functions ... everything stops working.

I really only changed a few lines of code shown in the comments.

Code that works:

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' AWESOME 80' 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

      

Code that doesn't work ...

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' AWESOME 80' 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

      

The navigation function is the same ...

I would appreciate any help on why things are not working.

All I did was take the code from the first section from the comment:% Simulation Loop IT WAS ORGANIZED and split it into 2 functions. One in the robot and one in the landmarks.

A new instance is created every time because it constantly prints the same heading for that line int robot class obj.heading = obj.heading + headingChange;

+2


a source to share


2 answers


Replace your definitions with:

classdef landmarks <handle 
classdef robots <handle

      



Then take a look at: http://www.mathworks.com/access/helpdesk/help/techdoc/matlab_oop/brfylq3.html

+1


a source


I will give you an explanation.

By default, when a method is called on a MATLAB object, the framework creates a copy of the object and calls the method on that copy. This is a completely different paradigm for C ++. In C ++, when you call a method on an object, you call the method to reference that object instance.

So when you call

obj.robot.updatePosition(headingChange);

      



Creates a new copy of the robot object and calls updatePosition on this copy. The state of the original robot remains unchanged.

An alternative to using descriptors is the following:

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

      

Another approach is to make the che class inherit from handle. In this case, each copy operation copies a reference to a class, not an instance, so the update functions change the state of the real objects.

+1


a source







All Articles