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

OutdoorAcoustics

- finished outdoor result class
- added folders for Urban and ART modules
parent 8aa98f7e
......@@ -4,14 +4,14 @@ set( SubDirs
)
set( DirFiles
raven_scene.h
raven_simulation_result.h
simulation_task.h
simulator.h
raven_worker_interface.h
worker_thread.h
simulator_interface.h
#_SourceFiles.cmake
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
)
set( DirFiles_SourceGroup "${RelativeSourceGroup}" )
......
#ifndef INCLUDE_WATCHER_ITA_SIMULATION_SCHEDULER_OUTDOOR_ACOUSTICS_ART_WORKER_THREAD
#define INCLUDE_WATCHER_ITA_SIMULATION_SCHEDULER_OUTDOOR_ACOUSTICS_ART_WORKER_THREAD
// std include
#include <string>
#include <memory>
// API includes
#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/update_scene.h>
// Vista includes
#include <VistaInterProcComm/Concurrency/VistaThreadLoop.h>
#include <VistaInterProcComm/Concurrency/VistaThreadEvent.h>
#include <ITAAtomicPrimitives.h>
namespace ITA
{
namespace SimulationScheduler
{
namespace OutdoorAcoustics
{
namespace ART
{
struct CARTConfig;
///
/// \brief Raven worker utilizing a thread to run the actual simulation.
///
class ITA_SIMULATION_SCHEDULER_API CWorkerThread : public IRavenWorkerInterface, VistaThreadLoop
{
public:
///
/// \brief Configuration class for a raven thread worker.
///
struct ITA_SIMULATION_SCHEDULER_API WorkerThreadConfig : public IRavenWorkerInterface::RavenWorkerConfig
{
explicit WorkerThreadConfig ( );
std::string sRavenProjectFilePath = "path/to/raven/project/file.rpf";
VistaPropertyList Store ( ) const override;
void Load ( const VistaPropertyList& oProperties ) override;
};
///
/// \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.
///
~CWorkerThread ( );
///
/// \copydoc IWorkerInterface::IsBusy
///
bool IsBusy ( ) override;
///
/// \copydoc IWorkerInterface::PushUpdate
///
void PushUpdate ( std::unique_ptr<CUpdateScene> pUpdate ) override;
///
/// \copydoc IWorkerInterface::Reset
/// \detail With the reset, the simulator get reset.
///
void Reset ( ) override;
///
/// \copydoc IWorkerInterface::Shutdown
///
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.
///
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 ( );
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
///
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.
///
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 );
private:
///
/// \brief The actual raven simulator
///
std::unique_ptr<ISimulatorInterface> m_pSimulator;
///
/// \brief True if a scene is loaded.
///
ITAAtomicBool m_bSceneLoaded;
///
/// \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;
///
/// \{
/// \brief Bools for handling the stop of the loop.
///
/// As these will be accessed by two threads, they have to be atomic.
///
ITAAtomicBool m_bStopIndicated = false;
ITAAtomicBool m_bResetIndicated = false;
/// \}
#ifdef WITH_PROFILER
static std::size_t iWorkerMaxID;
#endif
};
} // namespace ART
} // namespace OutdoorAcoustics
} // namespace SimulationScheduler
} // namespace ITA
#endif // INCLUDE_WATCHER_ITA_SIMULATION_SCHEDULER_OUTDOOR_ACOUSTICS_ART_WORKER_THREAD
\ No newline at end of file
......@@ -4,14 +4,14 @@ set( SubDirs
)
set( DirFiles
raven_scene.h
raven_simulation_result.h
simulation_task.h
simulator.h
raven_worker_interface.h
worker_thread.h
simulator_interface.h
#_SourceFiles.cmake
urban_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
)
set( DirFiles_SourceGroup "${RelativeSourceGroup}" )
......
#ifndef INCLUDE_WATCHER_ITA_SIMULATION_SCHEDULER_OUTDOOR_ACOUSTICS_URBAN_WORKER_THREAD
#define INCLUDE_WATCHER_ITA_SIMULATION_SCHEDULER_OUTDOOR_ACOUSTICS_URBAN_WORKER_THREAD
// std include
#include <string>
#include <memory>
// API includes
#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/update_scene.h>
// Vista includes
#include <VistaInterProcComm/Concurrency/VistaThreadLoop.h>
#include <VistaInterProcComm/Concurrency/VistaThreadEvent.h>
#include <ITAAtomicPrimitives.h>
namespace ITA
{
namespace SimulationScheduler
{
namespace OutdoorAcoustics
{
namespace Urban
{
struct CRavenConfig;
///
/// \brief Raven worker utilizing a thread to run the actual simulation.
///
class ITA_SIMULATION_SCHEDULER_API CWorkerThread : public IRavenWorkerInterface, VistaThreadLoop
{
public:
///
/// \brief Configuration class for a raven thread worker.
///
struct ITA_SIMULATION_SCHEDULER_API WorkerThreadConfig : public IRavenWorkerInterface::RavenWorkerConfig
{
explicit WorkerThreadConfig ( );
std::string sRavenProjectFilePath = "path/to/raven/project/file.rpf";
VistaPropertyList Store ( ) const override;
void Load ( const VistaPropertyList& oProperties ) override;
};
///
/// \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.
///
~CWorkerThread ( );
///
/// \copydoc IWorkerInterface::IsBusy
///
bool IsBusy ( ) override;
///
/// \copydoc IWorkerInterface::PushUpdate
///
void PushUpdate ( std::unique_ptr<CUpdateScene> pUpdate ) override;
///
/// \copydoc IWorkerInterface::Reset
/// \detail With the reset, the simulator get reset.
///
void Reset ( ) override;
///
/// \copydoc IWorkerInterface::Shutdown
///
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.
///
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 ( );
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
///
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.
///
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 );
private:
///
/// \brief The actual raven simulator
///
std::unique_ptr<ISimulatorInterface> m_pSimulator;
///
/// \brief True if a scene is loaded.
///
ITAAtomicBool m_bSceneLoaded;
///
/// \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;
///
/// \{
/// \brief Bools for handling the stop of the loop.
///
/// As these will be accessed by two threads, they have to be atomic.
///
ITAAtomicBool m_bStopIndicated = false;
ITAAtomicBool m_bResetIndicated = false;
/// \}
#ifdef WITH_PROFILER
static std::size_t iWorkerMaxID;
#endif
};
} // namespace Urban
} // namespace OutdoorAcoustics
} // namespace SimulationScheduler
} // namespace ITA
#endif // INCLUDE_WATCHER_ITA_SIMULATION_SCHEDULER_OUTDOOR_ACOUSTICS_URBAN_WORKER_THREAD
\ No newline at end of file
......@@ -9,9 +9,7 @@ if( ITA_SIMULATION_SCHEDULER_ART_MODULE )
endif( )
set( DirFiles
#master_simulation_controller.h
outdoor_simulation_result.h
outdoor_acoustics_worker_interface.h
#_SourceFiles.cmake
)
......
#ifndef INCLUDE_WATCHER_ITA_SIMULATION_SCHEDULER_ROOM_ACOUSTICS_MASTER_SIMULATION_CONTROLLER
#define INCLUDE_WATCHER_ITA_SIMULATION_SCHEDULER_ROOM_ACOUSTICS_MASTER_SIMULATION_CONTROLLER
// std includes
#include <memory>
#include <list>
// API includes
#include <ITA/SimulationScheduler/definitions.h>
// simulation scheduler includes
#include <ITA/SimulationScheduler/update_message.h>
#include <ITA/SimulationScheduler/scheduler_interface.h>
#include <ITA/SimulationScheduler/scheduler.h>
// VISTA includes
#include <VistaInterProcComm/Concurrency/VistaThreadLoop.h>
#include <VistaInterProcComm/Concurrency/VistaThreadEvent.h>
#include <VistaAspects/VistaPropertyList.h>
// ITA includes
#include <ITAAtomicPrimitives.h>
// Other includes
#include <tbb/concurrent_queue.h>
namespace ITA
{
namespace SimulationScheduler
{
class IResultHandler;
namespace RoomAcoustics
{
///
/// \brief Primary interaction class for room acoustic simulations.
///
/// This class represents the interface with which external software should interact with the simulation scheduler for room acoustic simulations.
/// It allows for easy interaction and configuration of the system.
/// - Updates can be issued via postUpdate().
/// - A IResultHandler can be registered via attachResultHandler.
/// - A simple replacement filter can be enabled for the CMasterSimulationController.
///
/// The actual computation takes place in its own thread (loop), see LoopBody().
/// \todo Inherit the scheduler interface? But we dont need handle simulation here :/
///
class ITA_SIMULATION_SCHEDULER_API CMasterSimulationController : public VistaThreadLoop
{
public:
///
/// \brief Configuration class for the master simulation controller.
///
struct ITA_SIMULATION_SCHEDULER_API MasterSimulationControllerConfig : public IConfig
{
std::shared_ptr<ISchedulerInterface::SchedulerConfig> oDSSchedulerConfig;
std::shared_ptr<ISchedulerInterface::SchedulerConfig> oERSchedulerConfig;
std::shared_ptr<ISchedulerInterface::SchedulerConfig> oDDSchedulerConfig;
bool bReplaceUpdates = true;
VistaPropertyList Store ( ) const override;
void Load ( const VistaPropertyList& oProperties ) override;
};
///
/// \brief Constructor for the CMasterSimulationController.
///
/// This constructor configures itself via the given configuration.
/// After a resultHandler is attached the controller is functional.
/// Note, that external schedulers have to be running for the master controller to work correctly.
/// \throw ITAException When creation or connection to schedulers failed.
/// \param pConfig the configuration from which to construct the CMasterSimulationController.
///
explicit CMasterSimulationController ( const MasterSimulationControllerConfig& pConfig );
///
/// \brief Destructor for CMasterSimulationController
///
~CMasterSimulationController ( );
///
/// \brief Post a new update to the CMasterSimulationController.
///
/// \note This method takes ownership of the update.
/// \param pUpdateMessage the new update for the CMasterSimulationController.
///
void PostUpdate ( std::unique_ptr<IUpdateMessage> pUpdateMessage );
///
/// \brief Attach a IResultHandler to the controller.
/// \remark Internally, the IResultHandler is attached to the simulators themselves.
/// \param pResultHandler the new IResultHandler.
/// \todo Maybe use shared_ptr ... resultHandler have to support make shared form this ... and consequently have to be shared_ptr. This would also mean ,that the scheduler own the handler.
///
void AttachResultHandler ( IResultHandler* pResultHandler ) const;
///
/// \brief Detach a IResultHandler from the controller.
/// \param pResultHandler the IResultHandler to detach.
///
void DetachResultHandler ( IResultHandler* pResultHandler ) const;
///
/// \brief Checks if the CMasterSimulationController is busy.
///
/// The CMasterSimulationController is busy if any of its scheduler is busy.
/// \return true if the CMasterSimulationController is busy, else false.
///
virtual bool IsBusy ( );
protected:
///
/// \brief Loop body for the CMasterSimulationController.
///
/// The following steps are done in the loop:
/// - Wait for a new update in m_qUpdateQueue.
/// - move the updates from the concurrent queue to a list.
/// - If the updates should be filtered, filterReplace() is called.
/// - The updates get copied, and send to the three schedulers.
/// - The m_lUpdateList gets cleared for the next loop iteration.
/// \return true if VistaThreadLoop::ThreadBody() shall call VistaThread::YieldThread() before the next loop, false else
///
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.
///
void PreLoop ( ) override;
///
/// \brief Removes duplicate updates for source-receiver-pairs in its m_qUpdateList.
///
/// If the m_qUpdateQueue has multiple updates for the same source-receiver-pair, this method removes all but the newest update.
///
void FilterReplace ( );
///
/// \brief Setter for the scheduler.
/// \note This function is primarily for testing.
/// However, it could also be useful in the long run.
/// \param pDSScheduler the DS scheduler.
/// \param pERScheduler the ER scheduler.
/// \param pDDScheduler the DD scheduler.
///
void SetScheduler ( std::unique_ptr<ISchedulerInterface> pDSScheduler,
std::unique_ptr<ISchedulerInterface> pERScheduler,
std::unique_ptr<ISchedulerInterface> pDDScheduler );
private:
///
/// \brief Modify a CScheduler::LocalSchedulerConfig so that all worker have the given ::FieldOfDuty.
/// \param oConfig the CScheduler::LocalSchedulerConfig to be modified.
/// \param eFOD the ::FieldOfDuty to set the workers to.
/// \throw std::bad_cast one of the worker configs is not a ::IRoomAcousticsWorkerInterface::RoomAcousticsWorkerInterfaceConfig
/// \return a modified copy of the given config.
///
static CScheduler::LocalSchedulerConfig SetWorkerFieldOfDuty ( const CScheduler::LocalSchedulerConfig& oConfig, FieldOfDuty eFOD );
///
/// \brief Update queue for the controller.
///
/// postUpdate() adds new updates to this queue before they get passed to the schedulers in LoopBody().
///
tbb::concurrent_queue<std::unique_ptr<IUpdateMessage>> m_qUpdateQueue;
std::list<std::unique_ptr<IUpdateMessage>> m_lUpdateList;
///
/// \brief True if the controller should filter its received updates using filterReplace().
///
bool m_bReplaceUpdates;
///
/// \brief The scheduler for the direct sound of the RIR.
///
std::unique_ptr<ISchedulerInterface> m_pDSScheduler;
///
/// \brief The scheduler for the early reflections of the RIR.
///
std::unique_ptr<ISchedulerInterface> m_pERScheduler;