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 paired 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 BaseSlamPairedViewsSparseReconstructorConfiguration<C extends BaseCalibrationData, 36 T extends BaseSlamPairedViewsSparseReconstructorConfiguration<C, T>> extends 37 BasePairedViewsSparseReconstructorConfiguration<T> 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, 48 * will 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 to the 60 * actual scene reconstruction. 61 * Calibration data is usually obtained by keeping the system in a constant state of 62 * 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 are 70 * close to the position estimation error variance. 71 * Values of this matrix are device specific and depends on factors such as resolution 72 * 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 79 * (Inertial 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 BaseSlamPairedViewsSparseReconstructorConfiguration() { 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 to the 106 * actual scene reconstruction. 107 * Calibration data is usually obtained by keeping the system in a constant state 108 * 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 to the 120 * actual scene reconstruction. 121 * Calibration data is usually obtained by keeping the system in a constant state 122 * 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 unchecked 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 are 138 * 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 are 152 * 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 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 unchecked 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 176 * matrix whose diagonal 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 (final AlgebraException ignore) { 187 // never happens 188 } 189 190 //noinspection unchecked 191 return (T) this; 192 } 193 194 /** 195 * Indicates whether new available SLAM state is notified each time that a whole set 196 * of IMU (Inertial Measurement Unit) data is received. IMU data contains 197 * accelerometer, gyroscope and orientation samples. 198 * 199 * @return true if new available SLAM state is notified each time that a whole set 200 * of IMU data is 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 208 * of IMU (Inertial Measurement Unit) data is received. IMU data contains accelerometer, 209 * gyroscope and orientation samples. 210 * 211 * @param notifyAvailableSlamData true if new available SLAM state is notified each 212 * time that a whole set of IMU data is received, false 213 * otherwise. 214 * @return this instance so that method can be easily chained. 215 */ 216 public T setNotifyAvailableSlamDataEnabled(final boolean notifyAvailableSlamData) { 217 this.notifyAvailableSlamData = notifyAvailableSlamData; 218 219 //noinspection unchecked 220 return (T) this; 221 } 222 223 /** 224 * Indicates whether any new camera that can be estimated by means of SLAM using IMU 225 * data, will be notified each time that accelerometer, gyroscope and orientation 226 * data is received. 227 * 228 * @return true if any newly estimated camera is notified, false otherwise. 229 */ 230 public boolean isNotifyEstimatedSlamCameraEnabled() { 231 return notifyEstimatedSlamCamera; 232 } 233 234 /** 235 * Specifies whether any new camera that can be estimated by means of SLAM using IMU 236 * data, will be notified each time that accelerometer, gyroscope and orientation 237 * data is received. 238 * 239 * @param notifyEstimatedSlamCamera true if any newly estimated camera is notified, 240 * false otherwise. 241 * @return this instance so that method can be easily chained. 242 */ 243 public T setNotifyEstimatedSlamCameraEnabled(final boolean notifyEstimatedSlamCamera) { 244 this.notifyEstimatedSlamCamera = notifyEstimatedSlamCamera; 245 246 //noinspection unchecked 247 return (T) this; 248 } 249 }