diff --git a/include/core/solver/factory_solver.h b/include/core/solver/factory_solver.h index e3cc58a4a0b6d269026312f9c946a490d1045923..fc2031cdb245ee6364aa9de3bb38e834812e22a7 100644 --- a/include/core/solver/factory_solver.h +++ b/include/core/solver/factory_solver.h @@ -21,192 +21,8 @@ struct ParamsSensorBase; namespace wolf { -/** \brief Sensor factory class +/** \brief Solver factory class * - * 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. - * Currently, the following sensor types are implemented, - * - "CAMERA" for SensorCamera - * - "ODOM 2d" for SensorOdom2d - * - "GPS FIX" for SensorGPSFix - * - * The rule to make new TYPE strings unique is that you skip the prefix 'Sensor' from your class name, - * and you build a string in CAPITALS with space separators, e.g.: - * - SensorCamera -> ````"CAMERA"```` - * - SensorLaser2d -> ````"LASER 2d"```` - * - 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. - * - * This documentation shows you how to: - * - Access the factory - * - 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(), - * - * \code - * FactorySensor::get() - * \endcode - * - * You can then call the methods you like, e.g. to create a sensor, you type: - * - * \code - * FactorySensor::get().create(...); // see below for creating sensors ... - * \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. - * - * Registering sensor creators into the factory is done through registerCreator(). - * You provide a sensor type string (above), and a pointer to a static method - * that knows how to create your specific sensor, e.g.: - * - * \code - * FactorySensor::get().registerCreator("CAMERA", 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. - * - * #### Achieving automatic registration - * Currently, registering is performed in each specific SensorXxxx source file, sensor_xxxx.cpp. - * For example, in sensor_camera.cpp we find the line: - * - * \code - * const bool registered_camera = FactorySensor::get().registerCreator("CAMERA", SensorCamera::create); - * \endcode - * - * which is a static invocation (i.e., it is placed at global scope outside of the SensorCamera class). - * Therefore, at application level, all sensors that have a .cpp file compiled are automatically registered. - * - * #### Unregistering sensor creators - * The method unregisterCreator() unregisters the SensorXxx::create() method. It only needs to be passed the string of the sensor type. - * - * \code - * FactorySensor::get().unregisterCreator("CAMERA"); - * \endcode - * - * #### Creating sensors - * Note: Prior to invoking the creation of a sensor of a particular type, - * you must register the creator for this type into the factory. - * - * To create e.g. a SensorCamera, you type: - * - * \code - * FactorySensor::get().create("CAMERA", "Front-left camera", extrinsics, intrinsics_ptr); - * \endcode - * - * where ABSOLUTELY ALL input parameters are important. In particular, the sensor name "Front-left camera" will be used to identify this camera - * and to assign it the appropriate processors. DO NOT USE IT WITH DUMMY PARAMETERS! - * - * #### See also - * - FactoryParamsSensor: to create intrinsic structs deriving from ParamsSensorBase directly from YAML files. - * - FactoryProcessor: to create processors that will be bound to sensors. - * - Problem::installSensor() : to install sensors in WOLF Problem. - * - * #### Example 1: writing a specific sensor creator - * 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) - * { - * // check extrinsics vector - * assert(_extrinsics_pq.size() == 7 && "Bad extrinsics vector length. Should be 7 for 3d."); - * - * // cast instrinsics to good type - * ParamsSensorCamera* intrinsics_ptr = (ParamsSensorCamera*) _intrinsics; - * - * // Do create the SensorCamera object, and complete its setup - * SensorCamera* sen_ptr = new SensorCamera(_extrinsics_pq, intrinsics_ptr); - * sen_ptr->setName(_unique_name); - * - * return sen_ptr; - * } - * \endcode - * - * #### Example 2: registering a sensor 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_camera = FactorySensor::get().registerCreator("CAMERA", SensorCamera::create); - * } - * main () { ... } - * \endcode - * or inside your main(), where a direct call is possible: - * \code - * main () { - * FactorySensor::get().registerCreator("CAMERA", SensorCamera::create); - * ... - * } - * \endcode - * - * - __Automatic registration__: registration is performed at library level. - * 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); - * } - * \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 sensors - * We finally provide the necessary steps to create a sensor of class SensorCamera in our application: - * - * \code - * #include "factory_sensor.h" - * #include "sensor_camera.h" // provides SensorCamera - * - * // Note: SensorCamera::create() is already registered, automatically. - * - * using namespace wolf; - * int main() { - * - * // To create a camera, provide: - * // a type = "CAMERA", - * // a name = "Front-left camera", - * // an extrinsics vector, and - * // a pointer to the intrinsics struct: - * - * Eigen::VectorXd extrinsics_1(7); // give it some values... - * ParamsSensorCamera intrinsics_1({...}); // see FactoryParamsSensor to fill in the derived struct - * - * SensorBasePtr camera_1_ptr = - * FactorySensor::get().create ( "CAMERA" , "Front-left camera" , extrinsics_1 , &intrinsics_1 ); - * - * // A second camera... with a different name! - * - * Eigen::VectorXd extrinsics_2(7); - * ParamsSensorCamera intrinsics_2({...}); - * - * SensorBasePtr camera_2_ptr = - * FactorySensor::get().create( "CAMERA" , "Front-right camera" , extrinsics_2 , &intrinsics_2 ); - * - * return 0; - * } - * \endcode - * - * You can also check the code in the example file ````src/examples/test_wolf_factories.cpp````. */ typedef Factory<SolverManager,