Ray Tracing with raytrace(): define a reception local area instead of a single point
13 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Laurent Storrer
el 28 de Abr. de 2021
Comentada: Saad Humayun
el 2 de Abr. de 2024
Hi,
I'm trying to use Matlab's raytrace() function from the Communications toolbox with the Shooting & Bouncing Rays method to compute the received rays in a local area around the receiver RX, instead of just in a single point (RX).
The context is the following: I'm trying to compute reflections of RF waves on a human body, using Matlab's raytrace() function. I model the human body as a cylinder, compute a triangulation (needed for the raytrace() function) for it and feed that to the raytrace() function. Let's say I put the cylinder at the perfect angle w.r.t. the transmitter TX and the receiver RX, a ray corresponding to a single reflection is found. However if I move the cylinder of 10 cm the reflection is not found, which is logical. It is illustrated on the plot below (left: a reflection is found, right: no reflection is found):
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/599550/image.png)
However since the human body is not a perfect cylinder, in reality there is a high chance that for such a small displacement (10 cm) from the ideal position a reflection would still be present. That is why I would like to compute all rays arriving in a local area around RX as it is usually done in ray tracing simulations to compute the received power at RX, rather than at the RX precise point. This way I would detect rays even when the human body is not at the perfect position w.r.t. TX and RX.
I've already considered instantiating several RXs in a local area, but then I detect several rays while there should be only one, so if I add a new cylinder in the scene then I will not be able to discriminate those artificial rays from the ones coming from that new cylinder. I've also dug in the raytrace() function code. At line 405 it calls another raytrace() function, which at line 313-323 makes the test I want to perform. It defines a radius around RX and checks if the ray falls within that radius (I'm using Matlab 2021a):
% Calculate reception radius, i.e., alpha*d/sqrt(3)
radius = ((rayDist + srcPrjDist) .* maxAngularSep)/sqrt(3);
% Detect which rays hit the Rx and mitigate double counting.
% Because the first segment for LOS is already covered, no need to
% perform detection for it.
if refIdx > 1
% Flags of the rays that reach Rx. Note that intDist can be NaN
% if the ray hits a sharp edge. But (NaN > a) = 0 for any value
% of a.
isRxReached = (srcPrjDist > 0) & (rxPrjDist <= radius) & ...
(intDist >= srcPrjDist);
A way to proceed would be to extend that radius, but the function cannot be modified unfortunately, and shadowing the function with a modified local copy is usually bad practice (and doesn't work in this case since some validations are done within the function, that require code accessible only from the toolbox folder).
So does someone have an idea on how to proceed to compute rays in a local area? I include herebelow the code I use to generate TX, RX, the cylinder and the propagation model.
%% TX/RX
fc = 2.45e9;
tx = txsite("cartesian", "AntennaPosition", [0; 0; 1],"TransmitterFrequency", fc);
rx = rxsite("cartesian","AntennaPosition", [0; 3; 1]);
%figure;
scatter3(tx.AntennaPosition(1,:), tx.AntennaPosition(2,:), tx.AntennaPosition(3,:), 'sr', 'filled');hold on;
scatter3(rx.AntennaPosition(1,:), rx.AntennaPosition(2,:), rx.AntennaPosition(3,:), 'sb', 'filled');hold on;
xlabel('x');ylabel('y');zlabel('z');
legend('TX','RX');
%% Model human body as a cylinder
r = 1; % [m]
height = 1.75; % [m]
theta = linspace(0,2*pi,36).';
xc = 1.5; % center of the cylinder
yc = 1.6;
x = repmat(xc + r*cos(theta),[2 1]);
y = repmat(yc + r*sin(theta),[2 1]);
z = [0*ones(length(theta),1);height*ones(length(theta),1)];
P = [x y z];
[k,vol] = convhulln(P); % convex hull: set of points defining the boundary of the volume
trisurf(k,P(:,1),P(:,2),P(:,3),'FaceColor','magenta')
TR = triangulation(k,P);
%% Propagation model and raytracing
pm = propagationModel("raytracing","CoordinateSystem","cartesian","Method","sbr","MaxNumReflections",2,"SurfaceMaterial","perfect-reflector",...
"AngularSeparation","low");
rays = raytrace(tx, rx, pm, 'Map', TR);
noMPC = 1;
rays_n = rays{1};
if length(rays_n) > 1
refl = rays_n(2).ReflectionLocations; % the first element of rays_n is the direct path
line1 = [tx.AntennaPosition refl];
line2 = [refl rx.AntennaPosition];
plot3(line1(1,:),line1(2,:),line1(3,:),'b');
plot3(line2(1,:),line2(2,:),line2(3,:),'b');
noMPC = 0;
else
disp('No MPC, only direct path');
end
Thank you for your help!
0 comentarios
Respuesta aceptada
Yue Shang
el 29 de Abr. de 2021
Hi Laurent,
First, creating a finer mesh for the cylinder may help. For example, you will find one ray in the failing case if you define
theta = linspace(0,2*pi,360).';
I would suggest instantiating multiple rx sites in the local area as you mentioned, instead of modifying the reception sphere radius which can invalidate the shooting bouncing rays (SBR) method. For example, you can define 27 rx sites in a cubic around the primary rx site of interest:
[x, y,z] = meshgrid(-0.1:0.1:0.1, 2.9:0.1:3.1, 0.9:0.1:1.1);
rx = rxsite("cartesian","AntennaPosition", [x(:),y(:),z(:)]');
In the ray tracing result, rays{14} would be the "true" rays arriving at the primary rx and the other cell array elements contain the "artificial" rays arriving at the local area, for any number of cylinders in the scene.
3 comentarios
Yue Shang
el 30 de Abr. de 2021
Hi Laurent,
In the SBR ray tracing method, each ray represents a cone-shape tube whose size grows as the ray travels. The overlap between adjacent tubes should be minimal, for which the current reception sphere radius is designed. Increasing the reception sphere will likely end up with more than one ray for one rx, while there should be only one. You can refer to the following page for some description of this ray tracing method:
When you have multiple "artificial" rays, you may just pick one from them for your applications.
Hope this helps.
Más respuestas (1)
Saad Humayun
el 31 de Mzo. de 2024
Would you by any chance know how to access this part of raytrace(0 function in the newer versions of MATLAB? I know this is super late, but I would like to see the calculation of reception sphere and flagging logic similarly in the later versions too, as some of my rays in simulations are being missed and I want to be able to explain that phenomenon.
3 comentarios
Saad Humayun
el 2 de Abr. de 2024
I was just exploring comm.internal.raytrace in R2023b, as that is the one I was using earlier. From what you said, that is literally the best conclusion I came up with, because unfortunately I wasn't lucky enough to find any actual flagging or computation, just that C++ line instead which obviously I don't think users have access to.
Thanks a lot Laurent, super grateful for the comment!
Saad Humayun
el 2 de Abr. de 2024
Aside from this, would you think logically and theoretically MATLAB would keep the calculations similar even for the later versions when it comes to reception mechanisms of rays and receiver sites? Even though the exact lines of code aren't visible in these versions.
Ver también
Categorías
Más información sobre Propagation and Channel Models en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!