Commit 1e1c76a3 authored by VAN TOLL Wouter's avatar VAN TOLL Wouter

Merge master changes into Wouter-API-DLL

parents 12830087 ee22f044
This diff is collapsed.
......@@ -31,7 +31,7 @@ set (CMAKE_CXX_STANDARD 14)
#set(Boost_USE_STATIC_LIBS ON)
#find_package(Boost COMPONENTS system filesystem regex REQUIRED)
include_directories( ./include )
include_directories(./3rd-party/tinyxml/)
include_directories(./3rd-party/tinyxml/ ./3rd-party/nanoflann/)
link_directories( ./lib/${CMAKE_BUILD_TYPE} )
......@@ -39,16 +39,16 @@ link_directories( ./lib/${CMAKE_BUILD_TYPE} )
#include_directories( ${Boost_INCLUDE_DIRS} )
file( GLOB_RECURSE source_files src/* include/*)
file( GLOB_RECURSE tinyxml_src 3rd-party/tinyxml/*)
file( GLOB_RECURSE 3rd_party 3rd-party/tinyxml/* 3rd-party/nanoflann/*)
add_library(Engine STATIC ${source_files} ${tinyxml_src})
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} ${tinyxml_src})
#add_executable(test_xmlparser ./test/test_xmlparser.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} ${tinyxml_src})
add_executable(test_localSearch ./test/TestLocalSearch.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})
add_library(OCSR_Library SHARED "APIFunctions.h" "APIFunctions.cpp")
target_link_libraries(OCSR_Library Engine)
......@@ -69,4 +69,4 @@ foreach(_source IN ITEMS ${source_files})
string(REPLACE "/" "\\" _group_path "${_source_path_rel}")
source_group("${_group_path}" FILES "${_source}")
endforeach()
source_group("3rd-party" FILES ${tinyxml_src})
source_group("3rd-party" FILES ${3rd_party})
......@@ -38,6 +38,7 @@ class FOEAvoidance : public CostFunction
private:
public:
const static std::string GetName() { return "FOEAvoidance"; }
const static std::string Name;
FOEAvoidance();
......@@ -46,7 +47,8 @@ class FOEAvoidance : public CostFunction
* Computes the value and gradient of the cost function.
* Return the values to the policy to update the agent.
*/
virtual CostFunctionValues GetCostFunctionGradient(Agent* agent, World * world);
virtual CostFunctionValues GetCostFunctionGradient(Agent* agent, WorldBase * world);
void parseParameters(tinyxml2::XMLElement* v) override;
virtual ~FOEAvoidance();
};
......
......@@ -38,13 +38,15 @@ class GenericCost : public CostFunction
public:
const static std::string Name;
const static std::string GetName() { return "Generic"; }
GenericCost();
/**
* Computes the value and gradient of the cost function.
* Return the values to the policy to update the agent.
*/
virtual CostFunctionValues GetCostFunctionGradient(Agent* agent, World * world);
virtual CostFunctionValues GetCostFunctionGradient(Agent* agent, WorldBase * world);
void parseParameters(tinyxml2::XMLElement* v) override;
virtual ~GenericCost();
};
......
......@@ -38,6 +38,7 @@ class PowerLaw : public CostFunction
private:
public:
const static std::string GetName() { return "PowerLaw"; }
float tau0 = 3;
......@@ -48,7 +49,8 @@ class PowerLaw : public CostFunction
* Computes the value and gradient of the cost function.
* Return the values to the policy to update the agent.
*/
virtual CostFunctionValues GetCostFunctionGradient(Agent* agent, World * world);
virtual CostFunctionValues GetCostFunctionGradient(Agent* agent, WorldBase * world);
void parseParameters(tinyxml2::XMLElement* v) override;
virtual ~PowerLaw();
};
......
......@@ -38,6 +38,7 @@ class RandomFunction : public CostFunction
std::default_random_engine RNGengine;
std::uniform_real_distribution<float> RNGdistribution;
public:
const static std::string GetName() { return "RandomFunction"; }
int RNGSeed = 0;
const static std::string Name;
......@@ -48,7 +49,8 @@ class RandomFunction : public CostFunction
* Computes the value and gradient of the cost function.
* Return the values to the policy to update the agent.
*/
virtual CostFunctionValues GetCostFunctionGradient(Agent* agent, World * world);
virtual CostFunctionValues GetCostFunctionGradient(Agent* agent, WorldBase * world);
void parseParameters(tinyxml2::XMLElement* v) override;
virtual ~RandomFunction();
};
......
......@@ -36,6 +36,7 @@ class SocialForcesAvoidance : public CostFunction
private:
float sigma = 0.3f;
public:
const static std::string GetName() { return "SocialForcesAvoidance"; }
const static std::string Name;
SocialForcesAvoidance();
......@@ -44,7 +45,8 @@ class SocialForcesAvoidance : public CostFunction
* Computes the value and gradient of the cost function.
* Return the values to the policy to update the agent.
*/
virtual CostFunctionValues GetCostFunctionGradient(Agent* agent, World * world);
virtual CostFunctionValues GetCostFunctionGradient(Agent* agent, WorldBase * world);
void parseParameters(tinyxml2::XMLElement* v) override;
virtual ~SocialForcesAvoidance();
};
......
......@@ -36,6 +36,7 @@ class SocialForcesGoalReaching : public CostFunction
private:
public:
const static std::string GetName() { return "SocialForcesGoalReaching"; }
const static std::string Name;
SocialForcesGoalReaching();
......@@ -44,7 +45,8 @@ class SocialForcesGoalReaching : public CostFunction
* Computes the value and gradient of the cost function.
* Return the values to the policy to update the agent.
*/
virtual CostFunctionValues GetCostFunctionGradient(Agent* agent, World * world);
virtual CostFunctionValues GetCostFunctionGradient(Agent* agent, WorldBase * world);
void parseParameters(tinyxml2::XMLElement* v) override;
virtual ~SocialForcesGoalReaching();
};
......
......@@ -56,7 +56,8 @@ class TtcaDca : public CostFunction
public:
const static std::string GetName() { return "TtcaDca"; }
/*
* Name of the cost function, to be used in configuration file
*/
......@@ -74,7 +75,8 @@ class TtcaDca : public CostFunction
* Computes the value and gradient of the cost function.
* Return the values to the policy to update the agent.
*/
virtual CostFunctionValues GetCostFunctionGradient(Agent* agent, World * world);
virtual CostFunctionValues GetCostFunctionGradient(Agent* agent, WorldBase * world);
void parseParameters(tinyxml2::XMLElement* v) override;
};
#endif //LIB_TTCADCA_H
/* Crowd Simulator Engine
** Copyright (C) 2018 - Inria Rennes - Rainbow - Julien Pettre
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the GNU General Public License
** as published by the Free Software Foundation; either version 2
** of the License, or (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**
**
**
** Authors: Axel Lopez Gandia, Javad Amirian, Florian Berton,
** Julien Legros, Lucas Pelerin, Beatriz Cabrero Daniel, Fabien Grzeskowiak
**
** Contact: crowd_group@inria.fr
*/
#ifndef LIB_DIRGOAL_REACHING_H
#define LIB_DIRGOAL_REACHING_H
#include <core/costFunction.h>
/*
* Performs a directional goal reaching at the desired speed of the agent.
* CF = AV - ADS*GD
* CF: Cost function, ADS: Agent Desired Speed, AV: Agent current Velocity.
*/
class DirGoalReaching : public CostFunction
{
private:
public:
const static std::string Name;
const static std::string GetName() { return "DirectionalGoalReaching"; }
DirGoalReaching();
/**
* Computes the value and gradient of the cost function.
* Return the values to the policy to update the agent.
*/
virtual CostFunctionValues GetCostFunctionGradient(Agent* agent, WorldBase * world);
void parseParameters(tinyxml2::XMLElement* v) override;
virtual ~DirGoalReaching();
};
#endif //LIB_DIRGOAL_REACHING_H
......@@ -38,6 +38,7 @@ class GoalReaching : public CostFunction
private:
public:
const static std::string GetName() { return "GoalReaching"; }
const static std::string Name;
GoalReaching();
......@@ -46,7 +47,8 @@ class GoalReaching : public CostFunction
* Computes the value and gradient of the cost function.
* Return the values to the policy to update the agent.
*/
virtual CostFunctionValues GetCostFunctionGradient(Agent* agent, World * world);
virtual CostFunctionValues GetCostFunctionGradient(Agent* agent, WorldBase * world);
void parseParameters(tinyxml2::XMLElement* v) override;
virtual ~GoalReaching();
};
......
......@@ -36,6 +36,7 @@ class SocialForces : public CostFunction
private:
public:
const static std::string GetName() { return "SocialForces"; }
const static std::string Name;
......@@ -48,7 +49,8 @@ class SocialForces : public CostFunction
* Computes the value and gradient of the cost function.
* Return the values to the policy to update the agent.
*/
virtual CostFunctionValues GetCostFunctionGradient(Agent* agent, World * world);
virtual CostFunctionValues GetCostFunctionGradient(Agent* agent, WorldBase * world);
void parseParameters(tinyxml2::XMLElement* v) override;
virtual ~SocialForces();
};
......
......@@ -31,7 +31,7 @@
#include <core/policy.h>
#include <memory>
class World;
class WorldBase;
/**
* Represents an agent, contains its position, speed and the policy to influence its motion.
......@@ -53,7 +53,7 @@ class Agent {
//Private constructor only the world should create agents
Agent();
friend World;
friend WorldBase;
friend std::unique_ptr<Agent> std::make_unique<Agent>(); //Spawn agents through this function in the world class
void setID(int id); //the world sets the id
public:
......@@ -62,7 +62,7 @@ class Agent {
/**
* Ask policy for new state and update next_velocity_ accordingly
*/
void runPolicy(World* world);
void runPolicy(WorldBase* world);
const Vector2D& getPosition() const;
void setPosition(const Vector2D &position);
......
......@@ -25,13 +25,13 @@
#ifndef LIB_COST_FUNCTION_H
#define LIB_COST_FUNCTION_H
#include "tinyxml2.h"
#include <tools/vector2D.h>
#include <string>
//#include <agent/agent.h>
//#include <world/world.h>
class World;
class WorldBase;
class Agent;
struct CostFunctionValues {
......@@ -39,14 +39,38 @@ struct CostFunctionValues {
Vector2D Gradient = Vector2D(0,0);
};
/*
*
* To create a new cost function you need to create a new class and derive it (public inheritance) from CostFunction.
* Then you need to override the functions GetCostFunctionGradient(Agent* agent, WorldBase * world), parseParameters(tinyxml2::XMLElement* v)
* and add a new one const static std::string GetName() { return "MyCostFuncID"; }. Finally in the cpp file you must add REGISTER_COST_FUNCTION(MyNewFunction)
*
It should look like this:
MyNewFunction.h
class MyNewFunction : public CostFunction{
public:
const static std::string GetName() { return "MyNewFunctionId"; }
CostFunctionValues GetCostFunctionGradient(Agent* agent, WorldBase * world) override;
void parseParameters(tinyxml2::XMLElement* v) override;
};
MyNewFunction.cpp
REGISTER_COST_FUNCTION(MyNewFunction)
*
*
*
*
*/
class CostFunction {
protected:
//unsigned int agentId_;
//float sigMovementCost_;
//float lambdaMovementCost_;
//World* world_;
//WorldBase* world_;
std::string name_;
float coefficient_;
float coefficient_ = 1;
public:
CostFunction();
......@@ -55,8 +79,11 @@ class CostFunction {
* Computes the value and gradient of the cost function.
* Return the values to the policy to update the agent.
*/
virtual CostFunctionValues GetCostFunctionGradient(Agent* agent, World * world) = 0;
void setCoefficient(float v);
virtual CostFunctionValues GetCostFunctionGradient(Agent* agent, WorldBase * world) = 0;
/**
* Parses the parameters of the cost function.
*/
virtual void parseParameters(tinyxml2::XMLElement* v);
virtual ~CostFunction();
std::string getName() const;
......
......@@ -3,13 +3,38 @@
#include <memory>
#include <core/costFunction.h>
#include <functional>
#include <map>
#include <string>
class CostFunctionFactory
{
public:
typedef std::function < std::shared_ptr<CostFunction>() > Creator;
typedef std::map<std::string, Creator> Registry;
CostFunctionFactory();
~CostFunctionFactory();
static std::shared_ptr<CostFunction> CreateCostFunction(const std::string& name);
static void RegisterCostFunction(const std::string &name, Creator creator);
private:
static Registry& GetRegistry();
};
template<typename Type>
std::shared_ptr<CostFunction> DefaultObjectCreator() {
return std::make_shared<Type>();
}
class CostFunctionRegistrator {
public:
CostFunctionRegistrator(const std::string &name, CostFunctionFactory::Creator creator);
};
#define REGISTER_COST_FUNCTION(classname) CostFunctionRegistrator g_##classname(classname::GetName(), DefaultObjectCreator<classname>);
#endif
......@@ -27,16 +27,16 @@
#define LIB_CROWD_SIMULATOR_H
#include <memory>
#include <core/world.h>
#include <core/worldBase.h>
#include <core/agent.h>
#include <fstream>
class CSVWriter;
#include "tools/csvwriter.h"
class CrowdSimulator {
private:
std::unique_ptr<World> world_;
CSVWriter* writer;
std::unique_ptr<WorldBase> world_;
CSVWriter writer;
public:
......@@ -91,9 +91,9 @@ public:
//void addAgentToSimulation(Agent * agent);
Agent* createAgent();
void createNewWorld(/*Type of world*/);
void createNewWorld(WorldType type);
World * getWorld() { return world_.get(); }
WorldBase * getWorld() { return world_.get(); }
};
......
......@@ -26,13 +26,13 @@
#ifndef LIB_POLICY_H
#define LIB_POLICY_H
#include "tinyxml2.h"
#include <core/costFunction.h>
#include <tools/vector2D.h>
#include <vector>
#include <memory>
class World;
class WorldBase;
class Agent;
class Policy {
......@@ -41,9 +41,9 @@ class Policy {
//std::vector<double> parameters_;
public:
Vector2D getNewVelocity(Agent* agent, World * world);
Vector2D getNewVelocity(Agent* agent, WorldBase * world);
void addCostFunction(const std::shared_ptr<CostFunction>& costFunction, float weight = 1);
void addCostFunction(const std::shared_ptr<CostFunction>& costFunction, tinyxml2::XMLElement* args);
//std::vector<double> getParameters() const;
std::vector<std::shared_ptr<CostFunction> > & getCostFunctions();
......
......@@ -23,25 +23,43 @@
** Contact: crowd_group@inria.fr
*/
#ifndef LIB_WORLD_H
#define LIB_WORLD_H
#ifndef LIB_WORLD_BASE_H
#define LIB_WORLD_BASE_H
#include <vector>
#include <memory>
#include <string>
#include "core/agent.h"
#include "core/obstacle.h"
#include "tools/vector2D.h"
//#include "tools/lq2D.h"
#include <nanoflann.hpp>
/*
* Types of world allowed.
*/
enum WorldType { BASE, INFINITE, TORIC };
WorldType StringToWorldType(std::string type);
/*
* Define phantom agents. Neighbor queries should return instances of this struct.
*/
struct PhantomAgent {
Vector2D position;
Vector2D velocity;
Agent * realAgent; //reference to the corresponding agent (if any)
PhantomAgent(Vector2D pos, Vector2D vel, Agent * agent = nullptr) : position(pos), velocity(vel), realAgent(agent){}
PhantomAgent() {}
};
/**
* Contains the state of the world (agents and obstacles).
* Defines the scenario (Infinite, toroidal, etc).
* Updates agent position and manages collisions.
*/
class World
class WorldBase
{
private:
protected:
const WorldType type_;
//std::vector<Agent*> agents_;
//std::vector<Obstacle*> obstacles_;
......@@ -53,11 +71,14 @@ class World
float time_;
/*lqInternalDB2D *lqDB;
std::vector<lqClientProxy2D*> lqProxies;*/
static void perNeighborCallBackFunction (void* clientObject, float /*distanceSquared*/, void* clientQueryState);
//nanoflann kdtree class
typedef nanoflann::KDTreeSingleIndexAdaptor <
nanoflann::L2_Simple_Adaptor<float, WorldBase >,
WorldBase,
2 /* dim */
> kd_tree_t;
kd_tree_t kdtree;
/**
* Finds the nearest neighbor of an agent
......@@ -69,18 +90,28 @@ class World
Agent * findNearestNeighborWithinRadius(size_t agent_id, const Vector2D & agentPosition, float search_radius);
public :
World();
WorldBase(WorldType type);
/**
* Computes a simple neighbourhood of an agent
* @param agent_id
* @returns a vector containing the agents located in the neighbourhood
*/
std::vector<Agent*> getNeighboursOfAgent(int agent_id, float search_radius);
std::vector<PhantomAgent> getNeighboursOfAgent(int agent_id, float search_radius);
/*
* Virtual function. Every world does a different neighbor search.
*/
virtual std::vector<PhantomAgent> getNeighbours(Vector2D position, float search_radius) = 0;
/*
* Neighbor search for an infinite flat world (helper for other neighbor search functions).s
*/
std::vector<Agent*> getNeighboursFlat(Vector2D position, float search_radius);
/**
* Computes each agent's new velocity
* Computes each agent's new velocity and position
*/
void updateAllAgents();
virtual void updateAllAgents();
/**
* Updates each agent's position according to their wanted new velocity,
......@@ -91,6 +122,11 @@ class World
//void setAgents(const std::vector<Agent *> &agents);
//void setObstacles(const std::vector<Obstacle *> &obstacles);
/*
* Get agent id.
*/
Agent* getAgent(int id);
int getNumAgents();
std::vector<Agent *> getAgents() const;
std::vector<Obstacle *> getObstacles() const;
float getTime() const;
......@@ -104,6 +140,30 @@ class World
* Creates an Agent. Agents should only be created through this function.
*/
Agent* createAgent();
WorldType getType();
virtual ~WorldBase();
/*******Nanoflann interface********/
// Must return the number of data agents
inline size_t kdtree_get_point_count() const { return agents_.size(); }
// Returns the dim'th component of the idx'th point in the class:
// Since this is inlined and the "dim" argument is typically an immediate value, the
// "if/else's" are actually solved at compile time.
inline float kdtree_get_pt(const size_t idx, const size_t dim) const
{
if (dim == 0) return agents_[idx]->getPosition().x();
else return agents_[idx]->getPosition().y();
}
// Optional bounding-box computation: return false to default to a standard bbox computation loop.
// Return true if the BBOX was already computed by the class and returned in "bb" so it can be avoided to redo it again.
// Look at bb.size() to find out the expected dimensionality (e.g. 2 or 3 for point clouds)
template <class BBOX>
bool kdtree_get_bbox(BBOX& /* bb */) const { return false; }
/*******End Nanoflann interface********/
};
#endif //LIB_WORLD_H
#endif //LIB_WORLD_BASE_H
/* Crowd Simulator Engine
** Copyright (C) 2018 - Inria Rennes - Rainbow - Julien Pettre
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the GNU General Public License
** as published by the Free Software Foundation; either version 2
** of the License, or (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**
**
**
** Authors: Axel Lopez Gandia, Javad Amirian, Florian Berton,
** Julien Legros, Lucas Pelerin, Beatriz Cabrero Daniel, Fabien Grzeskowiak
**
** Contact: crowd_group@inria.fr
*/
#ifndef LIB_WORLD_INFINITE_H
#define LIB_WORLD_INFINITE_H
#include <vector>
#include <memory>
#include "core/agent.h"
#include "core/obstacle.h"
#include "core/worldBase.h"
#include "tools/vector2D.h"
#include <nanoflann.hpp>
/**
* Contains the state of the world (agents and obstacles).
* Defines the scenario (Infinite, toroidal, etc).
* Updates agent position and manages collisions.
*/
class WorldInfinite : public WorldBase
{
public :
WorldInfinite();
/*
* Neighbor search in an infinite world.
*/
std::vector<PhantomAgent> getNeighbours(Vector2D position, float search_radius) override;
};
#endif //LIB_WORLD_INFINITE_H
/* Crowd Simulator Engine
** Copyright (C) 2018 - Inria Rennes - Rainbow - Julien Pettre
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the GNU General Public License
** as published by the Free Software Foundation; either version 2
** of the License, or (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**
**
**
** Authors: Axel Lopez Gandia, Javad Amirian, Florian Berton,
** Julien Legros, Lucas Pelerin, Beatriz Cabrero Daniel, Fabien Grzeskowiak
**
** Contact: crowd_group@inria.fr
*/
#ifndef LIB_WORLD_TORIC_H
#define LIB_WORLD_TORIC_H
#include <vector>
#include <memory>
#include "core/agent.h"
#include "core/obstacle.h"
#include "core/worldBase.h"
#include "tools/vector2D.h"
#include <nanoflann.hpp>
/**
* Contains the state of the world (agents and obstacles).
* Defines the scenario (Infinite, toroidal, etc).
* Updates agent position and manages collisions.
*/
class WorldToric : public WorldBase
{
float worldSize_;
public:
WorldToric();
std::vector<PhantomAgent> getNeighbours(Vector2D position, float search_radius) override;
void SetWorldSize(float size);
/*
* Toric world update, agents loop in the world of size [-worldSize, worldSize] for each axis.
*/
virtual void updateAllAgents();
};
#endif //LIB_WORLD_TORIC_H
......@@ -74,6 +74,7 @@ public:
void appendPedTrajectort(int pid, const std::vector<Vector2D>& traj);
void appendTrajectories(const std::vector<std::vector<Vector2D> >& trajs);
~CSVWriter();
};
#endif // _CSV_WRITER_H
This diff is collapsed.
......@@ -23,31 +23,21 @@
** Contact: crowd_group@inria.fr
*/
//========================================================================
/*!