Merge pull request #358 from borglab/feature/rot-print

Consistent Rot3 printing
release/4.3a0
Varun Agrawal 2020-07-28 09:56:37 -04:00 committed by GitHub
commit c985701fdc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 54 additions and 43 deletions

View File

@ -136,20 +136,24 @@ Vector operator^(const Matrix& A, const Vector & v) {
return A.transpose() * v; return A.transpose() * v;
} }
const Eigen::IOFormat& matlabFormat() {
static const Eigen::IOFormat matlab(
Eigen::StreamPrecision, // precision
Eigen::DontAlignCols, // flags set such that rowSpacers are not added
", ", // coeffSeparator
";\n", // rowSeparator
"\t", // rowPrefix
"", // rowSuffix
"[\n", // matPrefix
"\n]" // matSuffix
);
return matlab;
}
/* ************************************************************************* */ /* ************************************************************************* */
//3 argument call //3 argument call
void print(const Matrix& A, const string &s, ostream& stream) { void print(const Matrix& A, const string &s, ostream& stream) {
static const Eigen::IOFormat matlab( cout << s << A.format(matlabFormat()) << endl;
Eigen::StreamPrecision, // precision
0, // flags
", ", // coeffSeparator
";\n", // rowSeparator
"\t", // rowPrefix
"", // rowSuffix
"[\n", // matPrefix
"\n]" // matSuffix
);
cout << s << A.format(matlab) << endl;
} }
/* ************************************************************************* */ /* ************************************************************************* */

View File

@ -76,6 +76,10 @@ GTSAM_MAKE_MATRIX_DEFS(9);
typedef Eigen::Block<Matrix> SubMatrix; typedef Eigen::Block<Matrix> SubMatrix;
typedef Eigen::Block<const Matrix> ConstSubMatrix; typedef Eigen::Block<const Matrix> ConstSubMatrix;
// Matrix formatting arguments when printing.
// Akin to Matlab style.
const Eigen::IOFormat& matlabFormat();
/** /**
* equals with a tolerance * equals with a tolerance
*/ */

View File

@ -106,9 +106,7 @@ Vector6 Pose3::adjointTranspose(const Vector6& xi, const Vector6& y,
/* ************************************************************************* */ /* ************************************************************************* */
void Pose3::print(const string& s) const { void Pose3::print(const string& s) const {
cout << s; cout << (s.empty() ? s : s + " ") << *this << endl;
R_.print("R:\n");
cout << t_ << ";" << endl;
} }
/* ************************************************************************* */ /* ************************************************************************* */
@ -439,9 +437,9 @@ boost::optional<Pose3> align(const vector<Point3Pair>& baPointPairs) {
/* ************************************************************************* */ /* ************************************************************************* */
std::ostream &operator<<(std::ostream &os, const Pose3& pose) { std::ostream &operator<<(std::ostream &os, const Pose3& pose) {
os << pose.rotation() << "\n"; // Both Rot3 and Point3 have ostream definitions so we use them.
const Point3& t = pose.translation(); os << "R: " << pose.rotation() << "\n";
os << '[' << t.x() << ", " << t.y() << ", " << t.z() << "]\';\n"; os << "t: " << pose.translation();
return os; return os;
} }

View File

@ -32,7 +32,8 @@ namespace gtsam {
/* ************************************************************************* */ /* ************************************************************************* */
void Rot3::print(const std::string& s) const { void Rot3::print(const std::string& s) const {
gtsam::print((Matrix)matrix(), s); cout << (s.empty() ? "R: " : s + " ");
gtsam::print(static_cast<Matrix>(matrix()));
} }
/* ************************************************************************* */ /* ************************************************************************* */
@ -222,10 +223,7 @@ pair<Matrix3, Vector3> RQ(const Matrix3& A) {
/* ************************************************************************* */ /* ************************************************************************* */
ostream &operator<<(ostream &os, const Rot3& R) { ostream &operator<<(ostream &os, const Rot3& R) {
os << "\n"; os << R.matrix().format(matlabFormat());
os << '|' << R.r1().x() << ", " << R.r2().x() << ", " << R.r3().x() << "|\n";
os << '|' << R.r1().y() << ", " << R.r2().y() << ", " << R.r3().y() << "|\n";
os << '|' << R.r1().z() << ", " << R.r2().z() << ", " << R.r3().z() << "|\n";
return os; return os;
} }

View File

@ -254,7 +254,7 @@ namespace gtsam {
/// @{ /// @{
/** print */ /** print */
void print(const std::string& s="R") const; void print(const std::string& s="") const;
/** equals with an tolerance */ /** equals with an tolerance */
bool equals(const Rot3& p, double tol = 1e-9) const; bool equals(const Rot3& p, double tol = 1e-9) const;

View File

@ -862,7 +862,8 @@ TEST( Pose3, stream)
Pose3 T; Pose3 T;
std::ostringstream os; std::ostringstream os;
os << T; os << T;
EXPECT(os.str() == "\n|1, 0, 0|\n|0, 1, 0|\n|0, 0, 1|\n\n[0, 0, 0]';\n"); string expected = "R: [\n\t1, 0, 0;\n\t0, 1, 0;\n\t0, 0, 1\n]\nt: [0, 0, 0]'";
EXPECT(os.str() == expected);
} }
//****************************************************************************** //******************************************************************************
@ -1032,19 +1033,22 @@ TEST(Pose3, print) {
std::stringstream expected; std::stringstream expected;
Point3 translation(1, 2, 3); Point3 translation(1, 2, 3);
// Add expected rotation
expected << "R: [\n\t1, 0, 0;\n\t0, 1, 0;\n\t0, 0, 1\n]\n";
#ifdef GTSAM_TYPEDEF_POINTS_TO_VECTORS #ifdef GTSAM_TYPEDEF_POINTS_TO_VECTORS
expected << "1\n" expected << "1\n"
"2\n" "2\n"
"3;\n"; "3;\n";
#else #else
expected << '[' << translation.x() << ", " << translation.y() << ", " << translation.z() << "]\';"; expected << "t: [" << translation.x() << ", " << translation.y() << ", " << translation.z() << "]'\n";
#endif #endif
// reset cout to the original stream // reset cout to the original stream
std::cout.rdbuf(oldbuf); std::cout.rdbuf(oldbuf);
// Get substring corresponding to translation part // Get substring corresponding to translation part
std::string actual = redirectStream.str().substr(38, 11); std::string actual = redirectStream.str();
CHECK_EQUAL(expected.str(), actual); CHECK_EQUAL(expected.str(), actual);
} }

View File

@ -608,7 +608,8 @@ TEST( Rot3, stream)
Rot3 R; Rot3 R;
std::ostringstream os; std::ostringstream os;
os << R; os << R;
EXPECT(os.str() == "\n|1, 0, 0|\n|0, 1, 0|\n|0, 0, 1|\n"); string expected = "[\n\t1, 0, 0;\n\t0, 1, 0;\n\t0, 0, 1\n]";
EXPECT(os.str() == expected);
} }
/* ************************************************************************* */ /* ************************************************************************* */

View File

@ -421,21 +421,11 @@ JacobianFactor::JacobianFactor(const GaussianFactorGraph& graph,
/* ************************************************************************* */ /* ************************************************************************* */
void JacobianFactor::print(const string& s, void JacobianFactor::print(const string& s,
const KeyFormatter& formatter) const { const KeyFormatter& formatter) const {
static const Eigen::IOFormat matlab(
Eigen::StreamPrecision, // precision
0, // flags
" ", // coeffSeparator
";\n", // rowSeparator
"\t", // rowPrefix
"", // rowSuffix
"[\n", // matPrefix
"\n ]" // matSuffix
);
if (!s.empty()) if (!s.empty())
cout << s << "\n"; cout << s << "\n";
for (const_iterator key = begin(); key != end(); ++key) { for (const_iterator key = begin(); key != end(); ++key) {
cout << boost::format(" A[%1%] = ") % formatter(*key); cout << boost::format(" A[%1%] = ") % formatter(*key);
cout << getA(key).format(matlab) << endl; cout << getA(key).format(matlabFormat()) << endl;
} }
cout << formatMatrixIndented(" b = ", getb(), true) << "\n"; cout << formatMatrixIndented(" b = ", getb(), true) << "\n";
if (model_) if (model_)

View File

@ -88,15 +88,15 @@ Matrix7 NavState::matrix() const {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
ostream& operator<<(ostream& os, const NavState& state) { ostream& operator<<(ostream& os, const NavState& state) {
os << "R:" << state.attitude(); os << "R: " << state.attitude() << "\n";
os << "p:" << state.position() << endl; os << "p: " << state.position() << "\n";
os << "v:" << Point3(state.velocity()) << endl; os << "v: " << Point3(state.velocity());
return os; return os;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void NavState::print(const string& s) const { void NavState::print(const string& s) const {
cout << s << *this << endl; cout << (s.empty() ? s : s + " ") << *this << endl;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------

View File

@ -237,6 +237,18 @@ TEST(NavState, CorrectPIM) {
EXPECT(assert_equal(numericalDerivative22(correctPIM, kState1, xi), aH2)); EXPECT(assert_equal(numericalDerivative22(correctPIM, kState1, xi), aH2));
} }
/* ************************************************************************* */
TEST(NavState, Stream)
{
NavState state;
std::ostringstream os;
os << state;
string expected = "R: [\n\t1, 0, 0;\n\t0, 1, 0;\n\t0, 0, 1\n]\np: [0, 0, 0]'\nv: [0, 0, 0]'";
EXPECT(os.str() == expected);
}
/* ************************************************************************* */ /* ************************************************************************* */
int main() { int main() {
TestResult tr; TestResult tr;

View File

@ -131,7 +131,7 @@ TEST(FunctorizedFactor, Print) {
"FunctorizedFactor(X0)\n" "FunctorizedFactor(X0)\n"
" measurement: [\n" " measurement: [\n"
" 1, 0;\n" " 1, 0;\n"
" 0, 1\n" " 0, 1\n"
"]\n" "]\n"
" noise model sigmas: 1 1 1 1 1 1 1 1 1\n"; " noise model sigmas: 1 1 1 1 1 1 1 1 1\n";