Is there a function that automatically reads when the line crosses the mesh?

3 次查看(过去 30 天)
I made buildings using the addmesh function, and I even connected the satellite and uav signals with lines, but I wonder if there is a function that automatically reads the lines that are blocked in the building as shown in the picture.
If the line gets stuck in the building as shown in the picture, I wonder if you can change the color or make a thorn. To make it easier, I want to distinguish between blocked line and line of sight.
Is it possible to use the rayIntersection function or the external function TriangleRayIntersection? If that's not possible, should we use the [faces and vertices] in the addmesh to find the points where the lines touch one by one?
referenceLocation=[37.498759 127.027487 0];
stopTime = 1;
scene = uavScenario(ReferenceLocation=referenceLocation,UpdateRate=10,StopTime=stopTime);
xTerrainLimits = [-200 200];
yTerrainLimits = [-200 200];
xBuildingLimits = [-150 150];
yBuildingLimits = [-150 150];
color = [0.80302 0.80298 0.8029];
info = addMesh(scene,"buildings",{"gangnam_11exit.osm" xBuildingLimits yBuildingLimits,"auto"},color,Verbose=true);
uavTrajectory = waypointTrajectory([-85 -20 50; -85 -20 50],TimeOfArrival=[0 stopTime],ReferenceFrame="ENU");
plat = uavPlatform("UAV",scene,Trajectory=uavTrajectory,ReferenceFrame="ENU");
updateMesh(plat,"quadrotor",{1},[1 0 0],eye(4));
settingTime = datetime('2025-01-01 00:00:00.000', 'TimeZone', 'Asia/Seoul', 'Format', 'yyyy-MM-dd HH:mm:ss.SSS');
gnssModel = gnssMeasurementGenerator(ReferenceLocation=referenceLocation,InitialTime=settingTime);
gnss = uavSensor("GNSS",plat,gnssModel);
fig = figure;
ax = show3D(scene);
uavPosition = uavTrajectory.lookupPose(linspace(0,stopTime,35));
hold on
uavTrajectoryLine = plot3(uavPosition(:,1),uavPosition(:,2),uavPosition(:,3),".",LineWidth=1.5,Color="cyan",MarkerSize=15);
legend(uavTrajectoryLine,"Trajectory",Location="northeast")
clf(fig,"reset")
set(fig,Position=[400 458 1120 420])
hScenePlot = uipanel(fig,Position=[0 0 0.5 1]);
ax = axes(hScenePlot);
[~,pltFrames] = show3D(scene,Parent=ax);
hold(ax,"on")
uavMarker = plot(pltFrames.UAV.BodyFrame,0,0,Marker="o",MarkerFaceColor="cyan");
uavTrajectoryLine = plot3(uavPosition(:,1),uavPosition(:,2),uavPosition(:,3),"--",LineWidth=1.5,Color="cyan");
legend(ax,[uavMarker uavTrajectoryLine],["UAV","Trajectory"],Location="northeast")
view(ax,[0 90])
axis(ax,"equal")
hold(ax,"off")
currTime = gnss.SensorModel.InitialTime;
setup(scene)
wgs84 = wgs84Ellipsoid('meter');
while scene.IsRunning
[~,~,p,satPos,status] = gnss.read ();
allSatPos = gnssconstellation(currTime); % ecef
[~,trueRecPos] = plat.read; % lla
trueRecPos_ecef = lla2ecef(trueRecPos); % uav ecef
trueRecPos_enu = lla2enu(trueRecPos,referenceLocation,"flat"); %uav enu
[az,el] = lookangles(trueRecPos,satPos,gnss.SensorModel.MaskAngle);
nsat = length(satPos(:,1));
enu_sat = zeros(nsat,3);
for k = 1:1:nsat
[enu_sat(k,1), enu_sat(k,2), enu_sat(k,3)] = ecef2enu(...
satPos(k,1), satPos(k,2), satPos(k,3), ...
trueRecPos(1), trueRecPos(2), trueRecPos(3), wgs84);
end
temp=1;
unit_sat = normalize(enu_sat,'norm',1);
target_z = 150;
scale_factors = target_z ./ unit_sat(:,3);
unit_sat_scaled = unit_sat .* scale_factors;
X = [trueRecPos_enu(1) * ones(nsat,1), unit_sat_scaled(:,1)]';
Y = [trueRecPos_enu(2) * ones(nsat,1), unit_sat_scaled(:,2)]';
Z = [trueRecPos_enu(3) * ones(nsat,1), unit_sat_scaled(:,3)]';
hold on;
uavSatLines = plot3(X,Y,Z, '-r', 'LineWidth', 1.5);
hold off;
end

回答(1 个)

Jianxin Sun
Jianxin Sun 2025-4-10
Hi, this example https://www.mathworks.com/help/uav/ug/simulate-gnss-multipath-effects-on-uav-flying-in-urban-environment.html shows how to categorize visible satellite into "visible", "blocked" and "multi-path". Using these categories, you can update your lines with different colors, similar to how this example set marker size and color accourding to the categories.
Relavent code
% Read the satellite pseudoranges.
[~,~,p,satPos,status] = gnss.read();
allSatPos = gnssconstellation(currTime);
currTime = currTime + seconds(1/scene.UpdateRate);
% Get the satellite azimuths and elevations from satellite positions.
[~,trueRecPos] = plat.read;
% NOTE: use lookangles twice to get multi-path information as well as
% blocked satellite information
[az,el] = lookangles(trueRecPos,satPos,gnss.SensorModel.MaskAngle);
[allAz,allEl,vis] = lookangles(trueRecPos,allSatPos,gnss.SensorModel.MaskAngle);
allEl(allEl<0) = NaN;
% Set categories of satellites based on the status (Blocked, Multipath, or Visible).
groups = categorical([-ones(size(allAz)); status.LOS],[-1 0 1],["Blocked","Multipath","Visible"]);
% NOTE: following code apply to skyplot, but similar workflow is
% possible with line plot as well
% Set different marker sizes so that you can see the multiple measurements from the same satellite.
markerSizes = 100*ones(size(groups));
markerSizes(groups=="Multipath") = 150;
% Update the sky plot.
set(sp,AzimuthData=[allAz; az],ElevationData=[allEl; el],GroupData=groups,MarkerSizeData=markerSizes);
  1 个评论
inhyeok
inhyeok 2025-4-11
It is correct that I made it with reference to this. But what I want is a visualized line, not a skyplot, but I wonder if I can change this code. And I wonder if I can use rayIntersection. Thank you for your answer.

请先登录,再进行评论。

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by