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;
a source to share
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
a source to share
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.
a source to share