Skip to content
Snippets Groups Projects
Commit a9456797 authored by Joan Solà Ortega's avatar Joan Solà Ortega
Browse files

Update factory_sensor.h

parent 05cf0814
No related branches found
No related tags found
1 merge request!350Resolve "Factory documentation"
Pipeline #5594 passed
This commit is part of merge request !350. Comments created here will be created in the context of that merge request.
...@@ -25,41 +25,61 @@ namespace wolf ...@@ -25,41 +25,61 @@ namespace wolf
* *
* This factory can create objects of classes deriving from SensorBase. * 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, * Currently, the following sensor types are implemented,
* - "SensorCamera" for SensorCamera
* - "SensorOdom2d" for SensorOdom2d * - "SensorOdom2d" for SensorOdom2d
* - "SensorOdom3d" for SensorOdom3d * - "SensorOdom3d" for SensorOdom3d
* - "SensorDiffDrive" for SensorDiffDrive * - "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.: * TYPE is always a std::string with literally the same text as the derived class name, e.g.:
* - SensorCamera -> ````"CAMERA"```` * - SensorCamera -> `"SensorCamera"`
* - SensorLaser2d -> ````"LASER 2d"```` * - SensorLaser2d -> `"SensorLaser2d"`
* - etc. * - etc.
* *
* The methods to create specific sensors are called __creators__. * The methods to create specific sensors are called __creators__.
* Creators must be registered to the factory before they can be invoked for sensor creation. * 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: * This documentation shows you how to:
* - Access the factory * - Write sensor creators.
* - Register and unregister creators * - Register and unregister creators
* - Create sensors * - Create sensors
* - Write a sensor creator for SensorCamera (example).
* *
* #### Accessing the factory * #### Write sensor creators
* 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. * Sensor creators have the following API:
* To obtain an instance of it, use the static method get(),
* *
* \code * \code
* FactorySensor::get() * static SensorBasePtr create(const std::string& _name, Eigen::VectorXd& _params_extrinsics, ParamsSensorBasePtr _params_sensor);
* \endcode * \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 * \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 * \endcode
* *
*
*
* #### Registering sensor creators * #### Registering sensor creators
* Prior to invoking the creation of a sensor of a particular type, * Prior to invoking the creation of a sensor of a particular type,
* you must register the creator for this type into the factory. * you must register the creator for this type into the factory.
...@@ -72,17 +92,7 @@ namespace wolf ...@@ -72,17 +92,7 @@ namespace wolf
* FactorySensor::get().registerCreator("SensorCamera", SensorCamera::create); * FactorySensor::get().registerCreator("SensorCamera", SensorCamera::create);
* \endcode * \endcode
* *
* The method SensorCamera::create() exists in the SensorCamera class as a static method. * The method SensorCamera::create(...) is the creator written in the previous section.
* 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.
* *
* #### Achieving automatic registration * #### Achieving automatic registration
* Currently, registering is performed in each specific SensorXxxx source file, sensor_xxxx.cpp. * Currently, registering is performed in each specific SensorXxxx source file, sensor_xxxx.cpp.
...@@ -109,7 +119,7 @@ namespace wolf ...@@ -109,7 +119,7 @@ namespace wolf
* To create e.g. a SensorCamera, you type: * To create e.g. a SensorCamera, you type:
* *
* \code * \code
* FactorySensor::get().create("SensorCamera", "Front-left camera", extrinsics, intrinsics_ptr); * FactorySensor::get().create("SensorCamera", "Front-left camera", params_extrinsics, params_camera);
* \endcode * \endcode
* *
* where ABSOLUTELY ALL input parameters are important. In particular, the sensor name "Front-left camera" will be used to identify this camera * 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 ...@@ -124,16 +134,16 @@ namespace wolf
* Here is an example of SensorCamera::create() extracted from sensor_camera.cpp: * Here is an example of SensorCamera::create() extracted from sensor_camera.cpp:
* *
* \code * \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 * // check extrinsics vector
* assert(_extrinsics_pq.size() == 7 && "Bad extrinsics vector length. Should be 7 for 3d."); * assert(_extrinsics_pq.size() == 7 && "Bad extrinsics vector length. Should be 7 for 3d.");
* *
* // cast instrinsics to good type * // 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 * // 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); * sen_ptr->setName(_unique_name);
* *
...@@ -156,7 +166,7 @@ namespace wolf ...@@ -156,7 +166,7 @@ namespace wolf
* or inside your main(), where a direct call is possible: * or inside your main(), where a direct call is possible:
* \code * \code
* main () { * main () {
* FactorySensor::get().registerCreator("CAMERA", SensorCamera::create); * FactorySensor::get().registerCreator("SensorCamera", SensorCamera::create);
* ... * ...
* } * }
* \endcode * \endcode
...@@ -165,7 +175,7 @@ namespace wolf ...@@ -165,7 +175,7 @@ namespace wolf
* Put the code at the last line of the sensor_xxx.cpp file, * Put the code at the last line of the sensor_xxx.cpp file,
* \code * \code
* namespace { * namespace {
* const bool registered_camera = FactorySensor::get().registerCreator("CAMERA", SensorCamera::create); * const bool registered_camera = FactorySensor::get().registerCreator("SensorCamera", SensorCamera::create);
* } * }
* \endcode * \endcode
* Automatic registration is recommended in wolf, and implemented in the classes shipped with it. * Automatic registration is recommended in wolf, and implemented in the classes shipped with it.
...@@ -190,36 +200,37 @@ namespace wolf ...@@ -190,36 +200,37 @@ namespace wolf
* // a pointer to the intrinsics struct: * // a pointer to the intrinsics struct:
* *
* Eigen::VectorXd extrinsics_1(7); // give it some values... * 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 = * 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! * // A second camera... with a different name!
* *
* Eigen::VectorXd extrinsics_2(7); * 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 = * 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; * return 0;
* } * }
* \endcode * \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, typedef Factory<SensorBase,
const std::string&, const std::string&,
const Eigen::VectorXd&, const Eigen::VectorXd&,
...@@ -231,6 +242,16 @@ inline std::string FactorySensor::getClass() const ...@@ -231,6 +242,16 @@ inline std::string FactorySensor::getClass() const
return "FactorySensor"; 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) \ #define WOLF_REGISTER_SENSOR(SensorType) \
namespace{ const bool WOLF_UNUSED SensorType##Registered = \ namespace{ const bool WOLF_UNUSED SensorType##Registered = \
FactorySensor::get().registerCreator(#SensorType, SensorType::create); } \ FactorySensor::get().registerCreator(#SensorType, SensorType::create); } \
......
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