Commit 1fd95bb8 authored by Armin Erraji's avatar Armin Erraji

Added PerceptionalCulling() that culls propagation paths, which level dropped below a threshold

parent 7fc0faab
......@@ -40,7 +40,7 @@ namespace ITAPropagationPathSim
void ConstructPropagationPaths(CPropagationPathList& oPaths);
private:
......@@ -94,6 +94,9 @@ namespace ITAPropagationPathSim
//Filter not visible, intersected, paths
void FilterVisiblePaths(const vector<CPropagationShapeShared> vpAllPathsIn, vector<CPropagationShapeShared>& vpVisiblePathsOut);
//Culling of unperceived paths
void PerceptionalCulling(const vector<CPropagationShapeShared> vpAllPathsIn, vector<CPropagationShapeShared>& vpAudiblePathsOut);
//Convert the propagation list
void ConvertShapeListsToPropagationPaths(ITAGeo::CPropagationPathList& oPathsOut);
......
......@@ -104,7 +104,8 @@ void ITAPropagationPathSim::CombinedModel::CPathEngine::ApplyEmitter(shared_ptr<
//Construct image edges
ImageConstruction::ConstructImageEdges(m_pEmitter, m_vpPropagationTree);
//Calculate accumulated angle and angle culling for tree
//Following not working accurately
//Calculate accumulated angle and angle culling for tree
//if (*m_pAccumulatedAngleThreshold > 0)
//{
// Diffraction::AccumulatedAngleCulling(*m_pAccumulatedAngleThreshold, m_pEmitter,m_vpPropagationTree, m_vpPropagationTree);
......@@ -143,6 +144,15 @@ void ITAPropagationPathSim::CombinedModel::CPathEngine::ConstructPropagationPath
Reflection::ConstructPointsOfReflection(m_pSensor, m_vpPropagationLists, m_vpPropagationLists);
std::cout << m_vpPropagationLists.size() << " path candidates after points of reflection calculated. Calculation time: " << timeToString(sw.stop()) << endl;
//Calculate perceptional culling
if (*m_pMaxLevelReduction > 0.0f)
{
sw.start();
PerceptionalCulling(m_vpPropagationLists, m_vpPropagationLists);
std::cout << m_vpPropagationLists.size() << " path candidates after perceptional culling. Calculation time: " << timeToString(sw.stop()) << endl;
}
//Calculate accumulated angle and filter lists
if (*m_pAccumulatedAngleThreshold > 0)
{
......@@ -167,6 +177,100 @@ void ITAPropagationPathSim::CombinedModel::CPathEngine::ConstructPropagationPath
}
void ITAPropagationPathSim::CombinedModel::CPathEngine::PerceptionalCulling(const vector<CPropagationShapeShared> vpAllPathsIn, vector<CPropagationShapeShared>& vpAudiblePathsOut)
{
vpAudiblePathsOut.clear();
bool bIsPerceived;
//Length of current path divided into two parts. The first length is the path length from the emitter to the first edge
//and the second length is the path length from the first edge to the sensor
float fLength1, fLength2;
//Accumulated penalty in dB for reflections and diffractions
float fAccumulatedPenalty;
for (auto vpPropagationList : vpAllPathsIn)
{
if (vpPropagationList == nullptr)
continue;
auto pCurrentShape = vpPropagationList;
fLength1 = (m_pEmitter->v3InteractionPoint - *pCurrentShape->v3InteractionPoint).GetLength();
fLength2 = -1.f;
if (pCurrentShape->iShapeType == CPropagationShape::FACE)
{
fAccumulatedPenalty = *m_pReflectionPenalty;
}
else
{
fAccumulatedPenalty = *m_pDiffractionPenalty;
}
while (pCurrentShape->pChild != nullptr)
{
auto pLastShape = pCurrentShape;
pCurrentShape = pCurrentShape->pChild;
if (pCurrentShape->iShapeType == CPropagationShape::FACE)
{
fAccumulatedPenalty += *m_pReflectionPenalty;
if (fLength2 < -Vista::Epsilon)
{
fLength1 += (*pLastShape->v3InteractionPoint - *pCurrentShape->v3InteractionPoint).GetLength();
}
else
{
fLength2 += (*pLastShape->v3InteractionPoint - *pCurrentShape->v3InteractionPoint).GetLength();
}
}
else
{
fAccumulatedPenalty += *m_pDiffractionPenalty;
if (fLength2 < -Vista::Epsilon)
{
fLength1 += (*pLastShape->v3InteractionPoint - *pCurrentShape->v3InteractionPoint).GetLength();
fLength2 = 0.0f;
}
else
{
fLength2 += (*pLastShape->v3InteractionPoint - *pCurrentShape->v3InteractionPoint).GetLength();
}
}
}
//Add length between last shape and sensor
if (fLength2 < -Vista::Epsilon)
{
fLength1 += (m_pSensor->v3InteractionPoint - *pCurrentShape->v3InteractionPoint).GetLength();
}
else
{
fLength2 += (m_pSensor->v3InteractionPoint - *pCurrentShape->v3InteractionPoint).GetLength();
}
//Penalty plus level drop of spherical source
float fTotalLevelDrop = fAccumulatedPenalty + 20 * log10f(fLength1);
//Added level drop of line source after first edge
if (fLength2 > Vista::Epsilon)
fTotalLevelDrop += 10 * log10f(fLength2*(fLength1 + fLength2) / fLength1);
//Compare total level drop with threshold
bIsPerceived = (*m_pMaxLevelReduction - fTotalLevelDrop) > 0.0f;
//Add propagation path if it is in the audible range
if (bIsPerceived)
vpAudiblePathsOut.push_back(vpPropagationList);
}
}
void ITAPropagationPathSim::CombinedModel::CPathEngine::FilterVisiblePaths(const vector<CPropagationShapeShared> vpAllPathsIn, vector<CPropagationShapeShared>& vpVisiblePathsOut)
{
vpVisiblePathsOut.clear();
......@@ -1029,14 +1133,33 @@ void ITAPropagationPathSim::CombinedModel::CPathEngine::ConstructPropagationShap
{
CITAMesh::EdgeHandle hEdge(*cf_et++);
//Halfedge representation of edge
auto hHalfedge = pMesh->halfedge_handle(hEdge, 0);
//Main and opposite face
auto hMainFace = pMesh->face_handle(hHalfedge);
auto hOppositeFace = pMesh->opposite_face_handle(hHalfedge);
//Ignore edge if only one face is connected with halfedge. One example is the ground surface
if (!hMainFace.is_valid() || !hOppositeFace.is_valid())
continue;
//Main and opposite face normals
auto v3MainFaceNormal = pMesh->calc_face_normal(hMainFace);
auto v3OppositeFaceNormal = pMesh->calc_face_normal(hOppositeFace);
//Ignore edge if normals of the two aligned faces are the same. In this case, the edge is not really an edge
if ((v3MainFaceNormal - v3OppositeFaceNormal).length()< ITAConstants::EPS_F_L)
continue;
CPropagationEdgeShared pPropagationEdge = make_shared<CPropagationEdge>();
pPropagationEdge->iShapeType = CPropagationShape::EDGE;
pPropagationEdge->sMeshModelName = psMeshModelName;
pPropagationEdge->pIsIlluminableBySensor = make_shared<Tristate>(Tristate::Undefined);
pPropagationEdge->hEdge = hEdge;
pPropagationEdge->hHalfedge = pMesh->halfedge_handle(hEdge, 0);
pPropagationEdge->hShape = pPropagationEdge->hHalfedge;
pPropagationEdge->hHalfedge = hHalfedge;
pPropagationEdge->hShape = hHalfedge;
//Set vertices
auto hFromVertex = pMesh->from_vertex_handle(pPropagationEdge->hHalfedge);
......@@ -1050,10 +1173,10 @@ void ITAPropagationPathSim::CombinedModel::CPathEngine::ConstructPropagationShap
pPropagationEdge->SetBoundarySphere();
//Set face normals
pPropagationEdge->hMainFace = pMesh->face_handle(pPropagationEdge->hHalfedge);
pPropagationEdge->hOppositeFace = pMesh->opposite_face_handle(pPropagationEdge->hHalfedge);
pPropagationEdge->v3MainFaceNormal = make_shared<VistaVector3D>(pMesh->calc_face_normal(pPropagationEdge->hMainFace).data());
pPropagationEdge->v3OppositeFaceNormal = make_shared<VistaVector3D>(pMesh->calc_face_normal(pPropagationEdge->hOppositeFace).data());
pPropagationEdge->hMainFace = hMainFace;
pPropagationEdge->hOppositeFace = hOppositeFace;
pPropagationEdge->v3MainFaceNormal = make_shared<VistaVector3D>(v3MainFaceNormal.data());
pPropagationEdge->v3OppositeFaceNormal = make_shared<VistaVector3D>(v3OppositeFaceNormal.data());
m_vpPropagationShapes.push_back(pPropagationEdge);
}
......
......@@ -89,12 +89,12 @@ int main( int iNumInArgs, char* pcInArgs[] )
const float fIntersectionTestResolution = 0.001;
const int iNumIterations = 5;//!< Number of iterations for the calculation of the aperture points
const int fMaxAccumulatedDiffractionAngle = ITAConstants::PI_F;
const int fMaxAccumulatedDiffractionAngle = 2*ITAConstants::PI_F;
const int iMaxDiffractionOrder = 4;
const int iMaxReflectionOrder = 3;
const int iMaxCombinedOrder = 5;
const float fLevelDropThreshhold = 90.f - 30.f - 11.f; //90 dB Power level car; 40 dB background noise; 11 dB initial power level drop
const float fLevelDropThreshhold = 90.f - 30.f - 11.f; //90 dB Power level car; 40 dB background noise; 11 dB initial power level drop
const float fReflectionPenalty = -20 * log10f(0.7); //Level reduction of a reflection with reflection factor R = 0.7
const float fDiffractionPenalty = 2.5f; // Minimum level reduction of a diffracted signal into the shadow region for a low frequency (Taken from BA Filbert Figure 16. UTD)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment