Skip to content
Snippets Groups Projects

Resolve "Factory documentation"

Merged Joan Solà Ortega requested to merge 299-factory-documentation into devel
1 file
+ 66
45
Compare changes
  • Side-by-side
  • Inline
@@ -25,41 +25,61 @@ namespace wolf
*
* This factory can create objects of classes deriving from SensorBase.
*
* Specific object creation is invoked by ````create(TYPE, params ... )````, and the TYPE of sensor is identified with a string.
* Specific object creation is invoked by `create(TYPE, params ... )`, and the TYPE of sensor is identified with a string.
* Currently, the following sensor types are implemented,
* - "SensorCamera" for SensorCamera
* - "SensorOdom2d" for SensorOdom2d
* - "SensorOdom3d" for SensorOdom3d
* - "SensorDiffDrive" for SensorDiffDrive
* - "SensorCamera" for SensorCamera // in plugin 'vision'
* - "SensorLaser2d" for SensorLaser2d // in plugin 'laser'
*
* among others
*
* TYPE is always a std::string with literally the same text as the derived class name, e.g.:
* - SensorCamera -> ````"CAMERA"````
* - SensorLaser2d -> ````"LASER 2d"````
* - SensorCamera -> `"SensorCamera"`
* - SensorLaser2d -> `"SensorLaser2d"`
* - etc.
*
* The methods to create specific sensors are called __creators__.
* Creators must be registered to the factory before they can be invoked for sensor creation.
*
* Find general Factory documentation in class Factory.
*
* This documentation shows you how to:
* - Access the factory
* - Write sensor creators.
* - Register and unregister creators
* - Create sensors
* - Write a sensor creator for SensorCamera (example).
*
* #### Accessing the factory
* The FactorySensor class is a <a href="http://stackoverflow.com/questions/1008019/c-singleton-design-pattern#1008289">singleton</a>: it can only exist once in your application.
* To obtain an instance of it, use the static method get(),
* #### Write sensor creators
* Sensor creators have the following API:
*
* \code
* FactorySensor::get()
* static SensorBasePtr create(const std::string& _name, Eigen::VectorXd& _params_extrinsics, ParamsSensorBasePtr _params_sensor);
* \endcode
*
* You can then call the methods you like, e.g. to create a sensor, you type:
* The follow the general implementation shown below:
*
* \code
* FactorySensor::get().create(...); // see below for creating sensors ...
* static SensorBasePtr create(const std::string& _unique_name, Eigen::VectorXd& _params_extrinsics, ParamsSensorBasePtr _params_sensor)
* {
* // check extrinsics vector --- example: 3D pose
* assert(_params_extrinsics.size() == 7 && "Bad extrinsics vector length. Should be 7 for 3d.");
*
* // cast sensor parameters to good type --- example: ParamsSensorCamera
* auto intrinsics_ptr = std::static_pointer_cast<ParamsSensorCamera>(_params_sensor);
*
* // Do create the Sensor object --- example: SensorCamera
* auto sen_ptr = std::make_shared<SensorCamera>(_extrinsics_pq, intrinsics_ptr);
*
* // Complete the sensor setup with a unique name identifying the sensor
* sen_ptr->setName(_unique_name);
*
* return sen_ptr;
* }
* \endcode
*
*
*
* #### Registering sensor creators
* Prior to invoking the creation of a sensor of a particular type,
* you must register the creator for this type into the factory.
@@ -72,17 +92,7 @@ namespace wolf
* FactorySensor::get().registerCreator("SensorCamera", SensorCamera::create);
* \endcode
*
* The method SensorCamera::create() exists in the SensorCamera class as a static method.
* All these ````SensorXxx::create()```` methods need to have exactly the same API, regardless of the sensor type.
* This API includes a sensor name, a vector of extrinsic parameters,
* and a pointer to a base struct of intrinsic parameters, ParamsSensorBasePtr,
* that can be derived for each derived sensor:
*
* \code
* static SensorBasePtr create(const std::string& _name, Eigen::VectorXd& _extrinsics_pq, ParamsSensorBasePtr _intrinsics)
* \endcode
*
* See further down for an implementation example.
* The method SensorCamera::create(...) is the creator written in the previous section.
*
* #### Achieving automatic registration
* Currently, registering is performed in each specific SensorXxxx source file, sensor_xxxx.cpp.
@@ -109,7 +119,7 @@ namespace wolf
* To create e.g. a SensorCamera, you type:
*
* \code
* FactorySensor::get().create("SensorCamera", "Front-left camera", extrinsics, intrinsics_ptr);
* FactorySensor::get().create("SensorCamera", "Front-left camera", params_extrinsics, params_camera);
* \endcode
*
* where ABSOLUTELY ALL input parameters are important. In particular, the sensor name "Front-left camera" will be used to identify this camera
@@ -124,16 +134,16 @@ namespace wolf
* Here is an example of SensorCamera::create() extracted from sensor_camera.cpp:
*
* \code
* static SensorBasePtr create(const std::string& _name, Eigen::VectorXd& _extrinsics_pq, ParamsSensorBasePtr _intrinsics)
* static SensorBasePtr create(const std::string& _unique_name, Eigen::VectorXd& _extrinsics_pq, ParamsSensorBasePtr _intrinsics)
* {
* // check extrinsics vector
* assert(_extrinsics_pq.size() == 7 && "Bad extrinsics vector length. Should be 7 for 3d.");
*
* // cast instrinsics to good type
* ParamsSensorCameraPtr intrinsics_ptr = std::static_pointer_cast<ParamsSensorCamera>(_intrinsics);
* auto intrinsics_ptr = std::static_pointer_cast<ParamsSensorCamera>(_intrinsics);
*
* // Do create the SensorCamera object, and complete its setup
* SensorCameraPtr sen_ptr = std::make_shared<SensorCamera>(_extrinsics_pq, intrinsics_ptr);
* auto sen_ptr = std::make_shared<SensorCamera>(_extrinsics_pq, intrinsics_ptr);
*
* sen_ptr->setName(_unique_name);
*
@@ -156,7 +166,7 @@ namespace wolf
* or inside your main(), where a direct call is possible:
* \code
* main () {
* FactorySensor::get().registerCreator("CAMERA", SensorCamera::create);
* FactorySensor::get().registerCreator("SensorCamera", SensorCamera::create);
* ...
* }
* \endcode
@@ -165,7 +175,7 @@ namespace wolf
* Put the code at the last line of the sensor_xxx.cpp file,
* \code
* namespace {
* const bool registered_camera = FactorySensor::get().registerCreator("CAMERA", SensorCamera::create);
* const bool registered_camera = FactorySensor::get().registerCreator("SensorCamera", SensorCamera::create);
* }
* \endcode
* Automatic registration is recommended in wolf, and implemented in the classes shipped with it.
@@ -190,36 +200,37 @@ namespace wolf
* // a pointer to the intrinsics struct:
*
* Eigen::VectorXd extrinsics_1(7); // give it some values...
* ParamsSensorCameraPtr intrinsics_1 = FactoryParamsSensor::get().create("ParamsSensorCamera", camera_1.yaml); // see FactoryParamsSensor to fill in the derived struct
*
* // Create a pointer to the struct of sensor parameters stored in a YAML file ( see FactoryParamsSensor )
* ParamsSensorCameraPtr intrinsics_1 =
* FactoryParamsSensor::get().create("ParamsSensorCamera",
* camera_1.yaml);
*
* SensorBasePtr camera_1_ptr =
* FactorySensor::get().create ( "SensorCamera" , "Front-left camera" , extrinsics_1 , intrinsics_1 );
* FactorySensor::get().create ( "SensorCamera" ,
* "Front-left camera" ,
* extrinsics_1 ,
* intrinsics_1 );
*
* // A second camera... with a different name!
*
* Eigen::VectorXd extrinsics_2(7);
* ParamsSensorCameraPtr intrinsics_2 = FactoryParamsSensor::get().create("ParamsSensorCamera", camera_2.yaml);
*
* ParamsSensorCameraPtr intrinsics_2 =
* FactoryParamsSensor::get().create("ParamsSensorCamera",
* camera_2.yaml);
*
* SensorBasePtr camera_2_ptr =
* FactorySensor::get().create( "SensorCamera" , "Front-right camera" , extrinsics_2 , intrinsics_2 );
* FactorySensor::get().create( "SensorCamera" ,
* "Front-right camera" ,
* extrinsics_2 ,
* intrinsics_2 );
*
* return 0;
* }
* \endcode
*
*/
// ParamsSensor factory
struct ParamsSensorBase;
typedef Factory<ParamsSensorBase,
const std::string&> FactoryParamsSensor;
template<>
inline std::string FactoryParamsSensor::getClass() const
{
return "FactoryParamsSensor";
}
// Sensor factory
typedef Factory<SensorBase,
const std::string&,
const Eigen::VectorXd&,
@@ -231,6 +242,16 @@ inline std::string FactorySensor::getClass() const
return "FactorySensor";
}
// ParamsSensor factory
struct ParamsSensorBase;
typedef Factory<ParamsSensorBase,
const std::string&> FactoryParamsSensor;
template<>
inline std::string FactoryParamsSensor::getClass() const
{
return "FactoryParamsSensor";
}
#define WOLF_REGISTER_SENSOR(SensorType) \
namespace{ const bool WOLF_UNUSED SensorType##Registered = \
FactorySensor::get().registerCreator(#SensorType, SensorType::create); } \
Loading