Commit bd6d93c1 authored by Dipl.-Ing. Jonas Stienen's avatar Dipl.-Ing. Jonas Stienen
Browse files

Adding free field simulation worker and some fixes in outdoor simulator

parent 11bda799
set( RelativeDir "include/ITA/SimulationScheduler/OutdoorAcoustics/FreeField" )
set( RelativeSourceGroup "Header Files\\ITA\\SimulationScheduler\\OutdoorAcoustics\\FreeField" )
set( SubDirs
)
set( DirFiles
ff_simulator.h
)
set( DirFiles_SourceGroup "${RelativeSourceGroup}" )
set( LocalSourceGroupFiles )
foreach( File ${DirFiles} )
list( APPEND LocalSourceGroupFiles "${RelativeDir}/${File}" )
list( APPEND ProjectSources "${RelativeDir}/${File}" )
endforeach()
source_group( ${DirFiles_SourceGroup} FILES ${LocalSourceGroupFiles} )
set( SubDirFiles "" )
foreach( Dir ${SubDirs} )
list( APPEND SubDirFiles "${RelativeDir}/${Dir}/_SourceFiles.cmake" )
endforeach()
foreach( SubDirFile ${SubDirFiles} )
include( ${SubDirFile} )
endforeach()
#ifndef INCLUDE_WATCHER_ITA_SIMULATION_SCHEDULER_OUTDOOR_ACOUSTICS_URBAN_FREEFIELD
#define INCLUDE_WATCHER_ITA_SIMULATION_SCHEDULER_OUTDOOR_ACOUSTICS_URBAN_FREEFIELD
// API includes
#include <ITA/SimulationScheduler/definitions.h>
// std includes
#include <string>
#include <memory>
// simulation scheduler includes
#include <ITA/SimulationScheduler/OutdoorAcoustics/outdoor_simulator_interface.h>
// ITAGeo includes
#include <ITAGeo/Base.h>
namespace ITA
{
namespace SimulationScheduler
{
namespace OutdoorAcoustics
{
namespace FreeField
{
//! \brief Simulator using the Atmospheric Ray Tracing framework from ITAGeometricalAcoustics.
/**
* This Simulator uses a single Atmosphere::EigenraySearch::Engine instance.
* The simulation is run synchronous/blocking. Thus, only one simulation can be run at the same time.
*/
class ITA_SIMULATION_SCHEDULER_API CFreeFieldSimulator : public OutdoorAcoustics::ISimulatorInterface
{
public:
//! \brief Configuration class for a outdoor acoustics simulator.
struct ITA_SIMULATION_SCHEDULER_API FreeFieldSimulatorConfig : public ISimulatorInterface::SimulatorConfig
{
inline explicit FreeFieldSimulatorConfig() {};
VistaPropertyList Store() const override;
void Load( const VistaPropertyList& oProperties ) override;
CoordinateSystem eClientCoordinateSystem = CoordinateSystem::Cartesian; //!< 0 = Cartesian, 1 = OpenGL
double dSpeedOfSound;
};
CFreeFieldSimulator( const FreeFieldSimulatorConfig& oConfig );
CFreeFieldSimulator( const CFreeFieldSimulator& other ) = delete;
CFreeFieldSimulator( CFreeFieldSimulator&& other ) = delete;
CFreeFieldSimulator& operator=( const CFreeFieldSimulator& other ) = delete;
CFreeFieldSimulator& operator=( CFreeFieldSimulator&& other ) = delete;
static std::unique_ptr< ISimulatorInterface > Create( std::shared_ptr< const ISimulatorInterface::SimulatorConfig > );
//! \brief Reset the simulator.
inline void Reset() override { };
//! \brief Simulate the given task.
std::unique_ptr< COutdoorSimulationResult > Compute( std::unique_ptr< CUpdateScene > pSceneUpdate ) override;
inline static std::string GetType()
{
return "FreeFieldSimulator";
};
private:
inline static VistaVector3D OpenGLToCart( const VistaVector3D& v3In )
{
return VistaVector3D( v3In[ Vista::X ], -v3In[ Vista::Z ], v3In[ Vista::Y ] );
};
inline static VistaVector3D CartToOpenGL( const VistaVector3D& v3In )
{
return VistaVector3D( v3In[ Vista::X ], v3In[ Vista::Z ], -v3In[ Vista::Y ] );
};
private:
//! \brief Coordinate system used by client (e.g. VA)
CoordinateSystem m_eClientCoordinateSystem;
std::shared_ptr< ITAGeo::CSensor > m_pSensor;
std::shared_ptr< ITAGeo::CEmitter > m_pEmitter;
std::unique_ptr< CUpdateScene > m_pSceneUpdate;
FreeFieldSimulatorConfig m_oInitialConfig;
};
} // namespace FreeField
} // namespace OutdoorAcoustics
} // namespace SimulationScheduler
} // namespace ITA
#endif // INCLUDE_WATCHER_ITA_SIMULATION_SCHEDULER_OUTDOOR_ACOUSTICS_URBAN_FREEFIELD
\ No newline at end of file
......@@ -71,14 +71,24 @@ namespace ITA
};
private:
static VistaVector3D OpenGLToCart( const VistaVector3D& v3In );
static VistaVector3D CartToOpenGL( const VistaVector3D& v3In );
inline static VistaVector3D OpenGLToISO( const VistaVector3D& v3In )
{
return VistaVector3D( v3In[ Vista::X ], -v3In[ Vista::Z ], v3In[ Vista::Y ] );
};
inline static VistaVector3D ISOToOpenGL( const VistaVector3D& v3In )
{
return VistaVector3D( v3In[ Vista::X ], v3In[ Vista::Z ], -v3In[ Vista::Y ] );
};
private:
//! \brief Coordinate system used by client (e.g. VA)
CoordinateSystem m_eClientCoordinateSystem;
std::shared_ptr< ITAPropagationPathSim::CombinedModel::CPathEngine > m_pPathEngine;
std::shared_ptr< ITAGeo::Halfedge::CMeshModelList > m_pMeshModelList; //! Static geo model
std::shared_ptr< ITAGeo::CSensor > m_pSensor;
std::shared_ptr< ITAGeo::CEmitter > m_pEmitter;
......
set( RelativeDir "include/ITA/SimulationScheduler/OutdoorAcoustics" )
set( RelativeSourceGroup "Header Files\\ITA\\SimulationScheduler\\OutdoorAcoustics" )
list( APPEND SubDirs FreeField )
if( ITA_SIMULATION_SCHEDULER_URBAN_MODULE )
list( APPEND SubDirs Urban )
endif( )
......
......@@ -50,7 +50,7 @@ namespace ITA
ITABase::CThirdOctaveFactorMagnitudeSpectrum oGeoAttenuationSpectrum; //!< Combined attenuation of geometry interaction (reflections and diffractions)
ITABase::CThirdOctaveFactorMagnitudeSpectrum oAirAttenuationSpectrum;
VistaVector3D v3SourceWaveFrontNormal; //!< Outgoing wave front normal at source
VistaVector3D v3SourceWaveFrontNormal; //!< Outgoing wave front normal at source (retarded?)
VistaVector3D v3ReceiverWaveFrontNormal; //!< Incident wave front normal at receiver
int Serialize(IVistaSerializer& pSerializer) const override;
......
set( RelativeDir "src/ITA/SimulationScheduler/OutdoorAcoustics/FreeField" )
set( RelativeSourceGroup "Source Files\\ITA\\SimulationScheduler\\OutdoorAcoustics\\FreeField" )
set( SubDirs
)
set( DirFiles
ff_simulator.cpp
)
set( DirFiles_SourceGroup "${RelativeSourceGroup}" )
set( LocalSourceGroupFiles )
foreach( File ${DirFiles} )
list( APPEND LocalSourceGroupFiles "${RelativeDir}/${File}" )
list( APPEND ProjectSources "${RelativeDir}/${File}" )
endforeach()
source_group( ${DirFiles_SourceGroup} FILES ${LocalSourceGroupFiles} )
set( SubDirFiles "" )
foreach( Dir ${SubDirs} )
list( APPEND SubDirFiles "${RelativeDir}/${Dir}/_SourceFiles.cmake" )
endforeach()
foreach( SubDirFile ${SubDirFiles} )
include( ${SubDirFile} )
endforeach()
// Header include
#include <ITA/SimulationScheduler/OutdoorAcoustics/FreeField/ff_simulator.h>
#include <ITA/SimulationScheduler/Profiler/profiler.h>
#include <ITA/SimulationScheduler/Utils/data_type_utils.h>
#include "../../configuration_keys.h"
// ITA Base
#include <ITAException.h>
#include <ITAConstants.h>
// STD
#include <ostream>
#include <memory>
using namespace ITA;
using namespace SimulationScheduler;
using namespace OutdoorAcoustics;
using namespace FreeField;
using namespace ITAGeo;
#pragma region CONFIG
VistaPropertyList CFreeFieldSimulator::FreeFieldSimulatorConfig::Store() const
{
auto oProperties = ISimulatorInterface::SimulatorConfig::Store();
oProperties.SetValue( CLIENT_COORDINATE_SYSTEM_KEY, AsInteger( eClientCoordinateSystem ) );
return oProperties;
}
void CFreeFieldSimulator::FreeFieldSimulatorConfig::Load( const VistaPropertyList& oProperties )
{
ISimulatorInterface::SimulatorConfig::Load( oProperties );
if( oProperties.HasProperty( CLIENT_COORDINATE_SYSTEM_KEY ) )
eClientCoordinateSystem = static_cast< CoordinateSystem >( oProperties.GetValue< int >( CLIENT_COORDINATE_SYSTEM_KEY ) );
else
eClientCoordinateSystem = CoordinateSystem::Cartesian;
oProperties.GetValueOrDefault( SPEED_OF_SOUND, dSpeedOfSound, ITAConstants::DEFAULT_SPEED_OF_SOUND_D );
}
#pragma endregion
#pragma region SIMULATOR
CFreeFieldSimulator::CFreeFieldSimulator( const FreeFieldSimulatorConfig& oConfig )
: m_oInitialConfig( oConfig )
{
m_eClientCoordinateSystem = oConfig.eClientCoordinateSystem;
m_pSensor = std::make_shared< ITAGeo::CSensor >();
m_pEmitter = std::make_shared< ITAGeo::CEmitter >();
}
std::unique_ptr< ISimulatorInterface > CFreeFieldSimulator::Create( std::shared_ptr< const ISimulatorInterface::SimulatorConfig > pConfig )
{
std::shared_ptr< const FreeFieldSimulatorConfig > pConfigGenericShared = std::dynamic_pointer_cast< const FreeFieldSimulatorConfig >( pConfig );
if( !pConfigGenericShared )
ITA_EXCEPT_INVALID_PARAMETER( "Pointer to invalid config given." );
const FreeFieldSimulatorConfig& oConf( *pConfigGenericShared );
return std::make_unique< CFreeFieldSimulator >( oConf );
}
std::unique_ptr< COutdoorSimulationResult > CFreeFieldSimulator::Compute( std::unique_ptr< CUpdateScene > pUpdateScene )
{
PROFILER_FUNCTION();
m_pSceneUpdate = std::move( pUpdateScene );
PROFILER_SECTION( "SceneAdaption" );
// Don't change order of sensor and emitter update calls
auto v3SensorPos = m_pSceneUpdate->GetSourceReceiverPair().receiver->GetPosition();
if( m_eClientCoordinateSystem == CoordinateSystem::OpenGL )
m_pSensor->v3InteractionPoint = OpenGLToCart( v3SensorPos );
else
m_pSensor->v3InteractionPoint = v3SensorPos;
m_pSensor->sName = "id" + std::to_string( m_pSceneUpdate->GetSourceReceiverPair().receiver->GetId() );
auto v3EmitterPos = m_pSceneUpdate->GetSourceReceiverPair().source->GetPosition();
if( m_eClientCoordinateSystem == CoordinateSystem::OpenGL )
m_pEmitter->v3InteractionPoint = OpenGLToCart( v3EmitterPos );
else
m_pEmitter->v3InteractionPoint = v3EmitterPos;
m_pEmitter->sName = "id" + std::to_string( m_pSceneUpdate->GetSourceReceiverPair().source->GetId() );
PROFILER_END_SECTION();
PROFILER_SECTION( "Simulation" );
CPropagationPath oDirectSoundPath;
oDirectSoundPath.sIdentifier = "ds";
oDirectSoundPath.push_back( m_pEmitter );
oDirectSoundPath.push_back( m_pSensor );
CPropagationPathList oPathList;
oPathList.push_back( oDirectSoundPath );
PROFILER_END_SECTION();
auto pResult = std::make_unique< COutdoorSimulationResult >();
pResult->sourceReceiverPair = m_pSceneUpdate->GetSourceReceiverPair();
pResult->dTimeStamp = m_pSceneUpdate->GetTimeStamp();
PROFILER_SECTION( "Modelling" );
pResult->voPathProperties.resize( oPathList.size() );
for( size_t i = 0; i < oPathList.size(); i++ )
{
const CPropagationPath& oSimulationPath( oPathList[ i ] );
auto& oPathProp( pResult->voPathProperties[ i ] );
if( oSimulationPath.size() < 2 )
ITA_EXCEPT_INVALID_PARAMETER( "Result propagation path must have at least two propagation anchors, but received less, id = " + oSimulationPath.sIdentifier );
if( oSimulationPath.GetLength() <= 0.0f )
ITA_EXCEPT_INVALID_PARAMETER( "Result propagation path length was equal or less tan zero, id = " + oSimulationPath.sIdentifier );
// Static properties
oPathProp.sID = oSimulationPath.sIdentifier;
oPathProp.iDiffractionOrder = oSimulationPath.GetNumDiffractions();
oPathProp.iReflectionOrder = oSimulationPath.GetNumReflections();
// @todo move to a function that applies propagation models
oPathProp.dPropagationDelay = oSimulationPath.GetLength() / m_oInitialConfig.dSpeedOfSound;
oPathProp.dSpreadingLoss = 1 / oSimulationPath.GetLength();
oPathProp.oAirAttenuationSpectrum.SetIdentity();
oPathProp.oGeoAttenuationSpectrum.SetIdentity();
oPathProp.v3ReceiverWaveFrontNormal = oSimulationPath.GetReceiverWaveFrontNormal();
oPathProp.v3SourceWaveFrontNormal = oSimulationPath.GetSourceWaveFrontNormal();
}
PROFILER_END_SECTION();
return std::move( pResult );
}
#pragma endregion
......@@ -8,6 +8,7 @@
// ITAGeo
#include <ITAGeo/Halfedge/MeshModel.h>
#include <ITAGeo/SketchUp/Model.h>
// ITA Base
#include <ITAFileSystemUtils.h>
......@@ -31,7 +32,7 @@ using namespace ITAPropagationPathSim;
VistaPropertyList CUrbanSimulator::UrbanSimulatorConfig::Store() const
{
auto oProperties = ISimulatorInterface::SimulatorConfig::Store();
//oProperties.SetValue(CLIENT_COORDINATE_SYSTEM_KEY, AsInteger(eClientCoordinateSystem));
oProperties.SetValue( CLIENT_COORDINATE_SYSTEM_KEY, AsInteger( eClientCoordinateSystem ) );
oProperties.SetValue( GEOMETRY_FILE_PATH, sJSONGeometryFilePath );
return oProperties;
}
......@@ -40,11 +41,17 @@ void CUrbanSimulator::UrbanSimulatorConfig::Load( const VistaPropertyList& oProp
{
ISimulatorInterface::SimulatorConfig::Load( oProperties );
//eClientCoordinateSystem = static_cast<CoordinateSystem>(oProperties.GetValue <int>(CLIENT_COORDINATE_SYSTEM_KEY));
if( !oProperties.HasProperty( GEOMETRY_FILE_PATH ) )
ITA_EXCEPT_INVALID_PARAMETER( "Urban simulator configuration is missing a geometry file path" );
oProperties.GetValue( GEOMETRY_FILE_PATH, sJSONGeometryFilePath );
if( oProperties.HasProperty( CLIENT_COORDINATE_SYSTEM_KEY ) )
eClientCoordinateSystem = static_cast< CoordinateSystem >( oProperties.GetValue< int >( CLIENT_COORDINATE_SYSTEM_KEY ) );
else
eClientCoordinateSystem = CoordinateSystem::Cartesian;
oProperties.GetValueOrDefault( SPEED_OF_SOUND, dSpeedOfSound, ITAConstants::DEFAULT_SPEED_OF_SOUND_D );
oProperties.GetValueOrDefault( MAX_DIFFRACTION_ORDER , iMaxDiffractionOrder, 1 );
oProperties.GetValueOrDefault( MAX_REFLECTION_ORDER, iMaxReflectionOrder, 1 );
}
......@@ -60,29 +67,32 @@ CUrbanSimulator::CUrbanSimulator( const UrbanSimulatorConfig& oConfig )
try
{
auto pMeshModelList = make_shared< Halfedge::CMeshModelList >();
m_pMeshModelList = std::make_shared< Halfedge::CMeshModelList >();
if( !pMeshModelList->Load( oConfig.sJSONGeometryFilePath ) )
if( !m_pMeshModelList->Load( oConfig.sJSONGeometryFilePath ) )
ITA_EXCEPT_INVALID_PARAMETER( "Could not load mes model froom file path " + oConfig.sJSONGeometryFilePath );
m_pSensor = make_shared< ITAGeo::CSensor >();
m_pEmitter = make_shared< ITAGeo::CEmitter >();
m_pSensor = std::make_shared< ITAGeo::CSensor >();
m_pEmitter = std::make_shared< ITAGeo::CEmitter >();
// Configuration
CombinedModel::CPathEngine::CSimulationConfig oConf;
oConf.bFilterIntersectedPaths = true;
oConf.bFilterIlluminatedRegionDiffraction = true;
oConf.bFilterEmitterToEdgeIntersectedPaths = true;
oConf.bFilterSensorToEdgeIntersectedPaths = true;
CombinedModel::CPathEngine::CAbortionCriteria oAbort;
oAbort.iMaxDiffractionOrder = oConfig.iMaxDiffractionOrder;
oAbort.iMaxReflectionOrder = oConfig.iMaxReflectionOrder;
m_pPathEngine = make_shared< CombinedModel::CPathEngine >();
m_pPathEngine->SetSimulationConfiguration( oConf );
m_pPathEngine->SetAbortionCriteria( oAbort );
m_pPathEngine->InitializePathEnvironment( pMeshModelList );
m_pPathEngine->InitializePathEnvironment( m_pMeshModelList );
}
catch( const ITAException& err )
......@@ -113,19 +123,25 @@ std::unique_ptr< COutdoorSimulationResult > CUrbanSimulator::Compute( std::uniqu
PROFILER_SECTION( "SceneAdaption" );
// Don't change order of sensor and emitter update calls
auto v3SensorPos = m_pSceneUpdate->GetSourceReceiverPair().receiver->GetPosition();
m_pSensor->v3InteractionPoint = v3SensorPos;
const VistaVector3D v3SensorPosUserContext( m_pSceneUpdate->GetSourceReceiverPair().receiver->GetPosition() );
VistaVector3D& v3SensorPosSim( m_pSensor->v3InteractionPoint );
if( m_eClientCoordinateSystem == CoordinateSystem::OpenGL )
v3SensorPosSim = OpenGLToISO( v3SensorPosUserContext );
else
v3SensorPosSim = v3SensorPosSim;
m_pSensor->sName = "id" + std::to_string( m_pSceneUpdate->GetSourceReceiverPair().receiver->GetId() );
m_pPathEngine->UpdateTargetEntity( m_pSensor );
auto v3EmitterPos = m_pSceneUpdate->GetSourceReceiverPair().source->GetPosition();
m_pEmitter->v3InteractionPoint = v3EmitterPos;
const VistaVector3D v3EmitterPosUserContext( m_pSceneUpdate->GetSourceReceiverPair().source->GetPosition() );
VistaVector3D& v3EmitterPosSim( m_pEmitter->v3InteractionPoint );
if( m_eClientCoordinateSystem == CoordinateSystem::OpenGL )
v3EmitterPosSim = OpenGLToISO( v3EmitterPosUserContext );
else
v3EmitterPosSim = v3EmitterPosUserContext;
m_pEmitter->sName = "id" + std::to_string( m_pSceneUpdate->GetSourceReceiverPair().source->GetId() );
m_pPathEngine->UpdateOriginEntity( m_pEmitter );
// old
//m_pPathEngine->SetEntities( m_pEmitter, m_pSensor );
PROFILER_END_SECTION();
......@@ -135,6 +151,10 @@ std::unique_ptr< COutdoorSimulationResult > CUrbanSimulator::Compute( std::uniqu
m_pPathEngine->ConstructPropagationPaths( oPathList );
ITAGeoUtils::AddIdentifier( oPathList );
auto pVisualisationMeshModel = make_shared< ITAGeo::SketchUp::CModel >(); // @todo only perform if requested (once?)
pVisualisationMeshModel->Load( m_oInitialConfig.sJSONGeometryFilePath );
PROFILER_END_SECTION();
......@@ -156,6 +176,8 @@ std::unique_ptr< COutdoorSimulationResult > CUrbanSimulator::Compute( std::uniqu
if( oSimulationPath.GetLength() <= 0.0f )
ITA_EXCEPT_INVALID_PARAMETER( "Result propagation path length was equal or less tan zero, id = " + oSimulationPath.sIdentifier );
pVisualisationMeshModel->AddPropagationPathVisualization( oSimulationPath, oSimulationPath.sIdentifier );
// Static properties
oPathProp.sID = oSimulationPath.sIdentifier;
oPathProp.iDiffractionOrder = oSimulationPath.GetNumDiffractions();
......@@ -172,6 +194,8 @@ std::unique_ptr< COutdoorSimulationResult > CUrbanSimulator::Compute( std::uniqu
PROFILER_END_SECTION();
pVisualisationMeshModel->Store( "urban_simulator_" + oPathList.sIdentifier + ".skp" );
return std::move( pResult );
}
......
set( RelativeDir "src/ITA/SimulationScheduler/OutdoorAcoustics" )
set( RelativeSourceGroup "Source Files\\ITA\\SimulationScheduler\\OutdoorAcoustics" )
list( APPEND SubDirs FreeField )
if( ITA_SIMULATION_SCHEDULER_URBAN_MODULE )
list( APPEND SubDirs Urban )
endif()
if( ITA_SIMULATION_SCHEDULER_ART_MODULE )
list( APPEND SubDirs ART )
endif()
......
......@@ -5,6 +5,7 @@
// simulation scheduler includes
#include "../configuration_keys.h"
#include <ITA/SimulationScheduler/OutdoorAcoustics/FreeField/ff_simulator.h>
#ifdef WITH_ART
#include <ITA/SimulationScheduler/OutdoorAcoustics/ART/art_simulator.h>
#endif
......@@ -69,6 +70,7 @@ namespace ITA
std::map<std::string, std::pair<CSimulatorFactory::CreateCallback, CSimulatorFactory::ConfigCreateCallback>> CSimulatorFactory::m_mRegisteredSimulatorTypes =
{
{ OutdoorAcoustics::FreeField::CFreeFieldSimulator::GetType(), { OutdoorAcoustics::FreeField::CFreeFieldSimulator::Create, std::make_shared< OutdoorAcoustics::FreeField::CFreeFieldSimulator::FreeFieldSimulatorConfig > } },
#ifdef WITH_ART
{ OutdoorAcoustics::ART::CARTSimulator::GetType(), { OutdoorAcoustics::ART::CARTSimulator::Create, std::make_shared< OutdoorAcoustics::ART::CARTSimulator::ARTSimulatorConfig > } },
#endif
......
......@@ -40,22 +40,26 @@ namespace ITA
{
const std::string WORKER_SIMULATOR_SECTION_NAME = "Simulator";
const std::string SIMULATOR_TYPE_KEY = "@SimulatorType";
const std::string CLIENT_COORDINATE_SYSTEM_KEY = "@ClientCoordinateSystem";
namespace ART
{
const std::string STRATIFIED_ATMOSPHERE_KEY = "@StratifiedAtmosphere";
const std::string CLIENT_COORDINATE_SYSTEM_KEY = "@ClientCoordinateSystem";
}
namespace Urban
{
const std::string GEOMETRY_FILE_PATH = "@GeometryFilePath";
const std::string CLIENT_COORDINATE_SYSTEM_KEY = "@ClientCoordinateSystem";
const std::string SPEED_OF_SOUND = "@SpeedOfSound";
const std::string MAX_REFLECTION_ORDER = "@MaxReflectionOrder";
const std::string MAX_DIFFRACTION_ORDER = "@MaxDiffractionOrder";
}
namespace FreeField
{
const std::string SPEED_OF_SOUND = "@SpeedOfSound";
}
}
namespace AudibilityFilter
......
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