File: DOCS.md

package info (click to toggle)
gtsam 4.2.0%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 46,108 kB
  • sloc: cpp: 127,191; python: 14,312; xml: 8,442; makefile: 252; sh: 119; ansic: 101
file content (232 lines) | stat: -rw-r--r-- 10,560 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
## Wrap Module Definition

### Important

The python wrapper supports keyword arguments for functions/methods. Hence, the argument names matter. An implementation restriction is that in overloaded methods or functions, arguments of different types *have* to have different names.

### Requirements

- Classes must start with an uppercase letter.
    - The wrapper can wrap a typedef, e.g. `typedef TemplatedClass<Arg> EasyName;`.

- Only one Method/Constructor per line, though methods/constructors can extend across multiple lines.

- Methods can return
    - Eigen types: `Matrix`, `Vector`.
    - C/C++ basic types: `string`, `bool`, `size_t`, `int`, `double`, `char`, `unsigned char`.
    - `void`
    - Any class with which be copied with `boost::make_shared()`.
    - `boost::shared_ptr` of any object type.

- Constructors
    - Overloads are supported, but arguments of different types *have* to have different names.
    - A class with no constructors can be returned from other functions but not allocated directly in MATLAB.

- Methods
    - Constness has no effect.
    - Specify by-value (not reference) return types, even if C++ method returns reference.
    - Must start with a letter (upper or lowercase).
    - Overloads are supported.

- Static methods
    - Must start with a letter (upper or lowercase) and use the "static" keyword, e.g. `static void func()`.
    - The first letter will be made uppercase in the generated MATLAB interface.
    - Overloads are supported, but arguments of different types *have* to have different names.

- Arguments to functions can be any of
    - Eigen types: `Matrix`, `Vector`.
    - Eigen types and classes as an optionally const reference.
    - C/C++ basic types: `string`, `bool`, `size_t`, `size_t`, `double`, `char`, `unsigned char`.
    - Any class with which be copied with `boost::make_shared()` (except Eigen).
    - `boost::shared_ptr` of any object type (except Eigen).

- Properties or Variables
    - You can specify class variables in the interface file as long as they are in the `public` scope, e.g.

    ```cpp
    class Sample {
        double seed;
    };
    ```

    - Class variables are read-write so they can be updated directly in Python.
    - For the Matlab wrapper, specifying the full property type (including namespaces) is required.

    ```cpp
    class TriangulationResult {
      gtsam::SharedNoiseModel noiseModel;
    };
    ```

    - If the property is part of an enum within the class, the type should be specified as `gtsam::Class::Enum`. Similarly for templated types where `This` is used, e.g. `gtsam::This::Enum`.

    ```cpp
    class TriangulationResult {
      enum Status { VALID, DEGENERATE, BEHIND_CAMERA, OUTLIER, FAR_POINT };
      gtsam::TriangulationResult::Status status;
    };

    template<PARAMS>
    virtual class GncParams {
      enum Verbosity {
        SILENT,
        SUMMARY,
        VALUES
      };
      gtsam::This::Verbosity verbosity;
    };
    ```

- Operator Overloading (Python only)
    - You can overload operators just like in C++.

    ```cpp
    class Overload {
        Overload operator*(const Overload& other) const;
    };
    ```
    - Supported operators are the intersection of those supported in C++ and in Python.
    - Operator overloading definitions have to be marked as `const` methods.

- Pointer types
    - To declare a simple/raw pointer, simply add an `@` to the class name, e.g.`Pose3@`.
    - To declare a shared pointer (e.g. `gtsam::noiseModel::Base::shared_ptr`), use an asterisk (i.e. `*`). E.g. `gtsam::noiseModel::Base*` to define the wrapping for the `Base` noise model shared pointer.

- Comments can use either C++ or C style, with multiple lines.

- Namespace definitions
    - Names of namespaces must start with a lowercase letter.
    - Start a namespace with `namespace example_ns {`, where `example_ns` is the namespace name.
    - End a namespace with exactly `}`
    - Namespaces can be nested.

- Namespace usage
     - Namespaces can be specified for classes in arguments and return values.
     - In each case, the namespace must be fully specified, e.g., `namespace1::namespace2::ClassName`.

- Includes in C++ wrappers
    - All includes will be collected and added in a single file.
    - All namespaces must have angle brackets, e.g. `#include <path>`.
    - No default includes will be added.

- Global/Namespace functions
    - Functions specified outside of a class are **global**.
    - Can be overloaded with different arguments.
    - Can have multiple functions of the same name in different namespaces.
    - Functions can be templated and have multiple template arguments, e.g.
        ```cpp
        template<T, R, S>
        ```
- Global variables
    - Similar to global functions, the wrapper supports global variables as well.
    - Currently we only support primitive types, such as `double`, `int`, `string`, etc.
    - E.g.
        ```cpp
        const double kGravity = -9.81;
        ```

- Using classes defined in other modules
    - If you are using a class `OtherClass` not wrapped in an interface file, add `class OtherClass;` as a forward declaration to avoid a dependency error.
    - `OtherClass` may not be in the same project. If this is the case, include the header for the appropriate project `#include <other_project/OtherClass.h>`.

- Virtual inheritance
    - Specify fully-qualified base classes, i.e. `virtual class Derived : ns::Base {` where `ns` is the namespace.
    - Mark with `virtual` keyword, e.g. `virtual class Base {`, and also `virtual class Derived : ns::Base {`.
    - Base classes can be templated, e.g. `virtual class Dog: ns::Animal<Pet> {};`. This is useful when you want to inherit from specialized classes.
    - Forward declarations must also be marked virtual, e.g. `virtual class ns::Base;` and
      also `virtual class ns::Derived;`.
    - Pure virtual (abstract) classes should list no constructors in the interface file.
    - Virtual classes must have a `clone()` function in C++ (though it does not have to be included
      in the interface file). `clone()` will be called whenever an object copy is needed, instead
      of using the copy constructor (which is used for non-virtual objects).
    - Signature of clone function - `clone()` will be called virtually, so must appear at least at the top of the inheritance tree

        ```cpp
        virtual boost::shared_ptr<CLASS_NAME> clone() const;
        ```

- Templates
    - Basic templates are supported either with an explicit list of types to instantiate,
      e.g.

      ```cpp
      template<T = {gtsam::Pose2, gtsam::Rot2, gtsam::Point3}> class Class1 { ... };
      ```

      or with typedefs, e.g.

      ```cpp
      template<T, U> class Class2 { ... };
      typedef Class2<Type1, Type2> MyInstantiatedClass;
      ```
    - Templates can also be defined for constructors, methods, properties and static methods.
    - In the class definition, appearances of the template argument(s) will be replaced with their
      instantiated types, e.g. `void setValue(const T& value);`.
    - Values scoped within templates are supported. E.g. one can use the form `T::Value` where T is a template, as an argument to a method.
    - To refer to the instantiation of the template class itself, use `This`, i.e. `static This Create();`.
    - To create new instantiations in other modules, you must copy-and-paste the whole class definition
      into the new module, but use only your new instantiation types.
    - When forward-declaring template instantiations, use the generated/typedef'd name, e.g.

      ```cpp
      class gtsam::Class1Pose2;
      class gtsam::MyInstantiatedClass;
      ```
    - Template arguments can be templates themselves, e.g.

      ```cpp
      // Typedef'd PinholeCamera
      template<CALIBRATION>
      class PinholeCamera { ... };
      typedef gtsam::PinholeCamera<gtsam::Cal3_S2> PinholeCameraCal3_S2;

      template<CAMERA>
      class SfmFactor { ... };
      // This is valid.
      typedef gtsam::SfmFactor<gtsam::PinholeCamera<gtsam::Cal3_S2>> BasicSfmFactor;
      ```

- `Boost.serialization` within the wrapper:
    - You need to mark classes as being serializable in the markup file (see `gtsam.i` for examples).
    - There are two options currently, depending on the class.  To "mark" a class as serializable,
      add a function with a particular signature so that `wrap` will catch it.
       - Add `void serialize()` to a class to create serialization functions for a class.
         Adding this flag subsumes the `serializable()` flag below.
         
         Requirements:
            - A default constructor must be publicly accessible.
            - Must not be an abstract base class.
            - The class must have an actual boost.serialization `serialize()` function.

       - Add `void serializable()` to a class if you only want the class to be serialized as a
         part of a container (such as `noiseModel`). This version does not require a publicly
         accessible default constructor.

- Forward declarations and class definitions for **Pybind**:
    - Need to specify the base class (both this forward class and base class are declared in an external Pybind header)
    - This is so that Pybind can generate proper inheritance.

    - Example for when wrapping a gtsam-based project:

        ```cpp
         // forward declarations
         virtual class gtsam::NonlinearFactor
         virtual class gtsam::NoiseModelFactor : gtsam::NonlinearFactor
         // class definition
         #include <MyFactor.h>
         virtual class MyFactor : gtsam::NoiseModelFactor {...};
         ```

   - **DO NOT** re-define an overriden function already declared in the external (forward-declared) base class. This will cause an ambiguity problem in the Pybind header file.

- Splitting wrapper over multiple files
    - The Pybind11 wrapper supports splitting the wrapping code over multiple files.
    - To be able to use classes from another module, simply import the C++ header file in that wrapper file.
    - Unfortunately, this means that aliases can no longer be used.
    - Similarly, there can be multiple `preamble.h` and `specializations.h` files. Each of these should match the module file name.

### TODO
- Handle `gtsam::Rot3M` conversions to quaternions.
- Parse return of const ref arguments.
- Parse `std::string` variants and convert directly to special string.
- Add generalized serialization support via `boost.serialization` with hooks to MATLAB save/load.