Commit 959ab5e9 authored by Ricardo Ortiz's avatar Ricardo Ortiz
Browse files

ENH: Fix initialization order in the VegaFEMSceneModel.

Refactor ObjectSimulator.
parent 1c27c80b
Pipeline #4823 passed with stage
......@@ -56,7 +56,7 @@ public:
long double elapsed();
private:
TimePointType begin; //!< Begining of time point
TimePointType begin; //!< Beginning of time point
};
} //core
......
......@@ -32,7 +32,7 @@
#include "Mesh/VegaVolumetricMesh.h"
// Include required simulators
#include "Simulators/VegaFemSimulator.h"
#include "Simulators/VegaFEMModelSimulator.h"
#include "Simulators/DefaultSimulator.h"
#include "Core/CollisionPair.h"
......@@ -69,7 +69,7 @@ int main(int ac, char **av)
// Create scene actor 1: fem scene object + fem simulator
//-------------------------------------------------------
// create a FEM simulator
auto femSimulator = std::make_shared<VegaFemSimulator>(sdk->getErrorLog());
auto femSimulator = std::make_shared<VegaFEMModelSimulator>();
// create a Vega based FEM object and attach it to the fem simulator
auto femObject = std::make_shared<VegaFemSceneObject>(sdk->getErrorLog(),configFile);
......@@ -81,7 +81,7 @@ int main(int ac, char **av)
// Create scene actor 2: plane + dummy simulator
//-------------------------------------------------------
// Create dummy simulator
auto staticSimulator = std::make_shared<DefaultSimulator>(sdk->getErrorLog());
auto staticSimulator = std::make_shared<DefaultSimulator>();
// Create a static plane scene object of given normal and position
auto staticObject = std::make_shared<StaticSceneObject>();
......
......@@ -35,7 +35,7 @@
#include "VirtualTools/ToolCoupler.h"
// Include required simulators
#include "Simulators/VegaFemSimulator.h"
#include "Simulators/VegaFEMModelSimulator.h"
#include "Simulators/DefaultSimulator.h"
#include "Core/CollisionPair.h"
......@@ -66,29 +66,29 @@ int main(int ac, char** av)
// 3. Create default scene (scene 0)
//-------------------------------------------------------
auto sdk = SDK::createStandardSDK();
auto client = std::make_shared<VRPNForceDevice>();
// auto client = std::make_shared<VRPNForceDevice>();
// auto server = std::make_shared<VRPNDeviceServer>();
//get some user input and setup device url
std::string input = "Phantom@10.171.2.217";//"Phantom0@localhost";
std::cout << "Enter the VRPN device URL(" << client->getDeviceURL() << "): ";
std::getline(std::cin, input);
if (!input.empty())
{
client->setDeviceURL(input);
}
auto controller = std::make_shared<ToolCoupler>(client);
controller->setScalingFactor(20.0);
// std::string input = "Phantom@10.171.2.217";//"Phantom0@localhost";
// std::cout << "Enter the VRPN device URL(" << client->getDeviceURL() << "): ";
// std::getline(std::cin, input);
// if (!input.empty())
// {
// client->setDeviceURL(input);
// }
// auto controller = std::make_shared<ToolCoupler>(client);
// controller->setScalingFactor(20.0);
// sdk->registerModule(server);
sdk->registerModule(client);
sdk->registerModule(controller);
// sdk->registerModule(client);
// sdk->registerModule(controller);
//-------------------------------------------------------
// Create scene actor 1: fem scene object + fem simulator
//-------------------------------------------------------
// create a FEM simulator
auto femSimulator = std::make_shared<VegaFemSimulator>(sdk->getErrorLog());
auto femSimulator = std::make_shared<VegaFEMModelSimulator>();
//femSimulator->setHapticTool(controller);
// create a Vega based FEM object and attach it to the fem simulator
......@@ -115,7 +115,7 @@ int main(int ac, char** av)
//-------------------------------------------------------
// Create scene actor 2: plane
//-------------------------------------------------------
auto staticSimulator = std::make_shared<DefaultSimulator>(sdk->getErrorLog());
auto staticSimulator = std::make_shared<DefaultSimulator>();
// create a static plane scene object of given normal and position
auto staticObject = std::make_shared<StaticSceneObject>();
......@@ -155,9 +155,9 @@ int main(int ac, char** av)
loliMesh->transform(transform);
loliMesh->updateInitialVertices();
auto loliSimulator = std::make_shared<DefaultSimulator>(sdk->getErrorLog());
auto loliSimulator = std::make_shared<DefaultSimulator>();
sdk->addSceneActor(loliSceneObject, loliSimulator);
controller->setMesh(loliCollisionModel->getMesh());
// controller->setMesh(loliCollisionModel->getMesh());
//-------------------------------------------------------
// Register both object simulators
......
......@@ -24,3 +24,95 @@
// SimMedTK includes
#include "SceneModels/DeformableSceneObject.h"
DeformableSceneObject::DeformableSceneObject():
OdeSystem(),
integrationScheme(TimeIntegrator::ImplicitEuler)
{
}
//---------------------------------------------------------------------------
void DeformableSceneObject::applyContactForces()
{
for(const auto & cf : this->getContactForces())
{
auto i = cf.first;
f(i) += cf.second(0);
f(i + 1) += cf.second(1);
f(i + 2) += cf.second(2);
}
}
//---------------------------------------------------------------------------
void DeformableSceneObject::setTimeIntegrator(TimeIntegrator::IntegratorType integrator)
{
this->integrationScheme = integrator;
}
//---------------------------------------------------------------------------
void DeformableSceneObject::initialize()
{
switch(integrationScheme)
{
case TimeIntegrator::ImplicitEuler:
{
this->odeSolver = std::make_shared<BackwardEuler>(this);
break;
}
case TimeIntegrator::ExplicitEuler:
{
this->odeSolver = std::make_shared<ForwardEuler>(this);
break;
}
default:
{
// TODO: Log this
std::cerr << "Invalid time integration scheme." << std::endl;
}
}
}
//---------------------------------------------------------------------------
bool DeformableSceneObject::configure(const std::string &)
{
return false;
}
//---------------------------------------------------------------------------
void DeformableSceneObject::update(const double dt)
{
if(!this->odeSolver)
{
std::cerr << "Ode solver needs to be set." << std::endl;
return;
}
*this->newState = *this->currentState;
this->odeSolver->solve(*this->currentState, *this->newState, dt);
this->currentState.swap(this->previousState);
this->currentState.swap(this->newState);
// TODO: Check state validity
}
//---------------------------------------------------------------------------
void DeformableSceneObject::resetToInitialState()
{
*this->currentState = *this->initialState;
*this->previousState = *this->initialState;
}
//---------------------------------------------------------------------------
std::shared_ptr< OdeSystemState > DeformableSceneObject::getCurrentState()
{
return this->currentState;
}
//---------------------------------------------------------------------------
std::shared_ptr< OdeSystemState > DeformableSceneObject::getPreviousState()
{
return this->previousState;
}
......@@ -21,8 +21,8 @@
// Contact:
//---------------------------------------------------------------------------
#ifndef SMVEGAFEMSCENEOBJECT_DEFORMABLE_H
#define SMVEGAFEMSCENEOBJECT_DEFORMABLE_H
#ifndef DEFORMABLESCENEOBJECT_H
#define DEFORMABLESCENEOBJECT_H
// SimMedTK includes
#include "SceneModels/SceneObject.h"
......@@ -39,11 +39,7 @@ public:
///
/// \brief Constructor
///
DeformableSceneObject() :
OdeSystem(),
integrationScheme(TimeIntegrator::ImplicitEuler)
{
}
DeformableSceneObject();
///
/// \brief Destructor
......@@ -53,96 +49,39 @@ public:
///
/// \brief Append the contact forces (if any) to external forces
///
void applyContactForces()
{
for(const auto &cf : this->getContactForces())
{
int i = cf.first;
f(i) += cf.second(0);
f(i+1) += cf.second(1);
f(i+2) += cf.second(2);
}
}
void applyContactForces();
///
/// \brief Set the integration scheme used to solve the ODE system.
///
void setTimeIntegrator(TimeIntegrator::IntegratorType integrator)
{
this->integrationScheme = integrator;
}
void setTimeIntegrator(TimeIntegrator::IntegratorType integrator);
///
/// \brief Initialize the ode solver.
///
void initialize() override
{
auto thisPointer = this->safeDownCast<DeformableSceneObject>();
switch(integrationScheme)
{
case TimeIntegrator::ImplicitEuler:
{
this->odeSolver = std::make_shared<BackwardEuler>(thisPointer);
}
case TimeIntegrator::ExplicitEuler:
{
this->odeSolver = std::make_shared<ForwardEuler>(thisPointer);
}
default:
{
std::cerr << "Invalid time integration scheme." << std::endl;
}
}
}
virtual bool configure(const std::string &)
{
return false;
}
void initialize() override;
virtual bool configure(const std::string &);
///
/// \brief Update states
///
void update(const double dt)
{
if(!this->odeSolver)
{
std::cerr << "Ode solver needs to be set." << std::endl;
return;
}
this->odeSolver->solve(*this->currentState,*this->newState,dt);
this->currentState.swap(this->previousState);
this->currentState.swap(this->newState);
// TODO: Check state validity
}
void update(const double dt);
///
/// \brief Reset the current state to the initial state
///
virtual void resetToInitialState()
{
*this->currentState = *this->initialState;
*this->previousState = *this->initialState;
}
virtual void resetToInitialState();
///
/// \brief Return the current state.
///
std::shared_ptr<OdeSystemState> getCurrentState()
{
return this->currentState;
}
std::shared_ptr<OdeSystemState> getCurrentState();
///
/// \brief Return the previous state.
///
std::shared_ptr<OdeSystemState> getPreviousState()
{
return this->previousState;
}
std::shared_ptr<OdeSystemState> getPreviousState();
///////////////////////////////////////////////////////////////////////////////
//////////// TODO: These are pure virtual methods from superclass. ////////////
......@@ -181,4 +120,4 @@ protected:
TimeIntegrator::IntegratorType integrationScheme; ///> Integration scheme used.
};
#endif // SMVEGAFEMSCENEOBJECT_DEFORMABLE_H
#endif // DEFORMABLESCENEOBJECT_H
......@@ -71,7 +71,7 @@ public:
virtual void handleEvent(std::shared_ptr<core::Event>) override {}
void update(const double dt)
void update(const double /*dt*/)
{}
};
......
......@@ -38,10 +38,16 @@ go_bandit([]()
describe("Vega Deformable Scene Object", [&]()
{
auto sceneObject = std::make_shared<VegaFEMDeformableSceneObject>("box.veg","box.config");
it("constructs ", [&]()
it("constructs", [&]()
{
AssertThat(sceneObject != nullptr, IsTrue());
});
it("updates", [&]()
{
sceneObject->update(0.01);
});
});
});
......@@ -78,8 +78,6 @@
/// [default = 500.0]
/// inversionThreshold Inversion threshold parameter for the invertible methods
/// [default = -infinity]
/// materialDensity Homogenious material density
/// [default = 1000]
/// numberOfThreads Number of threads spawned by the force model
/// [default = 0]
///
......@@ -126,8 +124,8 @@ VegaConfiguration::VegaConfiguration(const std::string &configurationFile, bool
{
if(configurationFile.empty())
{
// TODO: Log this.
std::cout << "Empty configuration filename." << std::endl;
return;
}
this->vegaConfigFile = configurationFile;
......@@ -184,20 +182,16 @@ VegaConfiguration::VegaConfiguration(const std::string &configurationFile, bool
&inversionThreshold,
inversionThreshold);
double materialDensity = 1000.0;
vegaConfigFileOptions.addOptionOptional("materialDensity",
&materialDensity,
materialDensity);
int numberOfThreads = 0;
vegaConfigFileOptions.addOptionOptional("numberOfThreads",
&numberOfThreads,
numberOfThreads);
// Parse the configuration file
if(vegaConfigFileOptions.parseOptions(configurationFile.data()) != 0)
if(!configurationFile.empty() &&
vegaConfigFileOptions.parseOptions(configurationFile.data()) != 0)
{
std::cout << "VEGA: error! parsing options.\n";
/// TODO: Log this.
}
// Print option variables
......@@ -221,7 +215,6 @@ VegaConfiguration::VegaConfiguration(const std::string &configurationFile, bool
this->floatsOptionMap.emplace("gravity", gravity);
this->floatsOptionMap.emplace("compressionResistance", compressionResistance);
this->floatsOptionMap.emplace("inversionThreshold", inversionThreshold);
this->floatsOptionMap.emplace("materialDensity", materialDensity);
// Store parsed int values
this->intsOptionMap.emplace("numberOfThreads", numberOfThreads);
......@@ -272,7 +265,7 @@ VegaFEMDeformableSceneObject::VegaFEMDeformableSceneObject(const std::string &me
this->loadVolumeMesh(meshFilename);
if(!this->volumetricMesh)
{
// TODO: Rise error
// TODO: Rise error and log
return;
}
......@@ -324,6 +317,9 @@ void VegaFEMDeformableSceneObject::loadInitialStates()
this->currentState = std::make_shared<OdeSystemState>();
*this->currentState = *this->initialState;
this->newState = std::make_shared<OdeSystemState>();
this->previousState = std::make_shared<OdeSystemState>();
}
//---------------------------------------------------------------------------
......@@ -335,6 +331,9 @@ void VegaFEMDeformableSceneObject::initialize()
this->initConstitutiveModel();
this->initForceModel();
this->initMassMatrix();
this->initDampingMatrix();
this->initTangentStiffnessMatrix();
}
//---------------------------------------------------------------------------
......@@ -342,9 +341,10 @@ bool VegaFEMDeformableSceneObject::configure(const std::string &configFile)
{
this->vegaFemConfig = Core::make_unique<VegaConfiguration>(configFile);
this->initMassMatrix();
this->initTangentStiffnessMatrix();
this->initDampingMatrix();
this->setMassMatrix();
this->setTangentStiffnessMatrix();
this->setDampingMatrix();
this->setOdeRHS();
size_t numNodes = this->volumetricMesh->getNumberOfVertices();
this->numOfDOF = 3 * numNodes;
......@@ -359,6 +359,7 @@ void VegaFEMDeformableSceneObject::initMassMatrix(bool saveToDisk)
{
if(!this->volumetricMesh)
{
// TODO: log this
return;
}
......@@ -383,6 +384,7 @@ void VegaFEMDeformableSceneObject::initMassMatrix(bool saveToDisk)
this->massMatrixColIndices.data(),
this->massMatrixValues.data());
this->M.makeCompressed();
if(saveToDisk)
{
char name[] = "ComputedMassMatrix.mass";
......@@ -395,6 +397,7 @@ void VegaFEMDeformableSceneObject::initTangentStiffnessMatrix()
{
if(!this->forceModel)
{
// TODO: log this
return;
}
......@@ -403,6 +406,7 @@ void VegaFEMDeformableSceneObject::initTangentStiffnessMatrix()
if(!matrix)
{
// TODO: log this
return;
}
......@@ -410,6 +414,7 @@ void VegaFEMDeformableSceneObject::initTangentStiffnessMatrix()
if(!this->vegaMassMatrix)
{
// TODO: log this
return;
}
......@@ -417,6 +422,7 @@ void VegaFEMDeformableSceneObject::initTangentStiffnessMatrix()
if(!this->dampingMatrix)
{
// TODO: log this
return;
}
......@@ -436,6 +442,7 @@ void VegaFEMDeformableSceneObject::initTangentStiffnessMatrix()
this->tangentStiffnessMatrixRowPointers.data(),
this->tangentStiffnessMatrixColIndices.data(),
this->tangentStiffnessMatrixValues.data());
this->K.makeCompressed();
}
//---------------------------------------------------------------------------
......@@ -445,6 +452,7 @@ void VegaFEMDeformableSceneObject::initDampingMatrix()
if(!meshGraph)
{
// TODO: log this
return;
}
......@@ -453,6 +461,7 @@ void VegaFEMDeformableSceneObject::initDampingMatrix()
if(!matrix)
{
// TODO: log this
return;
}
......@@ -475,6 +484,7 @@ void VegaFEMDeformableSceneObject::initDampingMatrix()
this->dampingMatrixColPointers.data(),
this->dampingMatrixColIndices.data(),
this->dampingMatrixValues.data());
this->D.makeCompressed();
}
//---------------------------------------------------------------------------
......@@ -804,7 +814,7 @@ void VegaFEMDeformableSceneObject::setOdeRHS()
//---------------------------------------------------------------------------
void VegaFEMDeformableSceneObject::setTangentStiffnessMatrix()
{
auto tangentStiffness = [this](const OdeSystemState & s)
auto tangentStiffness = [&,this](const OdeSystemState & s)
{
double *data = const_cast<double*>(s.getPositions().data());
this->forceModel->GetTangentStiffnessMatrix(data,
......
......@@ -105,7 +105,7 @@ std::shared_ptr<Simulator> SDK::createSimulator()
{
if(!this->simulator)
{
simulator = std::make_shared<Simulator>(errorLog);
simulator = std::make_shared<Simulator>();
simulator->sceneList = this->sceneList;
registerModule(simulator);
}
......
......@@ -45,7 +45,7 @@ void Simulator::initAsyncThreadPool()
for (size_t i = 0; i < simulators.size(); i++)
{
if (simulators[i]->execType == SIMMEDTK_SIMEXECUTION_ASYNCMODE)
if (simulators[i]->getExecutionType() == ObjectSimulator::ExecutionType::AsyncMode)
{
asyncThreadPoolSize++;
}
......@@ -63,7 +63,7 @@ void Simulator::run()
if (isInitialized == false)
{
log->addError("Simulator is not initialized.");
// TODO: Log error
return;
}
......@@ -75,13 +75,13 @@ void Simulator::run()
asyncResults.reserve(this->asyncThreadPoolSize);
for (size_t i = 0; i < simulators.size(); i++)
{
if (simulators[i]->execType == SIMMEDTK_SIMEXECUTION_ASYNCMODE)
if (simulators[i]->getExecutionType() == ObjectSimulator::ExecutionType::AsyncMode)
{
objectSimulator = simulators[i];
asyncResults.emplace_back(asyncPool->enqueue(
[objectSimulator]()
{
objectSimulator->run();
objectSimulator->exec();
return 0; //this return is just so we have a results value
})
);
......@@ -108,12 +108,12 @@ void Simulator::run()
{
objectSimulator = simulators[i];
if (objectSimulator->execType == SIMMEDTK_SIMEXECUTION_ASYNCMODE)
if (objectSimulator->getExecutionType() == ObjectSimulator::ExecutionType::AsyncMode)
{
continue;
}
if (objectSimulator->enabled == false)
if (objectSimulator->isEnabled() == false)
{
continue;
}
......@@ -122,7 +122,7 @@ void Simulator::run()
results.emplace_back(threadPool->enqueue(
[objectSimulator]()
{
objectSimulator->run();
objectSimulator->exec();
return 0; //this return is just so we have a results value
})
);
......@@ -201,7 +201,7 @@ void Simulator::run()
void Simulator::registerObjectSimulator(std::shared_ptr<ObjectSimulator> objectSimulator)
{
simulators.emplace_back(objectSimulator);
objectSimulator->enabled = true;
objectSimulator->setEnabled(true);
}
/// \brief
......@@ -237,7 +237,7 @@ bool Simulator::init()
for(size_t i = 0; i < this->simulators.size(); i++)