Skip to content

Commit d94e50a

Browse files
authored
Merge pull request #1790 from garygra/develop
Adding test and fix for issue #1596
2 parents 5471192 + 6dfd567 commit d94e50a

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed

gtsam/symbolic/SymbolicFactor-inst.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ namespace gtsam
4242
// Gather all keys
4343
KeySet allKeys;
4444
for(const std::shared_ptr<FACTOR>& factor: factors) {
45-
allKeys.insert(factor->begin(), factor->end());
45+
// Non-active factors are nullptr
46+
if (factor)
47+
allKeys.insert(factor->begin(), factor->end());
4648
}
4749

4850
// Check keys

tests/testGaussianISAM2.cpp

+50
Original file line numberDiff line numberDiff line change
@@ -994,6 +994,56 @@ TEST(ISAM2, calculate_nnz)
994994
EXPECT_LONGS_EQUAL(expected, actual);
995995
}
996996

997+
class FixActiveFactor : public NoiseModelFactorN<Vector2> {
998+
using Base = NoiseModelFactorN<Vector2>;
999+
bool is_active_;
1000+
1001+
public:
1002+
FixActiveFactor(const gtsam::Key& key, const bool active)
1003+
: Base(nullptr, key), is_active_(active) {}
1004+
1005+
virtual bool active(const gtsam::Values &values) const override {
1006+
return is_active_;
1007+
}
1008+
1009+
virtual Vector
1010+
evaluateError(const Vector2& x,
1011+
Base::OptionalMatrixTypeT<Vector2> H = nullptr) const override {
1012+
if (H) {
1013+
*H = Vector2::Identity();
1014+
}
1015+
return Vector2::Zero();
1016+
}
1017+
};
1018+
1019+
TEST(ActiveFactorTesting, Issue1596) {
1020+
// Issue1596: When a derived Nonlinear Factor is not active, the linearization returns a nullptr (NonlinearFactor.cpp:156), which
1021+
// causes an error when `EliminateSymbolic` is called (SymbolicFactor-inst.h:45) due to not checking if the factor is nullptr.
1022+
const gtsam::Key key{Symbol('x', 0)};
1023+
1024+
ISAM2 isam;
1025+
Values values;
1026+
NonlinearFactorGraph graph;
1027+
1028+
// Insert an active factor
1029+
values.insert<Vector2>(key, Vector2::Zero());
1030+
graph.emplace_shared<FixActiveFactor>(key, true);
1031+
1032+
// No problem here
1033+
isam.update(graph, values);
1034+
1035+
graph = NonlinearFactorGraph();
1036+
1037+
// Inserting a factor that is never active
1038+
graph.emplace_shared<FixActiveFactor>(key, false);
1039+
1040+
// This call throws the error if the pointer is not validated on (SymbolicFactor-inst.h:45)
1041+
isam.update(graph);
1042+
1043+
// If the bug is fixed, this line is reached.
1044+
EXPECT(isam.getFactorsUnsafe().size() == 2);
1045+
}
1046+
9971047
/* ************************************************************************* */
9981048
int main() { TestResult tr; return TestRegistry::runAllTests(tr);}
9991049
/* ************************************************************************* */

0 commit comments

Comments
 (0)