Merge pull request #1120 from borglab/ta-seed
Using a random number generator in translation averagingrelease/4.3a0
commit
a0d64a9448
|
@ -300,6 +300,7 @@ class GTSAM_EXPORT ShonanAveraging {
|
||||||
/**
|
/**
|
||||||
* Create initial Values of type SO(p)
|
* Create initial Values of type SO(p)
|
||||||
* @param p the dimensionality of the rotation manifold
|
* @param p the dimensionality of the rotation manifold
|
||||||
|
* @param rng random number generator
|
||||||
*/
|
*/
|
||||||
Values initializeRandomlyAt(size_t p, std::mt19937 &rng) const;
|
Values initializeRandomlyAt(size_t p, std::mt19937 &rng) const;
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,9 @@
|
||||||
using namespace gtsam;
|
using namespace gtsam;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
// In Wrappers we have no access to this so have a default ready.
|
||||||
|
static std::mt19937 kRandomNumberGenerator(42);
|
||||||
|
|
||||||
TranslationRecovery::TranslationRecovery(
|
TranslationRecovery::TranslationRecovery(
|
||||||
const TranslationRecovery::TranslationEdges &relativeTranslations,
|
const TranslationRecovery::TranslationEdges &relativeTranslations,
|
||||||
const LevenbergMarquardtParams &lmParams)
|
const LevenbergMarquardtParams &lmParams)
|
||||||
|
@ -88,13 +91,15 @@ void TranslationRecovery::addPrior(
|
||||||
edge->key2(), scale * edge->measured().point3(), edge->noiseModel());
|
edge->key2(), scale * edge->measured().point3(), edge->noiseModel());
|
||||||
}
|
}
|
||||||
|
|
||||||
Values TranslationRecovery::initalizeRandomly() const {
|
Values TranslationRecovery::initializeRandomly(std::mt19937 *rng) const {
|
||||||
|
uniform_real_distribution<double> randomVal(-1, 1);
|
||||||
// Create a lambda expression that checks whether value exists and randomly
|
// Create a lambda expression that checks whether value exists and randomly
|
||||||
// initializes if not.
|
// initializes if not.
|
||||||
Values initial;
|
Values initial;
|
||||||
auto insert = [&initial](Key j) {
|
auto insert = [&](Key j) {
|
||||||
if (!initial.exists(j)) {
|
if (!initial.exists(j)) {
|
||||||
initial.insert<Point3>(j, Vector3::Random());
|
initial.insert<Point3>(
|
||||||
|
j, Point3(randomVal(*rng), randomVal(*rng), randomVal(*rng)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -115,10 +120,14 @@ Values TranslationRecovery::initalizeRandomly() const {
|
||||||
return initial;
|
return initial;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Values TranslationRecovery::initializeRandomly() const {
|
||||||
|
return initializeRandomly(&kRandomNumberGenerator);
|
||||||
|
}
|
||||||
|
|
||||||
Values TranslationRecovery::run(const double scale) const {
|
Values TranslationRecovery::run(const double scale) const {
|
||||||
auto graph = buildGraph();
|
auto graph = buildGraph();
|
||||||
addPrior(scale, &graph);
|
addPrior(scale, &graph);
|
||||||
const Values initial = initalizeRandomly();
|
const Values initial = initializeRandomly();
|
||||||
LevenbergMarquardtOptimizer lm(graph, initial, params_);
|
LevenbergMarquardtOptimizer lm(graph, initial, params_);
|
||||||
Values result = lm.optimize();
|
Values result = lm.optimize();
|
||||||
|
|
||||||
|
|
|
@ -16,18 +16,16 @@
|
||||||
* @brief Recovering translations in an epipolar graph when rotations are given.
|
* @brief Recovering translations in an epipolar graph when rotations are given.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#include <gtsam/geometry/Unit3.h>
|
||||||
|
#include <gtsam/nonlinear/LevenbergMarquardtOptimizer.h>
|
||||||
|
#include <gtsam/nonlinear/Values.h>
|
||||||
|
#include <gtsam/sfm/BinaryMeasurement.h>
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <gtsam/geometry/Unit3.h>
|
|
||||||
#include <gtsam/nonlinear/LevenbergMarquardtOptimizer.h>
|
|
||||||
#include <gtsam/nonlinear/Values.h>
|
|
||||||
#include <gtsam/sfm/BinaryMeasurement.h>
|
|
||||||
|
|
||||||
namespace gtsam {
|
namespace gtsam {
|
||||||
|
|
||||||
// Set up an optimization problem for the unknown translations Ti in the world
|
// Set up an optimization problem for the unknown translations Ti in the world
|
||||||
|
@ -102,9 +100,17 @@ class TranslationRecovery {
|
||||||
/**
|
/**
|
||||||
* @brief Create random initial translations.
|
* @brief Create random initial translations.
|
||||||
*
|
*
|
||||||
|
* @param rng random number generator
|
||||||
* @return Values
|
* @return Values
|
||||||
*/
|
*/
|
||||||
Values initalizeRandomly() const;
|
Values initializeRandomly(std::mt19937 *rng) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Version of initializeRandomly with a fixed seed.
|
||||||
|
*
|
||||||
|
* @return Values
|
||||||
|
*/
|
||||||
|
Values initializeRandomly() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Build and optimize factor graph.
|
* @brief Build and optimize factor graph.
|
||||||
|
|
|
@ -115,8 +115,8 @@ TEST(TranslationRecovery, TwoPoseTest) {
|
||||||
const auto result = algorithm.run(/*scale=*/3.0);
|
const auto result = algorithm.run(/*scale=*/3.0);
|
||||||
|
|
||||||
// Check result for first two translations, determined by prior
|
// Check result for first two translations, determined by prior
|
||||||
EXPECT(assert_equal(Point3(0, 0, 0), result.at<Point3>(0)));
|
EXPECT(assert_equal(Point3(0, 0, 0), result.at<Point3>(0), 1e-8));
|
||||||
EXPECT(assert_equal(Point3(3, 0, 0), result.at<Point3>(1)));
|
EXPECT(assert_equal(Point3(3, 0, 0), result.at<Point3>(1), 1e-8));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(TranslationRecovery, ThreePoseTest) {
|
TEST(TranslationRecovery, ThreePoseTest) {
|
||||||
|
@ -152,9 +152,9 @@ TEST(TranslationRecovery, ThreePoseTest) {
|
||||||
const auto result = algorithm.run(/*scale=*/3.0);
|
const auto result = algorithm.run(/*scale=*/3.0);
|
||||||
|
|
||||||
// Check result
|
// Check result
|
||||||
EXPECT(assert_equal(Point3(0, 0, 0), result.at<Point3>(0)));
|
EXPECT(assert_equal(Point3(0, 0, 0), result.at<Point3>(0), 1e-8));
|
||||||
EXPECT(assert_equal(Point3(3, 0, 0), result.at<Point3>(1)));
|
EXPECT(assert_equal(Point3(3, 0, 0), result.at<Point3>(1), 1e-8));
|
||||||
EXPECT(assert_equal(Point3(1.5, -1.5, 0), result.at<Point3>(3)));
|
EXPECT(assert_equal(Point3(1.5, -1.5, 0), result.at<Point3>(3), 1e-8));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(TranslationRecovery, ThreePosesIncludingZeroTranslation) {
|
TEST(TranslationRecovery, ThreePosesIncludingZeroTranslation) {
|
||||||
|
@ -189,9 +189,9 @@ TEST(TranslationRecovery, ThreePosesIncludingZeroTranslation) {
|
||||||
const auto result = algorithm.run(/*scale=*/3.0);
|
const auto result = algorithm.run(/*scale=*/3.0);
|
||||||
|
|
||||||
// Check result
|
// Check result
|
||||||
EXPECT(assert_equal(Point3(0, 0, 0), result.at<Point3>(0)));
|
EXPECT(assert_equal(Point3(0, 0, 0), result.at<Point3>(0), 1e-8));
|
||||||
EXPECT(assert_equal(Point3(3, 0, 0), result.at<Point3>(1)));
|
EXPECT(assert_equal(Point3(3, 0, 0), result.at<Point3>(1), 1e-8));
|
||||||
EXPECT(assert_equal(Point3(3, 0, 0), result.at<Point3>(2)));
|
EXPECT(assert_equal(Point3(3, 0, 0), result.at<Point3>(2), 1e-8));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(TranslationRecovery, FourPosesIncludingZeroTranslation) {
|
TEST(TranslationRecovery, FourPosesIncludingZeroTranslation) {
|
||||||
|
@ -230,10 +230,10 @@ TEST(TranslationRecovery, FourPosesIncludingZeroTranslation) {
|
||||||
const auto result = algorithm.run(/*scale=*/4.0);
|
const auto result = algorithm.run(/*scale=*/4.0);
|
||||||
|
|
||||||
// Check result
|
// Check result
|
||||||
EXPECT(assert_equal(Point3(0, 0, 0), result.at<Point3>(0)));
|
EXPECT(assert_equal(Point3(0, 0, 0), result.at<Point3>(0), 1e-8));
|
||||||
EXPECT(assert_equal(Point3(4, 0, 0), result.at<Point3>(1)));
|
EXPECT(assert_equal(Point3(4, 0, 0), result.at<Point3>(1), 1e-8));
|
||||||
EXPECT(assert_equal(Point3(4, 0, 0), result.at<Point3>(2)));
|
EXPECT(assert_equal(Point3(4, 0, 0), result.at<Point3>(2), 1e-8));
|
||||||
EXPECT(assert_equal(Point3(2, -2, 0), result.at<Point3>(3)));
|
EXPECT(assert_equal(Point3(2, -2, 0), result.at<Point3>(3), 1e-8));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(TranslationRecovery, ThreePosesWithZeroTranslation) {
|
TEST(TranslationRecovery, ThreePosesWithZeroTranslation) {
|
||||||
|
@ -260,9 +260,9 @@ TEST(TranslationRecovery, ThreePosesWithZeroTranslation) {
|
||||||
const auto result = algorithm.run(/*scale=*/4.0);
|
const auto result = algorithm.run(/*scale=*/4.0);
|
||||||
|
|
||||||
// Check result
|
// Check result
|
||||||
EXPECT(assert_equal(Point3(0, 0, 0), result.at<Point3>(0)));
|
EXPECT(assert_equal(Point3(0, 0, 0), result.at<Point3>(0), 1e-8));
|
||||||
EXPECT(assert_equal(Point3(0, 0, 0), result.at<Point3>(1)));
|
EXPECT(assert_equal(Point3(0, 0, 0), result.at<Point3>(1), 1e-8));
|
||||||
EXPECT(assert_equal(Point3(0, 0, 0), result.at<Point3>(2)));
|
EXPECT(assert_equal(Point3(0, 0, 0), result.at<Point3>(2), 1e-8));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
|
Loading…
Reference in New Issue