View Javadoc
1   /*
2    * Copyright (C) 2017 Alberto Irurueta Carro (alberto@irurueta.com)
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *         http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package com.irurueta.ar.sfm;
18  
19  import com.irurueta.algebra.AlgebraException;
20  import com.irurueta.algebra.Matrix;
21  import com.irurueta.ar.slam.BaseCalibrationData;
22  import com.irurueta.geometry.Point3D;
23  
24  import java.io.Serializable;
25  
26  /**
27   * Contains base configuration for a multiple view sparse re-constructor using SLAM (Simultaneous
28   * Location And Mapping) to determine the scale of the scene (i.e. the baseline or separation
29   * between cameras) by fusing both camera data and data from sensors like an accelerometer or
30   * gyroscope.
31   *
32   * @param <C> type defining calibration data.
33   * @param <T> an actual implementation of a configuration class.
34   */
35  public class BaseSlamSparseReconstructorConfiguration<C extends BaseCalibrationData,
36          T extends BaseSlamSparseReconstructorConfiguration<C, T>> extends BaseSparseReconstructorConfiguration<T>
37          implements Serializable {
38  
39      /**
40       * Indicates that by default new available SLAM state is notified each time that a whole set of IMU
41       * (Inertial Measurement Unit) data is received (accelerometer, gyroscope and orientation). SLAM state
42       * contains position, velocity, linear acceleration, orientation and angular speed.
43       */
44      public static final boolean DEFAULT_NOTIFY_SLAM_DATA_AVAILABLE = true;
45  
46      /**
47       * Indicates that by default any new camera that can be estimated by means of SLAM using IMU data, will
48       * be notified each time that accelerometer, gyroscope and orientation data is received.
49       */
50      public static final boolean DEFAULT_NOTIFY_ESTIMATED_SLAM_CAMERA = true;
51  
52      /**
53       * Default variance for coordinates of estimated camera positions.
54       */
55      private static final double DEFAULT_CAMERA_POSITION_VARIANCE = 1e-6;
56  
57      /**
58       * Calibration data for accelerometer and gyroscope.
59       * This data is usually captured and estimated in an offline step previous
60       * to the actual scene reconstruction.
61       * Calibration data is usually obtained by keeping the system in a constant
62       * state of motion (e.g. acceleration and rotation).
63       * If this is null, no calibration data will be used.
64       */
65      private C calibrationData;
66  
67      /**
68       * Matrix containing covariance of measured camera positions.
69       * This should usually be an "almost" diagonal matrix, where diagonal elements
70       * are close to the position estimation error variance.
71       * Values of this matrix are device specific and depends on factors such as
72       * resolution of images, pictures quality, gyroscope and accelerometer accuracy.
73       * This matrix must be a 3x3 symmetric positive definite matrix.
74       */
75      private Matrix cameraPositionCovariance;
76  
77      /**
78       * Indicates whether new available SLAM state is notified each time that a whole set of IMU (Inertial
79       * Measurement Unit) data is received.
80       */
81      private boolean notifyAvailableSlamData = DEFAULT_NOTIFY_SLAM_DATA_AVAILABLE;
82  
83      /**
84       * Indicates whether any new camera that can be estimated by means of SLAM using IMU data, will be
85       * notified each time that accelerometer, gyroscope and orientation data is received.
86       */
87      private boolean notifyEstimatedSlamCamera = DEFAULT_NOTIFY_ESTIMATED_SLAM_CAMERA;
88  
89      /**
90       * Constructor.
91       */
92      public BaseSlamSparseReconstructorConfiguration() {
93          // initialize default covariance
94          try {
95              cameraPositionCovariance = Matrix.identity(Point3D.POINT3D_INHOMOGENEOUS_COORDINATES_LENGTH,
96                      Point3D.POINT3D_INHOMOGENEOUS_COORDINATES_LENGTH);
97              cameraPositionCovariance.multiplyByScalar(DEFAULT_CAMERA_POSITION_VARIANCE);
98          } catch (final AlgebraException ignore) {
99              // never happens
100         }
101     }
102 
103     /**
104      * Gets calibration data for accelerometer and gyroscope.
105      * This data is usually captured and estimated in an offline step previous
106      * to the actual scene reconstruction.
107      * Calibration data is usually obtained by keeping the system in a constant
108      * state of motion (e.g. acceleration and rotation).
109      * If this is null, no calibration data will be used.
110      *
111      * @return calibration data or null.
112      */
113     public C getCalibrationData() {
114         return calibrationData;
115     }
116 
117     /**
118      * Specifies calibration data for accelerometer and gyroscope.
119      * This data is usually captured and estimated in an offline step previous
120      * to the actual scene reconstruction.
121      * Calibration data is usually obtained by keeping the system in a constant
122      * state of motion (e.g. acceleration and rotation).
123      * If set to null, no calibration data will be used.
124      *
125      * @param calibrationData calibration data or null.
126      * @return this instance so that method can be easily chained.
127      */
128     public T setCalibrationData(final C calibrationData) {
129         this.calibrationData = calibrationData;
130 
131         //noinspection all
132         return (T) this;
133     }
134 
135     /**
136      * Gets matrix containing covariance of measured camera positions.
137      * This should usually be an "almost" diagonal matrix, where diagonal elements
138      * are close to the position estimation error variance.
139      * Values of this matrix are device specific and depends on factors such as
140      * resolution of images, pictures quality, gyroscope and accelerometer accuracy.
141      * This matrix must be a 3x3 symmetric positive definite matrix.
142      *
143      * @return covariance of measured camera positions.
144      */
145     public Matrix getCameraPositionCovariance() {
146         return cameraPositionCovariance;
147     }
148 
149     /**
150      * Sets matrix containing covariance of measured camera positions.
151      * This should usually be an "almost" diagonal matrix, where diagonal elements
152      * are close to the position estimation error variance.
153      * Values of this matrix are device specific and depends on factors such as
154      * resolution of images, pictures quality, gyroscope and accelerometer accuracy.
155      * This matrix must be a 3x3 symmetric positive definite matrix.
156      *
157      * @param cameraPositionCovariance covariance of measured camera positions.
158      * @return this instance so that method can be easily chained.
159      * @throws IllegalArgumentException if provided matrix is not 3x3.
160      */
161     public T setCameraPositionCovariance(final Matrix cameraPositionCovariance) {
162         if (cameraPositionCovariance.getRows() != Point3D.POINT3D_INHOMOGENEOUS_COORDINATES_LENGTH
163                 || cameraPositionCovariance.getColumns() != Point3D.POINT3D_INHOMOGENEOUS_COORDINATES_LENGTH) {
164             throw new IllegalArgumentException();
165         }
166 
167         this.cameraPositionCovariance = cameraPositionCovariance;
168 
169         //noinspection all
170         return (T) this;
171     }
172 
173     /**
174      * Sets independent variance of coordinates of measured camera positions.
175      * When using this method, camera position covariance matrix is set as a diagonal matrix whose diagonal
176      * elements are equal to provided value.
177      *
178      * @param variance variance of coordinates of measured camera positions.
179      * @return this instance so that method can be easily chained.
180      */
181     public T setCameraPositionVariance(final double variance) {
182         try {
183             cameraPositionCovariance = Matrix.identity(Point3D.POINT3D_INHOMOGENEOUS_COORDINATES_LENGTH,
184                     Point3D.POINT3D_INHOMOGENEOUS_COORDINATES_LENGTH);
185             cameraPositionCovariance.multiplyByScalar(variance);
186         } catch (AlgebraException ignore) {
187             // never happens
188         }
189 
190         //noinspection all
191         return (T) this;
192     }
193 
194     /**
195      * Indicates whether new available SLAM state is notified each time that a whole set of IMU (Inertial
196      * Measurement Unit) data is received. IMU data contains accelerometer, gyroscope and orientation
197      * samples.
198      *
199      * @return true if new available SLAM state is notified each time that a whole set of IMU data is
200      * received.
201      */
202     public boolean isNotifyAvailableSlamDataEnabled() {
203         return notifyAvailableSlamData;
204     }
205 
206     /**
207      * Specifies whether new available SLAM state is notified each time that a whole set of IMU (Inertial
208      * Measurement Unit) data is received. IMU data contains accelerometer, gyroscope and orientation
209      * samples.
210      *
211      * @param notifyAvailableSlamData true if new available SLAM state is notified each time that a whole
212      *                                set of IMU data is received, false otherwise.
213      * @return this instance so that method can be easily chained.
214      */
215     public T setNotifyAvailableSlamDataEnabled(final boolean notifyAvailableSlamData) {
216         this.notifyAvailableSlamData = notifyAvailableSlamData;
217 
218         //noinspection all
219         return (T) this;
220     }
221 
222     /**
223      * Indicates whether any new camera that can be estimated by means of SLAM using IMU data, will be
224      * notified each time that accelerometer, gyroscope and orientation data is received.
225      *
226      * @return true if any newly estimated camera is notified, false otherwise.
227      */
228     public boolean isNotifyEstimatedSlamCameraEnabled() {
229         return notifyEstimatedSlamCamera;
230     }
231 
232     /**
233      * Specifies whether any new camera that can be estimated by means of SLAM using IMU data, will be
234      * notified each time that accelerometer, gyroscope and orientation data is received.
235      *
236      * @param notifyEstimatedSlamCamera true if any newly estimated camera is notified, false otherwise.
237      * @return this instance so that method can be easily chained.
238      */
239     public T setNotifyEstimatedSlamCameraEnabled(final boolean notifyEstimatedSlamCamera) {
240         this.notifyEstimatedSlamCamera = notifyEstimatedSlamCamera;
241 
242         //noinspection all
243         return (T) this;
244     }
245 }