├── .gitattributes
├── .gitignore
├── FGS_SE.m
├── Figures
├── CorrectPlacement_MaximumLikelihood.fig
├── CorrectPlacement_MaximumLikelihood.jpg
├── CorrectPlacement_Minmax.fig
├── CorrectPlacement_Minmax.jpg
├── CorrectPlacement_Minmax_ZoomedIn.jpg
├── CorrectPlacement_Trilateration.fig
├── CorrectPlacement_Trilateration.jpg
├── GoldoniTestbed_MaximumLikelihood.fig
├── GoldoniTestbed_MaximumLikelihood.jpg
├── GoldoniTestbed_MinMax.fig
├── GoldoniTestbed_MinMax.jpg
├── GoldoniTestbed_MinMax_SS=0.jpg
├── GoldoniTestbed_Trilateration.fig
├── GoldoniTestbed_Trilateration.jpg
├── PerformanceTest_ShadowSpread_10Sensors.fig
├── PerformanceTest_ShadowSpread_10Sensors.jpg
├── PerformanceTest_ShadowSpread_4Sensors.fig
├── PerformanceTest_ShadowSpread_4Sensors.jpg
├── PerformanceTest_ShadowSpread_50Sensors.fig
└── PerformanceTest_ShadowSpread_50Sensors.jpg
├── GoldoniTestbed.m
├── MaximumLikelihood.m
├── MinMax.m
├── PerformanceTest_ShadowSpread.m
├── Related Reports
├── Performance and Recreating the results of Goldoni's Article.pdf
└── RSS Ranging Method Implementations.pdf
├── SingleTest.m
└── Trilateration.m
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 | *.sln merge=union
7 | *.csproj merge=union
8 | *.vbproj merge=union
9 | *.fsproj merge=union
10 | *.dbproj merge=union
11 |
12 | # Standard to msysgit
13 | *.doc diff=astextplain
14 | *.DOC diff=astextplain
15 | *.docx diff=astextplain
16 | *.DOCX diff=astextplain
17 | *.dot diff=astextplain
18 | *.DOT diff=astextplain
19 | *.pdf diff=astextplain
20 | *.PDF diff=astextplain
21 | *.rtf diff=astextplain
22 | *.RTF diff=astextplain
23 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | #################
2 | ## Eclipse
3 | #################
4 |
5 | *.pydevproject
6 | .project
7 | .metadata
8 | bin/
9 | tmp/
10 | *.tmp
11 | *.bak
12 | *.swp
13 | *~.nib
14 | local.properties
15 | .classpath
16 | .settings/
17 | .loadpath
18 |
19 | # External tool builders
20 | .externalToolBuilders/
21 |
22 | # Locally stored "Eclipse launch configurations"
23 | *.launch
24 |
25 | # CDT-specific
26 | .cproject
27 |
28 | # PDT-specific
29 | .buildpath
30 |
31 |
32 | #################
33 | ## Visual Studio
34 | #################
35 |
36 | ## Ignore Visual Studio temporary files, build results, and
37 | ## files generated by popular Visual Studio add-ons.
38 |
39 | # User-specific files
40 | *.suo
41 | *.user
42 | *.sln.docstates
43 |
44 | # Build results
45 |
46 | [Dd]ebug/
47 | [Rr]elease/
48 | x64/
49 | build/
50 | [Bb]in/
51 | [Oo]bj/
52 |
53 | # MSTest test Results
54 | [Tt]est[Rr]esult*/
55 | [Bb]uild[Ll]og.*
56 |
57 | *_i.c
58 | *_p.c
59 | *.ilk
60 | *.meta
61 | *.obj
62 | *.pch
63 | *.pdb
64 | *.pgc
65 | *.pgd
66 | *.rsp
67 | *.sbr
68 | *.tlb
69 | *.tli
70 | *.tlh
71 | *.tmp
72 | *.tmp_proj
73 | *.log
74 | *.vspscc
75 | *.vssscc
76 | .builds
77 | *.pidb
78 | *.log
79 | *.scc
80 |
81 | # Visual C++ cache files
82 | ipch/
83 | *.aps
84 | *.ncb
85 | *.opensdf
86 | *.sdf
87 | *.cachefile
88 |
89 | # Visual Studio profiler
90 | *.psess
91 | *.vsp
92 | *.vspx
93 |
94 | # Guidance Automation Toolkit
95 | *.gpState
96 |
97 | # ReSharper is a .NET coding add-in
98 | _ReSharper*/
99 | *.[Rr]e[Ss]harper
100 |
101 | # TeamCity is a build add-in
102 | _TeamCity*
103 |
104 | # DotCover is a Code Coverage Tool
105 | *.dotCover
106 |
107 | # NCrunch
108 | *.ncrunch*
109 | .*crunch*.local.xml
110 |
111 | # Installshield output folder
112 | [Ee]xpress/
113 |
114 | # DocProject is a documentation generator add-in
115 | DocProject/buildhelp/
116 | DocProject/Help/*.HxT
117 | DocProject/Help/*.HxC
118 | DocProject/Help/*.hhc
119 | DocProject/Help/*.hhk
120 | DocProject/Help/*.hhp
121 | DocProject/Help/Html2
122 | DocProject/Help/html
123 |
124 | # Click-Once directory
125 | publish/
126 |
127 | # Publish Web Output
128 | *.Publish.xml
129 | *.pubxml
130 |
131 | # NuGet Packages Directory
132 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line
133 | #packages/
134 |
135 | # Windows Azure Build Output
136 | csx
137 | *.build.csdef
138 |
139 | # Windows Store app package directory
140 | AppPackages/
141 |
142 | # Others
143 | sql/
144 | *.Cache
145 | ClientBin/
146 | [Ss]tyle[Cc]op.*
147 | ~$*
148 | *~
149 | *.dbmdl
150 | *.[Pp]ublish.xml
151 | *.pfx
152 | *.publishsettings
153 |
154 | # RIA/Silverlight projects
155 | Generated_Code/
156 |
157 | # Backup & report files from converting an old project file to a newer
158 | # Visual Studio version. Backup files are not needed, because we have git ;-)
159 | _UpgradeReport_Files/
160 | Backup*/
161 | UpgradeLog*.XML
162 | UpgradeLog*.htm
163 |
164 | # SQL Server files
165 | App_Data/*.mdf
166 | App_Data/*.ldf
167 |
168 | #############
169 | ## Windows detritus
170 | #############
171 |
172 | # Windows image file caches
173 | Thumbs.db
174 | ehthumbs.db
175 |
176 | # Folder config file
177 | Desktop.ini
178 |
179 | # Recycle Bin used on file shares
180 | $RECYCLE.BIN/
181 |
182 | # Mac crap
183 | .DS_Store
184 |
185 |
186 | #############
187 | ## Python
188 | #############
189 |
190 | *.py[co]
191 |
192 | # Packages
193 | *.egg
194 | *.egg-info
195 | dist/
196 | build/
197 | eggs/
198 | parts/
199 | var/
200 | sdist/
201 | develop-eggs/
202 | .installed.cfg
203 |
204 | # Installer logs
205 | pip-log.txt
206 |
207 | # Unit test / coverage reports
208 | .coverage
209 | .tox
210 |
211 | #Translations
212 | *.mo
213 |
214 | #Mr Developer
215 | .mr.developer.cfg
216 | *.asv
217 |
--------------------------------------------------------------------------------
/FGS_SE.m:
--------------------------------------------------------------------------------
1 | %% Iterative Grid Search for RSS-Based Emitter Localization
2 | % Main function implements the Full Grid search method provided in the
3 | % article given in the title. The variables required as input to the
4 | % function is described below. Detailed descriptions of these variables are
5 | % given in under the "Main Function" section.
6 | %
7 | %
8 | %
9 | % Name | Description |
10 | % ROI | Region of Interest |
11 | % gridSize | Grid Size |
12 | % N_s | Number of Sensors |
13 | % P_T | Real Emitter Transmit Power |
14 | % sigma | Shadow Spread |
15 | % alpha | Path Loss Exponent |
16 | % plotON | Plot Zoom Level |
17 | % dispON | Display placement and estimation |
18 | % assignS | Assign sensors, 0 otherwise |
19 | % assignE | Assign emitter, 0 otherwise |
20 | %
21 | %
22 | %
23 | % Dependencies for Plots:
24 | % makedatatip.m
25 | % subtightplot.m
26 |
27 | function [estErr, sPos, ePos, estELoc] = ...
28 | FGS_SE( ROI, gridSize, N_s, P_T, P_E, sigma, alpha_actual, alpha_assumed...
29 | , recSens ...
30 | , plotON, dispON, tableON...
31 | , useTime, useKE...
32 | , assignS, assignE, centerSensors, centerEmitters)
33 | %% Main Function
34 | % This function implements a single estimation of an emitter using sensors
35 | % that are placed randomly. First a gridded coordinate system is created.
36 | % Then sensor and emitter locations are assigned. After placement received
37 | % signal power values are created. Using these values and the known sensor
38 | % locations emitters location is estimated. The error of estimation is
39 | % found and returned at the end of the function.
40 | %
41 | % If plotON is given as 0 nothing will be displayed and there will be no
42 | % plots. Changing it to something larger than 1 will create a plot multiple
43 | % subplots that shows the cost function with different vertical zoom levels
44 | % . Also sensor and emitter placements and the estimation is displayed.
45 |
46 |
47 | if useTime
48 | ccsTime = tic();
49 | end
50 |
51 | %% Creating the coordinate system
52 | % Here we create the 2D coordinate system as two matrices each including
53 | % their associated indexes. This plane will be our Region of Interest(ROI).
54 | % ROI is divided into grids to minimize computation.
55 | %
56 | % Vectorization in MATLAB is important as reallocation of memory takes a
57 | % lot of time in simulations therefore everything should be predefined for
58 | % best performance.
59 |
60 | % Locations on x axis
61 | u = 0:1:ROI-1;
62 | % Locations on y axis
63 | v = 0:1:ROI-1;
64 | % 2D plane indices for x and y
65 | [x,y] = meshgrid(u, v);
66 |
67 | newROI = ceil(ROI/gridSize); % ROI size with grid
68 | xGrid = zeros(newROI ,newROI );
69 | yGrid = zeros(newROI ,newROI );
70 |
71 | for k=0:gridSize:ROI-1
72 | xGrid(:,(k/gridSize+1)) ...
73 | = x(1:newROI , k+1)+gridSize/2;
74 | yGrid((k/gridSize+1),:) ...
75 | = y(k+1,1:newROI)+gridSize/2;
76 | end
77 |
78 | % Calculate time passed from start
79 | if useTime
80 | disp(['Creating the coordinate system took '...
81 | ,num2str(toc(ccsTime)), ' seconds']);
82 | pseTime = tic();
83 | end
84 |
85 | %% Placing Sensors/Emitter and Creating Sensor Distance Matrix
86 | % Making use of the vectorized coordinate system we will put the sensors
87 | % and the emitter in the simulation and create the distance matrices.
88 | % Sensors and the emitter is placed randomly. They are selected so that
89 | % none of them are on the same coordinates.
90 | %
91 | % The number of sensors is defined here. To change the number of sensors we
92 | % can increase N_s. Sensor and emitter locations are assigned randomly.
93 | % They are never in the same coordinates.
94 |
95 | if assignS
96 | sPos = assignS;
97 |
98 | if (dispON>0)
99 | for i=1:N_s
100 | disp(['Sensor '... % Display selected coordinates
101 | , num2str(i), ' is located at (', num2str(sPos(1,i))...
102 | ,',', num2str(sPos(2,i)), ').']);
103 | end
104 | end
105 | else
106 | % Sensor positions on (x,y) plane
107 | sPos = zeros(2,N_s);
108 | for i=1:N_s
109 | isDistinct = 0; % Boolean flag
110 | while ~isDistinct
111 | if(~centerSensors)
112 | sPos(:,i) = [rand()*ROI;rand()*ROI];
113 | else
114 | sPos(:,i) = [xGrid(1,randi([1 newROI], 1, 1)); ...
115 | yGrid(randi([1 newROI], 1, 1),1)];
116 | end
117 | isDistinct = 1; % True unless proven otherwise
118 | for j=1:i-1
119 | if (abs(sPos(1,i)-sPos(1,j))0)
126 | disp(['Sensor '... % Display selected coordinates
127 | , num2str(i), ' is located at (', num2str(sPos(1,i))...
128 | ,',', num2str(sPos(2,i)), ').']);
129 | end
130 | end
131 | end
132 | if assignE
133 | ePos = assignE;
134 | if (dispON>0)
135 | disp(['Emitter is placed at ('... % Display selected coordinates
136 | , num2str(ePos(1,1)) ,',', num2str(ePos(2,1)), ').']);
137 | end
138 | else
139 | % Emitter position on (x,y) plane
140 | ePos = zeros(2,1);
141 | isDistinct = 0; % Boolean flag
142 | while ~isDistinct
143 | if(~centerEmitters)
144 | ePos(:,1) = [rand()*ROI;rand()*ROI];
145 | else
146 | ePos(:,1) = [xGrid(1,randi([1 newROI], 1, 1)); ...
147 | yGrid(randi([1 newROI], 1, 1),1)];
148 | end
149 | isDistinct = 1; % Unless proven otherwise, true
150 | for i=1:N_s
151 | if (abs(sPos(1,i)-ePos(1,1))0)
160 | disp(['Emitter is placed at ('... % Display selected coordinates
161 | , num2str(ePos(1,1)) ,',', num2str(ePos(2,1)), ').']);
162 | end
163 | end
164 |
165 | % Distance from Sensor matrices
166 | sDist = zeros(newROI, newROI, N_s);
167 | for i=1:N_s
168 | sDist(:,:,i) = sqrt((sPos(1,i)-xGrid).^2 + (sPos(2,i)-yGrid).^2);
169 | end
170 |
171 | if useTime
172 | disp(['Placing sensors and emitter took '...
173 | , num2str(toc(pseTime)), ' seconds']);
174 | crssTime = tic();
175 | end
176 |
177 | %% Creating Received Signal Strength Values
178 | % These variables are required to create the signal model
179 | % $m_i = (P_T) (d_i)^{- \alpha}$ in Watts where
180 | % $1 \geq i \geq N_s$, $$P_T$ is the the transmit power of the emitter,
181 | % $\alpha$ is the path loss exponent and
182 | % $d_i=\sqrt{(x_i-x_0)^2 + (y_i-y_0)^2}$ is the distance between the
183 | % transmitter and the ith sensor.
184 | %
185 | % The sensor's experience log-normal shadowing. If the fast fading effects
186 | % are sufficiently averaged over time then the resulting unknown measured
187 | % power from the emitter to the ith sensor is given as
188 | % $r_i = 10^{log_{10} (m_i) + \frac{\omega_i}{10}}$ where
189 | % $\omega_i$ is a normal random variable with
190 | % mean of 0 and a variance of $\sigma^2$.
191 |
192 | % Sensor and emitter Distance
193 | d = sqrt((sPos(1,:)-ePos(1,:)).^2 + (sPos(2,:)-ePos(2,:)).^2);
194 |
195 | m = P_T * d.^(-alpha_actual); % Received signal in Watts
196 | r = m;
197 | for i=1:N_s
198 | r(i) = 10^(log10(m(i)) + normrnd(0,sigma)/10);
199 | % If received signal strength value is smaller than receiver
200 | % sensitivity we assume we didn't receive it
201 | if(r(i)0
265 | if length(ex)>1
266 | disp([num2str(length(ex)), ' possible solutions are found']);
267 | end
268 | end
269 | if dispON>0
270 | for i=1:length(ex)
271 | disp(['Emitter found at (', num2str(ex(i))...
272 | , ',', num2str(ey(i)), ').']);
273 | end
274 | end
275 | ex = ex(1);
276 | ey = ey(1);
277 |
278 | % Assign estimated emitter location
279 | estELoc = [ex;ey];
280 |
281 | % Now we have both the emitter location and the estimation, we can find
282 | % the error.
283 | estErr = sqrt((ePos(1,:)-ex).^2 + (ePos(2,:)-ey).^2);
284 |
285 | if dispON>0
286 | disp(['Estimation error is ', num2str(estErr) , ' meters.']);
287 | end
288 |
289 | % Draw the cost function table
290 | % Not implemented correctly yet. Assigns the cost function to the workspace
291 | % instead.
292 |
293 | if tableON
294 | ynames = xGrid(1,:);
295 | xnames = yGrid(:,1);
296 | assignin('base', 'ynames', ynames);
297 | assignin('base', 'xnames', xnames);
298 | assignin('base', 'theta', theta);
299 | assignin('base', 'sDist', sDist);
300 | disp('To see the table open ''theta'' variable in the workspace.')
301 | disp(['Emitter is minimum at the indices ['...
302 | , num2str(Iy(1)), ','...
303 | , num2str(Ix(1)), '] of the theta variable.']);
304 | end
305 |
306 | % Plot the resulting cost function
307 | if(plotON~=0)
308 | % We will use this figure to plot the cost function 3D
309 | figure('name','Emitter Location Estimation','numbertitle','off');
310 |
311 | % Find how many subplots are neccessary
312 | plotSize = 0;
313 | while(abs(plotON)>plotSize^2)
314 | plotSize=plotSize+1;
315 | end
316 |
317 | h=zeros(1,plotSize);
318 | for i=1:abs(plotON)
319 | if (exist('subtightplot', 'file'))
320 | subtightplot(plotSize,plotSize,i...
321 | ,[0.1 0.1], [0.1 0.1], [0.1 0.1]);
322 | else
323 | subplot(plotSize,plotSize,i)
324 | end
325 | % Change large values to NaN for better visual
326 | visual = theta;
327 | if(plotON>0)
328 | for j=1:i-1
329 | visual(visual>=(max(visual(:))-min(visual(:)))/2) = NaN;
330 | end
331 | end
332 | if(plotON<0)
333 | visual(visual>=nanmean(visual(:))) = NaN;
334 | for j=1:i
335 | visual(visual>=nanmean(visual(:))) = NaN;
336 | end
337 | end
338 | colormap([jet(128);gray(128)])
339 | h(i) = surf(xGrid,yGrid,visual);
340 |
341 | % Initially, both CDatas are equal to cost.
342 | color_S = 128; % 128-elements is each colormap
343 |
344 | % CData for surface
345 | cmin = min(visual(:));
346 | cmax = max(visual(:));
347 | C1 = min(color_S,round((color_S-1)*(visual-cmin)/(cmax-cmin))+1);
348 |
349 | % CData for pcolor
350 | C2 = 128+C1;
351 |
352 | % Update the CDatas for each object.
353 | set(h(i),'CData',C1);
354 |
355 | % Change the CLim property of axes so that it spans the
356 | % CDatas of both objects.
357 | caxis([min(C1(:)) max(C2(:))])
358 |
359 | set(h(i),'EdgeColor','none'); % This setting will make sure
360 | % that the plot is not black
361 | % because of default wire mesh
362 |
363 | % Set labels and title
364 | title(['Vertical Zoom Level ', num2str(i)]);
365 | xlabel('x');
366 | ylabel('y');
367 | zlabel('Cost/Objective Function');
368 |
369 |
370 | % Mark minimum on the map
371 | try
372 | makedatatip(h(i),[Iy Ix]);
373 | catch
374 | disp('Minimum value not shown as makedatatip.m is not found.');
375 | end
376 | end
377 |
378 | % Enlarge figure
379 | set(gcf, 'units','normalized','outerposition',[0.05 0.13 0.9 0.8]);
380 | end
381 |
382 | if(dispON)
383 | plotSELocations(ROI, gridSize, sPos, ePos, estELoc, estDist);
384 | end
385 |
386 | if useTime
387 | disp(['Calculating theta took ' num2str(toc(ctTime)) ' seconds']);
388 | disp(['Total elapsed time is ' num2str(toc(ccsTime)) ' seconds']);
389 | end
390 |
391 | end
392 |
393 | function [] = plotSELocations(ROI, gridSize, sPos, ePos, estELoc, estDist)
394 | %% PLOTSELOCATIONS plots sensors and emittors on figure to show locations
395 | % Required inputs are;
396 | % - Region of interest axis length (ROI)
397 | % - Grid axis length (gridSize)
398 | % - Sensor positions given as [x;y] (sPos)
399 | % - Emitter positions given as [x;y] (ePos)
400 |
401 | figure();
402 |
403 | % Create whole area
404 | axis([0 ROI 0 ROI]);
405 | hold on;
406 |
407 | % Place actual sensors
408 | scatter(sPos(1,:),sPos(2,:), 70, 'c'...
409 | , 'MarkerFaceColor', [1 0 0] ...
410 | , 'MarkerEdgeColor', [1 0 0]);
411 |
412 | % Place actual emitters also determine color for each
413 | c(1,:)= [round(rand), round(rand), round(rand)];
414 | while isequal(c(1,:),[1 1 1])
415 | c(1,:)= [round(rand), round(rand), round(rand)];
416 | end
417 |
418 | scatter(ePos(1,1),ePos(2,1), 70, 's' ...
419 | , 'MarkerFaceColor', [0 0 0]...
420 | , 'MarkerEdgeColor', [0 0 0]);
421 |
422 | % Place estimated emitter locations
423 | scatter(estELoc(1,1), estELoc(2,1), 70, 'd'...
424 | , 'MarkerFaceColor', [0 0 0]...
425 | , 'MarkerEdgeColor', [0 0 0]);
426 |
427 | % plot the circles and the point found
428 | if(estDist)
429 | t = linspace(0,2*pi)';
430 | for i = 1:length(sPos(1,:))
431 | plot(sPos(1,i) + estDist(i)*cos(t),sPos(2,i) + estDist(i)*sin(t),'-')
432 | end
433 | end
434 |
435 | hold off;
436 | % Set grid on with the given size
437 | tickValues = 0:gridSize:ROI+1;
438 | set(gca,'YTick',tickValues)
439 | set(gca,'XTick',tickValues)
440 | grid on;
441 |
442 | % Set title, labels and legend
443 | title('Sensor and Emitter placements for FGS_{SE}');
444 | xlabel('x');
445 | ylabel('y');
446 | legend('Sensors', 'Emitter', 'Estimated Emitter');
447 |
448 | end
449 |
450 | function varargout = makedatatip(hObj,index)
451 | %MAKEDATATIP Adds data tips to specified data points of graphical objects.
452 | %
453 | % MAKEDATATIP(HOBJ,INDEX) adds a datatip to the graphical object HOBJ at
454 | % the data point defined by INDEX.
455 | %
456 | % HOUT = MAKEDATATIP(...) returns handles to the created datatips.
457 | %
458 | % If HOBJ is 1-dimensional, INDEX can be of any size and is assumed to be
459 | % a linear index into the data contained by HOBJ. HOUT will be of the
460 | % same size as INDEX.
461 | %
462 | % If HOBJ is 2-dimensional and INDEX is N-by-2, INDEX is assumed to be a
463 | % set of N subscripts, and HOUT will be N-by-1. If INDEX is of any other
464 | % size, it is assumed to a linear index and HOUT will be the same size as
465 | % INDEX. Note that if you wish to specify 2 linear indices, ensure INDEX
466 | % is a column vector, else it will be assumed to be a single set of
467 | % subscripts.
468 | %
469 | % Example:
470 | % x = 1:10;
471 | % y = rand(1,10);
472 | % hPlot = plot(x,y);
473 | % makedatatip(hPlot,[3 8])
474 | %
475 | % Example:
476 | % [X,Y,Z] = peaks(30);
477 | % hObj = surf(X,Y,Z);
478 | % makedatatip(hObj,[5 8; 20 12; 22 28])
479 | %
480 | % Example: Add a single data tip to data point (5,25)
481 | % [X,Y,Z] = peaks(30);
482 | % hObj = surf(X,Y,Z);
483 | % makedatatip(hObj,[5 25])
484 | %
485 | % Example: Add two data tips to data points (5) and (25)
486 | % [X,Y,Z] = peaks(30);
487 | % hObj = surf(X,Y,Z);
488 | % makedatatip(hObj,[5; 25])
489 | %
490 | % Example: Add two data tips to an image
491 | % load mandrill
492 | % figure
493 | % hObj = image(X);
494 | % colormap(map)
495 | % makedatatip(hObj, [103 348; 270 348])
496 |
497 | % Author: Tim Farajian
498 | % Release: 2.0
499 | % Release date: 6/27/2012
500 |
501 | % Check # of inputs
502 | narginchk(2, 2)
503 | nargoutchk(0, 1)
504 |
505 | if length(hObj)~=1
506 | error('MAKEDATATIP:InvalidSize',...
507 | 'HOBJ must be scalar.');
508 | end
509 |
510 | % Ensure hObj is valid target
511 | if ~ishandle(hObj)
512 | error('MAKEDATATIP:InvalidHandle',...
513 | 'HOBJ is an invalid handle object.');
514 | end
515 |
516 | isImage = strcmp(get(hObj, 'Type'), 'image'); %Determine if target is image
517 |
518 | % Read data from hObj
519 | try
520 | X = get(hObj,'XData');
521 | Y = get(hObj,'YData');
522 | catch ME
523 | % Object must have an XData and YData property to be valid
524 | error('MAKEDATATIP:InvalidObjectType',...
525 | 'Objects of class ''%s'' are not a valid targets for datatips.',...
526 | class(handle(hObj)))
527 | end
528 | try
529 | Z = get(hObj,'ZData');
530 | catch ME
531 | % Many objects do not have a ZData property. Some will work, some will
532 | % not.
533 | isImage = true;
534 | end
535 | % Ensure subscripts or indices are valid values and sizes
536 | if isempty(index)
537 | return
538 | elseif ~isnumeric(index)
539 | error('MAKEDATATIP:InvalidDataType',...
540 | 'Subscript indices must be of numeric data type.')
541 | elseif any(index(:)<1) ||...
542 | any(fix(index(:))~=index(:)) ||...
543 | any(isinf(index(:)))
544 | error('MAKEDATATIP:InvalidIndex',...
545 | 'Subscript indices must be positive integers.')
546 | elseif ~isvector(index) && ~any(size(index)==2)
547 | error('MAKEDATATIP:InvalidIndexMatrixSize',...
548 | 'Subscript indices must be a vector or N-by-2 matrix.')
549 | elseif (~isImage && isvector(X)) || size(index,2)~=2
550 | hDatatip = zeros(size(index));
551 | index = index(:);
552 | isLinear = true;
553 | else
554 | hDatatip = zeros(size(index,1),1);
555 | isLinear = false;
556 | end
557 |
558 | % Get handle to datacursor mode object
559 | hDataCursorMgr = datacursormode(ancestor(hObj,'figure'));
560 |
561 | % Loop through each specified data point
562 | for n = 1:size(index,1)
563 |
564 | % Create position vector
565 | if isImage && isLinear
566 | [i j] = ind2sub([X(2) Y(2)], index(n));
567 | pos = [i j 1];
568 | elseif isImage
569 | pos = [index(n, 1) index(n, 2) 1];
570 | elseif isempty(Z)
571 | pos = [X(index(n)) Y(index(n))];
572 | elseif isLinear
573 | pos = [X(index(n)) Y(index(n)) Z(index(n))];
574 | else
575 | pos = [...
576 | X(index(n,1),index(n,2))...
577 | Y(index(n,1),index(n,2))...
578 | Z(index(n,1),index(n,2))];
579 | end
580 |
581 | % Create datatip
582 | hDatatip(n) = createDatatip(hDataCursorMgr, hObj);
583 | % Specify data cursor properties
584 | if isImage
585 | set(get(hDatatip(n),'DataCursor'),'DataIndex',pos,...
586 | 'TargetPoint',pos(1:2))
587 | else
588 | set(get(hDatatip(n),'DataCursor'),'DataIndex',index(n, :),...
589 | 'TargetPoint',pos)
590 | end
591 |
592 | % Specify datatip properties
593 | set(hDatatip(n),'Position',pos)
594 |
595 | end
596 |
597 | % Update all data cursors
598 | updateDataCursors(hDataCursorMgr)
599 |
600 | % Return handles if requested
601 | if nargout==1
602 | varargout = {hDatatip};
603 | end
604 |
605 | end
606 |
--------------------------------------------------------------------------------
/Figures/CorrectPlacement_MaximumLikelihood.fig:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KeremKaratas/RSSLocalizationSimulations/1768103507ca3e76f1e9cad2e1d09182c6896c87/Figures/CorrectPlacement_MaximumLikelihood.fig
--------------------------------------------------------------------------------
/Figures/CorrectPlacement_MaximumLikelihood.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KeremKaratas/RSSLocalizationSimulations/1768103507ca3e76f1e9cad2e1d09182c6896c87/Figures/CorrectPlacement_MaximumLikelihood.jpg
--------------------------------------------------------------------------------
/Figures/CorrectPlacement_Minmax.fig:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KeremKaratas/RSSLocalizationSimulations/1768103507ca3e76f1e9cad2e1d09182c6896c87/Figures/CorrectPlacement_Minmax.fig
--------------------------------------------------------------------------------
/Figures/CorrectPlacement_Minmax.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KeremKaratas/RSSLocalizationSimulations/1768103507ca3e76f1e9cad2e1d09182c6896c87/Figures/CorrectPlacement_Minmax.jpg
--------------------------------------------------------------------------------
/Figures/CorrectPlacement_Minmax_ZoomedIn.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KeremKaratas/RSSLocalizationSimulations/1768103507ca3e76f1e9cad2e1d09182c6896c87/Figures/CorrectPlacement_Minmax_ZoomedIn.jpg
--------------------------------------------------------------------------------
/Figures/CorrectPlacement_Trilateration.fig:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KeremKaratas/RSSLocalizationSimulations/1768103507ca3e76f1e9cad2e1d09182c6896c87/Figures/CorrectPlacement_Trilateration.fig
--------------------------------------------------------------------------------
/Figures/CorrectPlacement_Trilateration.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KeremKaratas/RSSLocalizationSimulations/1768103507ca3e76f1e9cad2e1d09182c6896c87/Figures/CorrectPlacement_Trilateration.jpg
--------------------------------------------------------------------------------
/Figures/GoldoniTestbed_MaximumLikelihood.fig:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KeremKaratas/RSSLocalizationSimulations/1768103507ca3e76f1e9cad2e1d09182c6896c87/Figures/GoldoniTestbed_MaximumLikelihood.fig
--------------------------------------------------------------------------------
/Figures/GoldoniTestbed_MaximumLikelihood.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KeremKaratas/RSSLocalizationSimulations/1768103507ca3e76f1e9cad2e1d09182c6896c87/Figures/GoldoniTestbed_MaximumLikelihood.jpg
--------------------------------------------------------------------------------
/Figures/GoldoniTestbed_MinMax.fig:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KeremKaratas/RSSLocalizationSimulations/1768103507ca3e76f1e9cad2e1d09182c6896c87/Figures/GoldoniTestbed_MinMax.fig
--------------------------------------------------------------------------------
/Figures/GoldoniTestbed_MinMax.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KeremKaratas/RSSLocalizationSimulations/1768103507ca3e76f1e9cad2e1d09182c6896c87/Figures/GoldoniTestbed_MinMax.jpg
--------------------------------------------------------------------------------
/Figures/GoldoniTestbed_MinMax_SS=0.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KeremKaratas/RSSLocalizationSimulations/1768103507ca3e76f1e9cad2e1d09182c6896c87/Figures/GoldoniTestbed_MinMax_SS=0.jpg
--------------------------------------------------------------------------------
/Figures/GoldoniTestbed_Trilateration.fig:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KeremKaratas/RSSLocalizationSimulations/1768103507ca3e76f1e9cad2e1d09182c6896c87/Figures/GoldoniTestbed_Trilateration.fig
--------------------------------------------------------------------------------
/Figures/GoldoniTestbed_Trilateration.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KeremKaratas/RSSLocalizationSimulations/1768103507ca3e76f1e9cad2e1d09182c6896c87/Figures/GoldoniTestbed_Trilateration.jpg
--------------------------------------------------------------------------------
/Figures/PerformanceTest_ShadowSpread_10Sensors.fig:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KeremKaratas/RSSLocalizationSimulations/1768103507ca3e76f1e9cad2e1d09182c6896c87/Figures/PerformanceTest_ShadowSpread_10Sensors.fig
--------------------------------------------------------------------------------
/Figures/PerformanceTest_ShadowSpread_10Sensors.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KeremKaratas/RSSLocalizationSimulations/1768103507ca3e76f1e9cad2e1d09182c6896c87/Figures/PerformanceTest_ShadowSpread_10Sensors.jpg
--------------------------------------------------------------------------------
/Figures/PerformanceTest_ShadowSpread_4Sensors.fig:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KeremKaratas/RSSLocalizationSimulations/1768103507ca3e76f1e9cad2e1d09182c6896c87/Figures/PerformanceTest_ShadowSpread_4Sensors.fig
--------------------------------------------------------------------------------
/Figures/PerformanceTest_ShadowSpread_4Sensors.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KeremKaratas/RSSLocalizationSimulations/1768103507ca3e76f1e9cad2e1d09182c6896c87/Figures/PerformanceTest_ShadowSpread_4Sensors.jpg
--------------------------------------------------------------------------------
/Figures/PerformanceTest_ShadowSpread_50Sensors.fig:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KeremKaratas/RSSLocalizationSimulations/1768103507ca3e76f1e9cad2e1d09182c6896c87/Figures/PerformanceTest_ShadowSpread_50Sensors.fig
--------------------------------------------------------------------------------
/Figures/PerformanceTest_ShadowSpread_50Sensors.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KeremKaratas/RSSLocalizationSimulations/1768103507ca3e76f1e9cad2e1d09182c6896c87/Figures/PerformanceTest_ShadowSpread_50Sensors.jpg
--------------------------------------------------------------------------------
/GoldoniTestbed.m:
--------------------------------------------------------------------------------
1 | function [] = GoldoniTestbed()
2 | %% Goldoni Testbed
3 | % Initialize parameters for the simulation and run localization algorithms
4 | % with the placements done in Goldoni's article. Plot a scatterplot with 25
5 | % estimations and actual placements
6 |
7 | clear variables;
8 | clc;
9 | close all;
10 |
11 | %% Main simulation parameters
12 | % Area of Interest
13 | ROI = 19.5;
14 | % Grid Element Size
15 | gridSize = 0;
16 | % Number of Sensors
17 | N_s = 3;
18 | % Transmit Power of the Emitter (Watts)
19 | P_T = 1;
20 | % Assumed Transmit Power (Watts)
21 | P_E = 1;
22 | % Shadow Spread (dB)
23 | sigma = 2;
24 | % Path Loss Exponent (Actual)
25 | alpha_actual = 3.5;
26 | % Path Loss Exponent (Assumed)
27 | alpha_assumed = 3.5;
28 | % Receiver Sensitivity (Watts)
29 | recSens = -Inf;
30 |
31 | %% Output Flags
32 | % Display placements/estimation
33 | dispON = 0;
34 | % Time the Script
35 | useTime = 0;
36 |
37 | %% Simulation specific variables
38 | numOfEst = 25;
39 | % Goldoni placement
40 | sPos(:,1) = [17;2];
41 | sPos(:,2) = [9.5;10];
42 | sPos(:,3) = [2;2];
43 |
44 | % Assign Sensor Locations
45 | %sPos = 0;
46 | assignS = sPos;
47 |
48 | % T1
49 | ePosT1(:,1) = [17;9.5];
50 | % T2
51 | ePosT2(:,1) = [9.5;6];
52 | % T3
53 | ePosT3(:,1) = [9.5;9];
54 |
55 | %% Display Simulation Parameters
56 | % Display simulation paramaters if flag set
57 | if(dispON)
58 | disp(['Region of Interest is: ' ...
59 | , num2str(ROI), 'x', num2str(ROI)]);
60 | disp(['Region is divided into grids of size: '...
61 | , num2str(gridSize), 'x', num2str(gridSize)]);
62 | disp(['Number of sensors: ', num2str(N_s)]);
63 | disp(['Path Loss Exponent (Actual): ', num2str(alpha_actual)]);
64 | disp(['Path Loss Exponent (Assumed): ', num2str(alpha_assumed)]);
65 | disp(['Transmit Power (Actual): ', num2str(P_T)]);
66 | disp(['Transmit Power (Assumed): ', num2str(P_E)]);
67 | disp(['Shadow Spread (dB): ', num2str(sigma)]);
68 | end
69 |
70 | %% Main Function Call
71 | estELocT1 = zeros(2,numOfEst);
72 | estELocT2 = zeros(2,numOfEst);
73 | estELocT3 = zeros(2,numOfEst);
74 |
75 | estErrT1 = zeros(1,numOfEst);
76 | estErrT2 = zeros(1,numOfEst);
77 | estErrT3 = zeros(1,numOfEst);
78 |
79 | for k=1:numOfEst
80 | [estErrT1, ~, ~, estELocT1(:,k)] ...
81 | = MinMax( ROI, gridSize, N_s, P_T, P_E, sigma, alpha_actual ...
82 | , alpha_assumed, recSens ...
83 | , dispON ...
84 | , useTime, assignS, ePosT1);
85 | end
86 | disp(['Mean estimated error for T1: ' num2str(mean(estErrT1))])
87 |
88 | for k=1:numOfEst
89 | [estErrT2, ~, ~, estELocT2(:,k)] ...
90 | = MinMax( ROI, gridSize, N_s, P_T, P_E, sigma, alpha_actual ...
91 | , alpha_assumed, recSens ...
92 | , dispON ...
93 | , useTime, assignS, ePosT2);
94 | end
95 | disp(['Mean estimated error for T2: ' num2str(mean(estErrT2))])
96 |
97 | for k=1:numOfEst
98 | [estErrT3, ~, ~, estELocT3(:,k)] ...
99 | = MinMax( ROI, gridSize, N_s, P_T, P_E, sigma, alpha_actual ...
100 | , alpha_assumed, recSens ...
101 | , dispON ...
102 | , useTime, assignS, ePosT3);
103 | end
104 | disp(['Mean estimated error for T3: ' num2str(mean(estErrT3))])
105 |
106 | % Trilateration( ROI, gridSize, N_s, P_T, P_E, sigma, alpha_actual ...
107 | % , alpha_assumed, recSens ...
108 | % , dispON ...
109 | % , useTime, assignS, assignE);
110 | % MaximumLikelihood( ROI, gridSize, N_s, P_T, P_E, sigma, alpha_actual ...
111 | % , alpha_assumed, recSens ...
112 | % , dispON ...
113 | % , useTime, assignS, assignE);
114 |
115 | %% Plot known sensors and actual and estimated emitter locations
116 | plotSELocations(ROI, gridSize, sPos, ePosT1, ePosT2, ePosT3 ...
117 | , estELocT1, estELocT2, estELocT3);
118 |
119 | end
120 |
121 | function [] = plotSELocations(ROI, gridSize, sPos, ePosT1, ePosT2, ePosT3 ...
122 | , estELocT1, estELocT2, estELocT3)
123 | %% PLOTSELOCATIONS plots sensors and emittor on figure to show locations
124 | % Required inputs are;
125 | % - Region of interest axis length (ROI)
126 | % - Grid axis length (gridSize)
127 | % - Sensor positions given as [x;y] (sPos)
128 | % - Emitter positions given as [x;y] (ePos)
129 |
130 | figure();
131 |
132 | % Create whole area
133 | hold on;
134 | rectangle('Position', [0, 0, 19.5, 12]);
135 | % Place actual sensors
136 | scatter(sPos(1,:),sPos(2,:), 70, 'c'...
137 | , 'MarkerFaceColor', [1 0 0] ...
138 | , 'MarkerEdgeColor', [1 0 0]);
139 |
140 | % Place actual emitters also determine color for each
141 | c(1,:)= [round(rand), round(rand), round(rand)];
142 | while isequal(c(1,:),[1 1 1])
143 | c(1,:)= [round(rand), round(rand), round(rand)];
144 | end
145 |
146 | scatter(ePosT1(1,1),ePosT1(2,1), 70, 's' ...
147 | , 'MarkerFaceColor', [0 0 0]...
148 | , 'MarkerEdgeColor', [0 0 0]);
149 | scatter(ePosT2(1,1),ePosT2(2,1), 70, 's' ...
150 | , 'MarkerFaceColor', [0 0 0]...
151 | , 'MarkerEdgeColor', [0 0 0]);
152 | scatter(ePosT3(1,1),ePosT3(2,1), 70, 's' ...
153 | , 'MarkerFaceColor', [0 0 0]...
154 | , 'MarkerEdgeColor', [0 0 0]);
155 |
156 | % Place estimated emitter locations
157 | for k=1:length(estELocT1(1,:))
158 | hT1 = scatter(estELocT1(1,k), estELocT1(2,k), 60, '*'...
159 | , 'MarkerFaceColor', 'none'...
160 | , 'MarkerEdgeColor', [1 0 0]);
161 | end
162 | for k=1:length(estELocT2(1,:))
163 | hT2 = scatter(estELocT2(1,k), estELocT2(2,k), 60, '+'...
164 | , 'MarkerFaceColor', 'none'...
165 | , 'MarkerEdgeColor', [0 0 1]);
166 | end
167 | for k=1:length(estELocT3(1,:))
168 | hT3 = scatter(estELocT3(1,k), estELocT3(2,k), 60, 'p'...
169 | , 'MarkerFaceColor', 'none'...
170 | , 'MarkerEdgeColor', [0 1 0]);
171 | end
172 | hold off;
173 |
174 | % Set title, labels and legend
175 | title('Sensor and Emitter placements for FGS_{SE}');
176 | xlabel('x');
177 | ylabel('y');
178 | legend([hT1 hT2 hT3], {'T1', 'T2', 'T3'});
179 |
180 | end
--------------------------------------------------------------------------------
/MaximumLikelihood.m:
--------------------------------------------------------------------------------
1 | function [estErr, sPos, ePos, estELoc] = ...
2 | MaximumLikelihood( ROI, gridSize, N_s, P_T, P_E, sigma, alpha_actual ...
3 | , alpha_assumed, recSens ...
4 | , dispON ...
5 | , useTime, assignS, assignE)
6 | %% MAXIMUMLIKELIHOOD
7 | % This function implements Maximum Likelihood method to localize the
8 | % emitter. If sensor and emitter locations are not provided in assignS and
9 | % assignE they are randomly placed over the Region of Interest (ROI). This
10 | % random placement makes sure that sensors and emitters are placed in
11 | % seperate grids.
12 | %
13 | % ROI - Region of interest
14 | % gridSize - Length of the grids one side.
15 | % N_s - Number of Sensors
16 | % P_T - Actual transmit power of the emitter
17 | % P_E - Assumed transmit power of the emitter
18 | % sigma - shadowing effect in dB
19 | % alpha_actual - Actual value of the Path Loss Exponent
20 | % alpha_assumed - Assumed value of the Path Loss Exponent
21 | % recSens - Receiver Sensitivity
22 | % dispON - Flag for displaying simulation information (Set 1 to display)
23 | % useTime - Flag for timing parts of simulation (Set 1 to time)
24 | % assignS - Predefined locations for sensors (0 to randomly assign)
25 | % assignE - Predefined locations for emitter (0 to randomly assign)
26 |
27 | if useTime
28 | ccsTime = tic();
29 | end
30 |
31 | %% Placing Sensors/Emitter and Creating Sensor Distance Matrix
32 | % Making use of the vectorized coordinate system we will put the sensors
33 | % and the emitter in the simulation and create the distance matrices.
34 | % Sensors and the emitter is placed randomly. They are selected so that
35 | % none of them are on the same coordinates.
36 | %
37 | % The number of sensors is defined here. To change the number of sensors we
38 | % can increase N_s. Sensor and emitter locations are assigned randomly.
39 | % They are never in the same coordinates.
40 |
41 | if assignS
42 | sPos = assignS;
43 |
44 | if (dispON>0)
45 | for i=1:N_s
46 | disp(['Sensor '... % Display selected coordinates
47 | , num2str(i), ' is located at (', num2str(sPos(1,i))...
48 | ,',', num2str(sPos(2,i)), ').']);
49 | end
50 | end
51 | else
52 | % Sensor positions on (x,y) plane
53 | sPos = zeros(2,N_s);
54 | for i=1:N_s
55 | isDistinct = 0; % Boolean flag
56 | while ~isDistinct
57 | sPos(:,i) = [rand()*ROI;rand()*ROI];
58 | isDistinct = 1; % True unless proven otherwise
59 | for j=1:i-1
60 | if (abs(sPos(1,i)-sPos(1,j))0)
67 | disp(['Sensor '... % Display selected coordinates
68 | , num2str(i), ' is located at (', num2str(sPos(1,i))...
69 | ,',', num2str(sPos(2,i)), ').']);
70 | end
71 | end
72 | end
73 | if assignE
74 | ePos = assignE;
75 | if (dispON>0)
76 | disp(['Emitter is placed at ('... % Display selected coordinates
77 | , num2str(ePos(1,1)) ,',', num2str(ePos(2,1)), ').']);
78 | end
79 | else
80 | % Emitter position on (x,y) plane
81 | ePos = zeros(2,1);
82 | isDistinct = 0; % Boolean flag
83 | while ~isDistinct
84 | ePos(:,1) = [rand()*ROI;rand()*ROI];
85 | isDistinct = 1; % Unless proven otherwise, true
86 | for i=1:N_s
87 | if (abs(sPos(1,i)-ePos(1,1))0)
96 | disp(['Emitter is placed at ('... % Display selected coordinates
97 | , num2str(ePos(1,1)) ,',', num2str(ePos(2,1)), ').']);
98 | end
99 | end
100 |
101 | if useTime
102 | disp(['Placing sensors and emitter took '...
103 | , num2str(toc(ccsTime)), ' seconds']);
104 | crssTime = tic();
105 | end
106 |
107 | %% Creating Received Signal Strength Values
108 | % These variables are required to create the signal model
109 | % $m_i = (P_T) (d_i)^{- \alpha}$ in Watts where
110 | % $1 \geq i \geq N_s$, $$P_T$ is the the transmit power of the emitter,
111 | % $\alpha$ is the path loss exponent and
112 | % $d_i=\sqrt{(x_i-x_0)^2 + (y_i-y_0)^2}$ is the distance between the
113 | % transmitter and the ith sensor.
114 | %
115 | % The sensor's experience log-normal shadowing. If the fast fading effects
116 | % are sufficiently averaged over time then the resulting unknown measured
117 | % power from the emitter to the ith sensor is given as
118 | % $r_i = 10^{log_{10} (m_i) + \frac{\omega_i}{10}}$ where
119 | % $\omega_i$ is a normal random variable with
120 | % mean of 0 and a variance of $\sigma^2$.
121 |
122 | % Sensor and emitter Distance
123 | d = sqrt((sPos(1,:)-ePos(1,:)).^2 + (sPos(2,:)-ePos(2,:)).^2);
124 |
125 | % Received signal in Watts
126 | m = P_T * d.^(-alpha_actual);
127 | r = m;
128 | for i=1:N_s
129 | r(i) = 10^(log10(m(i)) + normrnd(0,sigma)/10);
130 | % If received signal strength value is smaller than receiver
131 | % sensitivity we assume we didn't receive it
132 | if(r(i)0
174 | if length(ex)>1
175 | disp([num2str(length(ex)), ' possible solutions are found']);
176 | end
177 | end
178 | if dispON>0
179 | for i=1:length(ex)
180 | disp(['Emitter found at (', num2str(ex(i))...
181 | , ',', num2str(ey(i)), ').']);
182 | end
183 | end
184 | ex = ex(1);
185 | ey = ey(1);
186 |
187 | % Assign estimated emitter location
188 | estELoc = [ex;ey];
189 |
190 | % Now we have both the emitter location and the estimation, we can find
191 | % the error.
192 | estErr = sqrt((ePos(1,:)-ex).^2 + (ePos(2,:)-ey).^2);
193 | if dispON>0
194 | disp(['Estimation error is ', num2str(estErr) , ' meters.']);
195 | end
196 |
197 | if(dispON)
198 | plotSELocations(ROI, gridSize, sPos, ePos, estELoc, estDist);
199 | end
200 |
201 | if useTime
202 | disp(['Calculating theta took ' num2str(toc(ctTime)) ' seconds']);
203 | disp(['Total elapsed time is ' num2str(toc(ccsTime)) ' seconds']);
204 | end
205 |
206 | end
207 |
208 | function [] = plotSELocations(ROI, gridSize, sPos, ePos, estELoc, estDist)
209 | %% PLOTSELOCATIONS plots sensors and emittors on figure to show locations
210 | % Required inputs are;
211 | % - Region of interest axis length (ROI)
212 | % - Grid axis length (gridSize)
213 | % - Sensor positions given as [x;y] (sPos)
214 | % - Emitter positions given as [x;y] (ePos)
215 |
216 | figure();
217 |
218 | % Create whole area
219 | hold on;
220 |
221 | % Place actual sensors
222 | scatter(sPos(1,:),sPos(2,:), 70, 'c'...
223 | , 'MarkerFaceColor', [1 0 0] ...
224 | , 'MarkerEdgeColor', [1 0 0]);
225 |
226 | % Place actual emitters also determine color for each
227 | c(1,:)= [round(rand), round(rand), round(rand)];
228 | while isequal(c(1,:),[1 1 1])
229 | c(1,:)= [round(rand), round(rand), round(rand)];
230 | end
231 |
232 | scatter(ePos(1,1),ePos(2,1), 70, 's' ...
233 | , 'MarkerFaceColor', [0 0 0]...
234 | , 'MarkerEdgeColor', [0 0 0]);
235 |
236 | % Place estimated emitter locations
237 | scatter(estELoc(1,1), estELoc(2,1), 70, 'd'...
238 | , 'MarkerFaceColor', [0 0 0]...
239 | , 'MarkerEdgeColor', [0 0 0]);
240 |
241 | % plot the circles and the point found
242 | t = linspace(0,2*pi)';
243 | for i = 1:length(sPos(1,:))
244 | plot(sPos(1,i) + estDist(i)*cos(t),sPos(2,i) + estDist(i)*sin(t),'-')
245 | end
246 |
247 | hold off;
248 | % Set grid on with the given size
249 | % tickValues = 0:gridSize:ROI+1;
250 | % set(gca,'YTick',tickValues)
251 | % set(gca,'XTick',tickValues)
252 | % grid on;
253 |
254 | % Set title, labels and legend
255 | title('Sensor and Emitter placements for FGS_{SE}');
256 | xlabel('x');
257 | ylabel('y');
258 | legend('Sensors', 'Emitter', 'Estimated Emitter');
259 |
260 | end
261 |
262 | function [x0,y0] = circleIntersect(X,Y,R)
263 | %% CIRCLEINTERSECT
264 | % Find the best point of intersection of 3 or more circles in the plane
265 | % usage: [x0,y0] = circleintersect(X,Y,R)
266 | %
267 | % X,Y,R are all vectors, listing the centers
268 | % and radii of each circle. All must be the
269 | % same size arrays. There must be at least 3
270 | % circles supplied.
271 | %
272 | % (x0,y0) forms the best estimate of the point
273 | % of intersection.
274 | %
275 | % Example:
276 | % X = rand(4,1);
277 | % Y = rand(4,1);
278 | % R = ones(4,1)*.5;
279 | % [x0,y0] = circleintersect(X,Y,R)
280 | %
281 | % x0 =
282 | % 0.23423
283 | % y0 =
284 | % 0.55481
285 | %
286 | % See also:
287 | %
288 | % Author: John D'Errico
289 | % e-mail: woodchips@rochester.rr.com
290 | % Release: 1.0
291 | % Release date: 2/26/09
292 |
293 | if nargin~= 3
294 | error('You must supply X, Y, R as separate vectors')
295 | end
296 |
297 | X = X(:);
298 | Y = Y(:);
299 | R = R(:);
300 |
301 | n = length(X);
302 | if (n ~= length(Y)) || (n ~= length(R))
303 | error('X, Y, R must all have the same number of elements')
304 | end
305 |
306 | if n < 3
307 | error('Must have at least 3 circles to find the overall intersection')
308 | end
309 |
310 | % time to do some actual work.
311 | % Pick one circle, subtract the equation
312 | % of that circle from the rest. This will
313 | % be a linear system in the intersection
314 | % point coordinates. When n > 3, the result
315 | % is not unique, depending on which circle
316 | % you choose to subtract from the remainder.
317 |
318 | % preallocate A and rhs so as not to grow
319 | % them in the loop.
320 | A = zeros((n-2)*(n-1),2);
321 | rhs = zeros((n-2)*(n-1),1);
322 |
323 | % loop over the circle to use as the
324 | % reference. This makes the solution unique,
325 | % thus finding the best overall point of near
326 | % intersection.
327 | k = 1:(n-1);
328 | for i = 1:n
329 | % the others are...
330 | j = setdiff(1:n,i);
331 |
332 | % build up the system of equations
333 | A(k,:) = 2*[X(i) - X(j),Y(i) - Y(j)];
334 |
335 | % and the right hand sides. Be careful here.
336 | % While I could have just squared these
337 | % elements, this can result in numerical
338 | % problems. Numerically more stable is to
339 | % do it this way, using the identity
340 | % A^2 - B^2 = (A-B)*(A+B)
341 | Xsq = (X(i) - X(j)).*(X(i) + X(j));
342 | Ysq = (Y(i) - Y(j)).*(Y(i) + Y(j));
343 | Rsq = (R(j) - R(i)).*(R(j) + R(i));
344 | rhs(k) = Rsq + Xsq + Ysq;
345 |
346 | % increment k until the last time through
347 | if i < n
348 | k = k + (n-1);
349 | end
350 | end
351 |
352 | % solve. backslash is best.
353 | xy0 = A\rhs;
354 | x0 = xy0(1);
355 | y0 = xy0(2);
356 |
357 | end
--------------------------------------------------------------------------------
/MinMax.m:
--------------------------------------------------------------------------------
1 | function [estErr, sPos, ePos, estELoc] = ...
2 | MinMax( ROI, gridSize, N_s, P_T, P_E, sigma, alpha_actual ...
3 | , alpha_assumed, recSens ...
4 | , dispON ...
5 | , useTime, assignS, assignE)
6 | %% MINMAX
7 | % This function implements Minmax method to localize the emitter. If
8 | % sensor and emitter locations are not provided in assignS and assignE they
9 | % are randomly placed over the Region of Interest (ROI). This random
10 | % placement makes sure that sensors and emitters are placed in seperate
11 | % grids.
12 | %
13 | % ROI - Region of interest
14 | % gridSize - Length of the grids one side.
15 | % N_s - Number of Sensors
16 | % P_T - Actual transmit power of the emitter
17 | % P_E - Assumed transmit power of the emitter
18 | % sigma - shadowing effect in dB
19 | % alpha_actual - Actual value of the Path Loss Exponent
20 | % alpha_assumed - Assumed value of the Path Loss Exponent
21 | % recSens - Receiver Sensitivity
22 | % dispON - Flag for displaying simulation information (Set 1 to display)
23 | % useTime - Flag for timing parts of simulation (Set 1 to time)
24 | % assignS - Predefined locations for sensors (0 to randomly assign)
25 | % assignE - Predefined locations for emitter (0 to randomly assign)
26 |
27 | if useTime
28 | ccsTime = tic();
29 | end
30 |
31 | %% Placing Sensors/Emitter and Creating Sensor Distance Matrix
32 | % Making use of the vectorized coordinate system we will put the sensors
33 | % and the emitter in the simulation and create the distance matrices.
34 | % Sensors and the emitter is placed randomly. They are selected so that
35 | % none of them are on the same coordinates.
36 | %
37 | % The number of sensors is defined here. To change the number of sensors we
38 | % can increase N_s. Sensor and emitter locations are assigned randomly.
39 | % They are never in the same coordinates.
40 |
41 | if assignS
42 | sPos = assignS;
43 |
44 | if (dispON>0)
45 | for i=1:N_s
46 | disp(['Sensor '... % Display selected coordinates
47 | , num2str(i), ' is located at (', num2str(sPos(1,i))...
48 | ,',', num2str(sPos(2,i)), ').']);
49 | end
50 | end
51 | else
52 | % Sensor positions on (x,y) plane
53 | sPos = zeros(2,N_s);
54 | for i=1:N_s
55 | isDistinct = 0; % Boolean flag
56 | while ~isDistinct
57 | sPos(:,i) = [rand()*ROI;rand()*ROI];
58 | isDistinct = 1; % True unless proven otherwise
59 | for j=1:i-1
60 | if (abs(sPos(1,i)-sPos(1,j))0)
67 | disp(['Sensor '... % Display selected coordinates
68 | , num2str(i), ' is located at (', num2str(sPos(1,i))...
69 | ,',', num2str(sPos(2,i)), ').']);
70 | end
71 | end
72 | end
73 | if assignE
74 | ePos = assignE;
75 | if (dispON>0)
76 | disp(['Emitter is placed at ('... % Display selected coordinates
77 | , num2str(ePos(1,1)) ,',', num2str(ePos(2,1)), ').']);
78 | end
79 | else
80 | % Emitter position on (x,y) plane
81 | ePos = zeros(2,1);
82 | isDistinct = 0; % Boolean flag
83 | while ~isDistinct
84 | ePos(:,1) = [rand()*ROI;rand()*ROI];
85 | isDistinct = 1; % Unless proven otherwise, true
86 | for i=1:N_s
87 | if (abs(sPos(1,i)-ePos(1,1))0)
96 | disp(['Emitter is placed at ('... % Display selected coordinates
97 | , num2str(ePos(1,1)) ,',', num2str(ePos(2,1)), ').']);
98 | end
99 | end
100 |
101 | if useTime
102 | disp(['Placing sensors and emitter took '...
103 | , num2str(toc(ccsTime)), ' seconds']);
104 | crssTime = tic();
105 | end
106 |
107 | %% Creating Received Signal Strength Values
108 | % These variables are required to create the signal model
109 | % $m_i = (P_T) (d_i)^{- \alpha}$ in Watts where
110 | % $1 \geq i \geq N_s$, $$P_T$ is the the transmit power of the emitter,
111 | % $\alpha$ is the path loss exponent and
112 | % $d_i=\sqrt{(x_i-x_0)^2 + (y_i-y_0)^2}$ is the distance between the
113 | % transmitter and the ith sensor.
114 | %
115 | % The sensor's experience log-normal shadowing. If the fast fading effects
116 | % are sufficiently averaged over time then the resulting unknown measured
117 | % power from the emitter to the ith sensor is given as
118 | % $r_i = 10^{log_{10} (m_i) + \frac{\omega_i}{10}}$ where
119 | % $\omega_i$ is a normal random variable with
120 | % mean of 0 and a variance of $\sigma^2$.
121 |
122 | % Sensor and emitter Distance
123 | d = sqrt((sPos(1,:)-ePos(1,:)).^2 + (sPos(2,:)-ePos(2,:)).^2);
124 |
125 | % Received signal in Watts
126 | m = P_T * d.^(-alpha_actual);
127 | r = m;
128 | for i=1:N_s
129 | r(i) = 10^(log10(m(i)) + normrnd(0,sigma)/10);
130 | % If received signal strength value is smaller than receiver
131 | % sensitivity we assume we didn't receive it
132 | if(r(i)0
164 | if length(ex)>1
165 | disp([num2str(length(ex)), ' possible solutions are found']);
166 | end
167 | end
168 | if dispON>0
169 | for i=1:length(ex)
170 | disp(['Emitter found at (', num2str(ex(i))...
171 | , ',', num2str(ey(i)), ').']);
172 | end
173 | end
174 | ex = ex(1);
175 | ey = ey(1);
176 |
177 | % Assign estimated emitter location
178 | estELoc = [ex;ey];
179 |
180 | % Now we have both the emitter location and the estimation, we can find
181 | % the error.
182 | estErr = sqrt((ePos(1,:)-ex).^2 + (ePos(2,:)-ey).^2);
183 | if dispON>0
184 | disp(['Estimation error is ', num2str(estErr) , ' meters.']);
185 | end
186 |
187 | if(dispON)
188 | plotSELocations(ROI, gridSize, sPos, ePos, estELoc, estDist);
189 | end
190 |
191 | if useTime
192 | disp(['Calculating theta took ' num2str(toc(ctTime)) ' seconds']);
193 | disp(['Total elapsed time is ' num2str(toc(ccsTime)) ' seconds']);
194 | end
195 |
196 | end
197 |
198 | function [] = plotSELocations(ROI, gridSize, sPos, ePos, estELoc, estDist)
199 | %% PLOTSELOCATIONS plots sensors and emittors on figure to show locations
200 | % Required inputs are;
201 | % - Region of interest axis length (ROI)
202 | % - Grid axis length (gridSize)
203 | % - Sensor positions given as [x;y] (sPos)
204 | % - Emitter positions given as [x;y] (ePos)
205 |
206 | figure();
207 |
208 | % Create whole area
209 | hold on;
210 |
211 | % Place actual sensors
212 | scatter(sPos(1,:),sPos(2,:), 70, 'c'...
213 | , 'MarkerFaceColor', [1 0 0] ...
214 | , 'MarkerEdgeColor', [1 0 0]);
215 |
216 | % Place actual emitters also determine color for each
217 | c(1,:)= [round(rand), round(rand), round(rand)];
218 | while isequal(c(1,:),[1 1 1])
219 | c(1,:)= [round(rand), round(rand), round(rand)];
220 | end
221 |
222 | scatter(ePos(1,1),ePos(2,1), 70, 's' ...
223 | , 'MarkerFaceColor', [0 0 0]...
224 | , 'MarkerEdgeColor', [0 0 0]);
225 |
226 | % Place estimated emitter locations
227 | scatter(estELoc(1,1), estELoc(2,1), 70, 'd'...
228 | , 'MarkerFaceColor', [0 0 0]...
229 | , 'MarkerEdgeColor', [0 0 0]);
230 |
231 | % plot the squares and the point found
232 | t = linspace(0,2*pi)';
233 | for i = 1:length(sPos(1,:))
234 | rectangle('Position', [sPos(1,i)-estDist(i) sPos(2,i)-estDist(i) ...
235 | estDist(i)*2 estDist(i)*2]);
236 | end
237 |
238 | hold off;
239 | % Set grid on with the given size
240 | % tickValues = 0:gridSize:ROI+1;
241 | % set(gca,'YTick',tickValues)
242 | % set(gca,'XTick',tickValues)
243 | % grid on;
244 |
245 | % Set title, labels and legend
246 | title('Sensor and Emitter placements for FGS_{SE}');
247 | xlabel('x');
248 | ylabel('y');
249 | legend('Sensors', 'Emitter', 'Estimated Emitter');
250 |
251 | end
--------------------------------------------------------------------------------
/PerformanceTest_ShadowSpread.m:
--------------------------------------------------------------------------------
1 | function [] = PerformanceTest_ShadowSpread()
2 | %% Performance test for shadow spread
3 | % Tests the performance of a localization technique for different shadow
4 | % spread values.
5 |
6 | clear variables;
7 | clc;
8 | close all;
9 |
10 | %% Main simulation parameters
11 | % Area of Interest
12 | ROI = 1000;
13 | % Grid Element Size
14 | gridSize = 1;
15 | % Number of Sensors
16 | N_s = 50;
17 | % Transmit Power of the Emitter (Watts)
18 | P_T = 1;
19 | % Assumed Transmit Power (Watts)
20 | P_E = 1;
21 | % Path Loss Exponent (Actual)
22 | alpha_actual = 3.5;
23 | % Path Loss Exponent (Assumed)
24 | alpha_assumed = 3.5;
25 | % Receiver Sensitivity (Watts)
26 | recSens = -Inf;
27 |
28 | %% Output Flags
29 | % Number of zoomed plots
30 | plotON = 0;
31 | % Display placements/estimation
32 | dispON = 0;
33 | % Assign Sensor Locations
34 | assignS = 0;
35 | % Assign Emitter Locations
36 | assignE = 0;
37 | % Time the Script
38 | useTime = 0;
39 |
40 | %% Simulation Spesific variables and Console Output of parameters
41 |
42 | % Number of Function Calls
43 | trialSize = 1000;
44 |
45 | % Shadow Spread Values
46 | SS = 0:2:10;
47 |
48 | % Calculation of mean estimated error values for different shadow spread.
49 | disp(' ');
50 | disp('Trilateration Mean Estimation Errors for Different Shadow Spread Values');
51 | disp(' ');
52 | disp('Simulation parameters are given below');
53 | disp(['ROI = ', num2str(ROI), ', N_s = ', num2str(N_s) ...
54 | , ', trialSize = ', num2str(trialSize)]);
55 | disp(['P_T = ', num2str(P_T), ', P_E = ', num2str(P_E) ...
56 | , ', gridSize = ', num2str(gridSize), ',']);
57 | disp(['Path Loss Exponent (Actual - Assumed) = ' ...
58 | , num2str(alpha_actual), ' - ', num2str(alpha_assumed)]);
59 | disp(' ');
60 | disp('Mean error per shadow spread value;');
61 |
62 | % Initialize simulation variables
63 | estErr = zeros(trialSize,length(SS));
64 | meanEstErrTrilateration = zeros(1,length(SS));
65 | meanEstErrMinMax = zeros(1,length(SS));
66 | meanEstErrMaximumLikelihood= zeros(1,length(SS));
67 |
68 | %% Trilateration Simulation
69 | disp(' ');
70 | disp('Trilateration Simulation');
71 | disp(' ');
72 |
73 | for sidx=1:numel(SS)
74 | sigma=SS(sidx);
75 | parfor i=1:trialSize
76 | estErr(i,sidx)...
77 | = Trilateration( ROI, gridSize, N_s, P_T, P_E, sigma, alpha_actual ...
78 | , alpha_assumed, recSens ...
79 | , dispON ...
80 | , useTime, assignS, assignE);
81 | end
82 | meanEstErrTrilateration(sidx) ...
83 | = sum(estErr(:,sidx))/trialSize;
84 | disp(['Shadow Spread ', num2str(sigma) ...
85 | , ' is complete with mean error: ' ...
86 | , num2str(meanEstErrTrilateration(sidx)), ' meters.']);
87 | end
88 |
89 |
90 | %% MinMax Simulation
91 | disp(' ');
92 | disp('MinMax Simulation');
93 | disp(' ');
94 |
95 | for sigma=SS
96 | for i=1:trialSize
97 | estErr(i,find(SS==sigma))...
98 | = MinMax( ROI, gridSize, N_s, P_T, P_E, sigma, alpha_actual ...
99 | , alpha_assumed, recSens ...
100 | , dispON ...
101 | , useTime, assignS, assignE);
102 | end
103 | meanEstErrMinMax(find(SS==sigma)) ...
104 | = sum(estErr(:,find(SS==sigma)))/trialSize;
105 | disp(['Shadow Spread ', num2str(sigma) ...
106 | , ' is complete with mean error: ' ...
107 | , num2str(meanEstErrMinMax(find(SS==sigma))), ' meters.']);
108 | end
109 |
110 | %% Maximum Likelihood Simulation
111 | disp(' ');
112 | disp('Maximum Likelihood Simulation');
113 | disp(' ');
114 |
115 | for sigma=SS
116 | for i=1:trialSize
117 | estErr(i,find(SS==sigma))...
118 | = MaximumLikelihood( ROI, gridSize, N_s, P_T, P_E, sigma, alpha_actual ...
119 | , alpha_assumed, recSens ...
120 | , dispON ...
121 | , useTime, assignS, assignE);
122 | end
123 | meanEstErrMaximumLikelihood(find(SS==sigma)) ...
124 | = sum(estErr(:,find(SS==sigma)))/trialSize;
125 | disp(['Shadow Spread ', num2str(sigma) ...
126 | , ' is complete with mean error: ' ...
127 | , num2str(meanEstErrMaximumLikelihood(find(SS==sigma))) ...
128 | , ' meters.']);
129 | end
130 | %% Plotting the Performance
131 | hold on;
132 | plot(SS, meanEstErrTrilateration, 'x-');
133 | plot(SS, meanEstErrMinMax, 'v-');
134 | plot(SS, meanEstErrMaximumLikelihood, 'p-');
135 | grid on;
136 | title('Mean Estimation Error for Different Shadow Spread Values');
137 | xlabel('Shadow spread (dB)');
138 | ylabel('Mean Estimation error (m)');
139 | legend('Trilateration' ...
140 | , 'MinMax' ...
141 | , 'Maximum Likelihood');
142 | hold off;
143 | end
--------------------------------------------------------------------------------
/Related Reports/Performance and Recreating the results of Goldoni's Article.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KeremKaratas/RSSLocalizationSimulations/1768103507ca3e76f1e9cad2e1d09182c6896c87/Related Reports/Performance and Recreating the results of Goldoni's Article.pdf
--------------------------------------------------------------------------------
/Related Reports/RSS Ranging Method Implementations.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KeremKaratas/RSSLocalizationSimulations/1768103507ca3e76f1e9cad2e1d09182c6896c87/Related Reports/RSS Ranging Method Implementations.pdf
--------------------------------------------------------------------------------
/SingleTest.m:
--------------------------------------------------------------------------------
1 | function [] = SingleTest()
2 | %% Example Test Function
3 | % Initialize parameters for the simulation and run localization algorithm
4 |
5 | clear variables;
6 | clc;
7 | close all;
8 |
9 | %% Main simulation parameters
10 | % Area of Interest
11 | ROI = 100;
12 | % Grid Element Size
13 | gridSize = 5;
14 | % Number of Sensors
15 | N_s = 3;
16 | % Transmit Power of the Emitter (Watts)
17 | P_T = 1;
18 | % Assumed Transmit Power (Watts)
19 | P_E = 1;
20 | % Shadow Spread (dB)
21 | sigma = 0;
22 | % Path Loss Exponent (Actual)
23 | alpha_actual = 3.5;
24 | % Path Loss Exponent (Assumed)
25 | alpha_assumed = 3.5;
26 | % Receiver Sensitivity (Watts)
27 | recSens = -Inf;
28 |
29 | %% Output Flags
30 | % Display placements/estimation
31 | dispON = 1;
32 | % Time the Script
33 | useTime = 0;
34 |
35 | % TEST Purposes
36 | % Corner Placement
37 | % sPos(:,1) = [0.001;100];
38 | % sPos(:,2) = [100;0.001];
39 | % sPos(:,3) = [100;100];
40 | % sPos(:,4) = [0.001;0.001];
41 | % Side Placement
42 | % sPos(:,1) = [0.001;50];
43 | % sPos(:,2) = [50;100];
44 | % sPos(:,3) = [50;0.001];
45 | % sPos(:,4) = [100;50];
46 | % Array Placement
47 | % sPos(:,1) = [50;0.001];
48 | % sPos(:,2) = [50;33];
49 | % sPos(:,3) = [50;66];
50 | % sPos(:,4) = [50;100];
51 | % Triangle Placement
52 | % sPos(:,1) = [0.001;0.001];
53 | % sPos(:,2) = [0.001;50];
54 | % sPos(:,3) = [100;50];
55 | % sPos(:,4) = [0.001;100];
56 | % ePos(:,1) = [71.01;70.01];
57 | % Errored Placement at GridSize 9 NonLinear KE
58 | % sPos(:,1) = [91.3337;15.2378];
59 | % sPos(:,2) = [82.5817;53.8342];
60 | % sPos(:,3) = [44.2678;10.6653];
61 | % sPos(:,4) = [96.1898;0.46342];
62 | % ePos(:,1) = [77.491;81.7303];
63 | % Errored Placement at GridSize 5
64 | % sPos(:,1) = [57.183;28.6018];
65 | % sPos(:,2) = [69.9134;79.6258];
66 | % sPos(:,3) = [44.1589;44.6216];
67 | % sPos(:,4) = [46.5662;27.9039];
68 | % ePos(:,1) = [67.5375;90.3665];
69 | % Errored Placement at GridSize 5 for KE with distances
70 | % sPos(:,1) = [63.6512;48.0362];
71 | % sPos(:,3) = [61.7058;65.3223];
72 | % sPos(:,4) = [54.9829;61.2566];
73 | % sPos(:,5) = [58.344;82.902];
74 | % ePos(:,1) = [72.5908;9.6768];
75 | % Random placement
76 | % sPos(:,1) = [82.5314;8.347];
77 | % sPos(:,2) = [13.3171;17.3389];
78 | % sPos(:,3) = [39.0938;83.138];
79 | % sPos(:,4) = [39.9258;52.6876];
80 | % ePos(:,1) = [41.6799;65.686];
81 | % Goldoni T1 placement
82 | sPos(:,1) = [17;2];
83 | sPos(:,2) = [9.5;10];
84 | sPos(:,3) = [2;2];
85 | ePos(:,1) = [17;9.5];
86 |
87 | % Assign Sensor Locations
88 | %sPos = 0;
89 | assignS = sPos;
90 |
91 | % Assign Emitter Locations
92 | %ePos = 0;
93 | assignE = ePos; % Assign Sensors, 0 otherwise
94 |
95 | %% Display Simulation Parameters
96 | % Display simulation paramaters if flag set
97 | if(dispON)
98 | disp(['Region of Interest is: ' ...
99 | , num2str(ROI), 'x', num2str(ROI)]);
100 | disp(['Region is divided into grids of size: '...
101 | , num2str(gridSize), 'x', num2str(gridSize)]);
102 | disp(['Number of sensors: ', num2str(N_s)]);
103 | disp(['Path Loss Exponent (Actual): ', num2str(alpha_actual)]);
104 | disp(['Path Loss Exponent (Assumed): ', num2str(alpha_assumed)]);
105 | disp(['Transmit Power (Actual): ', num2str(P_T)]);
106 | disp(['Transmit Power (Assumed): ', num2str(P_E)]);
107 | disp(['Shadow Spread (dB): ', num2str(sigma)]);
108 | end
109 |
110 | %% Main Function Call
111 | % FGS_SE( ROI, gridSize, N_s, P_T, P_E, sigma, alpha_actual, alpha_assumed...
112 | % , recSens ...
113 | % , plotON, dispON, tableON...
114 | % , useTime, useKE...
115 | % , assignS, assignE, centerSensors, centerEmitters);
116 | Trilateration( ROI, gridSize, N_s, P_T, P_E, sigma, alpha_actual ...
117 | , alpha_assumed, recSens ...
118 | , dispON ...
119 | , useTime, assignS, assignE);
120 | MinMax( ROI, gridSize, N_s, P_T, P_E, sigma, alpha_actual ...
121 | , alpha_assumed, recSens ...
122 | , dispON ...
123 | , useTime, assignS, assignE);
124 | MaximumLikelihood( ROI, gridSize, N_s, P_T, P_E, sigma, alpha_actual ...
125 | , alpha_assumed, recSens ...
126 | , dispON ...
127 | , useTime, assignS, assignE);
128 | end
--------------------------------------------------------------------------------
/Trilateration.m:
--------------------------------------------------------------------------------
1 | function [estErr, sPos, ePos, estELoc] = ...
2 | Trilateration( ROI, gridSize, N_s, P_T, P_E, sigma, alpha_actual ...
3 | , alpha_assumed, recSens ...
4 | , dispON ...
5 | , useTime, assignS, assignE)
6 | %% TRILATERATION
7 | % This function implements Trilateration method to localize the emitter. If
8 | % sensor and emitter locations are not provided in assignS and assignE they
9 | % are randomly placed over the Region of Interest (ROI). This random
10 | % placement makes sure that sensors and emitters are placed in seperate
11 | % grids.
12 | %
13 | % ROI - Region of interest
14 | % gridSize - Length of the grids one side.
15 | % N_s - Number of Sensors
16 | % P_T - Actual transmit power of the emitter
17 | % P_E - Assumed transmit power of the emitter
18 | % sigma - shadowing effect in dB
19 | % alpha_actual - Actual value of the Path Loss Exponent
20 | % alpha_assumed - Assumed value of the Path Loss Exponent
21 | % recSens - Receiver Sensitivity
22 | % dispON - Flag for displaying simulation information (Set 1 to display)
23 | % useTime - Flag for timing parts of simulation (Set 1 to time)
24 | % assignS - Predefined locations for sensors (0 to randomly assign)
25 | % assignE - Predefined locations for emitter (0 to randomly assign)
26 |
27 | if useTime
28 | ccsTime = tic();
29 | end
30 |
31 | %% Placing Sensors/Emitter and Creating Sensor Distance Matrix
32 | % Making use of the vectorized coordinate system we will put the sensors
33 | % and the emitter in the simulation and create the distance matrices.
34 | % Sensors and the emitter is placed randomly. They are selected so that
35 | % none of them are on the same coordinates.
36 | %
37 | % The number of sensors is defined here. To change the number of sensors we
38 | % can increase N_s. Sensor and emitter locations are assigned randomly.
39 | % They are never in the same coordinates.
40 |
41 | if assignS
42 | sPos = assignS;
43 |
44 | if (dispON>0)
45 | for i=1:N_s
46 | disp(['Sensor '... % Display selected coordinates
47 | , num2str(i), ' is located at (', num2str(sPos(1,i))...
48 | ,',', num2str(sPos(2,i)), ').']);
49 | end
50 | end
51 | else
52 | % Sensor positions on (x,y) plane
53 | sPos = zeros(2,N_s);
54 | for i=1:N_s
55 | isDistinct = 0; % Boolean flag
56 | while ~isDistinct
57 | sPos(:,i) = [rand()*ROI;rand()*ROI];
58 | isDistinct = 1; % True unless proven otherwise
59 | for j=1:i-1
60 | if (abs(sPos(1,i)-sPos(1,j))0)
67 | disp(['Sensor '... % Display selected coordinates
68 | , num2str(i), ' is located at (', num2str(sPos(1,i))...
69 | ,',', num2str(sPos(2,i)), ').']);
70 | end
71 | end
72 | end
73 | if assignE
74 | ePos = assignE;
75 | if (dispON>0)
76 | disp(['Emitter is placed at ('... % Display selected coordinates
77 | , num2str(ePos(1,1)) ,',', num2str(ePos(2,1)), ').']);
78 | end
79 | else
80 | % Emitter position on (x,y) plane
81 | ePos = zeros(2,1);
82 | isDistinct = 0; % Boolean flag
83 | while ~isDistinct
84 | ePos(:,1) = [rand()*ROI;rand()*ROI];
85 | isDistinct = 1; % Unless proven otherwise, true
86 | for i=1:N_s
87 | if (abs(sPos(1,i)-ePos(1,1))0)
96 | disp(['Emitter is placed at ('... % Display selected coordinates
97 | , num2str(ePos(1,1)) ,',', num2str(ePos(2,1)), ').']);
98 | end
99 | end
100 |
101 | if useTime
102 | disp(['Placing sensors and emitter took '...
103 | , num2str(toc(ccsTime)), ' seconds']);
104 | crssTime = tic();
105 | end
106 |
107 | %% Creating Received Signal Strength Values
108 | % These variables are required to create the signal model
109 | % $m_i = (P_T) (d_i)^{- \alpha}$ in Watts where
110 | % $1 \geq i \geq N_s$, $$P_T$ is the the transmit power of the emitter,
111 | % $\alpha$ is the path loss exponent and
112 | % $d_i=\sqrt{(x_i-x_0)^2 + (y_i-y_0)^2}$ is the distance between the
113 | % transmitter and the ith sensor.
114 | %
115 | % The sensor's experience log-normal shadowing. If the fast fading effects
116 | % are sufficiently averaged over time then the resulting unknown measured
117 | % power from the emitter to the ith sensor is given as
118 | % $r_i = 10^{log_{10} (m_i) + \frac{\omega_i}{10}}$ where
119 | % $\omega_i$ is a normal random variable with
120 | % mean of 0 and a variance of $\sigma^2$.
121 |
122 | % Sensor and emitter Distance
123 | d = sqrt((sPos(1,:)-ePos(1,:)).^2 + (sPos(2,:)-ePos(2,:)).^2);
124 |
125 | % Received signal in Watts
126 | m = P_T * d.^(-alpha_actual);
127 | r = m;
128 | for i=1:N_s
129 | r(i) = 10^(log10(m(i)) + normrnd(0,sigma)/10);
130 | % If received signal strength value is smaller than receiver
131 | % sensitivity we assume we didn't receive it
132 | if(r(i)0
154 | if length(ex)>1
155 | disp([num2str(length(ex)), ' possible solutions are found']);
156 | end
157 | end
158 | if dispON>0
159 | for i=1:length(ex)
160 | disp(['Emitter found at (', num2str(ex(i))...
161 | , ',', num2str(ey(i)), ').']);
162 | end
163 | end
164 | ex = ex(1);
165 | ey = ey(1);
166 |
167 | % Assign estimated emitter location
168 | estELoc = [ex;ey];
169 |
170 | % Now we have both the emitter location and the estimation, we can find
171 | % the error.
172 | estErr = sqrt((ePos(1,:)-ex).^2 + (ePos(2,:)-ey).^2);
173 | if dispON>0
174 | disp(['Estimation error is ', num2str(estErr) , ' meters.']);
175 | end
176 |
177 | if(dispON)
178 | plotSELocations(ROI, gridSize, sPos, ePos, estELoc, estDist);
179 | end
180 |
181 | if useTime
182 | disp(['Calculating theta took ' num2str(toc(ctTime)) ' seconds']);
183 | disp(['Total elapsed time is ' num2str(toc(ccsTime)) ' seconds']);
184 | end
185 |
186 | end
187 |
188 | function [] = plotSELocations(ROI, gridSize, sPos, ePos, estELoc, estDist)
189 | %% PLOTSELOCATIONS plots sensors and emittors on figure to show locations
190 | % Required inputs are;
191 | % - Region of interest axis length (ROI)
192 | % - Grid axis length (gridSize)
193 | % - Sensor positions given as [x;y] (sPos)
194 | % - Emitter positions given as [x;y] (ePos)
195 |
196 | figure();
197 |
198 | % Create whole area
199 | hold on;
200 |
201 | % Place actual sensors
202 | scatter(sPos(1,:),sPos(2,:), 70, 'c'...
203 | , 'MarkerFaceColor', [1 0 0] ...
204 | , 'MarkerEdgeColor', [1 0 0]);
205 |
206 | % Place actual emitters also determine color for each
207 | c(1,:)= [round(rand), round(rand), round(rand)];
208 | while isequal(c(1,:),[1 1 1])
209 | c(1,:)= [round(rand), round(rand), round(rand)];
210 | end
211 |
212 | scatter(ePos(1,1),ePos(2,1), 70, 's' ...
213 | , 'MarkerFaceColor', [0 0 0]...
214 | , 'MarkerEdgeColor', [0 0 0]);
215 |
216 | % Place estimated emitter locations
217 | scatter(estELoc(1,1), estELoc(2,1), 70, 'd'...
218 | , 'MarkerFaceColor', [0 0 0]...
219 | , 'MarkerEdgeColor', [0 0 0]);
220 |
221 | % plot the circles and the point found
222 | t = linspace(0,2*pi)';
223 | for i = 1:length(sPos(1,:))
224 | plot(sPos(1,i) + estDist(i)*cos(t),sPos(2,i) + estDist(i)*sin(t),'-')
225 | end
226 |
227 | hold off;
228 | % Set grid on with the given size
229 | % tickValues = 0:gridSize:ROI+1;
230 | % set(gca,'YTick',tickValues)
231 | % set(gca,'XTick',tickValues)
232 | % grid on;
233 |
234 | % Set title, labels and legend
235 | title('Sensor and Emitter placements for FGS_{SE}');
236 | xlabel('x');
237 | ylabel('y');
238 | legend('Sensors', 'Emitter', 'Estimated Emitter');
239 |
240 | end
241 |
242 | function [x0,y0] = circleIntersect(X,Y,R)
243 | %% CIRCLEINTERSECT
244 | % Find the best point of intersection of 3 or more circles in the plane
245 | % usage: [x0,y0] = circleintersect(X,Y,R)
246 | %
247 | % X,Y,R are all vectors, listing the centers
248 | % and radii of each circle. All must be the
249 | % same size arrays. There must be at least 3
250 | % circles supplied.
251 | %
252 | % (x0,y0) forms the best estimate of the point
253 | % of intersection.
254 | %
255 | % Example:
256 | % X = rand(4,1);
257 | % Y = rand(4,1);
258 | % R = ones(4,1)*.5;
259 | % [x0,y0] = circleintersect(X,Y,R)
260 | %
261 | % x0 =
262 | % 0.23423
263 | % y0 =
264 | % 0.55481
265 | %
266 | % See also:
267 | %
268 | % Author: John D'Errico
269 | % e-mail: woodchips@rochester.rr.com
270 | % Release: 1.0
271 | % Release date: 2/26/09
272 |
273 | if nargin~= 3
274 | error('You must supply X, Y, R as separate vectors')
275 | end
276 |
277 | X = X(:);
278 | Y = Y(:);
279 | R = R(:);
280 |
281 | n = length(X);
282 | if (n ~= length(Y)) || (n ~= length(R))
283 | error('X, Y, R must all have the same number of elements')
284 | end
285 |
286 | if n < 3
287 | error('Must have at least 3 circles to find the overall intersection')
288 | end
289 |
290 | % time to do some actual work.
291 | % Pick one circle, subtract the equation
292 | % of that circle from the rest. This will
293 | % be a linear system in the intersection
294 | % point coordinates. When n > 3, the result
295 | % is not unique, depending on which circle
296 | % you choose to subtract from the remainder.
297 |
298 | % preallocate A and rhs so as not to grow
299 | % them in the loop.
300 | A = zeros((n-2)*(n-1),2);
301 | rhs = zeros((n-2)*(n-1),1);
302 |
303 | % loop over the circle to use as the
304 | % reference. This makes the solution unique,
305 | % thus finding the best overall point of near
306 | % intersection.
307 | k = 1:(n-1);
308 | for i = 1:n
309 | % the others are...
310 | j = setdiff(1:n,i);
311 |
312 | % build up the system of equations
313 | A(k,:) = 2*[X(i) - X(j),Y(i) - Y(j)];
314 |
315 | % and the right hand sides. Be careful here.
316 | % While I could have just squared these
317 | % elements, this can result in numerical
318 | % problems. Numerically more stable is to
319 | % do it this way, using the identity
320 | % A^2 - B^2 = (A-B)*(A+B)
321 | Xsq = (X(i) - X(j)).*(X(i) + X(j));
322 | Ysq = (Y(i) - Y(j)).*(Y(i) + Y(j));
323 | Rsq = (R(j) - R(i)).*(R(j) + R(i));
324 | rhs(k) = Rsq + Xsq + Ysq;
325 |
326 | % increment k until the last time through
327 | if i < n
328 | k = k + (n-1);
329 | end
330 | end
331 |
332 | % solve. backslash is best.
333 | xy0 = A\rhs;
334 | x0 = xy0(1);
335 | y0 = xy0(2);
336 |
337 | end
--------------------------------------------------------------------------------