├── .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 | % 10 | % 11 | % 12 | % 13 | % 14 | % 15 | % 16 | % 17 | % 18 | % 19 | % 20 | %
Name Description
ROI Region of Interest
gridSize Grid Size
N_s Number of Sensors
P_T Real Emitter Transmit Power
sigma Shadow Spread
alpha Path Loss Exponent
plotON Plot Zoom Level
dispON Display placement and estimation
assignS Assign sensors, 0 otherwise
assignE Assign emitter, 0 otherwise
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 --------------------------------------------------------------------------------