Agrarsense
LidarNoiseModel.cpp
Go to the documentation of this file.
1// Copyright(c) 2022 FrostBit Software Lab at the Lapland University of Applied Sciences
2//
3// This work is licensed under the terms of the MIT license.
4// For a copy, see <https://opensource.org/licenses/MIT>.
5
6#include "LidarNoiseModel.h"
8
9#include "Math/UnrealMathUtility.h"
10#include <stdlib.h>
11
12bool LidarNoiseModel::CheckSnowflakeHit(FHitResult& HitInfo, const FVector EndTrace, const FVector LidarLocation, const FWeatherParameters& WeatherParameters)
13{
14 return CheckSnowflakeHitWinterSim(HitInfo, WeatherParameters.Precipitation, WeatherParameters.PrecipitationParticleSize, EndTrace, LidarLocation);;
15}
16
17bool LidarNoiseModel::CheckSnowflakeHitWinterSim(FHitResult& HitInfo, const float PrecipitationAmount, const float ParticleSize, const FVector EndTrace, const FVector LidarLocation)
18{
19 // Create random value between 0.0 and 1.0
20 const float RandomValue = FMath::FRandRange(0.0, 1.0f);
21
22 FVector MaxDistance = EndTrace; // lidar max range
23 FVector StartPoint = LidarLocation; // start point is lidar position
24
25 float PrecipitationClass = CalculatePrecipitationClass(PrecipitationAmount, ParticleSize);
26
27 if (HitInfo.bBlockingHit)
28 {
29 MaxDistance = HitInfo.ImpactPoint;
30 }
31
32 FVector DirectionVector = EndTrace - StartPoint;
33 FVector NewStartPoint = StartPoint + 0.01 * DirectionVector; // make start point away from center of lidar
34 FVector NewVector = MaxDistance - NewStartPoint; // new vector from new start point to end point
35 FVector NewHitpoint = NewStartPoint + RandomValue * NewVector; // generate new point from new start point to end point
36 NewHitpoint *= 1e-2;
37 float Distance = FVector::Dist(StartPoint, NewHitpoint) / 100; // distance between NewHitpoint and NewStartPoint divided by 100 to get meters
38
39 // Actual probability formula calculation
40 const float ProbabilityFormula = PrecipitationClass / 10 * exp(-pow(Distance - (4 + 0.2 * PrecipitationClass), 2.0)
41 / pow(2, 2.0)) + 0.2 * PrecipitationClass / 10 * exp(-pow(Distance - (7 + 0.2 * PrecipitationClass), 2.0) / pow(1, 2.0));
42
43 // If RandomValue is smaller than ProbabilityFormula from formula we 'hit' the trace to snowflake
44 bool HitSnowflake = RandomValue < ProbabilityFormula;
45 if (HitSnowflake)
46 {
47 // Assign new hitpoint
48 HitInfo.ImpactPoint = NewHitpoint;
49
50 // To identify the snowflake later, set component to nullptr if hitpoint is snowflake
51 HitInfo.Component = nullptr;
52 }
53
54 return HitSnowflake;
55}
56
57float LidarNoiseModel::CalculatePrecipitationClass(const float PrecipitationAmount, float ParticleSize)
58{
59 float PrecipitationClass = 0;
60
61 // Ensure ParticleSize is within the specified bounds (1.0 to 3.0) and adjust if necessary
62 if (ParticleSize < 1.0f) ParticleSize = 1.0f;
63 if (ParticleSize > 3.0f) ParticleSize = 3.0f;
64
65 if (PrecipitationAmount > 0 && PrecipitationAmount <= 33.33f) PrecipitationClass = 1 + ParticleSize;
66 else if (PrecipitationAmount > 33.33 && PrecipitationAmount <= 66.66f) PrecipitationClass = 2 + ParticleSize;
67 else if (PrecipitationAmount > 66.66 && PrecipitationAmount <= 100.00f) PrecipitationClass = 3 + ParticleSize;
68
69 return PrecipitationClass;
70}
static float CalculatePrecipitationClass(const float PrecipitationAmount, float ParticleSize)
static bool CheckSnowflakeHitWinterSim(FHitResult &HitInfo, const float PrecipitationAmount, const float ParticleSize, const FVector EndTrace, const FVector LidarLocation)
static bool CheckSnowflakeHit(FHitResult &HitInfo, const FVector EndTrace, const FVector LidarLocation, const FWeatherParameters &WeatherParameters)