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

📄 slam_if_1d.m

📁 这是移动机器人同时定位与地图创建的第三部分
💻 M
📖 第 1 页 / 共 2 页
字号:
%% SLAM_IF_1D performs an interactive simulation of SLAM with information filter.%   SLAM_IF_1D() is a one-dimensional (i.e. monobot) linear simulation of %   Simultaneous Localization and Mapping (SLAM) with the information filter. %   It is meant to serve as an introduction to the basic steps of IF SLAM and %   to explore some important traits of feature-based SLAM information filters.%%   This code was written by Matthew R. Walter (Massachusetts Institute of%   Technology) as part of a 2006 SLAM Summer School lab on the information%   filter. Feel free to play with the parameter settings to see how they%   affect the information filter.%%   For the most part, I have tried to be pretty verbose when it comes%   to my comments and hope that they help you to understand what is going on.%   Also, while there were not any obvious bugs upon my final writing, I can%   not guarantee that the code is free of errors.%% ------------% References:%%   R. Eustice, H. Singh, and J. Leonard. Exactly Sparse Delayed State%   Filters. ICRA 2005.%%   M. Walter, R. Eustice, and J. Leonard. A Provably Consistent Method%   for Imposing Exact Sparsity in Feature-based SLAM Information Filters.%   ISRR 2005.%%-----------------------------------------------------------------%    History:%    Date            Who         What%    -----------     -------     -----------------------------%    08-10-2006      mrw         Created and written.function slam_if_1d()% Clear variablesclear global;clear all;global TheJournal;global Truth;global Graphics;global Params;global Data;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Simulation ParametersParams.verbose = 0;     % Verbose outputParams.PlotSwitch = 1;  % Flag that turns plotting on/off. Should be set to 1 (plotting on)Params.nSteps = 20;Params.density = 0.35;      % density of featuresnumfeatures = 5;Params.nObsPerIteration = 1;% System ParametersParams.Q = 0.15^2;Params.R = 0.05^2;% Filter initializationSigma = 0.001;     % initial 2x2 covariance matrixx = [0];                      % initial state%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Set simulation parameters and generate vehicle motionParams.maxVelocity = 0.5;   Params.ObsFrequency = 1;        % [0,1] likelihood of observationsData.Velocity = [1:Params.nSteps; repmat(Params.maxVelocity,1,Params.nSteps)];U = chol(Params.Q)';TrueVelocity = Data.Velocity(2,:) + U*randn(1,Params.nSteps);Truth.VehicleTrajectory = [1:Params.nSteps; cumsum(TrueVelocity)];mapsize = max(Truth.VehicleTrajectory(2,:));        % width and height of the mapParams.MaxObsRange = 0.3*mapsize;% Make the featuresTruth.Features = 1:((mapsize-1)/numfeatures):mapsize;Truth.Features = [2:(size(Truth.Features,2)+1); Truth.Features];%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Initial information matrix, Lambda = inv(Sigma), and information vector, eta = Lambda*xTheJournal.Lambda = spalloc(1,1,(1+size(Truth.Features,2))^2);TheJournal.Lambda(1,1) = inv(Sigma);TheJournal.eta = TheJournal.Lambda*x;% A lookup table to keep track of feature id's and their corresponding location within the state vectorTheJournal.LookUP = [NaN 1; 1 1];% The information form utilizes the inverse of Q and R in sparse formParams.Q = sparse(Params.Q);Params.R = sparse(Params.R);Params.Qinv = inv(Params.Q);Params.Rinv = inv(Params.R);TheJournal.Feature = [];%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Set the figure marginsif(Params.PlotSwitch)    Graphics.MainFigure = figure(1);    clf;    Graphics.axes1 = subplot(2,1,1);    hold on;    set(gcf,'DoubleBuffer','on','Color',[1 1 1]);    set(gca,'Box','on');    set(gca,'xlim',[-1 mapsize]);    set(gca,'ylim',[-0.5 0.5]);    temp = get(gca,'position');    temp(end) = 0.1;    temp(2) = 0.8;    set(gca,'position',temp,'ytick',[],'yticklabel',[]);    plot([-1 mapsize]',[0 0]','k:');            Graphics.axes2 = subplot(2,1,2);    set(gcf,'ColorMap',colormap(flipud(colormap('gray'))));    temp = get(gca,'position');    temp(4) = 0.5;    set(gca,'position',temp);        if(Params.verbose)        Graphics.SecondFigure = figure(2);        clf;        Temp = get(gcf,'Position');        Temp(3:4) = [300 300];        set(gcf,'ColorMap',colormap(flipud(colormap('gray'))),'Position',Temp);    end;        figure(Graphics.MainFigure);                %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%    % Graphic settings    Graphics.TrueColor = 'g';    Graphics.Color = 'r';    Graphics.curLaser = [];    Graphics.TrueVehiclePose = [];  % handle for plot of true vehicle pose    Graphics.VehiclePose = [];      % handle for plot of filter estimate for vehicle pose    Graphics.Features = [];         % handle for plot of filter estimates for feature locations    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%        % Plot true feature locations    subplot(Graphics.axes1);    plot(Truth.Features(2,:), zeros(1,size(Truth.Features,2)),'k.');    end;for k=1:size(Truth.VehicleTrajectory,2)    if(Params.PlotSwitch & ~isempty(Graphics.curLaser))        set(Graphics.curLaser,'Visible','off');    end;    % Perform the motion update in the information form as the addition of the new pose    % to the state followed by the marginalization of the past pose    Information_DoProjection(k);    % update the plot of the vehicle and map;    if(Params.PlotSwitch)        PlotState(k);        title(['k = ' int2str(k) ' ( ' num2str(100*k/size(Truth.VehicleTrajectory,2),2) ' percent )']);        drawnow;    end;            % Simulate feature observations    % Observations is a 2xm array with one column per observation, [feature_id; x_feature - x_vehicle]    Observations = GetFeatureObservations(k);    if(~isempty(Observations))        % Differentiate between features that have already been mapped and those that are new        if(size(TheJournal.LookUP,1) > 2)            [C,IA,IB] = intersect(Observations(1,:),TheJournal.LookUP(3:end,1));            OldObs = Observations(:,IA);                        [C,IA] = setdiff(Observations(1,:),OldObs(1,:));            NewObs = Observations(:,IA);        else            OldObs = [];            NewObs = Observations;        end;                % Visualize observations        if(Params.PlotSwitch)            xv = GetMean(1);  % Estimate of the current vehicle pose            [C,IA,IB] = intersect(Truth.Features(1,:),Observations(1,:));            X = Truth.Features(2,IA);            Y = repmat(0,1,size(Observations,2));                        figure(Graphics.MainFigure);            subplot(Graphics.axes1);            Graphics.curLaser = plot(X,Y,'yo','MarkerSize',12);            set(Graphics.curLaser,'Color',[0.268 0.686 1.00]);        end;                            % If the vehicle has observed new features, add them        if(~isempty(NewObs))            Information_AddFeature(NewObs);        end;                % If we have reobserved known features, run an update step        if(~isempty(OldObs))            Information_DoUpdate(OldObs);        end;    end;            % update the plot of the vehicle and map;    if(Params.PlotSwitch)        PlotState(k);        title(['k = ' int2str(k) ' ( ' num2str(100*k/size(Truth.VehicleTrajectory,2),2) ' percent )']);        drawnow;        ShowLinkStrength();    end;        DoLogging(k);    if(~issparse(TheJournal.Lambda))        fprintf(1,'k = %i : Lambda is no longer sparse \n',k);    end;end;% Plot the strength of the links between the robot and map over timefigure(3);hold on;cmap = [colormap('hot'); colormap('jet'); colormap('gray')];Temp = randperm(size(cmap,1));Handles = [];IDs = [];for i=1:size(TheJournal.Feature,2)    IDs = [IDs; TheJournal.Feature{i}.id];    thandle = plot(TheJournal.Feature{i}.Link(1,:),(abs(TheJournal.Feature{i}.Link(2,:))),'k-');    set(thandle,'Color',cmap(Temp(i),:));    Handles(end+1) = thandle;end;    legend(Handles,int2str(IDs));xlabel('Time','FontSize',14);ylabel('Link Strength','FontSize',14);title('Shared Feature-Vehicle Information vs Time','FontSize',14);axis tight;set(gca,'box','on','yscale','log','ylim',[0 Truth.VehicleTrajectory(1,end)],'FontSize',14);return;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% This function executes the motion update for the information filter by forming it as the addition% of the new pose to the state vector followed by the marginalization of the previous posefunction Information_DoProjection(k);global Params;global TheJournal;global Data;global Graphics;% Motion model:%   x_new = x_old + velocity_x * delta_time%   y_new = y_old + velocity_y * delta_time% JacobianF = speye(1);% Velocity vectoru = Data.Velocity(2,find(Data.Velocity(1,:)==k));%%%%%%%%%%%%%%%% The time projection operation for the information matrix and information vector% as viewed as the process of (1) augmenting the state to include the new% pose and, subsequently, (2) marginalizing over the old pose. A% description can be found in Eustice et al. (eustice05a) Section III.A.% Step 1:   Add the new pose, xv(t+1), into the state vector%% Notice that the modifications to the information matrix require a small,% bounded number of computations, proportional to the size of the robot% pose. None of the elements corresponding to the map are affected.LambdaOld = TheJournal.Lambda;Lambda_11 = Params.Qinv;Lambda_12 = -Params.Qinv*F;Lambda_13 = zeros(1,size(TheJournal.Lambda,2)-1);Lambda_22 = TheJournal.Lambda(1,1) + F'*Params.Qinv*F;Lambda_23 = TheJournal.Lambda(1,2:end);Lambda_33 = TheJournal.Lambda(2:end,2:end);Lambda = [Lambda_11 Lambda_12 Lambda_13;...          Lambda_12' Lambda_22 Lambda_23;...          Lambda_13' Lambda_23' Lambda_33];% As with Lambda, the computational cost of altering the information vector% is minimal and does not scale with the size of the map. Of course, in the% nonlinear case, the computational benefits are contingent on knowledge of% the mean for xv(t).eta_1 = Params.Qinv*u;eta_2 = TheJournal.eta(1) - F'*Params.Qinv*u;eta_3 = TheJournal.eta(2:end);eta = [eta_1; eta_2; eta_3];% Let's show how the structure of the information matrix has changed now% that the new robot pose has been addedif(Params.verbose)    ShowLinkStrength(Lambda,1);    ShowLinkStrength(LambdaOld,0,Graphics.SecondFigure);    fprintf(1,'\n\n');    fprintf(1,'----------------------- \n\n');    fprintf(1,'TIME PROJECTION STEP: \n\n')    fprintf(1,'i)  The first component of the time projection step is to add \n');    fprintf(1,'    the new robot pose x_v(t+1) into the state vector. \n\n');    fprintf(1,'    Notice in Figure 1 that the new pose is only linked to the \n')    fprintf(1,'    old pose while the rest of the structure remains unchanged. \n');    fprintf(1,'    Compare this with the structure prior to state augmentation (Figure 2). \n');    pause;end;% Now, we marginalize over the old pose. Referring to the marginalization% table:%           alpha = [xv(t+1); map];     what we want to keep%           beta  = xv(t);              what we are marginalizing overalpha_indices = [1 3:size(Lambda,1)];beta_indices = 2;Lambda_aa = Lambda(alpha_indices,alpha_indices);Lambda_ab = Lambda(alpha_indices,beta_indices);Lambda_bb = Lambda(beta_indices,beta_indices);eta_a = eta(alpha_indices);

⌨️ 快捷键说明

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