2

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

ナビ機能はそのまま…

なぜ物事がうまくいかないのかについての助けをいただければ幸いです。

私がしたことは、コメントの下の最初のセクションからコードを取得することでした: %Simulation Loop THIS WAS ORGANIZED で、2 つの関数に分割しました。ロボットに 1 つ、ランドマークに 1 つ。

ロボット クラス obj.heading = obj.heading + readingChange; で、この行の同じ見出しを常に出力しているため、毎回作成される新しいインスタンスです。

4

2 に答える 2

1

説明します。

既定では、MATLAB オブジェクトでメソッドを呼び出すと、フレームワークはオブジェクトのコピーを作成し、このコピーでメソッドを呼び出します。これは、C++ とはまったく異なるパラダイムです。C++ では、オブジェクトのメソッドを呼び出すとき、そのオブジェクト インスタンスへの参照でメソッドを呼び出しています。

だから、あなたが電話するとき

obj.robot.updatePosition(headingChange);

ロボット オブジェクトの新しいコピーを作成し、このコピーに対して updatePosition を呼び出しています。元のロボットの状態は変更されません。

ハンドルを使用する代わりに、次のようにコーディングします。

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

もう 1 つのアプローチは、クラスをハンドルから継承させることです。この場合、すべてのコピー操作は、インスタンスではなくクラスへの参照をコピーします。これが、更新関数が実際のオブジェクトの状態を変更する理由です。

于 2010-05-09T23:23:17.927 に答える
1

定義を次のように置き換えます。

classdef landmarks <handle 
classdef robots <handle

次に見てみましょう: http://www.mathworks.com/access/helpdesk/help/techdoc/matlab_oop/brfylq3.html

于 2010-05-07T20:45:51.763 に答える