diff --git a/.cproject b/.cproject
index 79cf43d60..7eaf0065f 100644
--- a/.cproject
+++ b/.cproject
@@ -340,6 +340,7 @@
make
+-j2
testVSLAMFactor.run
true
true
@@ -355,6 +356,7 @@
make
+-j2
testGaussianConditional.run
true
true
@@ -378,6 +380,7 @@
make
+-j2
testNonlinearOptimizer.run
true
true
@@ -401,6 +404,7 @@
make
+-j2
testNonlinearFactorGraph.run
true
true
@@ -416,6 +420,7 @@
make
+-j2
testVectorConfig.run
true
true
@@ -423,6 +428,7 @@
make
+-j2
testPoint2.run
true
true
@@ -462,6 +468,7 @@
make
+
testBayesTree.run
true
false
@@ -469,7 +476,6 @@
make
-
testSymbolicBayesNet.run
true
false
@@ -477,6 +483,7 @@
make
+
testSymbolicFactorGraph.run
true
false
@@ -500,6 +507,7 @@
make
+-j2
testVSLAMGraph.run
true
true
@@ -507,6 +515,7 @@
make
+-j2
testNonlinearEquality.run
true
true
@@ -522,6 +531,7 @@
make
+-j2
testNonlinearConstraint.run
true
true
@@ -561,6 +571,7 @@
make
+-j2
testControlGraph.run
true
true
@@ -576,6 +587,7 @@
make
+-j2
testPose2Constraint.run
true
true
@@ -599,6 +611,7 @@
make
+-j2
testPose3Factor.run
true
true
@@ -606,6 +619,7 @@
make
+-j2
testUrbanGraph.run
true
true
@@ -613,6 +627,7 @@
make
+-j2
testUrbanConfig.run
true
true
@@ -620,6 +635,7 @@
make
+-j2
testUrbanMeasurement.run
true
true
@@ -635,6 +651,7 @@
make
+-j2
testIterative.run
true
true
@@ -642,6 +659,7 @@
make
+-j2
testGaussianISAM2.run
true
true
@@ -665,6 +683,7 @@
make
+-j2
testPose2Factor.run
true
true
@@ -672,6 +691,7 @@
make
+-j2
timeRot3.run
true
true
@@ -679,6 +699,7 @@
make
+-j2
install
true
true
@@ -686,7 +707,6 @@
make
-
testPose2Graph.run
true
true
@@ -694,14 +714,30 @@
make
-
testPose2Config.run
true
true
true
+
+make
+-j2
+testPose3Config.run
+true
+true
+true
+
+
+make
+-j2
+testPose3Graph.run
+true
+true
+true
+
make
+-j2
install
true
true
@@ -709,6 +745,7 @@
make
+-j2
clean
true
true
@@ -716,6 +753,7 @@
make
+-j2
check
true
true
diff --git a/cpp/Makefile.am b/cpp/Makefile.am
index 170054092..5587cfd69 100644
--- a/cpp/Makefile.am
+++ b/cpp/Makefile.am
@@ -194,18 +194,27 @@ testSimulated3D_SOURCES = testSimulated3D.cpp
testSimulated3D_LDADD = libgtsam.la
check_PROGRAMS += testSimulated3D
-# Pose constraints
-headers += BetweenFactor.h Pose2Factor.h Pose2Prior.h Pose3Factor.h
+# 2D Pose constraints
+headers += BetweenFactor.h Pose2Factor.h Pose2Prior.h
sources += Pose2Config.cpp Pose2Graph.cpp
-check_PROGRAMS += testPose2Factor testPose2Config testPose2Graph testPose3Factor
+check_PROGRAMS += testPose2Factor testPose2Config testPose2Graph
testPose2Factor_SOURCES = $(example) testPose2Factor.cpp
testPose2Factor_LDADD = libgtsam.la
testPose2Config_SOURCES = $(example) testPose2Config.cpp
testPose2Config_LDADD = libgtsam.la
testPose2Graph_SOURCES = $(example) testPose2Graph.cpp
testPose2Graph_LDADD = libgtsam.la
+
+# 3D Pose constraints
+headers += Pose3Factor.h
+sources += Pose3Config.cpp Pose3Graph.cpp
+check_PROGRAMS += testPose3Factor testPose3Config testPose3Graph
testPose3Factor_SOURCES = $(example) testPose3Factor.cpp
testPose3Factor_LDADD = libgtsam.la
+testPose3Config_SOURCES = $(example) testPose3Config.cpp
+testPose3Config_LDADD = libgtsam.la
+testPose3Graph_SOURCES = $(example) testPose3Graph.cpp
+testPose3Graph_LDADD = libgtsam.la
# Cameras
sources += CalibratedCamera.cpp SimpleCamera.cpp
diff --git a/cpp/Pose3Config.cpp b/cpp/Pose3Config.cpp
new file mode 100644
index 000000000..b307959f2
--- /dev/null
+++ b/cpp/Pose3Config.cpp
@@ -0,0 +1,40 @@
+/**
+ * @file Pose3Config.cpp
+ * @brief Configuration of 3D poses
+ * @author Frank Dellaert
+ */
+
+#include "Pose3Config.h"
+#include "LieConfig-inl.h"
+
+using namespace std;
+
+namespace gtsam {
+
+ /** Explicit instantiation of templated methods and functions */
+ template class LieConfig;
+ template size_t dim(const LieConfig& c);
+ template LieConfig expmap(const LieConfig& c, const Vector& delta);
+ template LieConfig expmap(const LieConfig& c, const VectorConfig& delta);
+
+ /* ************************************************************************* */
+ // TODO: local version, should probably defined in LieConfig
+ static string symbol(char c, int index) {
+ stringstream ss;
+ ss << c << index;
+ return ss.str();
+ }
+
+ /* ************************************************************************* */
+ Pose3Config pose3Circle(size_t n, double R, char c) {
+ Pose3Config x;
+ double theta = 0, dtheta = 2*M_PI/n;
+ // Vehicle at p0 is looking towards y axis
+ Rot3 R0(Point3(0, 1, 0), Point3(1, 0, 0), Point3(0, 0, -1));
+ for (size_t i = 0; i < n; i++, theta += dtheta)
+ x.insert(symbol(c,i), Pose3(R0 * Rot3::yaw(-theta), Point3(cos(theta),sin(theta),0)));
+ return x;
+ }
+
+ /* ************************************************************************* */
+} // namespace
diff --git a/cpp/Pose3Config.h b/cpp/Pose3Config.h
new file mode 100644
index 000000000..655bc4cbe
--- /dev/null
+++ b/cpp/Pose3Config.h
@@ -0,0 +1,29 @@
+/**
+ * @file Pose3Config.cpp
+ * @brief Configuration of 3D poses
+ * @author Frank Dellaert
+ */
+
+#pragma once
+
+#include "Pose3.h"
+#include "LieConfig.h"
+
+namespace gtsam {
+
+ /**
+ * Pose3Config is now simply a typedef
+ */
+ typedef LieConfig Pose3Config;
+
+ /**
+ * Create a circle of n 3D poses tangent to circle of radius R, first pose at (R,0,0)
+ * The convention used is the Navlab/Aerospace convention: X-forward,Y-right,Z-down
+ * @param n number of poses
+ * @param R radius of circle
+ * @param c character to use for keys
+ * @return circle of n 2D poses
+ */
+ Pose3Config pose3Circle(size_t n, double R, char c = 'p');
+
+} // namespace
diff --git a/cpp/Pose3Factor.h b/cpp/Pose3Factor.h
index 7c386438a..03d891f79 100644
--- a/cpp/Pose3Factor.h
+++ b/cpp/Pose3Factor.h
@@ -5,18 +5,11 @@
#pragma once
-#include