commit
c66b227410
|
@ -172,6 +172,10 @@ if(WIN32) # Add 'lib' prefix to static library to avoid filename collision with
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(WIN32) # library to help with demangling variable names on Windows
|
||||||
|
target_link_libraries(gtsam PRIVATE Dbghelp)
|
||||||
|
endif()
|
||||||
|
|
||||||
install(
|
install(
|
||||||
TARGETS gtsam
|
TARGETS gtsam
|
||||||
EXPORT GTSAM-exports
|
EXPORT GTSAM-exports
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <gtsam/base/Manifold.h>
|
#include <gtsam/base/Manifold.h>
|
||||||
|
#include <gtsam/base/types.h>
|
||||||
#include <gtsam/base/Value.h>
|
#include <gtsam/base/Value.h>
|
||||||
|
|
||||||
#include <boost/make_shared.hpp>
|
#include <boost/make_shared.hpp>
|
||||||
|
@ -83,7 +84,7 @@ public:
|
||||||
|
|
||||||
/// Virtual print function, uses traits
|
/// Virtual print function, uses traits
|
||||||
virtual void print(const std::string& str) const {
|
virtual void print(const std::string& str) const {
|
||||||
std::cout << "(" << typeid(T).name() << ") ";
|
std::cout << "(" << demangle(typeid(T).name()) << ") ";
|
||||||
traits<T>::Print(value_, str);
|
traits<T>::Print(value_, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
/* ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
* GTSAM Copyright 2010, Georgia Tech Research Corporation,
|
||||||
|
* Atlanta, Georgia 30332-0415
|
||||||
|
* All Rights Reserved
|
||||||
|
* Authors: Frank Dellaert, et al. (see THANKS for the full author list)
|
||||||
|
|
||||||
|
* See LICENSE for the license information
|
||||||
|
|
||||||
|
* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file types.cpp
|
||||||
|
* @brief Functions for handling type information
|
||||||
|
* @author Varun Agrawal
|
||||||
|
* @date May 18, 2020
|
||||||
|
* @addtogroup base
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <gtsam/base/types.h>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <windows.h>
|
||||||
|
#include <DbgHelp.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __GNUG__
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cxxabi.h>
|
||||||
|
#include <string>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace gtsam {
|
||||||
|
|
||||||
|
/// Pretty print Value type name
|
||||||
|
std::string demangle(const char* name) {
|
||||||
|
// by default set to the original mangled name
|
||||||
|
std::string demangled_name = std::string(name);
|
||||||
|
|
||||||
|
#ifdef __GNUG__
|
||||||
|
// g++ version of demangle
|
||||||
|
char* demangled = nullptr;
|
||||||
|
int status = -1; // some arbitrary value to eliminate the compiler warning
|
||||||
|
demangled = abi::__cxa_demangle(name, nullptr, nullptr, &status),
|
||||||
|
|
||||||
|
demangled_name = (status == 0) ? std::string(demangled) : std::string(name);
|
||||||
|
|
||||||
|
std::free(demangled);
|
||||||
|
|
||||||
|
#elif _WIN32
|
||||||
|
char undecorated_name[1024];
|
||||||
|
|
||||||
|
if (UnDecorateSymbolName(
|
||||||
|
name, undecorated_name, sizeof(undecorated_name),
|
||||||
|
UNDNAME_COMPLETE))
|
||||||
|
{
|
||||||
|
// successful conversion, take value from: undecorated_name
|
||||||
|
demangled_name = std::string(undecorated_name);
|
||||||
|
}
|
||||||
|
// else keep using mangled name
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return demangled_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace gtsam */
|
|
@ -53,6 +53,9 @@
|
||||||
|
|
||||||
namespace gtsam {
|
namespace gtsam {
|
||||||
|
|
||||||
|
/// Function to demangle type name of variable, e.g. demangle(typeid(x).name())
|
||||||
|
std::string demangle(const char* name);
|
||||||
|
|
||||||
/// Integer nonlinear key type
|
/// Integer nonlinear key type
|
||||||
typedef std::uint64_t Key;
|
typedef std::uint64_t Key;
|
||||||
|
|
||||||
|
|
|
@ -232,10 +232,21 @@ namespace gtsam {
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
const char* ValuesIncorrectType::what() const throw() {
|
const char* ValuesIncorrectType::what() const throw() {
|
||||||
if(message_.empty())
|
if(message_.empty()) {
|
||||||
|
std::string storedTypeName = demangle(storedTypeId_.name());
|
||||||
|
std::string requestedTypeName = demangle(requestedTypeId_.name());
|
||||||
|
|
||||||
|
if (storedTypeName == requestedTypeName) {
|
||||||
|
message_ = "WARNING: Detected types with same name but different `typeid`. \
|
||||||
|
This is usually caused by incorrect linking/inlining settings when compiling libraries using GTSAM. \
|
||||||
|
If you are a user, please report to the author of the library using GTSAM. \
|
||||||
|
If you are a package maintainer, please consult `cmake/GtsamPybindWrap.cmake`, line 74 for details.";
|
||||||
|
} else {
|
||||||
message_ =
|
message_ =
|
||||||
"Attempting to retrieve value with key \"" + DefaultKeyFormatter(key_) + "\", type stored in Values is " +
|
"Attempting to retrieve value with key \"" + DefaultKeyFormatter(key_) + "\", type stored in Values is " +
|
||||||
std::string(storedTypeId_.name()) + " but requested type was " + std::string(requestedTypeId_.name());
|
storedTypeName + " but requested type was " + requestedTypeName;
|
||||||
|
}
|
||||||
|
}
|
||||||
return message_.c_str();
|
return message_.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,7 @@ public:
|
||||||
/// Streaming
|
/// Streaming
|
||||||
GTSAM_EXPORT
|
GTSAM_EXPORT
|
||||||
friend std::ostream& operator<<(std::ostream& os, const ExpressionNode& node) {
|
friend std::ostream& operator<<(std::ostream& os, const ExpressionNode& node) {
|
||||||
os << "Expression of type " << typeid(T).name();
|
os << "Expression of type " << demangle(typeid(T).name());
|
||||||
if (node.traceSize_ > 0) os << ", trace size = " << node.traceSize_;
|
if (node.traceSize_ > 0) os << ", trace size = " << node.traceSize_;
|
||||||
os << "\n";
|
os << "\n";
|
||||||
return os;
|
return os;
|
||||||
|
@ -219,7 +219,7 @@ static void PrintJacobianAndTrace(const std::string& indent,
|
||||||
const typename Jacobian<T, A>::type& dTdA,
|
const typename Jacobian<T, A>::type& dTdA,
|
||||||
const ExecutionTrace<A> trace) {
|
const ExecutionTrace<A> trace) {
|
||||||
static const Eigen::IOFormat kMatlabFormat(0, 1, " ", "; ", "", "", "[", "]");
|
static const Eigen::IOFormat kMatlabFormat(0, 1, " ", "; ", "", "", "[", "]");
|
||||||
std::cout << indent << "D(" << typeid(T).name() << ")/D(" << typeid(A).name()
|
std::cout << indent << "D(" << demangle(typeid(T).name()) << ")/D(" << demangle(typeid(A).name())
|
||||||
<< ") = " << dTdA.format(kMatlabFormat) << std::endl;
|
<< ") = " << dTdA.format(kMatlabFormat) << std::endl;
|
||||||
trace.print(indent);
|
trace.print(indent);
|
||||||
}
|
}
|
||||||
|
@ -605,7 +605,7 @@ class ScalarMultiplyNode : public ExpressionNode<T> {
|
||||||
/// Print to std::cout
|
/// Print to std::cout
|
||||||
void print(const std::string& indent) const {
|
void print(const std::string& indent) const {
|
||||||
std::cout << indent << "ScalarMultiplyNode::Record {" << std::endl;
|
std::cout << indent << "ScalarMultiplyNode::Record {" << std::endl;
|
||||||
std::cout << indent << "D(" << typeid(T).name() << ")/D(" << typeid(T).name()
|
std::cout << indent << "D(" << demangle(typeid(T).name()) << ")/D(" << demangle(typeid(T).name())
|
||||||
<< ") = " << scalar_dTdA << std::endl;
|
<< ") = " << scalar_dTdA << std::endl;
|
||||||
trace.print();
|
trace.print();
|
||||||
std::cout << indent << "}" << std::endl;
|
std::cout << indent << "}" << std::endl;
|
||||||
|
|
|
@ -589,6 +589,23 @@ TEST(Values, MatrixDynamicInsertFixedRead) {
|
||||||
CHECK_EXCEPTION(values.at<Matrix23>(key1), exception);
|
CHECK_EXCEPTION(values.at<Matrix23>(key1), exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Values, Demangle) {
|
||||||
|
Values values;
|
||||||
|
Matrix13 v; v << 5.0, 6.0, 7.0;
|
||||||
|
values.insert(key1, v);
|
||||||
|
string expected = "Values with 1 values:\nValue v1: (Eigen::Matrix<double, 1, 3, 1, 1, 3>) [\n 5, 6, 7\n]\n\n";
|
||||||
|
|
||||||
|
stringstream buffer;
|
||||||
|
streambuf * old = cout.rdbuf(buffer.rdbuf());
|
||||||
|
|
||||||
|
values.print();
|
||||||
|
|
||||||
|
string actual = buffer.str();
|
||||||
|
cout.rdbuf(old);
|
||||||
|
|
||||||
|
EXPECT(assert_equal(expected, actual));
|
||||||
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
int main() { TestResult tr; return TestRegistry::runAllTests(tr); }
|
int main() { TestResult tr; return TestRegistry::runAllTests(tr); }
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
|
Loading…
Reference in New Issue