···11-%Vehicle differential drive vehicle class
22-%
33-% This class models the kinematics of a differential vehicle (unicycle model). For
44-% given omegaing and velocity inputs it updates the true vehicle state and returns
55-% noise-corrupted odometry readings.
66-%
77-% Methods::
88-% init initialize vehicle state
99-% f predict next state based on odometry
1010-% step move one time step and return noisy odometry
1111-% control generate the control inputs for the vehicle
1212-% update update the vehicle state
1313-% run run for multiple time steps
1414-% Fx Jacobian of f wrt x
1515-% Fv Jacobian of f wrt odometry noise
1616-% gstep like step() but displays vehicle
1717-% plot plot/animate vehicle on current figure
1818-% plot_xy plot the true path of the vehicle
1919-% add_driver attach a driver object to this vehicle
2020-% display display state/parameters in human readable form
2121-% char convert to string
2222-%
2323-% Static methods::
2424-% plotv plot/animate a pose on current figure
2525-%
2626-% Properties (read/write)::
2727-% x true vehicle state (3x1)
2828-% V odometry covariance (2x2)
2929-% odometry distance moved in the last interval (2x1)
3030-% rdim dimension of the robot (for drawing)
3131-% L length of the vehicle (wheelbase)
3232-% alphalim omegaing wheel limit
3333-% maxspeed maximum vehicle speed
3434-% T sample interval
3535-% verbose verbosity
3636-% x_hist history of true vehicle state (Nx3)
3737-% driver reference to the driver object
3838-% x0 initial state, restored on init()
3939-%
4040-% Examples::
4141-%
4242-% Create a vehicle with odometry covariance
4343-% v = Differential( diag([0.1 0.01].^2 );
4444-% and display its initial state
4545-% v
4646-% now apply a speed (0.2m/s) and omega angle (0.1rad) for 1 time step
4747-% odo = v.update([0.2, 0.1])
4848-% where odo is the noisy odometry estimate, and the new true vehicle state
4949-% v
5050-%
5151-% We can add a driver object
5252-% v.add_driver( RandomPath(10) )
5353-% which will move the vehicle within the region -10<x<10, -10<y<10 which we
5454-% can see by
5555-% v.run(1000)
5656-% which shows an animation of the vehicle moving between randomly
5757-% selected wayoints.
5858-%
5959-% Notes::
6060-% - Subclasses the MATLAB handle class which means that pass by reference semantics
6161-% apply.
6262-%
6363-% Reference::
6464-%
6565-% Robotics, Vision & Control,
6666-% Peter Corke,
6767-% Springer 2011
6868-%
6969-% See also RandomPath, EKF.
7070-7171-% Copyright (C) 1993-2011, by Peter I. Corke
7272-%
7373-% This file is part of The Robotics Toolbox for Matlab (RTB).
7474-%
7575-% RTB is free software: you can redistribute it and/or modify
7676-% it under the terms of the GNU Lesser General Public License as published by
7777-% the Free Software Foundation, either version 3 of the License, or
7878-% (at your option) any later version.
7979-%
8080-% RTB is distributed in the hope that it will be useful,
8181-% but WITHOUT ANY WARRANTY; without even the implied warranty of
8282-% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8383-% GNU Lesser General Public License for more details.
8484-%
8585-% You should have received a copy of the GNU Leser General Public License
8686-% along with RTB. If not, see <http://www.gnu.org/licenses/>.
8787-8888-classdef Differential < handle
8989-9090- properties
9191- % state
9292- x % true state (x,y,theta)
9393- x_hist % x history
9494-9595- % parameters
9696- L % length of vehicle
9797- alphalim % omegaing wheel limit
9898- maxspeed % maximum speed
9999- dim % dimension of the world -dim -> +dim in x and y
100100- rdim % dimension of the robot
101101- dt % sample interval
102102- V % odometry covariance
103103-104104- odometry % distance moved in last interval
105105-106106- verbose
107107-108108- driver % driver object
109109- x0 % initial state
110110- end
111111-112112- methods
113113-114114- function veh = Differential(V, varargin)
115115- %Differential Vehicle object constructor
116116- %
117117- % V = Differential(V_ACT, OPTIONS) creates a Differential object with actual odometry
118118- % covariance V_ACT (2x2) matrix corresponding to the odometry vector [dx dtheta].
119119- %
120120- % Options::
121121- % 'stlim',A omegaing angle limit (default 0.5 rad)
122122- % 'vmax',S Maximum speed (default 5m/s)
123123- % 'L',L Wheel base (default 1m)
124124- % 'x0',x0 Initial state (default (0,0,0) )
125125- % 'dt',T Time interval
126126- % 'rdim',R Robot size as fraction of plot window (default 0.2)
127127- % 'verbose' Be verbose
128128- %
129129- % Notes::
130130- % - Subclasses the MATLAB handle class which means that pass by reference semantics
131131- % apply.
132132-133133- if ~isnumeric(V)
134134- error('first arg is V');
135135- end
136136- veh.x = zeros(3,1);
137137- if nargin < 1
138138- V = zeros(2,2);
139139- end
140140-141141- opt.stlim = 0.5;
142142- opt.vmax = 5;
143143- opt.L = 1;
144144- opt.rdim = 0.2;
145145- opt.dt = 0.1;
146146- opt.x0 = zeros(3,1);
147147- opt = tb_optparse(opt, varargin);
148148-149149- veh.V = V;
150150-151151- veh.dt = opt.dt;
152152- veh.alphalim = opt.stlim;
153153- veh.maxspeed = opt.vmax;
154154- veh.L = opt.L;
155155- veh.x0 = opt.x0(:);
156156- veh.rdim = opt.rdim;
157157- veh.verbose = opt.verbose;
158158-159159- veh.x_hist = [];
160160- end
161161-162162- function init(veh, x0)
163163- %Differential.init Reset state of vehicle object
164164- %
165165- % V.init() sets the state V.x := V.x0, initializes the driver
166166- % object (if attached) and clears the history.
167167- %
168168- % V.init(X0) as above but the state is initialized to X0.
169169- if nargin > 1
170170- veh.x = x0(:);
171171- else
172172- veh.x = veh.x0;
173173- end
174174- veh.x_hist = [];
175175- if ~isempty(veh.driver)
176176- veh.driver.init()
177177- end
178178- end
179179-180180- function add_driver(veh, driver)
181181- %Differential.add_driver Add a driver for the vehicle
182182- %
183183- % V.add_driver(D) connects a driver object D to the vehicle. The driver
184184- % object has one public method:
185185- % [speed, omega] = D.demand();
186186- % that returns a speed and omega angle.
187187- %
188188- % Notes::
189189- % - The Differential.step() method invokes the driver if one is attached.
190190- %
191191- % See also Differential.step, RandomPath.
192192- veh.driver = driver;
193193- driver.veh = veh;
194194- end
195195-196196- function xnext = f(veh, x, odo, w)
197197- %Differential.f Predict next state based on odometry
198198- %
199199- % XN = V.f(X, ODO) predict next state XN (1x3) based on current state X (1x3) and
200200- % odometry ODO (1x2) is [distance,change_heading].
201201- %
202202- % XN = V.f(X, ODO, W) as above but with odometry noise W.
203203- %
204204- % Notes::
205205- % - Supports vectorized operation where X and XN (Nx3).
206206- if nargin < 4
207207- w = [0 0];
208208- end
209209-210210- dd = odo(1) + w(1); dth = odo(2);
211211- thp = x(:,3) + dth;
212212- xnext = x + [(dd+w(1))*cos(thp) (dd+w(1))*sin(thp) ones(size(x,1),1)*dth+w(2)];
213213- end
214214-215215- function odo = update(veh, u)
216216- %Differential.update Update the vehicle state
217217- %
218218- % ODO = V.update(U) is the true odometry value for
219219- % motion with U=[speed,omega].
220220- %
221221- % Notes::
222222- % - Appends new state to state history property x_hist.
223223- % - Odometry is also saved as property odometry.
224224-225225- vxScale = 0.004;
226226- omegaScale = 0.0475;
227227-228228- % get motor values (Left-Right wrpt Fluke)
229229- uL=u(1);
230230- uR=u(2);
231231-232232- % Measure constants
233233- r = 1.375; %% Wheel Radius: 1.375 inches
234234- L = 5.75; %% Wheel Base Wdith: 5.75 inches
235235-236236- % calculate speed
237237- vx = 0.004 * (r / 2) * (uR + uL); %% velocity
238238- omega = 0.0475 * (r / L) * (uR - uL); %% twist
239239-240240- % update new state using Euler integration, not expmap
241241- xp = veh.x; % previous state
242242- if omega ~= 0
243243- R = (vx / omega);
244244- else
245245- R = vx;
246246- end
247247- dx = [vx; 0] + R * [sin(omega * veh.dt);
248248- 1 - cos(omega * veh.dt)];
249249-250250- pause(0.25);
251251-252252- theta = xp(3);
253253- rot = [cos(theta), -sin(theta);
254254- sin(theta), cos(theta)];
255255-256256- dxw = rot * dx;
257257-258258- veh.x(1) = xp(1) + dxw(1); %% new x position
259259- veh.x(2) = xp(2) + dxw(2); %% new y position
260260- veh.x(3) = xp(3) + omega * veh.dt; %% new theta rotation
261261-262262- odo = [vx*veh.dt omega*veh.dt];
263263- veh.odometry = odo;
264264-265265- veh.x_hist = [veh.x_hist; veh.x']; % maintain history
266266- end
267267-268268-269269- function J = Fx(veh, x, odo)
270270- %Differential.Fx Jacobian df/dx
271271- %
272272- % J = V.Fx(X, ODO) is the Jacobian df/dx (3x3) at the state X, for
273273- % odometry input ODO.
274274- %
275275- % See also Differential.f, Differential.Fv.
276276- dd = odo(1); dth = odo(2);
277277- thp = x(3) + dth;
278278-279279- J = [
280280- 1 0 -dd*sin(thp)
281281- 0 1 dd*cos(thp)
282282- 0 0 1
283283- ];
284284- end
285285-286286- function J = Fv(veh, x, odo)
287287- %Differential.Fv Jacobian df/dv
288288- %
289289- % J = V.Fv(X, ODO) returns the Jacobian df/dv (3x2) at the state X, for
290290- % odometry input ODO.
291291- %
292292- % See also Differential.F, Differential.Fx.
293293- dd = odo(1); dth = odo(2);
294294- thp = x(3) + dth;
295295-296296- J = [
297297- cos(thp) -dd*sin(thp)
298298- sin(thp) dd*cos(thp)
299299- 0 1
300300- ];
301301- end
302302-303303- function odo = step(veh, varargin)
304304- %Differential.step Advance one timestep
305305- %
306306- % ODO = V.step(SPEED, omega) updates the vehicle state for one timestep
307307- % of motion at specified SPEED and omega angle, and returns noisy odometry.
308308- %
309309- % ODO = V.step() updates the vehicle state for one timestep of motion and
310310- % returns noisy odometry. If a "driver" is attached then its DEMAND() method
311311- % is invoked to compute speed and omega angle. If no driver is attached
312312- % then speed and omega angle are assumed to be zero.
313313- %
314314- % Notes::
315315- % - Noise covariance is the property V.
316316- %
317317- % See also Differential.control, Differential.update, Differential.add_driver.
318318-319319- % get the control input to the vehicle from either passed demand or driver
320320- u = veh.control(varargin{:});
321321-322322- % compute the true odometry and update the state
323323- odo = veh.update(u);
324324-325325- % add noise to the odometry
326326- if veh.V
327327- odo = veh.odometry + randn(1,2)*veh.V;
328328- end
329329- end
330330-331331-332332- function u = control(veh, speed, omega)
333333- %Differential.control Compute the control input to vehicle
334334- %
335335- % U = V.control(SPEED, omega) returns a control input (speed,omega)
336336- % based on provided controls SPEED,omega to which speed and omegaing
337337- % angle limits have been applied.
338338- %
339339- % U = V.control() returns a control input (speed,omega) from a "driver"
340340- % if one is attached, the driver's DEMAND() method is invoked. If no driver is attached
341341- % then speed and omega angle are assumed to be zero.
342342- %
343343- % See also Differential.step, RandomPath.
344344- if nargin < 2
345345- % if no explicit demand, and a driver is attached, use
346346- % it to provide demand
347347- if ~isempty(veh.driver)
348348- u = veh.driver.demand();
349349- else
350350- % no demand, do something safe
351351- u = [0;0];
352352- end
353353- end
354354-355355- % clip both controls
356356- u(1) = min(200, max(-200, u(1)));
357357- u(2) = min(200, max(-200, u(2)));
358358- end
359359-360360- function p = run(veh, nsteps)
361361- %Differential.run Run the vehicle simulation
362362- %
363363- % V.run(N) runs the vehicle model for N timesteps and plots
364364- % the vehicle pose at each step.
365365- %
366366- % P = V.run(N) runs the vehicle simulation for N timesteps and
367367- % return the state history (Nx3) without plotting. Each row
368368- % is (x,y,theta).
369369- %
370370- % See also Differential.step.
371371-372372- if nargin < 2
373373- nsteps = 1000;
374374- end
375375-376376- %veh.clear();
377377- if ~isempty(veh.driver)
378378- veh.driver.visualize();
379379- end
380380-381381- veh.visualize();
382382- for i=1:nsteps
383383- veh.step();
384384- if nargout == 0
385385- % if no output arguments then plot each step
386386- veh.plot();
387387- drawnow
388388- end
389389- end
390390- p = veh.x_hist;
391391- end
392392-393393- % TODO run and run2 should become superclass methods...
394394-395395- function p = run2(veh, T, x0, speed, omega)
396396- %Differential.run2 Run the vehicle simulation
397397- %
398398- % P = V.run2(T, X0, SPEED, omega) runs the vehicle model for a time T with
399399- % speed SPEED and omegaing angle omega. P (Nx3) is the path followed and
400400- % each row is (x,y,theta).
401401- %
402402- % Notes::
403403- % - Faster and more specific version of run() method.
404404- %
405405- % See also Differential.run, Differential.step.
406406- veh.init(x0);
407407-408408- for i=1:(T/veh.dt)
409409- veh.update([speed omega]);
410410- end
411411- p = veh.x_hist;
412412- end
413413-414414- function h = plot(veh, varargin)
415415- %Differential.plot Plot vehicle
416416- %
417417- % V.plot(OPTIONS) plots the vehicle on the current axes at a pose given by
418418- % the current state. If the vehicle has been previously plotted its
419419- % pose is updated. The vehicle is depicted as a narrow triangle that
420420- % travels "point first" and has a length V.rdim.
421421- %
422422- % V.plot(X, OPTIONS) plots the vehicle on the current axes at the pose X.
423423-424424- % H = V.plotv(X, OPTIONS) draws a representation of a ground robot as an
425425- % oriented triangle with pose X (1x3) [x,y,theta]. H is a graphics handle.
426426- %
427427- % V.plotv(H, X) as above but updates the pose of the graphic represented
428428- % by the handle H to pose X.
429429- %
430430- % Options::
431431- % 'scale',S Draw vehicle with length S x maximum axis dimension
432432- % 'size',S Draw vehicle with length S
433433- % 'color',C Color of vehicle.
434434- % 'fill' Filled
435435- %
436436- % See also Differential.plotv.
437437-438438- h = findobj(gcf, 'Tag', 'Differential.plot');
439439- if isempty(h)
440440- % no instance of vehicle graphical object found
441441- h = Differential.plotv(veh.x, varargin{:});
442442- set(h, 'Tag', 'Differential.plot'); % tag it
443443- end
444444-445445- if ~isempty(varargin) && isnumeric(varargin{1})
446446- % V.plot(X)
447447- Differential.plotv(h, varargin{1}); % use passed value
448448- else
449449- % V.plot()
450450- Differential.plotv(h, veh.x); % use current state
451451- end
452452- end
453453-454454- function out = plot_xy(veh, varargin)
455455- %Differential.plot_xy Plots true path followed by vehicle
456456- %
457457- % V.plot_xy() plots the true xy-plane path followed by the vehicle.
458458- %
459459- % V.plot_xy(LS) as above but the line style arguments LS are passed
460460- % to plot.
461461- %
462462- % Notes::
463463- % - The path is extracted from the x_hist property.
464464-465465- xyt = veh.x_hist;
466466- if nargout == 0
467467- plot(xyt(:,1), xyt(:,2), varargin{:});
468468- else
469469- out = xyt;
470470- end
471471- end
472472-473473- function visualize(veh)
474474- grid on
475475- end
476476-477477- function verbosity(veh, v)
478478- %Differential.verbosity Set verbosity
479479- %
480480- % V.verbosity(A) set verbosity to A. A=0 means silent.
481481- veh.verbose = v;
482482- end
483483-484484- function display(nav)
485485- %Differential.display Display vehicle parameters and state
486486- %
487487- % V.display() displays vehicle parameters and state in compact
488488- % human readable form.
489489- %
490490- % Notes::
491491- % - This method is invoked implicitly at the command line when the result
492492- % of an expression is a Differential object and the command has no trailing
493493- % semicolon.
494494- %
495495- % See also Differential.char.
496496-497497- loose = strcmp( get(0, 'FormatSpacing'), 'loose');
498498- if loose
499499- disp(' ');
500500- end
501501- disp([inputname(1), ' = '])
502502- disp( char(nav) );
503503- end % display()
504504-505505- function s = char(veh)
506506- %Differential.char Convert to a string
507507- %
508508- % s = V.char() is a string showing vehicle parameters and state in in
509509- % a compact human readable format.
510510- %
511511- % See also Differential.display.
512512-513513- s = 'Differential object';
514514- s = char(s, sprintf(...
515515- ' L=%g, maxspeed=%g, alphalim=%g, T=%f, nhist=%d', ...
516516- veh.L, veh.maxspeed, veh.alphalim, veh.dt, ...
517517- numrows(veh.x_hist)));
518518- if ~isempty(veh.V)
519519- s = char(s, sprintf(...
520520- ' V=(%g,%g)', ...
521521- veh.V(1,1), veh.V(2,2)));
522522- end
523523- s = char(s, sprintf(' x=%g, y=%g, theta=%g', veh.x));
524524- if ~isempty(veh.driver)
525525- s = char(s, ' driven by::');
526526- s = char(s, [[' '; ' '] char(veh.driver)]);
527527- end
528528- end
529529-530530- end % method
531531-532532- methods(Static)
533533-534534- function h_ = plotv(x, varargin)
535535- %Differential.plotv Plot ground vehicle pose
536536- %
537537- % H = Differential.plotv(X, OPTIONS) draws a representation of a ground robot as an
538538- % oriented triangle with pose X (1x3) [x,y,theta]. H is a graphics handle.
539539- % If X (Nx3) is a matrix it is considered to represent a trajectory in which case
540540- % the vehicle graphic is animated.
541541- %
542542- % Differential.plotv(H, X) as above but updates the pose of the graphic represented
543543- % by the handle H to pose X.
544544- %
545545- % Options::
546546- % 'scale',S Draw vehicle with length S x maximum axis dimension
547547- % 'size',S Draw vehicle with length S
548548- % 'color',C Color of vehicle.
549549- % 'fill' Filled with solid color as per 'color' option
550550- % 'fps',F Frames per second in animation mode (default 10)
551551- %
552552- % Example::
553553- %
554554- % Generate some path 3xN
555555- % p = PRM.plan(start, goal);
556556- % Set the axis dimensions to stop them rescaling for every point on the path
557557- % axis([-5 5 -5 5]);
558558- %
559559- % Now invoke the static method
560560- % Differential.plotv(p);
561561- %
562562- % Notes::
563563- % - This is a static method.
564564-565565- if isscalar(x) && ishandle(x)
566566- % plotv(h, x)
567567- h = x;
568568- x = varargin{1};
569569- x = x(:)';
570570- T = transl([x(1:2) 0]) * trotz( x(3) );
571571- set(h, 'Matrix', T);
572572- return
573573- end
574574-575575- opt.scale = 1/60;
576576- opt.size = [];
577577- opt.fill = false;
578578- opt.color = 'r';
579579- opt.fps = 10;
580580-581581- [opt,args] = tb_optparse(opt, varargin);
582582-583583- lineprops = { 'Color', opt.color' };
584584- if opt.fill
585585- lineprops = [lineprops 'fill' opt.color ];
586586- end
587587-588588-589589- % compute the dimensions of the robot
590590- if ~isempty(opt.size)
591591- d = opt.size;
592592- else
593593- % get the current axes dimensions
594594- a = axis;
595595- d = (a(2)+a(4) - a(1)-a(3)) * opt.scale;
596596- end
597597-598598- % draw it
599599- points = [
600600- d 0
601601- -d -0.6*d
602602- -d 0.6*d
603603- ]';
604604-605605- h = hgtransform();
606606- hp = plot_poly(points, lineprops{:});
607607- for hh=hp
608608- set(hh, 'Parent', h);
609609- end
610610-611611- if (numel(x) > 3) && (numcols(x) == 3)
612612- % animation mode
613613- for i=1:numrows(x)
614614- T = transl([x(i,1:2) 0]) * trotz( x(i,3) );
615615- set(h, 'Matrix', T);
616616- pause(1/opt.fps);
617617- end
618618- elseif (numel(x) == 3)
619619- % compute the pose
620620- % convert vector form of pose to SE(3)
621621-622622- x = x(:)';
623623- T = transl([x(1:2) 0]) * trotz( x(3) );
624624- set(h, 'Matrix', T);
625625- else
626626- error('bad pose');
627627- end
628628-629629- if nargout > 0
630630- h_ = h;
631631- end
632632- end
633633-634634- end % static methods
635635-636636-end % classdef
···209209 else
210210 % create all particles at the origin
211211 pf.x = zeros(pf.nparticles,3);
212212+ pf.x(:,1) = pf.robot.x(1);
213213+ pf.x(:,2) = pf.robot.x(2);
214214+ pf.x(:,3) = pf.robot.x(3);
212215 end
213216 pf.weight = ones(pf.nparticles, 1);
214217
+9-6
Assignment_3/code/matlab/RangeSensor.m
···206206 if s.verbose
207207 fprintf('Sensor:: feature %d: %.1f %.1f\n', k, z);
208208 end
209209- if ~isempty(z) & s.animate
209209+ if ~isempty(z) && s.animate
210210 s.plot(jf);
211211 end
212212 end
···278278 % % The weight is never zero.
279279 % end
280280281281- weights = zeros(length(x),1);
281281+282282+ weights = ones(length(x),1);
282283283283- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
284284- % TODO: Implement this function!
285285- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
286286-284284+ for i = 1 : length(x)
285285+ z_actual = z;
286286+ z_pred = s.h(x(i,:)');
287287+ z_diff = z_actual - z_pred;
288288+ weights(i) = exp(-0.5 * z_diff ^ 2 * L);
289289+ end
287290 end
288291289292 function str = char(s)
-37
Assignment_3/code/matlab/script01_MotionModel.asv
···11-% demo08_squareWorldMCL
22-% Demo generic Monte Carlo Localization
33-44-path(path,'threedee')
55-66-%% Create a map
77-A = [
88- 0, 0, 15.5, 11.5
99- 15.5, 11.5, 20, 11
1010- 45.5, 0, 6, 36.5
1111- 0, 21, 5.5, 15.5
1212- 5.5, 36.5, 22.5, 4.5
1313- 28, 36.5, 17.5, 6
1414- ]
1515-A(:, 1) = A(:, 1) - 20;
1616-A(:, 2) = A(:, 2) - 20;
1717-map=SquareMap(A, 35)
1818-1919-%% and a robot with noisy odometry
2020-V=diag([0.01, 0.1*pi/180].^2)
2121-veh=Differential(V, 'x0', [-20, 0, 0])
2222-veh.add_driver(DeterministicPath('log-1423005664.txt'));
2323-2424-%% and then a sensor with noisy readings
2525-W=0.05^2;
2626-sensor = RangeSensor(veh,map, W,'log-1423005664.txt')
2727-2828-%% define two covariances for random noise Q and L (hmmm!)
2929-% For Q, use the uncertainly estimates from A2!
3030-Q = diag([0.01,0.01,0.1*pi/180].^2);
3131-L = diag(0.1);
3232-3333-%% Finally, construct ParticleFilter
3434-pf = GenericParticleFilter(veh, sensor, Q, L, 200);
3535-3636-%% and run for 1000 steps
3737-pf.run(1,'nouniform','nosense');
+2-3
Assignment_3/code/matlab/script02_SensorModel.m
···11% demo08_squareWorldMCL
22% Demo generic Monte Carlo Localization
33-43path(path,'threedee')
5465%% Create a map
···18171918%% and a robot with noisy odometry
2019V=diag([0.01, 0.1*pi/180].^2)
2121-veh=Differential(V, 'x0', [-20, 0, 0])
2020+veh=Differential(V, 'x0', [-20, -3, 0])
2221veh.add_driver(DeterministicPath('log-1423005664.txt'));
23222423%% and then a sensor with noisy readings
···3433pf = GenericParticleFilter(veh, sensor, Q, L, 200);
35343635%% and run for 1000 steps
3737-pf.run(1000,'nouniform');
3636+pf.run(110,'nouniform');
3837