Skip to content
Snippets Groups Projects
Commit 0cdf0e52 authored by Joan Vallvé Navarro's avatar Joan Vallvé Navarro
Browse files

wip

parent d5426d0e
No related branches found
No related tags found
1 merge request!418Resolve "Map factory"
Pipeline #6655 failed
This commit is part of merge request !418. Comments created here will be created in the context of that merge request.
......@@ -254,6 +254,9 @@ WOLF_LIST_TYPEDEFS(FactorBase);
// Map
WOLF_PTR_TYPEDEFS(MapBase);
// - - Map params
WOLF_STRUCT_PTR_TYPEDEFS(ParamsMapBase);
// - Landmark
WOLF_PTR_TYPEDEFS(LandmarkBase);
WOLF_LIST_TYPEDEFS(LandmarkBase);
......
/**
* \file factory_map.h
*
* Created on: Jul 25, 2016
* \author: jvallve
*/
#ifndef FACTORY_MAP_H_
#define FACTORY_MAP_H_
namespace wolf
{
class MapBase;
struct ParamsMapBase;
}
// wolf
#include "core/common/factory.h"
#include "core/utils/params_server.h"
namespace wolf
{
/** \brief Map factory class
*
* This factory can create objects of classes deriving from MapBase.
*
* Specific object creation is invoked by `create(TYPE, params ... )`, and the TYPE of map is identified with a string.
* Currently, the following map types are implemented,
* - "MapGrid2dGravity" in plugin 'imu'
*
* among others.
*
* Find general Factory documentation in class Factory:
* - Access the factory
* - Register/unregister creators
* - Invoke object creation
*
* This documentation shows you how to use the FactoryMap specifically:
* - Write map creators.
* - Create maps
*
* #### Write map creators
* Map creators have the following API:
*
* \code
* static MapBasePtr create(ParamsMapBasePtr _params_map);
* \endcode
*
* They follow the general implementation shown below:
*
* \code
* static MapBasePtr create(ParamsMapBasePtr _params_map)
* {
* // cast map parameters to good type --- example: ParamsMapGrid
* auto params_ptr = std::static_pointer_cast<ParamsMapGrid>(_params_map);
*
* // Do create the Map object --- example: MapGrid
* return map_ptr = std::make_shared<MapGrid>(params_ptr);
* }
* \endcode
*
* #### Creating maps
* Note: Prior to invoking the creation of a map of a particular type,
* you must register the creator for this type into the factory.
*
* To create e.g. a MapGrid, you type:
*
* \code
* auto grid_ptr = FactoryMap::create("MapGrid", params_grid);
* \endcode
*
* #### See also
* - FactoryParamsMap: to create parameter structs deriving from ParamsMapBase directly from YAML files.
*
* #### Example 1: writing a MapGrid creator
* Here is an example of MapGrid::create() extracted from map_grid.cpp:
*
* \code
* static MapBasePtr create(const std::string& _unique_name, Eigen::VectorXd& _extrinsics_pq, ParamsMapBasePtr _intrinsics)
* {
* // check extrinsics vector
* assert(_extrinsics_pq.size() == 7 && "Bad extrinsics vector length. Should be 7 for 3d.");
*
* // cast instrinsics to good type
* auto intrinsics_ptr = std::static_pointer_cast<ParamsMapGrid>(_intrinsics);
*
* // Do create the MapGrid object, and complete its setup
* auto sen_ptr = std::make_shared<MapGrid>(_extrinsics_pq, intrinsics_ptr);
*
* sen_ptr->setName(_unique_name);
*
* return sen_ptr;
* }
* \endcode
*
* #### Example 2: registering a map creator into the factory
* Registration can be done manually or automatically. It involves the call to static functions.
* It is advisable to put these calls within unnamed namespaces.
*
* - __Manual registration__: you control registration at application level.
* Put the code either at global scope (you must define a dummy variable for this),
* \code
* namespace {
* const bool registered_grid = FactoryMap::registerCreator("MapGrid", MapGrid::create);
* }
* main () { ... }
* \endcode
* or inside your main(), where a direct call is possible:
* \code
* main () {
* FactoryMap::registerCreator("MapGrid", MapGrid::create);
* ...
* }
* \endcode
*
* - __Automatic registration__: registration is performed at library level.
* Put the code at the last line of the map_xxx.cpp file,
* \code
* namespace {
* const bool registered_grid = FactoryMap::registerCreator("MapGrid", MapGrid::create);
* }
* \endcode
* Automatic registration is recommended in wolf, and implemented in the classes shipped with it.
* You are free to comment out these lines and place them wherever you consider it more convenient for your design.
*
* #### Example 2: creating maps
* We finally provide the necessary steps to create a map of class MapGrid in our application:
*
* \code
* #include "core/map/factory_map.h"
* #include "core/map/map_grid.h" // provides MapGrid
*
* // Note: MapGrid::create() is already registered, automatically.
*
* using namespace wolf;
* int main() {
*
* // To create a grid, provide:
* // a type = "MapGrid" and
* // a pointer to the intrinsics struct:
*
* // Create a pointer to the struct of map parameters stored in a YAML file ( see FactoryParamsMap )
* ParamsMapGridPtr params_1 =
* FactoryParamsMap::create("ParamsMapGrid",
* grid_1.yaml);
*
* MapBasePtr grid_1_ptr =
* FactoryMap::create ( "MapGrid" ,
* params_1 );
*
* return 0;
* }
* \endcode
*
*/
typedef Factory<MapBase,
const std::string&,
const Eigen::VectorXd&,
const ParamsMapBasePtr> FactoryMap;
template<>
inline std::string FactoryMap::getClass() const
{
return "FactoryMap";
}
// ParamsMap factory
struct ParamsMapBase;
typedef Factory<ParamsMapBase,
const std::string&> FactoryParamsMap;
template<>
inline std::string FactoryParamsMap::getClass() const
{
return "FactoryParamsMap";
}
#define WOLF_REGISTER_MAP(MapType) \
namespace{ const bool WOLF_UNUSED MapType##Registered = \
FactoryMap::registerCreator(#MapType, MapType::create); } \
typedef Factory<MapBase,
const std::string&,
const ParamsServer&> AutoConfFactoryMap;
template<>
inline std::string AutoConfFactoryMap::getClass() const
{
return "AutoConfFactoryMap";
}
#define WOLF_REGISTER_MAP_AUTO(MapType) \
namespace{ const bool WOLF_UNUSED MapType##AutoConfRegistered = \
AutoConfFactoryMap::registerCreator(#MapType, MapType::create); } \
} /* namespace wolf */
#endif /* SENSOR_FACTORY_H_ */
......@@ -11,11 +11,58 @@ class LandmarkBase;
//Wolf includes
#include "core/common/wolf.h"
#include "core/common/node_base.h"
#include "core/common/params_base.h"
//std includes
namespace wolf {
/*
* Macro for defining Autoconf map creator.
*
* Place a call to this macro inside your class declaration (in the map_class.h file),
* preferably just after the constructors.
*
* In order to use this macro, the derived map class, MapClass,
* must have a constructor available with the API:
*
* MapClass(const ParamsMapClassPtr _params);
*
* We recommend writing one of such constructors in your derived maps.
*/
#define WOLF_MAP_CREATE(MapClass, ParamsMapClass) \
static \
MapBasePtr create(const ParamsServer& _server) \
{ \
auto params = std::make_shared<ParamsMapClass>("map", _server); \
\
return std::make_shared<MapClass>(params); \
} \
\
static \
MapBasePtr create(const ParamsMapBasePtr _params) \
{ \
auto params = std::static_pointer_cast<ParamsMapClass>(_params); \
\
return std::make_shared<MapClass>(params); \
} \
/** \brief base struct for map parameters
*
* Derive from this struct to create structs of map parameters.
*/
struct ParamsMapBase: public ParamsBase
{
std::string prefix = "map/";
~ParamsMapBase() override = default;
using ParamsBase::ParamsBase;
std::string print() const override
{
return "";
}
};
//class MapBase
class MapBase : public NodeBase, public std::enable_shared_from_this<MapBase>
{
......@@ -25,7 +72,9 @@ class MapBase : public NodeBase, public std::enable_shared_from_this<MapBase>
LandmarkBasePtrList landmark_list_;
public:
MapBase();
MapBase(ParamsMapBasePtr _params, const std::string& _type = "Base");
WOLF_MAP_CREATE(MapBase, ParamsMapBase);
~MapBase() override;
protected:
......
// wolf
#include "core/map/map_base.h"
#include "core/landmark/landmark_base.h"
#include "core/common/factory.h"
//#include "core/common/factory.h"
// YAML
#include <yaml-cpp/yaml.h>
......@@ -16,8 +15,8 @@
namespace wolf {
MapBase::MapBase() :
NodeBase("MAP", "Base")
MapBase::MapBase(ParamsMapBasePtr _params, const std::string& _type) :
NodeBase("MAP", _type)
{
// std::cout << "constructed M"<< std::endl;
}
......@@ -127,3 +126,12 @@ bool MapBase::check(CheckLog& _log, std::shared_ptr<NodeBase> _node_ptr, bool _v
return _log.is_consistent_;
}
} // namespace wolf
// Register in the FactorySensor
#include "core/map/factory_map.h"
namespace wolf {
WOLF_REGISTER_MAP(MapBase);
WOLF_REGISTER_MAP_AUTO(MapBase);
} // namespace wolf
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment