diff --git a/include/core/sensor/factory_sensor.h b/include/core/sensor/factory_sensor.h index d16b46bb216871cd87b9ec74916d4560ab4569f8..210f30b882090f39335faa171f3de304453d7106 100644 --- a/include/core/sensor/factory_sensor.h +++ b/include/core/sensor/factory_sensor.h @@ -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); } \