Commit d1b90fdd authored by Philipp Schäfer's avatar Philipp Schäfer
Browse files

OutdoorAcoustics

- created first version of worker and simulator
parent d94bd9ba
......@@ -101,6 +101,9 @@ endif( )
if( ITA_SIMULATION_SCHEDULER_ART_MODULE )
add_definitions( -DWITH_ART )
vista_use_package( ITAGeo REQUIRED FIND_DEPENDENCIES )
vista_use_package( ITAPropagationModels REQUIRED FIND_DEPENDENCIES )
vista_use_package( ITAPropagationPathSim REQUIRED FIND_DEPENDENCIES )
endif( )
......
......@@ -5,13 +5,7 @@ set( SubDirs
set( DirFiles
art_worker_thread.h
#raven_scene.h
#raven_simulation_result.h
#simulation_task.h
#simulator.h
#raven_worker_interface.h
#worker_thread.h
#simulator_interface.h
art_simulator.h
)
set( DirFiles_SourceGroup "${RelativeSourceGroup}" )
......
#ifndef INCLUDE_WATCHER_ITA_SIMULATION_SCHEDULER_OUTDOOR_ACOUSTICS_ART_SIMULATOR
#define INCLUDE_WATCHER_ITA_SIMULATION_SCHEDULER_OUTDOOR_ACOUSTICS_ART_SIMULATOR
// API includes
#include <ITA/SimulationScheduler/definitions.h>
// std includes
#include <string>
#include <memory>
//#include <type_traits>
// simulation scheduler includes
#include <ITA/SimulationScheduler/update_scene.h>
#include <ITA/SimulationScheduler/OutdoorAcoustics/outdoor_simulator_interface.h>
#include <ITA/SimulationScheduler/OutdoorAcoustics/outdoor_simulation_result.h>
// ART includes
#include <ITAGeo/Atmosphere/StratifiedAtmosphere.h>
#include <ITAPropagationPathSim/AtmosphericRayTracing/EigenraySearch/EigenrayEngine.h>
using namespace ITAGeo;
using namespace ITAPropagationPathSim :: AtmosphericRayTracing;
namespace ITA
{
namespace SimulationScheduler
{
namespace OutdoorAcoustics
{
namespace ART
{
//! \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 CSimulator : public OutdoorAcoustics::ISimulatorInterface
{
public:
//! \brief Raven status types
enum class SimulatorStatus
{
uninitialized, ///< Simulator is uninitialized.
idle, ///< Raven instance is running but no geometry is loaded.
sceneLoaded, ///< Raven instance is running and a geometry is loaded.
filterEngineLoaded ///< Raven initialized the filter engine.
};
CSimulator ( );
CSimulator(const CSimulator& other) = delete;
CSimulator(CSimulator&& other) = delete;
CSimulator& operator=(const CSimulator& other) = delete;
CSimulator& operator=(CSimulator&& other) = delete;
//! \brief Reset the simulator.
void Reset ( ) override;
//! \brief Simulate the given task.
std::unique_ptr<COutdoorSimulationResult> Compute ( std::unique_ptr<CUpdateScene> pSceneUpdate ) override;
inline std::string GetType() override
{
return "ARTSimulator";
};
private:
//! \brief RT Eigenray-Engine instance.
EigenraySearch::CEngine m_oEngine;
//! \brief Stratified atmosphere
CStratifiedAtmosphere m_oAtmosphere;
std::unique_ptr<CUpdateScene> m_pSceneUpdate;
//! \brief Current status of the simulator.
SimulatorStatus m_eStatus;
//! \brief Initialise the raven instance.
//! The simulator is idle afterwards.
void Init ( );
};
inline bool operator<(const CSimulator::SimulatorStatus& lhs, const CSimulator::SimulatorStatus& rhs)
{
return std::underlying_type_t<CSimulator::SimulatorStatus>(lhs) < std::underlying_type_t<CSimulator::SimulatorStatus>(rhs);
};
} // namespace ART
} // namespace OutdoorAcoustics
} // namespace SimulationScheduler
} // namespace ITA
#endif // INCLUDE_WATCHER_ITA_SIMULATION_SCHEDULER_OUTDOOR_ACOUSTICS_ART_SIMULATOR
\ No newline at end of file
......@@ -9,9 +9,13 @@
#include <ITA/SimulationScheduler/definitions.h>
// simulation scheduler includes
#include <ITA/SimulationScheduler/RoomAcoustics/raven/raven_worker_interface.h>
#include <ITA/SimulationScheduler/RoomAcoustics/raven/simulator_interface.h>
#include <ITA/SimulationScheduler/worker_interface.h>
#include <ITA/SimulationScheduler/update_scene.h>
#include <ITA/SimulationScheduler/OutdoorAcoustics/outdoor_simulator_interface.h>
#ifdef WITH_ART
#include <ITA/SimulationScheduler/OutdoorAcoustics/ART/art_simulator.h>
#endif
// Vista includes
#include <VistaInterProcComm/Concurrency/VistaThreadLoop.h>
......@@ -26,127 +30,104 @@ namespace ITA
{
namespace ART
{
struct CARTConfig;
//struct CARonfig;
///
/// \brief Raven worker utilizing a thread to run the actual simulation.
///
class ITA_SIMULATION_SCHEDULER_API CWorkerThread : public IRavenWorkerInterface, VistaThreadLoop
//! \brief ART worker utilizing a thread to run the actual simulation.
class ITA_SIMULATION_SCHEDULER_API CWorkerThread : public IWorkerInterface, VistaThreadLoop
{
public:
///
/// \brief Configuration class for a raven thread worker.
///
struct ITA_SIMULATION_SCHEDULER_API WorkerThreadConfig : public IRavenWorkerInterface::RavenWorkerConfig
//! \brief Configuration class for a raven thread worker.
struct ITA_SIMULATION_SCHEDULER_API WorkerThreadConfig : public IWorkerInterface::WorkerConfig
{
explicit WorkerThreadConfig ( );
std::string sRavenProjectFilePath = "path/to/raven/project/file.rpf";
explicit WorkerThreadConfig(const std::string& sType);
VistaPropertyList Store ( ) const override;
void Load ( const VistaPropertyList& oProperties ) override;
const std::string& sSimulatorType;
private:
std::string m_sSimulatorType;
};
///
/// \brief Constructor for CWorkerThread.
/// \param oConfig the WorkerConfig used to configure the CWorkerThread.
/// \param pParent the parent scheduler of the worker.
///
//! \brief Constructor for CWorkerThread.
//! \param oConfig the WorkerConfig used to configure the CWorkerThread.
//! \param pParent the parent scheduler of the worker.
CWorkerThread ( const WorkerThreadConfig& oConfig, ISchedulerInterface* pParent );
///
/// \brief Destructor of CWorkerThread.
///
/// This waits till the simulation is finished and stops the thread loop gently.
///
//! \brief Destructor of CWorkerThread.
/**
* This waits till the simulation is finished and stops the thread loop gently.
*/
~CWorkerThread ( );
///
/// \copydoc IWorkerInterface::IsBusy
///
bool IsBusy ( ) override;
//! \brief Checks if the worker is busy.
inline bool IsBusy() override
{
return m_bBusy;
};
///
/// \copydoc IWorkerInterface::PushUpdate
///
//! \brief Push a new update to the worker.
//!
//! After a new Update is pushed to a worker, the update gets simulated immediately.
//! \note This method takes ownership of the update.
//! \param pUpdateMessage the new update for the scheduler.
void PushUpdate ( std::unique_ptr<CUpdateScene> pUpdate ) override;
///
/// \copydoc IWorkerInterface::Reset
/// \detail With the reset, the simulator get reset.
///
//! \brief Reset the worker.
//! \detail Also resets the simulator
void Reset ( ) override;
///
/// \copydoc IWorkerInterface::Shutdown
///
//! \brief Shutdown the worker safely.
void Shutdown() override;
///
/// \brief Factory function for CWorkerThread.
/// \param pConfig the WorkerConfig used to configure the CWorkerThread.
/// \param pParent the parent scheduler of the worker.
///
//! \brief Factory function for CWorkerThread.
//! \param pConfig the WorkerConfig used to configure the CWorkerThread.
//! \param pParent the parent scheduler of the worker.
static std::unique_ptr<IWorkerInterface> CreateWorker ( const std::shared_ptr<IWorkerInterface::WorkerConfig>& pConfig, ISchedulerInterface* pParent );
///
/// \brief Return a unique type identifying string.
/// \return a unique type identifying string.
///
static std::string GetType ( );
//! \brief Return a unique type identifying string.
//! \return a unique type identifying string.
inline static std::string GetType() { return "OutdoorAcousticsWorkerThread"; };
protected:
///
/// \brief Loop body for the CWorkerThread.
///
/// The following steps are done in the loop:
/// - Check if the scene is loaded, and load it if not.
/// - Simulate the Task.
/// - Forward the result to the scheduler.
/// \return true if VistaThreadLoop::ThreadBody() shall call VistaThread::YieldThread() before the next loop, false else
///
//! \brief Loop body for the CWorkerThread.
/** The following steps are done in the loop:
* - Check if the scene is loaded, and load it if not.
* - Simulate the Task.
* - Forward the result to the scheduler.
* \return true if VistaThreadLoop::ThreadBody() shall call VistaThread::YieldThread() before the next loop, false else
*/
virtual bool LoopBody ( ) override;
///
/// \brief Pre loop function.
///
/// This function is called once before the thread starts.
/// \note This is primarily used to set the thread name while profiling.
///
//! \brief Pre loop function.
/**
* This function is called once before the thread starts.
* \note This is primarily used to set the thread name while profiling.
*/
void PreLoop ( ) override;
///
/// \brief Set the simulator of the worker.
/// \param pSimulator the new simulator.
/// \note This function is primarily for testing.
/// However, it could also be useful in the long run.
///
void SetSimulator ( std::unique_ptr<ISimulatorInterface> pSimulator );
//! \brief Set the simulator of the worker.
/**
* \param pSimulator the new simulator.
* \note This function is primarily for testing.
* However, it could also be useful in the long run.
*/
//void SetSimulator ( std::unique_ptr<ISimulatorInterface> pSimulator );
private:
///
/// \brief The actual raven simulator
///
std::unique_ptr<ISimulatorInterface> m_pSimulator;
//! \brief Pointer to simulator interface for outdoor scenarios
std::unique_ptr<ISimulatorInterface> m_oSimulator;
///
/// \brief True if a scene is loaded.
///
ITAAtomicBool m_bSceneLoaded;
//! \brief If busy, this holds a pointer to the scene update to be simulated
std::unique_ptr<CUpdateScene> m_pUpdate = nullptr;
///
/// \brief Trigger for starting a thread loop.
///
//! \brief Trigger for starting a thread loop.
VistaThreadEvent m_evTriggerLoop;
///
/// \brief The task that is currently being simulated.
///
/// We need this to later reference the task when creating the result.
///
ITAAtomicPtr<CSimulationTask> m_pCurrentTask = nullptr;
//! Indicates whether worker is busy or not
ITAAtomicBool m_bBusy = false;
///
/// \{
......
......@@ -10,6 +10,7 @@ endif( )
set( DirFiles
outdoor_simulation_result.h
outdoor_simulator_interface.h
#_SourceFiles.cmake
)
......
#ifndef INCLUDE_WATCHER_ITA_SIMULATION_SCHEDULER_OUTDOOR_ACOUSTICS_SIMULATOR_INTERFACE
#define INCLUDE_WATCHER_ITA_SIMULATION_SCHEDULER_OUTDOOR_ACOUSTICS_SIMULATOR_INTERFACE
// API includes
#include <ITA/SimulationScheduler/definitions.h>
// std includes
#include <string>
#include <memory>
// simulation scheduler includes
#include <ITA/SimulationScheduler/update_scene.h>
#include <ITA/SimulationScheduler/OutdoorAcoustics/outdoor_simulation_result.h>
namespace ITA
{
namespace SimulationScheduler
{
namespace OutdoorAcoustics
{
//! \brief Interface to a Simulator for outdoor acoustics.
/**
* Defines the basic methods - especially running a simulation - to be used by the outdoor acoustic workers
*/
class ITA_SIMULATION_SCHEDULER_API ISimulatorInterface
{
public:
//! \brief Reset the simulator.
virtual void Reset() = 0;
//! \brief Simulate the given task.
virtual std::unique_ptr<COutdoorSimulationResult> Compute(std::unique_ptr<CUpdateScene> pSceneUpdate) = 0;
//! \brief Returns the type of the simulator
virtual std::string GetType() = 0;
};
} // namespace OutdoorAcoustics
} // namespace SimulationScheduler
} // namespace ITA
#endif // INCLUDE_WATCHER_ITA_SIMULATION_SCHEDULER_OUTDOOR_ACOUSTICS_SIMULATOR_INTERFACE
\ No newline at end of file
......@@ -4,12 +4,8 @@ set( SubDirs
)
set( DirFiles
#raven_scene.cpp
#simulation_task.cpp
#simulator.cpp
#raven_worker_interface.cpp
#worker_thread.cpp
#_SourceFiles.cmake
art_worker_thread.cpp
art_simulator.cpp
)
set( DirFiles_SourceGroup "${RelativeSourceGroup}" )
......
// Header include
#include <ITA/SimulationScheduler/OutdoorAcoustics/ART/art_simulator.h>
#include <ITA/SimulationScheduler/Profiler/profiler.h>
//#include <ITA/SimulationScheduler/Utils/utils.h>
//#include "ITALog.h"
namespace ITA
{
namespace SimulationScheduler
{
namespace OutdoorAcoustics
{
namespace ART
{
//#define RAVENSIMULATOR_REQUIRE_UNINITIALISED { if( operator<(m_eStatus, SimulatorStatus::uninitialized) ) ITA_EXCEPT1( MODAL_EXCEPTION, "Uninitialized mode required for this method, use Reset() prior to this call" ); };
//#define RAVENSIMULATOR_REQUIRE_IDLE { if( operator<(m_eStatus , SimulatorStatus::idle) ) ITA_EXCEPT1( MODAL_EXCEPTION, "Idle mode required for this method, use Reset() and Init() prior to this call" ); };
//#define RAVENSIMULATOR_REQUIRE_SCENE { if( operator<(m_eStatus , SimulatorStatus::sceneLoaded) ) ITA_EXCEPT1( MODAL_EXCEPTION, "Loaded scene required for this method, use LoadScene() prior to this call" ); };
//#define RAVENSIMULATOR_REQUIRE_FILTER_ENGINE { if( operator<(m_eStatus , SimulatorStatus::filterEngineLoaded) ) ITA_EXCEPT1( MODAL_EXCEPTION, "Loaded filter engine required for this method, probably an error in LoadScene() occured" ); };
const int g_iMaxNumSources = 1;
const int g_iMaxNumReceivers = 1;
CSimulator::CSimulator ( )
: m_eStatus ( SimulatorStatus::uninitialized )
{
//m_pRavenMasterController = std::make_unique<R_MasterController> ( );
//m_pRavenMasterController->m_currentConfig_General.applicationMode = NET_MODE;
Init ( ); // Danach: IDLE
}
void CSimulator::Reset ( )
{
PROFILER_EVENT_COUNT ( "Reset" );
Init ( );
}
std::unique_ptr<COutdoorSimulationResult> CSimulator::Compute ( std::unique_ptr<CUpdateScene> pUpdateScene )
{
PROFILER_FUNCTION ( );
PROFILER_SECTION ( "Adapt Scene" );
PROFILER_END_SECTION ( );
// Simulate
auto pResult = std::make_unique< COutdoorSimulationResult>();
return std::move(pResult);
}
void CSimulator::Init ( )
{
PROFILER_FUNCTION ( );
//m_oEigenrayEngine; //TODO INIT
m_eStatus = SimulatorStatus::idle;
}
} // namespace ART
} // namespace OutdoorAcoustics
} // namespace SimulationScheduler
} // namespace ITA
\ No newline at end of file
// Header include
#include <ITA/SimulationScheduler/OutdoorAcoustics/ART/art_worker_thread.h>
// Simulation scheduler includes
#include <ITA/SimulationScheduler/scheduler_interface.h>
#include <ITA/SimulationScheduler/OutdoorAcoustics/outdoor_simulation_result.h>
#include <ITA/SimulationScheduler/Profiler/profiler.h>
#include "../../configuration_keys.h"
// Vista includes
#include <VistaBase/VistaTimeUtils.h>
// ITA includes
#include "ITAException.h"
#include "ITALog.h"
#include <ITADebug.h>
namespace ITA
{
namespace SimulationScheduler
{
namespace OutdoorAcoustics
{
namespace ART
{
#ifdef WITH_PROFILER
std::size_t CWorkerThread::iWorkerMaxID = 0;
#endif
CWorkerThread::WorkerThreadConfig::WorkerThreadConfig ( )
: WorkerThreadConfig( "Unkown" )
{ }
CWorkerThread::WorkerThreadConfig::WorkerThreadConfig(const std::string& sType)
: WorkerConfig(GetType())
, m_sSimulatorType( sType )
, sSimulatorType( m_sSimulatorType )
{
}
VistaPropertyList CWorkerThread::WorkerThreadConfig::Store ( ) const
{
auto oProperties = WorkerConfig::Store ( );
oProperties.SetValue (SIMULATOR_TYPE_KEY, sSimulatorType );
return oProperties;
}
void CWorkerThread::WorkerThreadConfig::Load ( const VistaPropertyList& oProperties )
{
WorkerConfig::Load ( oProperties );
oProperties.GetValue (SIMULATOR_TYPE_KEY, m_sSimulatorType);
}
CWorkerThread::CWorkerThread ( const WorkerThreadConfig& oConfig, ISchedulerInterface* pParent ) :
IWorkerInterface ( pParent ), m_evTriggerLoop ( VistaThreadEvent::NON_WAITABLE_EVENT )
{
//oConfig;
//m_oSimulator = std::make_unique<CSimulator> ( m_eFieldOfDuty, oConfig.sRavenProjectFilePath );
Run ( );
}
CWorkerThread::~CWorkerThread ( )
{
m_bStopIndicated = true;
m_evTriggerLoop.SignalEvent ( );
// Wait for the end of the simulation
while ( IsBusy ( ) ) VistaTimeUtils::Sleep ( 100 );
StopGently ( true );
}
void CWorkerThread::PushUpdate ( std::unique_ptr<CUpdateScene> pUpdate )
{
//PROFILER_FUNCTION ( );
PROFILER_VALUE ( "Update to Worker", pUpdate->GetID ( ) );
//auto pTask = CreateTaskFromUpdate ( std::move ( pUpdate ) );
assert ( !IsBusy ( ) );
m_bBusy = true;
m_pUpdate = std::move(pUpdate);
// Stop if reset is running.
if ( m_bResetIndicated )
{
m_pUpdate = nullptr;
m_bBusy = false;
return;
}
// Start the loop and simulation.
m_evTriggerLoop.SignalEvent ( );
}
void CWorkerThread::Reset ( )
{
// Signal reset
m_bResetIndicated = true;
// Wait for the end of the simulation
while ( IsBusy ( ) ) VistaTimeUtils::Sleep ( 100 );
// Reset the simulator
m_oSimulator->Reset ( );
// Reset the flags
m_bResetIndicated = false;
}
void CWorkerThread::Shutdown()
{
m_bStopIndicated = true;
m_evTriggerLoop.SignalEvent ( );
// Wait for the end of the simulation
while ( IsBusy ( ) ) VistaTimeUtils::Sleep ( 100 );
StopGently ( true );
}
std::unique_ptr<IWorkerInterface> CWorkerThread::CreateWorker (