Commit f0f1902d authored by LOPEZ GANDIA Axel's avatar LOPEZ GANDIA Axel

Merge branch 'Wouter-API-DLL' into 'master'

Wouter api dll

See merge request !85
parents fe109972 ecb14c5f
......@@ -5,6 +5,7 @@ cmake-build-debug
build/
/.vs
/bin
/release
# Prerequisites
*.d
......
#define DLL_EXPORT
#include "APIFunctions.h"
#include <core/crowdSimulator.h>
#include <algorithm>
extern "C" {
CrowdSimulator* cs;
AgentData* agentData;
size_t agentDataSize;
API_FUNCTION bool StartSimulation(const char* configFileName)
{
// initialize a new crowd simulation with the given config file
cs = new CrowdSimulator();
cs->loadMasterConfigFile(std::string(configFileName));
// prepare the agentData array
agentDataSize = std::max((size_t)4, cs->getWorld()->getAgents().size() * 2);
agentData = new AgentData[agentDataSize];
return true;
}
API_FUNCTION bool GetSimulationTimeStep(float& result_dt)
{
if (cs == nullptr)
return false;
result_dt = cs->getWorld()->getDeltaTime();
return true;
}
API_FUNCTION bool DoSimulationSteps(int nrSteps)
{
if (cs == nullptr)
return false;
cs->runWorld(nrSteps);
return true;
}
API_FUNCTION bool GetAgentPositions(AgentData*& result_agentData, int& result_nrAgents)
{
if (cs == nullptr)
return false;
const auto& agents = cs->getWorld()->getAgents();
// check if the AgentData array is large enough; resize it if necessary
if (agents.size() > agentDataSize)
{
delete[] agentData;
agentDataSize *= 2;
agentData = new AgentData[agentDataSize];
}
else if (agents.size() * 4 < agentDataSize)
{
delete[] agentData;
agentDataSize /= 4;
agentData = new AgentData[agentDataSize];
}
// fill the AgentData array with the current agent data
int i = 0;
for (const auto& agent : agents)
{
agentData[i].id = agent->getID();
agentData[i].x = agent->getPosition().x();
agentData[i].y = agent->getPosition().y();
++i;
}
// store references to these results, for the client program to use
result_agentData = agentData;
result_nrAgents = (int)agents.size();
return true;
}
API_FUNCTION bool CleanUp()
{
if (cs == nullptr)
return false;
delete cs;
delete[] agentData;
return true;
}
}
\ No newline at end of file
#ifdef DLL_EXPORT
#ifdef WIN32
#define API_FUNCTION __declspec(dllexport)
#else
#define API_FUNCTION __attribute__((visibility("default")))
#endif
#endif
extern "C"
{
/// <summary>A struct that describes the status of a single agent in the simulation.
/// This struct is used for communication between the OCSR library and external applications.</summary>
struct AgentData
{
/// The unique ID of the agent.
int id;
/// The x coordinate of the agent at the current time.
float x;
/// The y coordinate of the agent at the current time.
float y;
};
/// <summary>Sets up a simulation based on a configuration file.
/// After this function call, the simulation will be ready for its first time step.</summary>
/// <returns>true if the operation was successful; false otherwise, e.g. if the configuration file is invalid.</returns>
API_FUNCTION bool StartSimulation(const char* configFileName);
/// <summary>Gets the step size of the simulation, in seconds.</summary>
/// <param ref="result_dt">[out] Will store the step size of the simulation.</param>
/// <returns>true if the operation was successful; false otherwise, i.e. if the simulation has not been initialized (correctly) yet.</returns>
API_FUNCTION bool GetSimulationTimeStep(float& result_dt);
/// <summary>Performs the given number of simulation steps.
/// To obtain the resulting status of the simulation, use the GetAgentPositions() function.</summary>
/// <param ref="nrSteps">The number of steps to perform.</param>
/// <returns>true if the operation was successful; false otherwise, i.e. if the simulation has not been initialized (correctly) yet.</returns>
API_FUNCTION bool DoSimulationSteps(int nrSteps);
/// <summary>Gets the current status of all agents in the simulation.</summary>
/// <param ref="result_agentData">[out] Will store a reference to an array of AgentData objects,
/// where each object describes the status of a single agent.</param>
/// <param ref="result_nrAgents">[out] Will store the number of agents in the simulation,
/// i.e. the number of useful entries in the AgentData array.</param>
/// <returns>true if the operation was successful; false otherwise, i.e. if the simulation has not been initialized (correctly) yet.</returns>
API_FUNCTION bool GetAgentPositions(AgentData*& result_agentData, int& result_nrAgents);
/// <summary>Cleans up some objects related to the simulation. Call this method just before you finish using the OCSR library.</summary>
/// <returns>true if the operation was successful; false otherwise, i.e. if the simulation has not been initialized (correctly) yet.</returns>
API_FUNCTION bool CleanUp();
}
\ No newline at end of file
......@@ -40,13 +40,25 @@ link_directories( ./lib/${CMAKE_BUILD_TYPE} )
file( GLOB_RECURSE source_files src/* include/*)
file( GLOB_RECURSE 3rd_party 3rd-party/tinyxml/* 3rd-party/nanoflann/*)
add_executable(my_app main.cpp ${source_files} ${3rd_party})
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
else()
#linux compatibility compiler option
add_definitions(-fPIC)
endif()
add_library(Engine STATIC ${source_files} ${3rd_party})
add_executable(OCSR_ConsoleApplication main.cpp)
target_link_libraries(OCSR_ConsoleApplication Engine)
#add_executable(test_xmlparser ./test/test_xmlparser.cpp ${source_files} ${3rd_party})
#add_executable(test_socialforces ./test/SocialForcesExample.cpp ${source_files} ${3rd_party})
#add_executable(test_socialforces ./test/SocialForcesExample.cpp ${source_files} ${tinyxml_src})
#add_executable(test_ttcaDca ./test/DcaTtcaExample.cpp ${source_files} ${3rd_party})
#add_executable(test_localSearch ./test/TestLocalSearch.cpp ${source_files} ${3rd_party})
target_link_libraries(my_app)
add_library(OCSR_Library SHARED "APIFunctions.h" "APIFunctions.cpp")
target_link_libraries(OCSR_Library Engine)
#target_link_libraries(my_app)
#target_link_libraries(test_xmlparser)
#target_link_libraries(test_socialforces)
#target_link_libraries(test_ttcaDca)
......
......@@ -36,7 +36,7 @@ class SocialForces : public CostFunction
private:
float AtractorForce = 1;
float RepulsionForce = 3;
float sigma = 0.3;
float sigma = 0.3f;
public:
const static std::string GetName() { return "SocialForces"; }
......
......@@ -28,13 +28,13 @@
#include <core/worldBase.h>
#include <core/agent.h>
#include <fstream>
#include "tools/csvwriter.h"
class CSVWriter;
class CrowdSimulator {
private:
std::unique_ptr<WorldBase> world_;
CSVWriter writer;
CSVWriter* writer;
public:
......
......@@ -32,11 +32,13 @@ CrowdSimulator::CrowdSimulator()
{
RegisterCostFunctions();
//createNewWorld(WorldType::INFINITE);
writer = nullptr;
}
CrowdSimulator::~CrowdSimulator()
{
if (writer != nullptr)
delete writer;
}
void CrowdSimulator::loadConfigFile(const std::string &filename)
......@@ -65,7 +67,9 @@ void CrowdSimulator::runMasterConfigFile(const std::string &filename)
void CrowdSimulator::setOutputDir(const std::string &dirname)
{
writer.setDirectory(dirname);
if (writer == nullptr)
writer = new CSVWriter();
writer->setDirectory(dirname);
}
void CrowdSimulator::AppendPosInOutput(std::ofstream &outfile, double time, Agent* agent)
......@@ -93,12 +97,15 @@ void CrowdSimulator::stepWorld()
float t = world_->getTime();
const std::vector<Agent*>& agents = world_->getAgents();
std::map<int, Vector2D> poss;
for (const Agent* agent : agents)
poss[agent->getID()] = agent->getPosition();
if (writer != nullptr)
{
std::map<int, Vector2D> poss;
for (const Agent* agent : agents)
poss[agent->getID()] = agent->getPosition();
writer.appendPedPositions(poss, t);
//writer.flush(); //! @todo: should be removed after test
writer->appendPedPositions(poss, t);
//writer.flush(); //! @todo: should be removed after test
}
}
/**
......@@ -111,10 +118,11 @@ void CrowdSimulator::runWorld(int steps)
std::cout << "|--------------------------------------------------|100%" << std::endl << "[";
for (int i = 0; i < steps; ++i){
stepWorld();
if(i%p == 0) std::cout << "#" << std::flush;
//if(i%p == 0) std::cout << "#" << std::flush;
}
std::cout << "]" << std::endl;
writer.flush();
if (writer != nullptr)
writer->flush();
}
void CrowdSimulator::createNewWorld(WorldType type) {
......
......@@ -80,7 +80,7 @@ std::vector<Agent*> WorldBase::getNeighboursFlat(Vector2D position, float search
//The behavior is probably incorrect and needs to be fixed
Agent * WorldBase::findNearestNeighborWithinRadius(size_t agent_id, const Vector2D& agentPosition, float search_radius)
{
Agent* nearestNeighbour = NULL;
Agent* nearestNeighbour = nullptr;
double nearestNeighbourDistance = search_radius;
for (size_t i = 0; i < agents_.size(); i++)
......@@ -116,7 +116,7 @@ void WorldBase::doStep()
//The behavior of finding the nearest neighbor is probably incorrect
Vector2D agentNextPosition = agents_[i]->getPosition() + agents_[i]->getNextVelocity() * delta_time_;
if(findNearestNeighborWithinRadius(i, agentNextPosition, agents_[i]->getRadius()) != NULL)
if(findNearestNeighborWithinRadius(i, agentNextPosition, agents_[i]->getRadius()) != nullptr)
{
// TODO : decide of a strategy in case of collision
// For now, we do nothing
......@@ -187,7 +187,7 @@ Agent* WorldBase::getAgent(int id) {
return agents_[id].get();
}
int WorldBase::getNumAgents() {
return agents_.size();
return (int)agents_.size();
}
WorldType WorldBase::getType() {
......
......@@ -31,7 +31,7 @@
*/
//========================================================================
#include "../include/tools/csvwriter.h"
#include "tools/csvwriter.h"
//#include <boost/filesystem.hpp>
#include <fstream>
......
......@@ -56,8 +56,8 @@ void XMLParser::loadMasterConfig(const std::string &filename, CrowdSimulator * c
// Location of the config file should be relative to the location of the *main* config file.
// Check if the main config file lies in a subfolder.
auto endOfPath = filename.find_last_of('/');
std::string mainPath = (endOfPath < 0 ? "" : filename.substr(0, endOfPath));
load(mainPath + "/" + simConfigPathElt->Attribute("path"), crowdsimulator);
std::string mainPath = (endOfPath == std::string::npos ? "" : filename.substr(0, endOfPath+1));
load(mainPath + simConfigPathElt->Attribute("path"), crowdsimulator);
}
else
std::cerr << "Warning: No paths for configuration in the XML file" << std::endl;
......@@ -157,12 +157,12 @@ void XMLParser::load(const std::string &filename, CrowdSimulator * crowdsimulato
pl->addCostFunction(costFunction, CostFunctionParameters(funcElement));
}
} while ((funcElement = funcElement->NextSiblingElement()) != NULL);
} while ((funcElement = funcElement->NextSiblingElement()) != nullptr);
++policyIndex;
} while ((policyElement = policyElement->NextSiblingElement()) != NULL);
} while ((policyElement = policyElement->NextSiblingElement()) != nullptr);
......@@ -248,7 +248,7 @@ void XMLParser::load(const std::string &filename, CrowdSimulator * crowdsimulato
agent_data->setPolicy(IDToPolicyMap[agentPolicyID]);
++agentIndex;
} while ((agentElement = agentElement->NextSiblingElement()) != NULL);
} while ((agentElement = agentElement->NextSiblingElement()) != nullptr);
}
......
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