Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
wolf
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
mobile_robotics
wolf_projects
wolf_lib
wolf
Merge requests
!350
Resolve "Factory documentation"
Code
Review changes
Check out branch
Download
Patches
Plain diff
Merged
Resolve "Factory documentation"
299-factory-documentation
into
devel
Overview
0
Commits
11
Pipelines
8
Changes
1
Merged
Joan Solà Ortega
requested to merge
299-factory-documentation
into
devel
5 years ago
Overview
0
Commits
11
Pipelines
8
Changes
1
Expand
Closes
#299 (closed)
Edited
5 years ago
by
Joan Solà Ortega
0
0
Merge request reports
Viewing commit
d50159ab
Prev
Next
Show latest version
1 file
+
42
−
103
Inline
Compare changes
Side-by-side
Inline
Show whitespace changes
Show one file at a time
d50159ab
Document FactoryProcessor
· d50159ab
Joan Solà Ortega
authored
5 years ago
include/core/processor/factory_processor.h
+
42
−
103
Options
@@ -27,143 +27,92 @@ namespace wolf
*
* Specific object creation is invoked by create(TYPE, params), and the TYPE of processor is identified with a string.
* For example, the following processor types are implemented,
* - "ODOM 3d" for ProcessorOdom3d
* - "ODOM 2d" for ProcessorOdom2d
* - "GPS" for ProcessorGPS
*
* The rule to make new TYPE strings unique is that you skip the prefix 'Processor' from your class name,
* and you build a string in CAPITALS with space separators.
* - ProcessorImageFeature -> ````"IMAGE"````
* - ProcessorLaser2d -> ````"LASER 2d"````
* - etc.
*
* The methods to create specific processors are called __creators__.
* Creators must be registered to the factory before they can be invoked for processor creation.
*
* This documentation shows you how to:
* - Access the Factory
* - Register and unregister creators
* - Create processors
* - Write a processor creator for ProcessorOdom2d (example).
*
* #### Accessing the Factory
* The FactoryProcessor class is a singleton: it can only exist once in your application.
* To obtain an instance of it, use the static method get(),
*
* \code
* FactoryProcessor::get()
* \endcode
* - "ProcessorOdom2d" for ProcessorOdom2d
* - "ProcessorOdom3d" for ProcessorOdom3d
* - "ProcessorDiffDrive" for ProcessorDiffDrive
*
* You can then call the methods you like, e.g. to create a processor, you type:
*
* \code
* FactoryProcessor::get().create(...); // see below for creating processors ...
* \endcode
*
* #### Registering processor creators
* Prior to invoking the creation of a processor of a particular type,
* you must register the creator for this type into the factory.
* among others.
*
* Registering processor creators into the factory is done through registerCreator().
* You provide a processor type string (above), and a pointer to a static method
* that knows how to create your specific processor, e.g.:
* Find general Factory documentation in class Factory:
* - Access the factory
* - Register/unregister creators
* - Invoke object creation
*
* \code
* FactoryProcessor::get().registerCreator("ProcessorOdom2d", ProcessorOdom2d::create);
* \endcode
*
* The method ProcessorOdom2d::create() exists in the ProcessorOdom2d class as a static method.
* All these ProcessorXxx::create() methods need to have exactly the same API, regardless of the processor type.
* This API includes a processor name, and a pointer to a base struct of parameters, ParamsProcessorBasePtr,
* that can be derived for each derived processor.
* This documentation shows you how to use the FactoryProcessor specifically:
* - Write a processor creator
* - Create processors
*
* Here is an example of ProcessorOdom2d::create() extracted from processor_odom_2d.h:
* #### Write processor creators
* Processor creators have the following API:
*
* \code
* static ProcessorBasePtr create(const std::string& _name, ParamsProcessorBasePtr _params)
* {
* // cast _params to good type
* ParamsProcessorOdom2d* params = (ParamsProcessorOdom2d*)_params;
*
* ProcessorBasePtr prc = new ProcessorOdom2d(params);
* prc->setName(_name); // pass the name to the created ProcessorOdom2d.
* return prc;
* }
* static ProcessorBasePtr create(const std::string& _name, ParamsProcessorBasePtr _params_processor);
* \endcode
*
* #### Achieving automatic registration
* Currently, registering is performed in each specific ProcessorXxxx source file, processor_xxxx.cpp.
* For example, in processor_odom_2d.cpp we find the line:
* They follow the general implementation shown below:
*
* \code
* const bool registered_odom_2d = FactoryProcessor::get().registerCreator("ProcessorOdom2d", ProcessorOdom2d::create);
* \endcode
* static ProcessorBasePtr create(const std::string& _unique_name, ParamsProcessorBasePtr _params_processor)
* {
* // cast processor parameters to good type --- example: ParamsProcessorOdom3d
* auto params_processor_ptr = std::static_pointer_cast<ParamsProcessorOdom3d>(_params_processor);
*
*
which is a static invocation (i.e., it is placed at global scope outside of the
ProcessorOdom
2d class).
*
Therefore, at application level, all processors that have a .cpp file compiled are automatically registered.
*
// Do create the Processor object --- example:
ProcessorOdom
3d
*
auto prc_ptr = std::make_shared<ProcessorOdom3d>(params_processor_ptr);
*
* #### Unregister processor creators
* The method unregisterCreator() unregisters the ProcessorXxx::create() method.
* It only needs to be passed the string of the processor type.
* // Complete the processor setup with a unique name identifying the processor
* prc_ptr->setName(_unique_name);
*
*
\code
*
FactoryProcessor::get().unregisterCreator("ProcessorOdom2d");
*
return prc_ptr;
*
}
* \endcode
*
* #### Creating processors
* Prior to invoking the creation of a processor of a particular type,
*
Note:
Prior to invoking the creation of a processor of a particular type,
* you must register the creator for this type into the factory.
*
* To create a ProcessorOdom2d, you type:
*
* \code
* FactoryProcessor::get().create("ProcessorOdom2d", "main odometry", params_ptr);
*
auto prc_odom2d_ptr =
FactoryProcessor::get().create("ProcessorOdom2d", "main odometry", params_ptr);
* \endcode
*
* #### Example 1 :
using the Factories alone
* #### Example 1 :
Create a sensor and its processor
* We provide the necessary steps to create a processor of class ProcessorOdom2d in our application,
* and bind it to a SensorOdom2d:
*
* \code
* #include "core/sensor/sensor_odom_2d.h" // provides SensorOdom2d and FactorySensor
* #include "core/sensor/sensor_odom_2d.h"
// provides SensorOdom2d and FactorySensor
* #include "core/processor/processor_odom_2d.h" // provides ProcessorOdom2d and FactoryProcessor
*
* // Note: SensorOdom2d::create() is already registered, automatically.
* // Note: ProcessorOdom2d::create() is already registered, automatically.
*
* // First create the sensor (See FactorySensor for details)
* SensorBasePtr sensor_ptr = FactorySensor::get().create ( "
Fact
orOdom2d" , "Main odometer" , extrinsics , &intrinsics );
* SensorBasePtr sensor_ptr = FactorySensor::get().create ( "
Sens
orOdom2d" , "Main odometer" , extrinsics , &intrinsics );
*
* // To create a odometry integrator, provide a type="
ODOM
2d", a name="main odometry", and a pointer to the parameters struct:
* // To create a odometry integrator, provide a type="
ProcessorOdom
2d", a name="main odometry", and a pointer to the parameters struct:
*
* ParamsProcessorOdom2d
params
({...}); // fill in the derived struct (note: ProcessorOdom2d actually has no input params)
*
auto params = make_shared<
ParamsProcessorOdom2d
>
({...}); // fill in the derived struct (note: ProcessorOdom2d actually has no input params)
*
* ProcessorBasePtr processor_ptr =
* FactoryProcessor::get().create ( "ProcessorOdom2d" , "main odometry" ,
&
params );
* FactoryProcessor::get().create ( "ProcessorOdom2d" , "main odometry" , params );
*
* // Bind processor to sensor
* sensor_ptr->addProcessor(processor_ptr);
* \endcode
*
* #### Example 2: Using the helper API in class Problem
* The WOLF uppermost node, Problem, makes the creation of sensors and processors, and the binding between them, even simpler.
*
* The creation is basically replicating the factories' API. The binding is accomplished by passing the sensor name to the Processor installer.
*
* The example 1 above can be accomplished as follows (we obviated for simplicity all the parameter creation),
*
* \code
* #include "core/sensor/sensor_odom_2d.h"
* #include "core/processor/processor_odom_2d.h"
* #include "core/problem/problem.h"
*
* Problem problem(FRM_PO_2d);
* problem.installSensor ( "SensorOdom2d" , "Main odometer" , extrinsics , &intrinsics );
* problem.installProcessor ( "ProcessorOdom2d" , "Odometry" , "Main odometer" , ¶ms );
* \endcode
*
* You can also check the code in the example file ````src/examples/test_wolf_factories.cpp````.
*/
typedef
Factory
<
ProcessorBase
,
const
std
::
string
&
,
const
ParamsProcessorBasePtr
>
FactoryProcessor
;
template
<
>
inline
std
::
string
FactoryProcessor
::
getClass
()
const
{
return
"FactoryProcessor"
;
}
// ParamsProcessor factory
struct
ParamsProcessorBase
;
@@ -175,16 +124,6 @@ inline std::string FactoryParamsProcessor::getClass() const
return
"FactoryParamsProcessor"
;
}
// Processor factory
typedef
Factory
<
ProcessorBase
,
const
std
::
string
&
,
const
ParamsProcessorBasePtr
>
FactoryProcessor
;
template
<
>
inline
std
::
string
FactoryProcessor
::
getClass
()
const
{
return
"FactoryProcessor"
;
}
#define WOLF_REGISTER_PROCESSOR(ProcessorType) \
namespace{ const bool WOLF_UNUSED ProcessorType##Registered = \
wolf::FactoryProcessor::get().registerCreator(#ProcessorType, ProcessorType::create); } \
Loading