⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 slam_if_2d.m

📁 这是移动机器人同时定位与地图创建的第三部分
💻 M
📖 第 1 页 / 共 2 页
字号:
if(Params.verbose)    ShowLinkStrength(TheJournal.Lambda(TheJournal.II,TheJournal.II),0,Graphics.SecondFigure);end;% Note that, in the linear case, we don't need the mean to add the feature% xf = g(xv,z) + w = (mu_v + z) + wfor i=1:size(Observations,2)    id = Observations(1,i);        II_new = TheJournal.II(end-1:end) + 2;        %%%%%%%%%%%%%%%    % The operation of adding features with the information form as described    % in Eustice et al. (eustice05a) Section III.A.        TheJournal.Lambda(1:2,II_new) = -G'*Params.Rinv;    TheJournal.Lambda(II_new,1:2) = -Params.Rinv*G;    TheJournal.Lambda(II_new,II_new) = Params.Rinv;    TheJournal.Lambda(1:2,1:2) = TheJournal.Lambda(1:2,1:2) + G'*Params.Rinv*G;    etaf_new = Params.Rinv*Observations(2:3,i);    TheJournal.eta = [TheJournal.eta; etaf_new];    TheJournal.eta(1:2) = TheJournal.eta(1:2) - G'*Params.Rinv*Observations(2:3,i);        TheJournal.II = [TheJournal.II; II_new];    %%%%%%%%%%%%%%%        % Plotting stuff    if(Params.PlotSwitch)        xyf = GetMean(1:2) + Observations(2:3,i);        figure(Graphics.MainFigure);        subplot(1,2,1);        thandle = plot(xyf(1),xyf(2),'rx');        Graphics.Features = [Graphics.Features [id; thandle]];    end;            % Keep track of the shared information between the robot and feature    TheJournal.Feature{end+1}.id = id;    LambdaNorm = rhomatrix(TheJournal.Lambda(TheJournal.II,TheJournal.II));    TheJournal.Feature{end}.Link = [TheJournal.LookUP(1,2); det(LambdaNorm(1:2,end-1:end))];        % Now, update the LookUP table    TheJournal.LookUP = [TheJournal.LookUP; id NaN*ones(1,size(TheJournal.LookUP,2)-1)];    TheJournal.LookUP(end,end) = length(TheJournal.eta)-1;end;    if(Params.verbose)    fprintf(1,'\n\n');    fprintf(1,'+++++++++++++++++++++++ \n\n');    fprintf(1,'ADDING FEATURE(S): \n\n')    fprintf(1,'    We have added features: ');    disp(Observations(1,:));    fprintf(1,'\n\n');    fprintf(1,'    Notice that they share information only with the robot state\n\n');    fprintf(1,'+++++++++++++++++++++++ \n\n');    ShowLinkStrength(TheJournal.Lambda(TheJournal.II,TheJournal.II),0);    pause;end;return;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Function which pictoralizes links in the information matrixfunction ShowLinkStrength(Lambda,twoposeflag,fhandle)global TheJournal;global Graphicsif(nargin <2)    twoposeflag = 0;end;% We are intersted in the normalized information matrixif(nargin==0)    LambdaNorm = rhomatrix(TheJournal.Lambda(TheJournal.II,TheJournal.II));else    LambdaNorm = rhomatrix(Lambda);end;% The strength of each link is proportional to the determinant of the% corresponding 2x2 submatrix of Lambda. In general, the determinant% of the matrices along the diagonal of Lambda (which represent self-links)% will be much larger and we "tone them down" for the sake of rendering.ILinks = sparse(size(LambdaNorm,1)/2,size(LambdaNorm,2)/2);for i=1:2:size(LambdaNorm,1)    for j=(i):2:size(LambdaNorm,2)        temp = det(LambdaNorm(i:(i+1),j:(j+1)));        ILinks((i+1)/2,(j+1)/2) = temp;        ILinks((j+1)/2,(i+1)/2) = temp;    end;end;if(size(ILinks,1) > 2)    %ILinks = spdiags(max(ILinks(:))*ones(size(ILinks,1),1),0,ILinks);end;if(nargin < 3)    figure(Graphics.MainFigure);    subplot(1,2,2);else    figure(fhandle);end;cla;imagesc(ILinks);axis image;hold on;set(gca,'xtick',1.5:1:(size(ILinks,1)-0.5),'ytick',1.5:1:(size(ILinks,1)-0.5));set(gca,'xtick',[],'ytick',[],'box','on');xlim = get(gca,'xlim');ylim = get(gca,'ylim');[X,Y] = meshgrid(xlim(1):1:xlim(2),xlim(1):1:xlim(2));plot(X,Y,'r-');plot(Y,X,'r-');temp = int2str(TheJournal.LookUP(3:end,1));if(twoposeflag)    temp = strvcat('v+','v-',temp);else    temp = strvcat('v+',temp);end;X = 1:size(ILinks,2);Y = repmat(0.2,1,length(X));text(X,Y,temp);text(Y-0.05*X(end),X,temp)[I,J] = find(ILinks);plot(I,J,'k.');xlabel('Dots denote nonzero entries','Fontsize',10);return;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% This function records datafunction DoLogging(k)global TheJournal;global Params;global Truth;if(size(TheJournal.LookUP,1) == 2)    return;end;Lambda = rhomatrix(TheJournal.Lambda(TheJournal.II,TheJournal.II));for i=3:size(TheJournal.LookUP,1)    xfi = TheJournal.LookUP(i,2);        TheJournal.Feature{i-2}.Link(:,end+1) = [k; det(Lambda(1:2,xfi:(xfi+1)))];end;% Enable to log errors in the state estimatesif(0)    % Calculate the covariance matrix and mean via brute-force inversion of the information matrix    Sigma = inv(TheJournal.Lambda(TheJournal.II,TheJournal.II));    Sigma = (Sigma + Sigma')/2;     % Ensures symmetry    x = Sigma*TheJournal.eta;    % Log vehicle data    xv_truth = Truth.VehicleTrajectory(2:3,find(Truth.VehicleTrajectory(1,:)==k));    verror = x(1:2) - xv_truth;    chisqr_error = verror'*inv(Sigma(1:2,1:2))*verror;    TheJournal.VehicleHistory = [TheJournal.VehicleHistory [k; verror; diag(Sigma(1:2,1:2)); chisqr_error]];    if(0 & size(TheJournal.LookUP,1) > 2)        TheJournal.MapError = [TheJournal.MapError [k; 0]];        nFeatures = size(TheJournal.LookUP,1)-2;        for i=3:size(TheJournal.LookUP,1)            id = TheJournal.LookUP(i,1);            xi = GetStateIndex(id,k);            % Error in estimated feature position            xf_truth = Truth.Features(2:3,find(Truth.Features(1,:)==id));            feat_error = x(xi:xi+1)-xf_truth;            %TheJournal.Feature{id}.History = [TheJournal.Feature{id}.History [k; feat_error; diag(Sigma(xi:xi+1,xi:xi+1)); feat_error'*inv(Sigma(xi:xi+1,xi:xi+1))*feat_error]];            % Keep track of map convergence            TheJournal.MapError(2,end) = TheJournal.MapError(2,end) + (feat_error'*feat_error)/nFeatures;        end;    end;end;return;    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Function to extract mean state estimates%function x = GetMean(xi)global TheJournal;% Right now, fully invert the information matrix to get the meanmu = TheJournal.Lambda(TheJournal.II,TheJournal.II)\TheJournal.eta;x = mu(xi);    return;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Function to generate feature observationsfunction Observations = GetFeatureObservations(k)global TheJournal;global Truth;global Params;global Data;Observations = [];xv = Truth.VehicleTrajectory(2:3,find(Truth.VehicleTrajectory(1,:)==k));vvel = Data.Velocity(2:3,find(Data.Velocity(1,:)==k));Temp = sqrt(sum((Truth.Features(2:3,:)-repmat(xv,1,size(Truth.Features,2))).^2));Temp = [Truth.Features(1,:); Temp];Temp = Temp(1,find(Temp(2,:) <= Params.MaxObsRange));    % Generate correlated measurement noise using the Cholesky Decomposition: R = X'*X% for which: w = U*randn(2,1) ---> cov(w) = U*I*U' = U*U' = R;  (U*U'=R=X'X --> U=X')U = chol(Params.R)';if(length(Temp) >= Params.nObsPerIteration)    while(size(Observations,2) < Params.nObsPerIteration)        i = ceil(rand*length(Temp));        fid = Temp(i);        Temp(i) = [];                xf = Truth.Features(2:3,find(Truth.Features(1,:)==fid));        ObsNoise = (xf-xv) + U*randn(2,1);        Observations = [Observations [fid; ObsNoise]];    end;else    for i=1:length(Temp)        fid = Temp(i);                xf = Truth.Features(2:3,find(Truth.Features(1,:)==fid));        ObsNoise = (xf-xv) + U*randn(2,1);        Observations = [Observations [fid; ObsNoise]];    end;end;return;        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%function PlotState(k);global TheJournal;global Graphics;global Truth;figure(Graphics.MainFigure);subplot(1,2,1)% Ground truth vehicle plotx = Truth.VehicleTrajectory(2:3,k);if(isempty(Graphics.TrueVehiclePose))    Graphics.TrueVehiclePose = plot(x(1),x(2),'ko','MarkerFaceColor','r','MarkerSize',6);    set(Graphics.TrueVehiclePose,'Color',Graphics.TrueColor);else    set(Graphics.TrueVehiclePose,'xdata',x(1),'ydata',x(2));end;% Brute-force estimate of the covariance matrix and mean vectorSigma = TheJournal.Lambda(TheJournal.II,TheJournal.II)\eye(length(TheJournal.II));x = Sigma*TheJournal.eta;if(isempty(Graphics.VehiclePose))    Graphics.VehiclePose = plot(x(1),x(2),'k^','MarkerFaceColor','r','MarkerEdgeColor','k','MarkerSize',8);    set(Graphics.VehiclePose,'Color',Graphics.Color);else    lastvx = get(Graphics.VehiclePose,'xdata');    lastvy = get(Graphics.VehiclePose,'ydata');    set(Graphics.VehiclePose,'xdata',x(1),'ydata',x(2));end;if(isempty(Graphics.VehicleEllipse))    Graphics.VehicleEllipse = DrawEllipse([x(1); x(2)],Sigma(1:2,1:2),3,Graphics.Color);else    [Sigmax,Sigmay] = GetEllipse([x(1); x(2)],Sigma(1:2,1:2),3);    set(Graphics.VehicleEllipse,'xdata',Sigmax,'ydata',Sigmay);end;for i=1:size(Graphics.Features,2)    id = Graphics.Features(1,i);    thandle = Graphics.Features(2,i);    xfi = GetStateIndex(id,k);    try        set(thandle,'xdata',x(xfi),'ydata',x(xfi+1));    catch        keyboard;    end;        if(isempty(Graphics.FeatureEllipse) | isempty(find(Graphics.FeatureEllipse(1,:)==id)))        thandle = DrawEllipse(x(xfi:xfi+1),Sigma(xfi:xfi+1,xfi:xfi+1),3,Graphics.Color);        Graphics.FeatureEllipse = [Graphics.FeatureEllipse [id; thandle]];    else        [Sigmax,Sigmay] = GetEllipse(x(xfi:xfi+1),Sigma(xfi:xfi+1,xfi:xfi+1),3);        thandle = Graphics.FeatureEllipse(2,find(Graphics.FeatureEllipse(1,:)==id));        set(thandle,'xdata',Sigmax,'ydata',Sigmay);    end;end;return;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%function h = DrawEllipse(x,P,nSigma,RGBCol)[V,D] = eig(P);y = nSigma*[cos(0:0.1:2*pi);sin(0:0.1:2*pi)];el = V*sqrtm(D)*y;el = [el el(:,1)]+repmat(x,1,size(el,2)+1);h = line(el(1,:),el(2,:));set(h, 'markersize',0.5,'color',RGBCol);return;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%function [XData,YData] = GetEllipse(x,P,nSigma)[V,D] = eig(P);y = nSigma*[cos(0:0.1:2*pi);sin(0:0.1:2*pi)];el = V*sqrtm(D)*y;el = [el el(:,1)]+repmat(x,1,size(el,2)+1);XData = el(1,:);YData = el(2,:);return;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Function which returns the index for a particular feature/posefunction xi = GetStateIndex(id,k)global TheJournal;iRow = find(TheJournal.LookUP(:,1) == id);iColumn = find(TheJournal.LookUP(1,:) == k);if(isempty(iRow) || isempty(iColumn))    fprintf(1,'!!!!!!   Error determining index for vehicle/feature %i at time %i \n',id,k);else    xi = TheJournal.LookUP(iRow,iColumn); end;return;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Function to generate point featuresfunction MakeFeatures()global Params;global Truth;global Graphics;Truth.Features = [];dist = Params.MaxObsRange/2;minx = min(Truth.VehicleTrajectory(2,:)) - dist;maxx = max(Truth.VehicleTrajectory(2,:)) + dist;miny = min(Truth.VehicleTrajectory(3,:)) - dist;maxy = max(Truth.VehicleTrajectory(3,:)) + dist;Truth.Features = repmat([minx; miny],1,Params.numFeatures) + [(maxx-minx) 0; 0 (maxy-miny)]*rand(2,Params.numFeatures);Truth.Features = [2:(Params.numFeatures+1); Truth.Features];if(Params.PlotSwitch)    figure(Graphics.MainFigure);    subplot(1,2,1)    plot(Truth.Features(2,:),Truth.Features(3,:),['k.']);    text(Truth.Features(2,:),Truth.Features(3,:)-1.0,int2str(Truth.Features(1,:)'));end;return; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Make me a survey pattern for a vehicle with 2 uncoupled doffunction pattern = MakeSurvey()global Params;global Truth;global Data;% Generate the 4 waypoints that comprise the corners of the route (a box)a = 0.8*Params.MapSize;b = 0.8*Params.MapSize;X0 = Params.MapSize*[0.1; 0.1];Params.Path = repmat([0 a a  0; 0 0 b b],1,Params.nRepeat);Params.Path = Params.Path + repmat(X0,1,size(Params.Path,2));Data.Velocity = [1 0 0]';xold = Params.Path(:,1);for i=2:size(Params.Path,2)    tlast = Data.Velocity(1,end);    xold = Params.Path(:,i-1);    xnew = Params.Path(:,i);    xdiff = xnew(1)-xold(1);    ydiff = xnew(2)-xold(2);    if(abs(xdiff) > abs(ydiff))        tend = tlast + ceil(abs(xdiff)/Params.maxVelocity);        xvel = sign(xdiff)*Params.maxVelocity;        yvel = ydiff/(tend-tlast);    elseif(abs(ydiff) > abs(xdiff))        tend = tlast + ceil(abs(ydiff)/Params.maxVelocity);        yvel = sign(ydiff)*Params.maxVelocity;        xvel = xdiff/(tend-tlast);    end;    XVel = repmat(xvel,1,tend-tlast);    YVel = repmat(yvel,1,tend-tlast);    Data.Velocity = [Data.Velocity [(tlast+1):tend; XVel; YVel]];end;% Generate the true, NOISE CORRUPTED, vehicle trajectory%% Generate correlated noise using the Cholesky Decomposition: Q = X'*X% for which: v = U*randn(2,1) --> cov(v) = U*I*U' = U*U' = Q    (U*U' = X'*X --> U = X')U = chol(Params.Q)';Truth.VehicleTrajectory = [1; [0;0]];for i=2:size(Data.Velocity,2)    VelocityNoise = Data.Velocity(2:3,i) + U*randn(2,1);    Truth.VehicleTrajectory = [Truth.VehicleTrajectory [i; Truth.VehicleTrajectory(2:3,end)+VelocityNoise]];end;return;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -