Merge branch 'develop' into fix/wrapper-todos
						commit
						2ebfdca175
					
				| 
						 | 
					@ -166,7 +166,7 @@ if(MSVC AND BUILD_SHARED_LIBS)
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Store these in variables so they are automatically replicated in GTSAMConfig.cmake and such.
 | 
					# Store these in variables so they are automatically replicated in GTSAMConfig.cmake and such.
 | 
				
			||||||
set(BOOST_FIND_MINIMUM_VERSION 1.43)
 | 
					set(BOOST_FIND_MINIMUM_VERSION 1.58)
 | 
				
			||||||
set(BOOST_FIND_MINIMUM_COMPONENTS serialization system filesystem thread program_options date_time timer chrono regex)
 | 
					set(BOOST_FIND_MINIMUM_COMPONENTS serialization system filesystem thread program_options date_time timer chrono regex)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
find_package(Boost ${BOOST_FIND_MINIMUM_VERSION} COMPONENTS ${BOOST_FIND_MINIMUM_COMPONENTS})
 | 
					find_package(Boost ${BOOST_FIND_MINIMUM_VERSION} COMPONENTS ${BOOST_FIND_MINIMUM_COMPONENTS})
 | 
				
			||||||
| 
						 | 
					@ -174,7 +174,7 @@ find_package(Boost ${BOOST_FIND_MINIMUM_VERSION} COMPONENTS ${BOOST_FIND_MINIMUM
 | 
				
			||||||
# Required components
 | 
					# Required components
 | 
				
			||||||
if(NOT Boost_SERIALIZATION_LIBRARY OR NOT Boost_SYSTEM_LIBRARY OR NOT Boost_FILESYSTEM_LIBRARY OR
 | 
					if(NOT Boost_SERIALIZATION_LIBRARY OR NOT Boost_SYSTEM_LIBRARY OR NOT Boost_FILESYSTEM_LIBRARY OR
 | 
				
			||||||
    NOT Boost_THREAD_LIBRARY OR NOT Boost_DATE_TIME_LIBRARY)
 | 
					    NOT Boost_THREAD_LIBRARY OR NOT Boost_DATE_TIME_LIBRARY)
 | 
				
			||||||
  message(FATAL_ERROR "Missing required Boost components >= v1.43, please install/upgrade Boost or configure your search paths.")
 | 
					  message(FATAL_ERROR "Missing required Boost components >= v1.58, please install/upgrade Boost or configure your search paths.")
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
option(GTSAM_DISABLE_NEW_TIMERS "Disables using Boost.chrono for timing" OFF)
 | 
					option(GTSAM_DISABLE_NEW_TIMERS "Disables using Boost.chrono for timing" OFF)
 | 
				
			||||||
| 
						 | 
					@ -490,7 +490,7 @@ set(CPACK_SOURCE_PACKAGE_FILE_NAME "gtsam-${GTSAM_VERSION_MAJOR}.${GTSAM_VERSION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Deb-package specific cpack
 | 
					# Deb-package specific cpack
 | 
				
			||||||
set(CPACK_DEBIAN_PACKAGE_NAME "libgtsam-dev")
 | 
					set(CPACK_DEBIAN_PACKAGE_NAME "libgtsam-dev")
 | 
				
			||||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libboost-dev (>= 1.43)") #Example: "libc6 (>= 2.3.1-6), libgcc1 (>= 1:3.4.2-12)")
 | 
					set(CPACK_DEBIAN_PACKAGE_DEPENDS "libboost-dev (>= 1.58)") #Example: "libc6 (>= 2.3.1-6), libgcc1 (>= 1:3.4.2-12)")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
###############################################################################
 | 
					###############################################################################
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,7 +13,7 @@ $ make install
 | 
				
			||||||
## Important Installation Notes
 | 
					## Important Installation Notes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
1. GTSAM requires the following libraries to be installed on your system:
 | 
					1. GTSAM requires the following libraries to be installed on your system:
 | 
				
			||||||
    - BOOST version 1.43 or greater (install through Linux repositories or MacPorts)
 | 
					    - BOOST version 1.58 or greater (install through Linux repositories or MacPorts)
 | 
				
			||||||
    - Cmake version 3.0 or higher
 | 
					    - Cmake version 3.0 or higher
 | 
				
			||||||
    - Support for XCode 4.3 command line tools on Mac requires CMake 2.8.8 or higher
 | 
					    - Support for XCode 4.3 command line tools on Mac requires CMake 2.8.8 or higher
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -40,7 +40,7 @@ $ make install
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Prerequisites:
 | 
					Prerequisites:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- [Boost](http://www.boost.org/users/download/) >= 1.43 (Ubuntu: `sudo apt-get install libboost-all-dev`)
 | 
					- [Boost](http://www.boost.org/users/download/) >= 1.58 (Ubuntu: `sudo apt-get install libboost-all-dev`)
 | 
				
			||||||
- [CMake](http://www.cmake.org/cmake/resources/software.html) >= 3.0 (Ubuntu: `sudo apt-get install cmake`)
 | 
					- [CMake](http://www.cmake.org/cmake/resources/software.html) >= 3.0 (Ubuntu: `sudo apt-get install cmake`)
 | 
				
			||||||
- A modern compiler, i.e., at least gcc 4.7.3 on Linux.
 | 
					- A modern compiler, i.e., at least gcc 4.7.3 on Linux.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,6 +21,7 @@
 | 
				
			||||||
#include <cstdlib>  // Provides size_t
 | 
					#include <cstdlib>  // Provides size_t
 | 
				
			||||||
#include <map>
 | 
					#include <map>
 | 
				
			||||||
#include <set>
 | 
					#include <set>
 | 
				
			||||||
 | 
					#include <vector>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace gtsam {
 | 
					namespace gtsam {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -120,4 +121,12 @@ class IndexPair : public std::pair<size_t,size_t> {
 | 
				
			||||||
  inline size_t i() const { return first; };
 | 
					  inline size_t i() const { return first; };
 | 
				
			||||||
  inline size_t j() const { return second; };
 | 
					  inline size_t j() const { return second; };
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef std::vector<IndexPair> IndexPairVector;
 | 
				
			||||||
 | 
					typedef std::set<IndexPair> IndexPairSet;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline IndexPairVector IndexPairSetAsArray(IndexPairSet& set) { return IndexPairVector(set.begin(), set.end()); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef std::map<IndexPair, IndexPairSet> IndexPairSetMap;
 | 
				
			||||||
 | 
					typedef DSFMap<IndexPair> DSFMapIndexPair;
 | 
				
			||||||
}  // namespace gtsam
 | 
					}  // namespace gtsam
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -700,9 +700,10 @@ inline typename internal::FixedSizeMatrix<Y,X5>::type numericalDerivative65(Y (*
 | 
				
			||||||
 * @return m*n Jacobian computed via central differencing
 | 
					 * @return m*n Jacobian computed via central differencing
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
template<class Y, class X1, class X2, class X3, class X4, class X5, class X6>
 | 
					template<class Y, class X1, class X2, class X3, class X4, class X5, class X6>
 | 
				
			||||||
typename internal::FixedSizeMatrix<Y,X5>::type numericalDerivative66(
 | 
					typename internal::FixedSizeMatrix<Y, X6>::type numericalDerivative66(
 | 
				
			||||||
    boost::function<Y(const X1&, const X2&, const X3&, const X4&, const X5&, const X6&)> h, const X1& x1,
 | 
					    boost::function<Y(const X1&, const X2&, const X3&, const X4&, const X5&, const X6&)> h,
 | 
				
			||||||
    const X2& x2, const X3& x3, const X4& x4, const X5& x5, const X6& x6, double delta = 1e-5) {
 | 
					    const X1& x1, const X2& x2, const X3& x3, const X4& x4, const X5& x5, const X6& x6,
 | 
				
			||||||
 | 
					    double delta = 1e-5) {
 | 
				
			||||||
  BOOST_STATIC_ASSERT_MSG( (boost::is_base_of<gtsam::manifold_tag, typename traits<Y>::structure_category>::value),
 | 
					  BOOST_STATIC_ASSERT_MSG( (boost::is_base_of<gtsam::manifold_tag, typename traits<Y>::structure_category>::value),
 | 
				
			||||||
      "Template argument Y must be a manifold type.");
 | 
					      "Template argument Y must be a manifold type.");
 | 
				
			||||||
  BOOST_STATIC_ASSERT_MSG( (boost::is_base_of<gtsam::manifold_tag, typename traits<X1>::structure_category>::value),
 | 
					  BOOST_STATIC_ASSERT_MSG( (boost::is_base_of<gtsam::manifold_tag, typename traits<X1>::structure_category>::value),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -259,11 +259,59 @@ class IndexPair {
 | 
				
			||||||
  size_t j() const;
 | 
					  size_t j() const;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<KEY = {gtsam::IndexPair}>
 | 
					// template<KEY = {gtsam::IndexPair}>
 | 
				
			||||||
class DSFMap {
 | 
					// class DSFMap {
 | 
				
			||||||
  DSFMap();
 | 
					//   DSFMap();
 | 
				
			||||||
  KEY find(const KEY& key) const;
 | 
					//   KEY find(const KEY& key) const;
 | 
				
			||||||
  void merge(const KEY& x, const KEY& y);
 | 
					//   void merge(const KEY& x, const KEY& y);
 | 
				
			||||||
 | 
					//   std::map<KEY, Set> sets();
 | 
				
			||||||
 | 
					// };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class IndexPairSet {
 | 
				
			||||||
 | 
					  IndexPairSet();
 | 
				
			||||||
 | 
					  // common STL methods
 | 
				
			||||||
 | 
					  size_t size() const;
 | 
				
			||||||
 | 
					  bool empty() const;
 | 
				
			||||||
 | 
					  void clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // structure specific methods
 | 
				
			||||||
 | 
					  void insert(gtsam::IndexPair key);
 | 
				
			||||||
 | 
					  bool erase(gtsam::IndexPair key); // returns true if value was removed
 | 
				
			||||||
 | 
					  bool count(gtsam::IndexPair key) const; // returns true if value exists
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class IndexPairVector {
 | 
				
			||||||
 | 
					  IndexPairVector();
 | 
				
			||||||
 | 
					  IndexPairVector(const gtsam::IndexPairVector& other);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // common STL methods
 | 
				
			||||||
 | 
					  size_t size() const;
 | 
				
			||||||
 | 
					  bool empty() const;
 | 
				
			||||||
 | 
					  void clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // structure specific methods
 | 
				
			||||||
 | 
					  gtsam::IndexPair at(size_t i) const;
 | 
				
			||||||
 | 
					  void push_back(gtsam::IndexPair key) const;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					gtsam::IndexPairVector IndexPairSetAsArray(gtsam::IndexPairSet& set);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class IndexPairSetMap {
 | 
				
			||||||
 | 
					  IndexPairSetMap();
 | 
				
			||||||
 | 
					  // common STL methods
 | 
				
			||||||
 | 
					  size_t size() const;
 | 
				
			||||||
 | 
					  bool empty() const;
 | 
				
			||||||
 | 
					  void clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // structure specific methods
 | 
				
			||||||
 | 
					  gtsam::IndexPairSet at(gtsam::IndexPair& key);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class DSFMapIndexPair {
 | 
				
			||||||
 | 
					  DSFMapIndexPair();
 | 
				
			||||||
 | 
					  gtsam::IndexPair find(const gtsam::IndexPair& key) const;
 | 
				
			||||||
 | 
					  void merge(const gtsam::IndexPair& x, const gtsam::IndexPair& y);
 | 
				
			||||||
 | 
					  gtsam::IndexPairSetMap sets();
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <gtsam/base/Matrix.h>
 | 
					#include <gtsam/base/Matrix.h>
 | 
				
			||||||
| 
						 | 
					@ -2929,6 +2977,13 @@ class BinaryMeasurement {
 | 
				
			||||||
typedef gtsam::BinaryMeasurement<gtsam::Unit3> BinaryMeasurementUnit3;
 | 
					typedef gtsam::BinaryMeasurement<gtsam::Unit3> BinaryMeasurementUnit3;
 | 
				
			||||||
typedef gtsam::BinaryMeasurement<gtsam::Rot3> BinaryMeasurementRot3;
 | 
					typedef gtsam::BinaryMeasurement<gtsam::Rot3> BinaryMeasurementRot3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class BinaryMeasurementsUnit3 {
 | 
				
			||||||
 | 
					  BinaryMeasurementsUnit3();
 | 
				
			||||||
 | 
					  size_t size() const;
 | 
				
			||||||
 | 
					  gtsam::BinaryMeasurement<gtsam::Unit3> at(size_t idx) const;
 | 
				
			||||||
 | 
					  void push_back(const gtsam::BinaryMeasurement<gtsam::Unit3>& measurement);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <gtsam/sfm/ShonanAveraging.h>
 | 
					#include <gtsam/sfm/ShonanAveraging.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TODO(frank): copy/pasta below until we have integer template paremeters in wrap!
 | 
					// TODO(frank): copy/pasta below until we have integer template paremeters in wrap!
 | 
				
			||||||
| 
						 | 
					@ -3050,6 +3105,16 @@ class ShonanAveraging3 {
 | 
				
			||||||
  pair<gtsam::Values, double> run(const gtsam::Values& initial, size_t min_p, size_t max_p) const;
 | 
					  pair<gtsam::Values, double> run(const gtsam::Values& initial, size_t min_p, size_t max_p) const;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <gtsam/sfm/TranslationRecovery.h>
 | 
				
			||||||
 | 
					class TranslationRecovery {
 | 
				
			||||||
 | 
					  TranslationRecovery(const gtsam::BinaryMeasurementsUnit3 &relativeTranslations,
 | 
				
			||||||
 | 
					                      const gtsam::LevenbergMarquardtParams &lmParams);
 | 
				
			||||||
 | 
					  TranslationRecovery(
 | 
				
			||||||
 | 
					      const gtsam::BinaryMeasurementsUnit3 & relativeTranslations);  // default LevenbergMarquardtParams
 | 
				
			||||||
 | 
					  gtsam::Values run(const double scale) const;
 | 
				
			||||||
 | 
					  gtsam::Values run() const;    // default scale = 1.0
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//*************************************************************************
 | 
					//*************************************************************************
 | 
				
			||||||
// Navigation
 | 
					// Navigation
 | 
				
			||||||
//*************************************************************************
 | 
					//*************************************************************************
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -218,28 +218,37 @@ Vector9 NavState::coriolis(double dt, const Vector3& omega, bool secondOrder,
 | 
				
			||||||
  const double dt2 = dt * dt;
 | 
					  const double dt2 = dt * dt;
 | 
				
			||||||
  const Vector3 omega_cross_vel = omega.cross(n_v);
 | 
					  const Vector3 omega_cross_vel = omega.cross(n_v);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Vector9 xi;
 | 
					  // Get perturbations in nav frame
 | 
				
			||||||
  Matrix3 D_dP_R;
 | 
					  Vector9 n_xi, xi;
 | 
				
			||||||
  dR(xi) << nRb.unrotate((-dt) * omega, H ? &D_dP_R : 0);
 | 
					  Matrix3 D_dR_R, D_dP_R, D_dV_R, D_body_nav;
 | 
				
			||||||
  dP(xi) << ((-dt2) * omega_cross_vel); // NOTE(luca): we got rid of the 2 wrt INS paper
 | 
					  dR(n_xi) << ((-dt) * omega);
 | 
				
			||||||
  dV(xi) << ((-2.0 * dt) * omega_cross_vel);
 | 
					  dP(n_xi) << ((-dt2) * omega_cross_vel); // NOTE(luca): we got rid of the 2 wrt INS paper
 | 
				
			||||||
 | 
					  dV(n_xi) << ((-2.0 * dt) * omega_cross_vel);
 | 
				
			||||||
  if (secondOrder) {
 | 
					  if (secondOrder) {
 | 
				
			||||||
    const Vector3 omega_cross2_t = omega.cross(omega.cross(n_t));
 | 
					    const Vector3 omega_cross2_t = omega.cross(omega.cross(n_t));
 | 
				
			||||||
    dP(xi) -= (0.5 * dt2) * omega_cross2_t;
 | 
					    dP(n_xi) -= (0.5 * dt2) * omega_cross2_t;
 | 
				
			||||||
    dV(xi) -= dt * omega_cross2_t;
 | 
					    dV(n_xi) -= dt * omega_cross2_t;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Transform n_xi into the body frame
 | 
				
			||||||
 | 
					  xi << nRb.unrotate(dR(n_xi), H ? &D_dR_R : 0, H ? &D_body_nav : 0), 
 | 
				
			||||||
 | 
					        nRb.unrotate(dP(n_xi), H ? &D_dP_R : 0),
 | 
				
			||||||
 | 
					        nRb.unrotate(dV(n_xi), H ? &D_dV_R : 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (H) {
 | 
					  if (H) {
 | 
				
			||||||
    H->setZero();
 | 
					    H->setZero();
 | 
				
			||||||
    const Matrix3 Omega = skewSymmetric(omega);
 | 
					    const Matrix3 Omega = skewSymmetric(omega);
 | 
				
			||||||
    const Matrix3 D_cross_state = Omega * R();
 | 
					    const Matrix3 D_cross_state = Omega * R();
 | 
				
			||||||
    H->setZero();
 | 
					    H->setZero();
 | 
				
			||||||
    D_R_R(H) << D_dP_R;
 | 
					    D_R_R(H) << D_dR_R;
 | 
				
			||||||
    D_t_v(H) << (-dt2) * D_cross_state;
 | 
					    D_t_v(H) << D_body_nav * (-dt2) * D_cross_state;
 | 
				
			||||||
    D_v_v(H) << (-2.0 * dt) * D_cross_state;
 | 
					    D_t_R(H) << D_dP_R;
 | 
				
			||||||
 | 
					    D_v_v(H) << D_body_nav * (-2.0 * dt) * D_cross_state;
 | 
				
			||||||
 | 
					    D_v_R(H) << D_dV_R;
 | 
				
			||||||
    if (secondOrder) {
 | 
					    if (secondOrder) {
 | 
				
			||||||
      const Matrix3 D_cross2_state = Omega * D_cross_state;
 | 
					      const Matrix3 D_cross2_state = Omega * D_cross_state;
 | 
				
			||||||
      D_t_t(H) -= (0.5 * dt2) * D_cross2_state;
 | 
					      D_t_t(H) -= D_body_nav * (0.5 * dt2) * D_cross2_state;
 | 
				
			||||||
      D_v_t(H) -= dt * D_cross2_state;
 | 
					      D_v_t(H) -= D_body_nav * dt * D_cross2_state;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return xi;
 | 
					  return xi;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -192,6 +192,49 @@ TEST(NavState, Coriolis2) {
 | 
				
			||||||
  EXPECT(assert_equal(numericalDerivative21(coriolis, state2, true), aH));
 | 
					  EXPECT(assert_equal(numericalDerivative21(coriolis, state2, true), aH));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(NavState, Coriolis3) {
 | 
				
			||||||
 | 
					  /** Consider a massless planet with an attached nav frame at 
 | 
				
			||||||
 | 
					   *  n_omega = [0 0 1]', and a body at position n_t = [1 0 0]', travelling with 
 | 
				
			||||||
 | 
					   *  velocity n_v = [0 1 0]'. Orient the body so that it is not instantaneously
 | 
				
			||||||
 | 
					   *  aligned with the nav frame (i.e., nRb != I_3x3). Test that first and 
 | 
				
			||||||
 | 
					   *  second order Coriolis corrections are as expected.
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Get true first and second order coriolis accelerations
 | 
				
			||||||
 | 
					  double dt = 2.0, dt2 = dt * dt;
 | 
				
			||||||
 | 
					  Vector3 n_omega(0.0, 0.0, 1.0), n_t(1.0, 0.0, 0.0), n_v(0.0, 1.0, 0.0);
 | 
				
			||||||
 | 
					  Vector3 n_aCorr1 = -2.0 * n_omega.cross(n_v),
 | 
				
			||||||
 | 
					          n_aCorr2 = -n_omega.cross(n_omega.cross(n_t));
 | 
				
			||||||
 | 
					  Rot3 nRb = Rot3(-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0),
 | 
				
			||||||
 | 
					       bRn = nRb.inverse();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Get expected first and second order corrections in the nav frame
 | 
				
			||||||
 | 
					  Vector3 n_dP1e = 0.5 * dt2 * n_aCorr1, 
 | 
				
			||||||
 | 
					          n_dP2e = 0.5 * dt2 * (n_aCorr1 + n_aCorr2),
 | 
				
			||||||
 | 
					          n_dV1e = dt * n_aCorr1, 
 | 
				
			||||||
 | 
					          n_dV2e = dt * (n_aCorr1 + n_aCorr2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Get expected first and second order corrections in the body frame
 | 
				
			||||||
 | 
					  Vector3 dRe = -dt * (bRn * n_omega),
 | 
				
			||||||
 | 
					          b_dP1e = bRn * n_dP1e, b_dP2e = bRn * n_dP2e,
 | 
				
			||||||
 | 
					          b_dV1e = bRn * n_dV1e, b_dV2e = bRn * n_dV2e;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Get actual first and scond order corrections in body frame
 | 
				
			||||||
 | 
					  NavState kState2(nRb, n_t, n_v);
 | 
				
			||||||
 | 
					  Vector9 dXi1a = kState2.coriolis(dt, n_omega, false),
 | 
				
			||||||
 | 
					          dXi2a = kState2.coriolis(dt, n_omega, true);
 | 
				
			||||||
 | 
					  Vector3 dRa = NavState::dR(dXi1a),
 | 
				
			||||||
 | 
					          b_dP1a = NavState::dP(dXi1a), b_dV1a = NavState::dV(dXi1a),
 | 
				
			||||||
 | 
					          b_dP2a = NavState::dP(dXi2a), b_dV2a = NavState::dV(dXi2a);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  EXPECT(assert_equal(dRe, dRa));
 | 
				
			||||||
 | 
					  EXPECT(assert_equal(b_dP1e, b_dP1a));
 | 
				
			||||||
 | 
					  EXPECT(assert_equal(b_dV1e, b_dV1a));
 | 
				
			||||||
 | 
					  EXPECT(assert_equal(b_dP2e, b_dP2a));
 | 
				
			||||||
 | 
					  EXPECT(assert_equal(b_dV2e, b_dV2a));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ************************************************************************* */
 | 
					/* ************************************************************************* */
 | 
				
			||||||
TEST(NavState, CorrectPIM) {
 | 
					TEST(NavState, CorrectPIM) {
 | 
				
			||||||
  Vector9 xi;
 | 
					  Vector9 xi;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1130,7 +1130,7 @@ bool readBAL(const string &filename, SfmData &data) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ************************************************************************* */
 | 
					/* ************************************************************************* */
 | 
				
			||||||
SfmData readBAL(const string &filename) {
 | 
					SfmData readBal(const string &filename) {
 | 
				
			||||||
  SfmData data;
 | 
					  SfmData data;
 | 
				
			||||||
  readBAL(filename, data);
 | 
					  readBAL(filename, data);
 | 
				
			||||||
  return data;
 | 
					  return data;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -283,7 +283,7 @@ GTSAM_EXPORT bool readBAL(const std::string& filename, SfmData &data);
 | 
				
			||||||
 * @param filename The name of the BAL file.
 | 
					 * @param filename The name of the BAL file.
 | 
				
			||||||
 * @return SfM structure where the data is stored.
 | 
					 * @return SfM structure where the data is stored.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
GTSAM_EXPORT SfmData readBAL(const std::string& filename);
 | 
					GTSAM_EXPORT SfmData readBal(const std::string& filename);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @brief This function writes a "Bundle Adjustment in the Large" (BAL) file from a
 | 
					 * @brief This function writes a "Bundle Adjustment in the Large" (BAL) file from a
 | 
				
			||||||
| 
						 | 
					@ -362,6 +362,7 @@ parse3DFactors(const std::string &filename,
 | 
				
			||||||
               const noiseModel::Diagonal::shared_ptr &model = nullptr,
 | 
					               const noiseModel::Diagonal::shared_ptr &model = nullptr,
 | 
				
			||||||
               size_t maxIndex = 0);
 | 
					               size_t maxIndex = 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using BinaryMeasurementsUnit3 = std::vector<BinaryMeasurement<Unit3>>;
 | 
				
			||||||
#ifdef GTSAM_ALLOW_DEPRECATED_SINCE_V41
 | 
					#ifdef GTSAM_ALLOW_DEPRECATED_SINCE_V41
 | 
				
			||||||
inline boost::optional<IndexedPose> parseVertex(std::istream &is,
 | 
					inline boost::optional<IndexedPose> parseVertex(std::istream &is,
 | 
				
			||||||
                                                const std::string &tag) {
 | 
					                                                const std::string &tag) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,11 +30,14 @@ set(ignore
 | 
				
			||||||
    gtsam::ISAM2ThresholdMapValue
 | 
					    gtsam::ISAM2ThresholdMapValue
 | 
				
			||||||
    gtsam::FactorIndices
 | 
					    gtsam::FactorIndices
 | 
				
			||||||
    gtsam::FactorIndexSet
 | 
					    gtsam::FactorIndexSet
 | 
				
			||||||
 | 
					    gtsam::IndexPairSetMap
 | 
				
			||||||
 | 
					    gtsam::IndexPairVector
 | 
				
			||||||
    gtsam::BetweenFactorPose2s
 | 
					    gtsam::BetweenFactorPose2s
 | 
				
			||||||
    gtsam::BetweenFactorPose3s
 | 
					    gtsam::BetweenFactorPose3s
 | 
				
			||||||
    gtsam::Point2Vector
 | 
					    gtsam::Point2Vector
 | 
				
			||||||
    gtsam::Pose3Vector
 | 
					    gtsam::Pose3Vector
 | 
				
			||||||
    gtsam::KeyVector)
 | 
					    gtsam::KeyVector
 | 
				
			||||||
 | 
					    gtsam::BinaryMeasurementsUnit3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pybind_wrap(gtsam_py # target
 | 
					pybind_wrap(gtsam_py # target
 | 
				
			||||||
            ${PROJECT_SOURCE_DIR}/gtsam/gtsam.i # interface_header
 | 
					            ${PROJECT_SOURCE_DIR}/gtsam/gtsam.i # interface_header
 | 
				
			||||||
| 
						 | 
					@ -76,7 +79,8 @@ set(ignore
 | 
				
			||||||
        gtsam::Point2Vector
 | 
					        gtsam::Point2Vector
 | 
				
			||||||
        gtsam::Pose3Vector
 | 
					        gtsam::Pose3Vector
 | 
				
			||||||
        gtsam::KeyVector
 | 
					        gtsam::KeyVector
 | 
				
			||||||
        gtsam::FixedLagSmootherKeyTimestampMapValue)
 | 
					        gtsam::FixedLagSmootherKeyTimestampMapValue
 | 
				
			||||||
 | 
					        gtsam::BinaryMeasurementsUnit3)
 | 
				
			||||||
pybind_wrap(gtsam_unstable_py # target
 | 
					pybind_wrap(gtsam_unstable_py # target
 | 
				
			||||||
        ${PROJECT_SOURCE_DIR}/gtsam_unstable/gtsam_unstable.i # interface_header
 | 
					        ${PROJECT_SOURCE_DIR}/gtsam_unstable/gtsam_unstable.i # interface_header
 | 
				
			||||||
        "gtsam_unstable.cpp" # generated_cpp
 | 
					        "gtsam_unstable.cpp" # generated_cpp
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,3 +9,4 @@ PYBIND11_MAKE_OPAQUE(std::vector<gtsam::Point2, Eigen::aligned_allocator<gtsam::
 | 
				
			||||||
PYBIND11_MAKE_OPAQUE(std::vector<gtsam::Pose3>);
 | 
					PYBIND11_MAKE_OPAQUE(std::vector<gtsam::Pose3>);
 | 
				
			||||||
PYBIND11_MAKE_OPAQUE(std::vector<boost::shared_ptr<gtsam::BetweenFactor<gtsam::Pose3> > >);
 | 
					PYBIND11_MAKE_OPAQUE(std::vector<boost::shared_ptr<gtsam::BetweenFactor<gtsam::Pose3> > >);
 | 
				
			||||||
PYBIND11_MAKE_OPAQUE(std::vector<boost::shared_ptr<gtsam::BetweenFactor<gtsam::Pose2> > >);
 | 
					PYBIND11_MAKE_OPAQUE(std::vector<boost::shared_ptr<gtsam::BetweenFactor<gtsam::Pose2> > >);
 | 
				
			||||||
 | 
					PYBIND11_MAKE_OPAQUE(std::vector<gtsam::IndexPair>);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,3 +9,6 @@ py::bind_vector<std::vector<gtsam::Point2, Eigen::aligned_allocator<gtsam::Point
 | 
				
			||||||
py::bind_vector<std::vector<gtsam::Pose3> >(m_, "Pose3Vector");
 | 
					py::bind_vector<std::vector<gtsam::Pose3> >(m_, "Pose3Vector");
 | 
				
			||||||
py::bind_vector<std::vector<boost::shared_ptr<gtsam::BetweenFactor<gtsam::Pose3> > > >(m_, "BetweenFactorPose3s");
 | 
					py::bind_vector<std::vector<boost::shared_ptr<gtsam::BetweenFactor<gtsam::Pose3> > > >(m_, "BetweenFactorPose3s");
 | 
				
			||||||
py::bind_vector<std::vector<boost::shared_ptr<gtsam::BetweenFactor<gtsam::Pose2> > > >(m_, "BetweenFactorPose2s");
 | 
					py::bind_vector<std::vector<boost::shared_ptr<gtsam::BetweenFactor<gtsam::Pose2> > > >(m_, "BetweenFactorPose2s");
 | 
				
			||||||
 | 
					py::bind_vector<std::vector<gtsam::BinaryMeasurement<gtsam::Unit3> > >(m_, "BinaryMeasurementsUnit3");
 | 
				
			||||||
 | 
					py::bind_map<gtsam::IndexPairSetMap>(m_, "IndexPairSetMap");
 | 
				
			||||||
 | 
					py::bind_vector<gtsam::IndexPairVector>(m_, "IndexPairVector");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,58 @@
 | 
				
			||||||
 | 
					from __future__ import print_function
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import numpy as np
 | 
				
			||||||
 | 
					import unittest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import gtsam
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					""" Returns example pose values of 3 points A, B and C in the world frame """
 | 
				
			||||||
 | 
					def ExampleValues():
 | 
				
			||||||
 | 
					    T = []
 | 
				
			||||||
 | 
					    T.append(gtsam.Point3(np.array([3.14, 1.59, 2.65])))
 | 
				
			||||||
 | 
					    T.append(gtsam.Point3(np.array([-1.0590e+00, -3.6017e-02, -1.5720e+00])))
 | 
				
			||||||
 | 
					    T.append(gtsam.Point3(np.array([8.5034e+00, 6.7499e+00, -3.6383e+00])))
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    data = gtsam.Values()
 | 
				
			||||||
 | 
					    for i in range(len(T)):
 | 
				
			||||||
 | 
					        data.insert(i, gtsam.Pose3(gtsam.Rot3(), T[i]))
 | 
				
			||||||
 | 
					    return data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					""" Returns binary measurements for the points in the given edges."""
 | 
				
			||||||
 | 
					def SimulateMeasurements(gt_poses, graph_edges):
 | 
				
			||||||
 | 
					    measurements = gtsam.BinaryMeasurementsUnit3()
 | 
				
			||||||
 | 
					    for edge in graph_edges:
 | 
				
			||||||
 | 
					        Ta = gt_poses.atPose3(edge[0]).translation()
 | 
				
			||||||
 | 
					        Tb = gt_poses.atPose3(edge[1]).translation()
 | 
				
			||||||
 | 
					        measurements.append(gtsam.BinaryMeasurementUnit3( \
 | 
				
			||||||
 | 
					            edge[0], edge[1], gtsam.Unit3(Tb - Ta), \
 | 
				
			||||||
 | 
					            gtsam.noiseModel.Isotropic.Sigma(3, 0.01)))
 | 
				
			||||||
 | 
					    return measurements
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					""" Tests for the translation recovery class """
 | 
				
			||||||
 | 
					class TestTranslationRecovery(unittest.TestCase):
 | 
				
			||||||
 | 
					    """Test selected Translation Recovery methods."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_constructor(self):
 | 
				
			||||||
 | 
					        """Construct from binary measurements."""
 | 
				
			||||||
 | 
					        algorithm = gtsam.TranslationRecovery(gtsam.BinaryMeasurementsUnit3())
 | 
				
			||||||
 | 
					        self.assertIsInstance(algorithm, gtsam.TranslationRecovery)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_run(self):
 | 
				
			||||||
 | 
					        gt_poses = ExampleValues()
 | 
				
			||||||
 | 
					        measurements = SimulateMeasurements(gt_poses, [[0, 1], [0, 2], [1, 2]])
 | 
				
			||||||
 | 
					        algorithm = gtsam.TranslationRecovery(measurements)
 | 
				
			||||||
 | 
					        scale = 2.0
 | 
				
			||||||
 | 
					        result = algorithm.run(scale)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        w_aTc = gt_poses.atPose3(2).translation() - gt_poses.atPose3(0).translation()
 | 
				
			||||||
 | 
					        w_aTb = gt_poses.atPose3(1).translation() - gt_poses.atPose3(0).translation()
 | 
				
			||||||
 | 
					        w_aTc_expected = w_aTc*scale/np.linalg.norm(w_aTb)
 | 
				
			||||||
 | 
					        w_aTb_expected = w_aTb*scale/np.linalg.norm(w_aTb)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        np.testing.assert_array_almost_equal(result.atPoint3(0), np.array([0,0,0]), 6, "Origin result is incorrect.")
 | 
				
			||||||
 | 
					        np.testing.assert_array_almost_equal(result.atPoint3(1), w_aTb_expected, 6, "Point B result is incorrect.")
 | 
				
			||||||
 | 
					        np.testing.assert_array_almost_equal(result.atPoint3(2), w_aTc_expected, 6, "Point C result is incorrect.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == "__main__":
 | 
				
			||||||
 | 
					    unittest.main()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,6 +35,20 @@ class TestDSFMap(GtsamTestCase):
 | 
				
			||||||
        dsf.merge(pair1, pair2)
 | 
					        dsf.merge(pair1, pair2)
 | 
				
			||||||
        self.assertEqual(key(dsf.find(pair1)), key(dsf.find(pair2)))
 | 
					        self.assertEqual(key(dsf.find(pair1)), key(dsf.find(pair2)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_sets(self):
 | 
				
			||||||
 | 
					        from gtsam import IndexPair
 | 
				
			||||||
 | 
					        dsf = gtsam.DSFMapIndexPair()
 | 
				
			||||||
 | 
					        dsf.merge(IndexPair(0, 1), IndexPair(1,2))
 | 
				
			||||||
 | 
					        dsf.merge(IndexPair(0, 1), IndexPair(3,4))
 | 
				
			||||||
 | 
					        dsf.merge(IndexPair(4,5), IndexPair(6,8))
 | 
				
			||||||
 | 
					        sets = dsf.sets()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for i in sets:
 | 
				
			||||||
 | 
					            s = sets[i]
 | 
				
			||||||
 | 
					            for val in gtsam.IndexPairSetAsArray(s):
 | 
				
			||||||
 | 
					                val.i()
 | 
				
			||||||
 | 
					                val.j()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__ == '__main__':
 | 
					if __name__ == '__main__':
 | 
				
			||||||
    unittest.main()
 | 
					    unittest.main()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue