Advertisement
Guest User

Untitled

a guest
Nov 25th, 2015
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
MatLab 10.25 KB | None | 0 0
  1. function EKFLocalization
  2.     clear; close all;
  3.  
  4.  
  5.     % Map configuration
  6.     Size = 50;
  7.     NumLandmarks = 10;
  8.     Map=CreateMap(NumLandmarks, Size);  % Create map of size [Size*2 Size*2]
  9.  
  10.     %mode = 'one_landmark';
  11.     %mode = 'one_landmark_in_fov';
  12.     mode = 'landmarks_in_fov';
  13.  
  14.     % Sensor characterization
  15.     SigmaR = 1; % Standard deviation of the range
  16.     SigmaB = 0.7; % Standard deviation of the bearing
  17.     Q = diag([SigmaR^2 SigmaB^2]); % Cov matrix
  18.     fov = pi/2;        % fov = 2*alpha
  19.     max_range = 1 * Size;  % maximum sensor measurement range
  20.  
  21.     % Robot base characterization
  22.     SigmaX = 0.8; % Standard deviation in the x axis
  23.     SigmaY = 0.8; % Standard deviation in the y axis
  24.     SigmaTheta = 0.1; % Bearing standar deviation
  25.     R = diag([SigmaX^2 SigmaY^2 SigmaTheta^2]); % Cov matrix
  26.  
  27.     % Initialization of poses
  28.     x = [-Size+Size/3 -Size+Size/3 pi/2]';      % Ideal robot pose
  29.     xTrue = [-Size+Size/3 -Size+Size/3 pi/2]';  % Real robot pose
  30.     xEst = [-Size+Size/3 -Size+Size/3 pi/2]';   % Estimated robot pose by EKF
  31.     sEst = zeros(3,3);                          % Uncertainty of estimated robot pose
  32.  
  33.     % Drawings
  34.     plot(Map(1,:),Map(2,:),'sc');
  35.     axis([-Size-5 Size+5 -Size-5 Size+5]);
  36.     hold on;
  37.     DrawRobot(x,'r');    
  38.     DrawRobot(xTrue,'b');
  39.     DrawRobot(xEst,'g');
  40.     PlotEllipse(xEst,sEst,4,'g');
  41.  
  42.     nSteps = 20; % Number of motions
  43.     turning = 5; % Number of motions before turning (square path)
  44.  
  45.     u = [(2*Size-2*Size/3)/turning;0;0]; % Control action
  46.  
  47.     pause;
  48.  
  49.     % Let's go!
  50.     for (k = 1:nSteps-3) % Main loop
  51.  
  52.         u(3) = 0;
  53.         if mod(k,turning) == 0 % Turn?
  54.             u(3) = -pi/2;
  55.         end
  56.  
  57.         x = tcomp(x,u);             % New pose without noise    
  58.         noise = sqrt(R)*randn(3,1);     % Generate noise
  59.         noisy_u = tcomp(u,noise);   % Apply noise to the control action        
  60.         xTrue = tcomp(xTrue,noisy_u);   % New noisy pose (real robot pose)  
  61.  
  62.         % Get sensor observation/s
  63.         %
  64.        
  65.         % Prediction (done for all steps)      
  66.         xMed = tcomp(xEst,u);
  67.         incertidumbreXmed = J1(xEst, u)*sEst *J1(xEst, u)' + J2(xEst, u)*R *J2(xEst, u)';
  68.        
  69.         if(strcmp(mode, 'one_landmark') == 1)
  70.  
  71.             [z, l] = getRandomObservationFromPose(xTrue, Map, Q);
  72.             line([xTrue(1), Map(1,l)], [xTrue(2), Map(2,l)], 'Color', 'red');
  73.            
  74.             lxy = [Map(1,l) Map(2,l)];
  75.             K = incertidumbreXmed*getObsJac(xMed,lxy)' * inv(getObsJac(xMed, lxy) * incertidumbreXmed *getObsJac(xMed, lxy)' + Q);
  76.             zH = [z(1)-(getDistance(xMed, lxy)) ; z(2)-(getBearing(xMed,lxy))];
  77.             xEst = xMed + K * zH;
  78.             sEst = (eye(3) - K * getObsJac(xMed, lxy))*incertidumbreXmed;
  79.         end
  80.        
  81.        
  82.        
  83.         if(strcmp(mode,'one_landmark_in_fov') == 1)
  84.             restrictedMap = getObservationsInsideFOV(xTrue,Map,fov,max_range, Q);
  85.             [z, l] = getRandomObservationFromPose(xTrue,restrictedMap,Q);
  86.             if(l > 0)
  87.                 line([xTrue(1), restrictedMap(1,l)], [xTrue(2), restrictedMap(2,l)], 'Color', 'red');
  88.                 %
  89.                 % EKF Localization
  90.                 %
  91.                 lxy = [restrictedMap(1,l) restrictedMap(2,l)];
  92.  
  93.                
  94.  
  95.                 % Correction  
  96.                 K = incertidumbreXmed*getObsJac(xMed,lxy)' * inv(getObsJac(xMed, lxy) * incertidumbreXmed *getObsJac(xMed, lxy)' + sqrt(Q));
  97.                 zH = [z(1)-(getDistance(xMed, lxy)) ; z(2)-(getBearing(xMed,lxy))];
  98.                
  99.                 xEst = xMed + K * zH;
  100.                 sEst = (eye(3) - K * getObsJac(xMed, lxy))*incertidumbreXmed;
  101.  
  102.             else
  103.                 xEst = xMed;
  104.                 sEst = incertidumbreXmed;
  105.             end
  106.         end
  107.         if(strcmp(mode,'landmarks_in_fov') == 1)
  108.            
  109.             restrictedMap = getObservationsInsideFOV(xTrue,Map,fov,max_range, Q);
  110.             [z, l] = getKRandomObservationsFromPose(xTrue,restrictedMap,Q);
  111.             if(l(1) > 0)
  112.                 newMap = [];
  113.                 for r=1:length(l)
  114.                     newMap = [newMap ; [restrictedMap(1,l(r)) restrictedMap(2,l(r))]];
  115.                     line([xTrue(1), restrictedMap(1,l(r))], [xTrue(2), restrictedMap(2,l(r))], 'Color', 'red');
  116.                 end
  117.                 %
  118.                 % EKF Localization
  119.                 %
  120.                 newMap = newMap';
  121.                 klands = length(l);
  122.                
  123.                 % Correction  
  124.                 K1 = incertidumbreXmed*getKObsJac(xMed,newMap)';
  125.                 %Create a replicated Q
  126.                 Qrep = eye(2*klands);
  127.                 for kk=1:(2*klands)
  128.                     if (mod(kk,2) == 0)
  129.                         Qrep(kk,kk) = Q(1,1);
  130.                     else
  131.                         Qrep(kk,kk) = Q(2,2);
  132.                     end
  133.                 end
  134.                
  135.                 K2 = inv(getKObsJac(xMed, newMap) * incertidumbreXmed *getKObsJac(xMed, newMap)' + Qrep);
  136.                 K = K1 * K2;
  137.                
  138.                 zH = [];
  139.                 newMap
  140.                 for kk=1:klands
  141.                     zHone = [0 0]';
  142.                    
  143.                     zHone(1) = z(kk,1)-(getDistance(xMed, [newMap(1,kk) newMap(2,kk)])) ;
  144.                     zHone(2) = z(kk,2)-(getBearing(xMed, [newMap(1,kk) newMap(2,kk)]));
  145.                     zH = [zH ; zHone];
  146.                 end
  147.                
  148.                
  149.                 xEst = xMed + K * zH;
  150.                 sEst = (eye(3) - K * getKObsJac(xMed, newMap))*incertidumbreXmed;
  151.                
  152.             else
  153.                 xEst = xMed;
  154.                 sEst = incertidumbreXmed;
  155.             end
  156.            
  157.         end
  158.         %line([xTrue(1), Map(1,l)], [xTrue(2), Map(2,l)], 'Color', 'g');
  159.        
  160.        
  161.        
  162.         % Drawings
  163.         DrawRobot(x,'r');
  164.         %if(strcmp(mode, 'one_landmark')==0)drawFOV(xTrue,fov,max_range,'b'); end
  165.         DrawRobot(xTrue,'b');
  166.         DrawRobot(xEst,'g');
  167.         PlotEllipse(xEst,sEst,4,'g');
  168.  
  169.         pause;
  170.  
  171.     end
  172.  
  173. end % main
  174.  
  175. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%Create Map
  176.  
  177. function Map=CreateMap(NumLandmarks, Size)
  178.  
  179. Map=Size*2*rand(2,NumLandmarks)-Size;
  180.  
  181. end
  182.  
  183. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%get a Random observation (1
  184. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%landmark)
  185.  
  186. function [z,landmark] = getRandomObservationFromPose(x,Map,Q)
  187.     z = [0 0]; %Initially we have no observation and no landmark
  188.     landmark = -1;
  189.     if (size(Map,2) > 0) %if there is any landmark in the map
  190.         landmark = round(abs(rand)*(size(Map,2)-1))+1; %choose one random landmark
  191.         d = getDistance([Map(1,landmark) Map(2,landmark)], x) + randn * sqrt(Q(1,1)); %get the distance from the pose to the observed landmark
  192.         ang = getBearing([Map(1,landmark) Map(2,landmark)], x) + randn * sqrt(Q(2,2)); %get the bearing
  193.         z = [d ang]; %return it as a vector
  194.     end
  195.  
  196. end
  197.  
  198.  
  199. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%get a Random observation (K
  200. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%landmarks
  201.  
  202. function [z,landmarks] = getKRandomObservationsFromPose(x,Map,Q)
  203.     z = [];
  204.     landmarks = [];
  205.     if (size(Map,2) > 0)
  206.         for i=1:size(Map,2)
  207.             if(rand <= 0.75) %Only take 75percent of the landmarks
  208.                 d = getDistance([Map(1,i) Map(2,i)], x) + randn * Q(1,1);
  209.                 ang = getBearing([Map(1,i) Map(2,i)], x) + randn * Q(2,2);
  210.                 z = [z ; [d ang]];
  211.                 landmarks = [landmarks ; i];
  212.             end
  213.         end
  214.     end
  215.     if (length(landmarks) == 0)
  216.         landmarks = -1;
  217.     end
  218. end
  219.  
  220. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%get Jacobians for the 1-landmark
  221. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%detection
  222.  
  223. function jH = getObsJac(xPred,Landmark)
  224.     r = sqrt((Landmark(1)-xPred(1))^2 + ((Landmark(2)-xPred(2))^2));
  225.     a = -(Landmark(1) - xPred(1))/r;
  226.     b = -(Landmark(2) - xPred(2))/r;
  227.     c = (Landmark(2) - xPred(2))/(r^2);
  228.     d = -(Landmark(1) - xPred(1))/(r^2);
  229.     jH = [ a b 0 ; c d -1];
  230. end
  231.  
  232. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%get Jacobians for the K-landmarks
  233. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%detection
  234.  
  235. function jH = getKObsJac(xPred,resMap)
  236.     jH = [];
  237.     for i=1:size(resMap,2)
  238.         Landmark = [resMap(1,i) resMap(2,i)];
  239.         r = sqrt((Landmark(1)-xPred(1))^2 + ((Landmark(2)-xPred(2))^2));
  240.         a = -(Landmark(1) - xPred(1))/r;
  241.         b = -(Landmark(2) - xPred(2))/r;
  242.         c = (Landmark(2) - xPred(2))/(r^2);
  243.         d = -(Landmark(1) - xPred(1))/(r^2);
  244.         jTemp = [ a b 0 ; c d -1];
  245.         jH = [jH ; jTemp];
  246.     end
  247. end
  248.  
  249. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%getObservations for 1-Landmark
  250. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%detection
  251.  
  252. function MapFOV = getObservationsInsideFOV(x,Map,fov,max_range, Q)
  253.     %Check which landmarks are in range
  254.     MapFOV = [;];
  255.     for i=1:size(Map,2)
  256.         d = getDistance([Map(1,i) Map(2,i)], x);
  257.         ang = (getBearing([Map(1,i) Map(2,i)], x));
  258.         %line([x(1), Map(1,i)], [x(2), Map(2,i)], 'Color', 'magenta');
  259.         if (d <= max_range)
  260.             if((ang - x(3)) < fov/2 && (ang-x(3)) >= -fov/2)
  261.                 MapFOV = [ MapFOV [Map(1,i) ; Map(2,i)]];
  262.             end
  263.         end
  264.     end
  265. end
  266.  
  267.  
  268. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%getDistance given cartesian
  269. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%coordinate points
  270.  
  271. function d = getDistance(p1, p2)
  272.     d = (sqrt((p1(1) - p2(1))^2 + ((p1(2) - p2(2))^2)));
  273. end
  274.  
  275. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%get bearing between two points p1
  276. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%and p2
  277.  
  278. function ang = getBearing(p1, p2)
  279.     ang = atan2(p1(2) - p2(2), p1(1) - p2(1));
  280. end
  281.  
  282. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%Draw Field of View
  283.  
  284. function h = drawFOV(x,fov,max_range,c)
  285.  
  286. if nargin< 4; c = 'b'; end
  287.  
  288. alpha = fov/2;
  289. angles = -alpha:0.01:alpha;
  290. nAngles = size(angles,2);
  291. arc_points = zeros(2,nAngles);
  292.  
  293. for i=1:nAngles
  294. arc_points(1,i) =  max_range*cos(angles(i));
  295. arc_points(2,i) =  max_range*sin(angles(i));
  296.  
  297. aux_point = tcomp(x,[arc_points(1,i);arc_points(2,i);1]);
  298. arc_points(:,i) = aux_point(1:2);
  299. end
  300.  
  301.     h = plot([x(1) arc_points(1,:) x(1)],[x(2) arc_points(2,:) x(2)],c);
  302.  
  303. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement