Merge pull request #1224 from borglab/ta-priors-fix
Fix the failure in TA when adding betweenTranslations without any measurements.release/4.3a0
commit
c663354d3f
|
|
@ -119,21 +119,24 @@ void TranslationRecovery::addPrior(
|
||||||
graph->emplace_shared<PriorFactor<Point3>>(edge->key1(), Point3(0, 0, 0),
|
graph->emplace_shared<PriorFactor<Point3>>(edge->key1(), Point3(0, 0, 0),
|
||||||
priorNoiseModel);
|
priorNoiseModel);
|
||||||
|
|
||||||
// Add between factors for optional relative translations.
|
|
||||||
for (auto edge : betweenTranslations) {
|
|
||||||
graph->emplace_shared<BetweenFactor<Point3>>(
|
|
||||||
edge.key1(), edge.key2(), edge.measured(), edge.noiseModel());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add a scale prior only if no other between factors were added.
|
// Add a scale prior only if no other between factors were added.
|
||||||
if (betweenTranslations.empty()) {
|
if (betweenTranslations.empty()) {
|
||||||
graph->emplace_shared<PriorFactor<Point3>>(
|
graph->emplace_shared<PriorFactor<Point3>>(
|
||||||
edge->key2(), scale * edge->measured().point3(), edge->noiseModel());
|
edge->key2(), scale * edge->measured().point3(), edge->noiseModel());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add between factors for optional relative translations.
|
||||||
|
for (auto prior_edge : betweenTranslations) {
|
||||||
|
graph->emplace_shared<BetweenFactor<Point3>>(
|
||||||
|
prior_edge.key1(), prior_edge.key2(), prior_edge.measured(),
|
||||||
|
prior_edge.noiseModel());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Values TranslationRecovery::initializeRandomly(
|
Values TranslationRecovery::initializeRandomly(
|
||||||
const std::vector<BinaryMeasurement<Unit3>> &relativeTranslations,
|
const std::vector<BinaryMeasurement<Unit3>> &relativeTranslations,
|
||||||
|
const std::vector<BinaryMeasurement<Point3>> &betweenTranslations,
|
||||||
std::mt19937 *rng, const Values &initialValues) const {
|
std::mt19937 *rng, const Values &initialValues) const {
|
||||||
uniform_real_distribution<double> randomVal(-1, 1);
|
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
|
||||||
|
|
@ -155,14 +158,20 @@ Values TranslationRecovery::initializeRandomly(
|
||||||
insert(edge.key1());
|
insert(edge.key1());
|
||||||
insert(edge.key2());
|
insert(edge.key2());
|
||||||
}
|
}
|
||||||
|
// There may be nodes in betweenTranslations that do not have a measurement.
|
||||||
|
for (auto edge : betweenTranslations) {
|
||||||
|
insert(edge.key1());
|
||||||
|
insert(edge.key2());
|
||||||
|
}
|
||||||
return initial;
|
return initial;
|
||||||
}
|
}
|
||||||
|
|
||||||
Values TranslationRecovery::initializeRandomly(
|
Values TranslationRecovery::initializeRandomly(
|
||||||
const std::vector<BinaryMeasurement<Unit3>> &relativeTranslations,
|
const std::vector<BinaryMeasurement<Unit3>> &relativeTranslations,
|
||||||
|
const std::vector<BinaryMeasurement<Point3>> &betweenTranslations,
|
||||||
const Values &initialValues) const {
|
const Values &initialValues) const {
|
||||||
return initializeRandomly(relativeTranslations, &kRandomNumberGenerator,
|
return initializeRandomly(relativeTranslations, betweenTranslations,
|
||||||
initialValues);
|
&kRandomNumberGenerator, initialValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
Values TranslationRecovery::run(
|
Values TranslationRecovery::run(
|
||||||
|
|
@ -187,8 +196,8 @@ Values TranslationRecovery::run(
|
||||||
&graph);
|
&graph);
|
||||||
|
|
||||||
// Uses initial values from params if provided.
|
// Uses initial values from params if provided.
|
||||||
Values initial =
|
Values initial = initializeRandomly(
|
||||||
initializeRandomly(nonzeroRelativeTranslations, initialValues);
|
nonzeroRelativeTranslations, nonzeroBetweenTranslations, initialValues);
|
||||||
|
|
||||||
// If there are no valid edges, but zero-distance edges exist, initialize one
|
// If there are no valid edges, but zero-distance edges exist, initialize one
|
||||||
// of the nodes in a connected component of zero-distance edges.
|
// of the nodes in a connected component of zero-distance edges.
|
||||||
|
|
|
||||||
|
|
@ -112,12 +112,15 @@ class TranslationRecovery {
|
||||||
*
|
*
|
||||||
* @param relativeTranslations unit translation directions between
|
* @param relativeTranslations unit translation directions between
|
||||||
* translations to be estimated
|
* translations to be estimated
|
||||||
|
* @param betweenTranslations relative translations (with scale) between 2
|
||||||
|
* points in world coordinate frame known a priori.
|
||||||
* @param rng random number generator
|
* @param rng random number generator
|
||||||
* @param intialValues (optional) initial values from a prior
|
* @param intialValues (optional) initial values from a prior
|
||||||
* @return Values
|
* @return Values
|
||||||
*/
|
*/
|
||||||
Values initializeRandomly(
|
Values initializeRandomly(
|
||||||
const std::vector<BinaryMeasurement<Unit3>> &relativeTranslations,
|
const std::vector<BinaryMeasurement<Unit3>> &relativeTranslations,
|
||||||
|
const std::vector<BinaryMeasurement<Point3>> &betweenTranslations,
|
||||||
std::mt19937 *rng, const Values &initialValues = Values()) const;
|
std::mt19937 *rng, const Values &initialValues = Values()) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -125,11 +128,14 @@ class TranslationRecovery {
|
||||||
*
|
*
|
||||||
* @param relativeTranslations unit translation directions between
|
* @param relativeTranslations unit translation directions between
|
||||||
* translations to be estimated
|
* translations to be estimated
|
||||||
|
* @param betweenTranslations relative translations (with scale) between 2
|
||||||
|
* points in world coordinate frame known a priori.
|
||||||
* @param initialValues (optional) initial values from a prior
|
* @param initialValues (optional) initial values from a prior
|
||||||
* @return Values
|
* @return Values
|
||||||
*/
|
*/
|
||||||
Values initializeRandomly(
|
Values initializeRandomly(
|
||||||
const std::vector<BinaryMeasurement<Unit3>> &relativeTranslations,
|
const std::vector<BinaryMeasurement<Unit3>> &relativeTranslations,
|
||||||
|
const std::vector<BinaryMeasurement<Point3>> &betweenTranslations,
|
||||||
const Values &initialValues = Values()) const;
|
const Values &initialValues = Values()) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -137,11 +143,15 @@ class TranslationRecovery {
|
||||||
*
|
*
|
||||||
* @param relativeTranslations the relative translations, in world coordinate
|
* @param relativeTranslations the relative translations, in world coordinate
|
||||||
* frames, vector of BinaryMeasurements of Unit3, where each key of a
|
* frames, vector of BinaryMeasurements of Unit3, where each key of a
|
||||||
* measurement is a point in 3D.
|
* measurement is a point in 3D. If a relative translation magnitude is zero,
|
||||||
|
* it is treated as a hard same-point constraint (the result of all nodes
|
||||||
|
* connected by a zero-magnitude edge will be the same).
|
||||||
* @param scale scale for first relative translation which fixes gauge.
|
* @param scale scale for first relative translation which fixes gauge.
|
||||||
* The scale is only used if betweenTranslations is empty.
|
* The scale is only used if betweenTranslations is empty.
|
||||||
* @param betweenTranslations relative translations (with scale) between 2
|
* @param betweenTranslations relative translations (with scale) between 2
|
||||||
* points in world coordinate frame known a priori.
|
* points in world coordinate frame known a priori. Unlike
|
||||||
|
* relativeTranslations, zero-magnitude betweenTranslations are not treated as
|
||||||
|
* hard constraints.
|
||||||
* @param initialValues intial values for optimization. Initializes randomly
|
* @param initialValues intial values for optimization. Initializes randomly
|
||||||
* if not provided.
|
* if not provided.
|
||||||
* @return Values
|
* @return Values
|
||||||
|
|
|
||||||
|
|
@ -323,6 +323,36 @@ TEST(TranslationRecovery, ThreePosesWithOneHardConstraint) {
|
||||||
EXPECT(assert_equal(Point3(2, 0, 0), result.at<Point3>(1), 1e-4));
|
EXPECT(assert_equal(Point3(2, 0, 0), result.at<Point3>(1), 1e-4));
|
||||||
EXPECT(assert_equal(Point3(1, -1, 0), result.at<Point3>(3), 1e-4));
|
EXPECT(assert_equal(Point3(1, -1, 0), result.at<Point3>(3), 1e-4));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(TranslationRecovery, NodeWithBetweenFactorAndNoMeasurements) {
|
||||||
|
// Checks that valid results are obtained when a between translation edge is
|
||||||
|
// provided with a node that does not have any other relative translations.
|
||||||
|
Values poses;
|
||||||
|
poses.insert<Pose3>(0, Pose3(Rot3(), Point3(0, 0, 0)));
|
||||||
|
poses.insert<Pose3>(1, Pose3(Rot3(), Point3(2, 0, 0)));
|
||||||
|
poses.insert<Pose3>(3, Pose3(Rot3(), Point3(1, -1, 0)));
|
||||||
|
poses.insert<Pose3>(4, Pose3(Rot3(), Point3(1, 2, 1)));
|
||||||
|
|
||||||
|
auto relativeTranslations = TranslationRecovery::SimulateMeasurements(
|
||||||
|
poses, {{0, 1}, {0, 3}, {1, 3}});
|
||||||
|
|
||||||
|
std::vector<BinaryMeasurement<Point3>> betweenTranslations;
|
||||||
|
betweenTranslations.emplace_back(0, 1, Point3(2, 0, 0),
|
||||||
|
noiseModel::Constrained::All(3, 1e2));
|
||||||
|
// Node 4 only has this between translation prior, no relative translations.
|
||||||
|
betweenTranslations.emplace_back(0, 4, Point3(1, 2, 1));
|
||||||
|
|
||||||
|
TranslationRecovery algorithm;
|
||||||
|
auto result =
|
||||||
|
algorithm.run(relativeTranslations, /*scale=*/0.0, betweenTranslations);
|
||||||
|
|
||||||
|
// Check result
|
||||||
|
EXPECT(assert_equal(Point3(0, 0, 0), result.at<Point3>(0), 1e-4));
|
||||||
|
EXPECT(assert_equal(Point3(2, 0, 0), result.at<Point3>(1), 1e-4));
|
||||||
|
EXPECT(assert_equal(Point3(1, -1, 0), result.at<Point3>(3), 1e-4));
|
||||||
|
EXPECT(assert_equal(Point3(1, 2, 1), result.at<Point3>(4), 1e-4));
|
||||||
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
int main() {
|
int main() {
|
||||||
TestResult tr;
|
TestResult tr;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue