From dda625b2e0fc148f032d05a6cf8486284aef0edf Mon Sep 17 00:00:00 2001 From: Frank Dellaert Date: Sun, 22 Jul 2012 18:46:35 +0000 Subject: [PATCH 01/11] Compile error on Mac, added "this->" --- gtsam/base/FastVector.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gtsam/base/FastVector.h b/gtsam/base/FastVector.h index f55d67b41..33bc5cb7c 100644 --- a/gtsam/base/FastVector.h +++ b/gtsam/base/FastVector.h @@ -90,7 +90,7 @@ public: /** Conversion to a standard STL container */ operator std::vector() const { - return std::vector(begin(), end()); + return std::vector(this->begin(), this->end()); } private: From 46b2971e459d78f89ef2652cdac3735d761a24f4 Mon Sep 17 00:00:00 2001 From: Alex Cunningham Date: Sun, 22 Jul 2012 18:49:07 +0000 Subject: [PATCH 02/11] Removed imu dynamics example slam namespace --- gtsam_unstable/dynamics/imuSystem.cpp | 63 --------------- gtsam_unstable/dynamics/imuSystem.h | 78 ------------------- .../dynamics/tests/testIMUSystem.cpp | 74 +++++++++++------- .../dynamics/tests/testVelocityConstraint.cpp | 4 +- gtsam_unstable/gtsam_unstable.h | 39 +--------- 5 files changed, 48 insertions(+), 210 deletions(-) delete mode 100644 gtsam_unstable/dynamics/imuSystem.cpp delete mode 100644 gtsam_unstable/dynamics/imuSystem.h diff --git a/gtsam_unstable/dynamics/imuSystem.cpp b/gtsam_unstable/dynamics/imuSystem.cpp deleted file mode 100644 index 376868583..000000000 --- a/gtsam_unstable/dynamics/imuSystem.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/** - * @file ilm3DSystem.cpp - * @brief Implementations of ilm 3D domain - * @author Alex Cunningham - */ - -#include -#include - -namespace imu { - -using namespace gtsam; - -/* ************************************************************************* */ -void Graph::addPrior(Key key, const PoseRTV& pose, const SharedNoiseModel& noiseModel) { - add(Prior(key, pose, noiseModel)); -} - -/* ************************************************************************* */ -void Graph::addConstraint(Key key, const PoseRTV& pose) { - add(Constraint(key, pose)); -} - -/* ************************************************************************* */ -void Graph::addHeightPrior(Key key, double z, const SharedNoiseModel& noiseModel) { - add(DHeightPrior(key, z, noiseModel)); -} - -/* ************************************************************************* */ -void Graph::addFullIMUMeasurement(Key key1, Key key2, - const Vector& accel, const Vector& gyro, double dt, const SharedNoiseModel& noiseModel) { - add(FullIMUMeasurement(accel, gyro, dt, key1, key2, noiseModel)); -} - -/* ************************************************************************* */ -void Graph::addIMUMeasurement(Key key1, Key key2, - const Vector& accel, const Vector& gyro, double dt, const SharedNoiseModel& noiseModel) { - add(IMUMeasurement(accel, gyro, dt, key1, key2, noiseModel)); -} - -/* ************************************************************************* */ -void Graph::addVelocityConstraint(Key key1, Key key2, double dt, const SharedNoiseModel& noiseModel) { - add(VelocityConstraint(key1, key2, dt, noiseModel)); -} - -/* ************************************************************************* */ -void Graph::addBetween(Key key1, Key key2, const PoseRTV& z, const SharedNoiseModel& noiseModel) { - add(Between(key1, key2, z, noiseModel)); -} - -/* ************************************************************************* */ -void Graph::addRange(Key key1, Key key2, double z, const SharedNoiseModel& noiseModel) { - add(Range(key1, key2, z, noiseModel)); -} - -/* ************************************************************************* */ -Values Graph::optimize(const Values& init) const { - return LevenbergMarquardtOptimizer(*this, init).optimize(); -} -/* ************************************************************************* */ - -} // \namespace imu - diff --git a/gtsam_unstable/dynamics/imuSystem.h b/gtsam_unstable/dynamics/imuSystem.h deleted file mode 100644 index ef5437fdf..000000000 --- a/gtsam_unstable/dynamics/imuSystem.h +++ /dev/null @@ -1,78 +0,0 @@ -/** - * @file imuSystem.h - * @brief A 3D Dynamic system domain as a demonstration of IMU factors - * @author Alex Cunningham - */ - -#pragma once - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -/** - * This domain focuses on a single class of variables: PoseRTV, which - * models a dynamic pose operating with IMU measurements and assorted priors. - * - * There are also partial priors that constraint certain components of the - * poses, as well as between and range factors to model other between-pose - * information. - */ -namespace imu { - -struct Values : public gtsam::Values { - typedef gtsam::Values Base; - - Values() {} - Values(const Values& values) : Base(values) {} - Values(const Base& values) : Base(values) {} - - void insertPose(gtsam::Key key, const gtsam::PoseRTV& pose) { insert(key, pose); } - gtsam::PoseRTV pose(gtsam::Key key) const { return at(key); } -}; - -// factors -typedef gtsam::IMUFactor IMUMeasurement; // IMU between measurements -typedef gtsam::FullIMUFactor FullIMUMeasurement; // Full-state IMU between measurements -typedef gtsam::BetweenFactor Between; // full odometry (including velocity) -typedef gtsam::NonlinearEquality Constraint; -typedef gtsam::PriorFactor Prior; -typedef gtsam::RangeFactor Range; - -// graph components -struct Graph : public gtsam::NonlinearFactorGraph { - typedef gtsam::NonlinearFactorGraph Base; - - Graph() {} - Graph(const Base& graph) : Base(graph) {} - Graph(const Graph& graph) : Base(graph) {} - - // prior factors - void addPrior(size_t key, const gtsam::PoseRTV& pose, const gtsam::SharedNoiseModel& noiseModel); - void addConstraint(size_t key, const gtsam::PoseRTV& pose); - void addHeightPrior(size_t key, double z, const gtsam::SharedNoiseModel& noiseModel); - - // inertial factors - void addFullIMUMeasurement(size_t key1, size_t key2, const gtsam::Vector& accel, const gtsam::Vector& gyro, double dt, const gtsam::SharedNoiseModel& noiseModel); - void addIMUMeasurement(size_t key1, size_t key2, const gtsam::Vector& accel, const gtsam::Vector& gyro, double dt, const gtsam::SharedNoiseModel& noiseModel); - void addVelocityConstraint(size_t key1, size_t key2, double dt, const gtsam::SharedNoiseModel& noiseModel); - - // other measurements - void addBetween(size_t key1, size_t key2, const gtsam::PoseRTV& z, const gtsam::SharedNoiseModel& noiseModel); - void addRange(size_t key1, size_t key2, double z, const gtsam::SharedNoiseModel& noiseModel); - - // optimization - Values optimize(const Values& init) const; -}; - -} // \namespace imu - diff --git a/gtsam_unstable/dynamics/tests/testIMUSystem.cpp b/gtsam_unstable/dynamics/tests/testIMUSystem.cpp index 783c420d4..2f6b8b201 100644 --- a/gtsam_unstable/dynamics/tests/testIMUSystem.cpp +++ b/gtsam_unstable/dynamics/tests/testIMUSystem.cpp @@ -7,23 +7,37 @@ #include -#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include using namespace std; using namespace gtsam; -using namespace imu; const double tol=1e-5; static const Key x0 = 0, x1 = 1, x2 = 2, x3 = 3, x4 = 4; static const Vector g = delta(3, 2, -9.81); +//typedef gtsam::IMUFactor IMUFactor; // IMU between measurements +//typedef gtsam::FullIMUFactor IMUFactor; // Full-state IMU between measurements +//typedef gtsam::BetweenFactor Between; // full odometry (including velocity) +//typedef gtsam::NonlinearEquality Constraint; +//typedef gtsam::PriorFactor Prior; +//typedef gtsam::RangeFactor Range; + /* ************************************************************************* */ TEST(testIMUSystem, instantiations) { // just checking for compilation PoseRTV x1_v; - imu::Values local_values; - Graph graph; gtsam::SharedNoiseModel model1 = gtsam::noiseModel::Unit::Create(1); gtsam::SharedNoiseModel model3 = gtsam::noiseModel::Unit::Create(3); @@ -32,13 +46,13 @@ TEST(testIMUSystem, instantiations) { Vector accel = ones(3), gyro = ones(3); - IMUMeasurement imu(accel, gyro, 0.01, x1, x2, model6); - FullIMUMeasurement full_imu(accel, gyro, 0.01, x1, x2, model9); - Constraint poseHardPrior(x1, x1_v); - Between odom(x1, x2, x1_v, model9); - Range range(x1, x2, 1.0, model1); + IMUFactor imu(accel, gyro, 0.01, x1, x2, model6); + FullIMUFactor full_imu(accel, gyro, 0.01, x1, x2, model9); + NonlinearEquality poseHardPrior(x1, x1_v); + BetweenFactor odom(x1, x2, x1_v, model9); + RangeFactor range(x1, x2, 1.0, model1); VelocityConstraint constraint(x1, x2, 0.1, 10000); - Prior posePrior(x1, x1_v, model9); + PriorFactor posePrior(x1, x1_v, model9); DHeightPrior heightPrior(x1, 0.1, model1); VelocityPrior velPrior(x1, ones(3), model3); } @@ -60,17 +74,17 @@ TEST( testIMUSystem, optimize_chain ) { imu34 = pose3.imuPrediction(pose4, dt); // assemble simple graph with IMU measurements and velocity constraints - Graph graph; - graph.add(Constraint(x1, pose1)); - graph.add(IMUMeasurement(imu12, dt, x1, x2, model)); - graph.add(IMUMeasurement(imu23, dt, x2, x3, model)); - graph.add(IMUMeasurement(imu34, dt, x3, x4, model)); + EasyFactorGraph graph; + graph.add(NonlinearEquality(x1, pose1)); + graph.add(IMUFactor(imu12, dt, x1, x2, model)); + graph.add(IMUFactor(imu23, dt, x2, x3, model)); + graph.add(IMUFactor(imu34, dt, x3, x4, model)); graph.add(VelocityConstraint(x1, x2, dt)); graph.add(VelocityConstraint(x2, x3, dt)); graph.add(VelocityConstraint(x3, x4, dt)); // ground truth values - imu::Values true_values; + Values true_values; true_values.insert(x1, pose1); true_values.insert(x2, pose2); true_values.insert(x3, pose3); @@ -80,13 +94,13 @@ TEST( testIMUSystem, optimize_chain ) { EXPECT_DOUBLES_EQUAL(0, graph.error(true_values), 1e-5); // initialize with zero values and optimize - imu::Values values; + Values values; values.insert(x1, PoseRTV()); values.insert(x2, PoseRTV()); values.insert(x3, PoseRTV()); values.insert(x4, PoseRTV()); - imu::Values actual = graph.optimize(values); + Values actual = graph.optimize(values); EXPECT(assert_equal(true_values, actual, tol)); } @@ -107,14 +121,14 @@ TEST( testIMUSystem, optimize_chain_fullfactor ) { imu34 = pose3.imuPrediction(pose4, dt); // assemble simple graph with IMU measurements and velocity constraints - Graph graph; - graph.add(Constraint(x1, pose1)); - graph.add(FullIMUMeasurement(imu12, dt, x1, x2, model)); - graph.add(FullIMUMeasurement(imu23, dt, x2, x3, model)); - graph.add(FullIMUMeasurement(imu34, dt, x3, x4, model)); + EasyFactorGraph graph; + graph.add(NonlinearEquality(x1, pose1)); + graph.add(FullIMUFactor(imu12, dt, x1, x2, model)); + graph.add(FullIMUFactor(imu23, dt, x2, x3, model)); + graph.add(FullIMUFactor(imu34, dt, x3, x4, model)); // ground truth values - imu::Values true_values; + Values true_values; true_values.insert(x1, pose1); true_values.insert(x2, pose2); true_values.insert(x3, pose3); @@ -124,7 +138,7 @@ TEST( testIMUSystem, optimize_chain_fullfactor ) { EXPECT_DOUBLES_EQUAL(0, graph.error(true_values), 1e-5); // initialize with zero values and optimize - imu::Values values; + Values values; values.insert(x1, PoseRTV()); values.insert(x2, PoseRTV()); values.insert(x3, PoseRTV()); @@ -132,7 +146,7 @@ TEST( testIMUSystem, optimize_chain_fullfactor ) { cout << "Initial Error: " << graph.error(values) << endl; // Initial error is 0.5 - need better prediction model - imu::Values actual = graph.optimize(values); + Values actual = graph.optimize(values); // EXPECT(assert_equal(true_values, actual, tol)); // FAIL } @@ -147,10 +161,10 @@ TEST( testIMUSystem, linear_trajectory) { Vector gyro = delta(3, 0, 0.1); // constant rotation SharedDiagonal model = noiseModel::Unit::Create(9); - imu::Values true_traj, init_traj; - Graph graph; + Values true_traj, init_traj; + EasyFactorGraph graph; - graph.add(Constraint(x0, start)); + graph.add(NonlinearEquality(x0, start)); true_traj.insert(x0, start); init_traj.insert(x0, start); @@ -159,7 +173,7 @@ TEST( testIMUSystem, linear_trajectory) { for (size_t i=1; i(accel - g, gyro, dt, xA, xB, model)); true_traj.insert(xB, cur_pose); init_traj.insert(xB, PoseRTV()); } diff --git a/gtsam_unstable/dynamics/tests/testVelocityConstraint.cpp b/gtsam_unstable/dynamics/tests/testVelocityConstraint.cpp index 61588841d..ea4a3493d 100644 --- a/gtsam_unstable/dynamics/tests/testVelocityConstraint.cpp +++ b/gtsam_unstable/dynamics/tests/testVelocityConstraint.cpp @@ -4,10 +4,10 @@ */ #include -#include + +#include using namespace gtsam; -using namespace imu; const double tol=1e-5; diff --git a/gtsam_unstable/gtsam_unstable.h b/gtsam_unstable/gtsam_unstable.h index c77c71e22..a14ad34f9 100644 --- a/gtsam_unstable/gtsam_unstable.h +++ b/gtsam_unstable/gtsam_unstable.h @@ -102,7 +102,7 @@ virtual class NonlinearEquality : gtsam::NonlinearFactor { NonlinearEquality(size_t j, const T& feasible, double error_gain); }; - +#include template virtual class IMUFactor : gtsam::NonlinearFactor { /** Standard constructor */ @@ -120,7 +120,7 @@ virtual class IMUFactor : gtsam::NonlinearFactor { size_t key2() const; }; - +#include template virtual class FullIMUFactor : gtsam::NonlinearFactor { /** Standard constructor */ @@ -167,38 +167,3 @@ virtual class DGroundConstraint : gtsam::NonlinearFactor { }///\namespace gtsam - -namespace imu { - -#include -class Values { - Values(); - void print(string s) const; - - void insertPose(size_t key, const gtsam::PoseRTV& pose); - gtsam::PoseRTV pose(size_t key) const; -}; - -class Graph { - Graph(); - void print(string s) const; - - // prior factors - void addPrior(size_t key, const gtsam::PoseRTV& pose, const gtsam::noiseModel::Base* noiseModel); - void addConstraint(size_t key, const gtsam::PoseRTV& pose); - void addHeightPrior(size_t key, double z, const gtsam::noiseModel::Base* noiseModel); - - // inertial factors - void addFullIMUMeasurement(size_t key1, size_t key2, const Vector& accel, const Vector& gyro, double dt, const gtsam::noiseModel::Base* noiseModel); - void addIMUMeasurement(size_t key1, size_t key2, const Vector& accel, const Vector& gyro, double dt, const gtsam::noiseModel::Base* noiseModel); - void addVelocityConstraint(size_t key1, size_t key2, double dt, const gtsam::noiseModel::Base* noiseModel); - - // other measurements - void addBetween(size_t key1, size_t key2, const gtsam::PoseRTV& z, const gtsam::noiseModel::Base* noiseModel); - void addRange(size_t key1, size_t key2, double z, const gtsam::noiseModel::Base* noiseModel); - - // optimization - imu::Values optimize(const imu::Values& init) const; -}; - -}///\namespace imu From 26fce2d400b14edc50930eb05bde1e392c86f1ee Mon Sep 17 00:00:00 2001 From: Alex Cunningham Date: Mon, 23 Jul 2012 14:09:40 +0000 Subject: [PATCH 03/11] Adding support for global functions - parsing works --- wrap/GlobalFunction.cpp | 29 ++++++++++++++++++++++++++++ wrap/GlobalFunction.h | 42 +++++++++++++++++++++++++++++++++++++++++ wrap/Module.cpp | 32 ++++++++++++++++++++++--------- wrap/Module.h | 4 ++++ wrap/tests/geometry.h | 3 +++ 5 files changed, 101 insertions(+), 9 deletions(-) create mode 100644 wrap/GlobalFunction.cpp create mode 100644 wrap/GlobalFunction.h diff --git a/wrap/GlobalFunction.cpp b/wrap/GlobalFunction.cpp new file mode 100644 index 000000000..e20a1f2f2 --- /dev/null +++ b/wrap/GlobalFunction.cpp @@ -0,0 +1,29 @@ +/** + * @file GlobalFunction.cpp + * + * @date Jul 22, 2012 + * @author Alex Cunningham + */ + +#include "GlobalFunction.h" + +namespace wrap { + +/* ************************************************************************* */ +void GlobalFunction::addOverload(bool verbose, const std::string& name, + const ArgumentList& args, const ReturnValue& retVal, const StrVec& ns_stack) { + this->verbose_ = verbose; + this->name = name; + this->argLists.push_back(args); + this->returnVals.push_back(retVal); + this->namespaces.push_back(ns_stack); +} + +/* ************************************************************************* */ + + +} // \namespace wrap + + + + diff --git a/wrap/GlobalFunction.h b/wrap/GlobalFunction.h new file mode 100644 index 000000000..0899bbdc9 --- /dev/null +++ b/wrap/GlobalFunction.h @@ -0,0 +1,42 @@ +/** + * @file GlobalFunction.h + * + * @brief Implements codegen for a global function wrapped in matlab + * + * @date Jul 22, 2012 + * @author Alex Cunningham + */ + +#pragma once + +#include "Argument.h" +#include "ReturnValue.h" + +namespace wrap { + +struct GlobalFunction { + + typedef std::vector StrVec; + + bool verbose_; + std::string name; + + // each overload, regardless of namespace + std::vector argLists; ///< arugments for each overload + std::vector returnVals; ///< returnVals for each overload + std::vector namespaces; ///< Stack of namespaces + + // Constructor only used in Module + GlobalFunction(bool verbose = true) : verbose_(verbose) {} + + // adds an overloaded version of this function + void addOverload(bool verbose, const std::string& name, + const ArgumentList& args, const ReturnValue& retVal, const StrVec& ns_stack); + +}; + +} // \namespace wrap + + + + diff --git a/wrap/Module.cpp b/wrap/Module.cpp index 1f077b31f..786a4de78 100644 --- a/wrap/Module.cpp +++ b/wrap/Module.cpp @@ -79,10 +79,10 @@ Module::Module(const string& interfacePath, vector arg_dup; ///keep track of duplicates Constructor constructor0(enable_verbose), constructor(enable_verbose); Deconstructor deconstructor0(enable_verbose), deconstructor(enable_verbose); - //Method method0(enable_verbose), method(enable_verbose); StaticMethod static_method0(enable_verbose), static_method(enable_verbose); Class cls0(enable_verbose),cls(enable_verbose); - ForwardDeclaration fwDec0, fwDec; + GlobalFunction globalFunc0(enable_verbose), globalFunc(enable_verbose); + ForwardDeclaration fwDec0, fwDec; vector namespaces, /// current namespace tag namespaces_return, /// namespace for current return type using_namespace_current; /// All namespaces from "using" declarations @@ -261,12 +261,12 @@ Module::Module(const string& interfacePath, >> ((':' >> classParent_p >> '{') | '{') >> *(functions_p | comments_p) >> str_p("};")) - [assign_a(constructor.name, cls.name)] - [assign_a(cls.constructor, constructor)] + [assign_a(constructor.name, cls.name)] + [assign_a(cls.constructor, constructor)] [assign_a(cls.namespaces, namespaces)] - [assign_a(cls.using_namespaces, using_namespace_current)] - [assign_a(deconstructor.name,cls.name)] - [assign_a(cls.deconstructor, deconstructor)] + [assign_a(cls.using_namespaces, using_namespace_current)] + [assign_a(deconstructor.name,cls.name)] + [assign_a(cls.deconstructor, deconstructor)] [bl::bind(&handle_possible_template, bl::var(classes), bl::var(cls), bl::var(templateArgument), bl::var(templateInstantiations))] [assign_a(deconstructor,deconstructor0)] [assign_a(constructor, constructor0)] @@ -274,6 +274,20 @@ Module::Module(const string& interfacePath, [clear_a(templateArgument)] [clear_a(templateInstantiations)]; + Rule global_function_p = + (returnType_p >> staticMethodName_p[assign_a(methodName)] >> + '(' >> argumentList_p >> ')' >> ';' >> *comments_p) + [bl::bind(&GlobalFunction::addOverload, + bl::var(global_functions)[bl::var(methodName)], + verbose, + bl::var(methodName), + bl::var(args), + bl::var(retVal), + bl::var(namespaces))] + [assign_a(methodName,methodName0)] + [assign_a(args,args0)] + [assign_a(retVal,retVal0)]; + Rule include_p = str_p("#include") >> ch_p('<') >> (*(anychar_p - '>'))[push_back_a(includes)] >> ch_p('>'); Rule namespace_def_p = @@ -281,7 +295,7 @@ Module::Module(const string& interfacePath, >> namespace_name_p[push_back_a(namespaces)] >> ch_p('{') >> *(include_p | class_p | templateSingleInstantiation_p | namespace_def_p | comments_p) - >> str_p("}///\\namespace") // end namespace, avoid confusion with classes + >> str_p("}///\\namespace") // end namespace, avoid confusion with classes // FIXME: check for absense of semicolon to disambiguate >> !namespace_name_p) [pop_a(namespaces)]; @@ -297,7 +311,7 @@ Module::Module(const string& interfacePath, [push_back_a(forward_declarations, fwDec)] [assign_a(fwDec, fwDec0)]; - Rule module_content_p = comments_p | using_namespace_p | include_p | class_p | templateSingleInstantiation_p | forward_declaration_p | namespace_def_p ; + Rule module_content_p = comments_p | using_namespace_p | include_p | class_p | templateSingleInstantiation_p | forward_declaration_p | global_function_p | namespace_def_p; Rule module_p = *module_content_p >> !end_p; diff --git a/wrap/Module.h b/wrap/Module.h index ce1a87969..a2c77bc9e 100644 --- a/wrap/Module.h +++ b/wrap/Module.h @@ -23,6 +23,7 @@ #include #include "Class.h" +#include "GlobalFunction.h" #include "TemplateInstantiationTypedef.h" #include "ForwardDeclaration.h" @@ -33,6 +34,8 @@ namespace wrap { */ struct Module { + typedef std::map GlobalFunctions; + std::string name; ///< module name std::vector classes; ///< list of classes std::vector templateInstantiationTypedefs; ///< list of template instantiations @@ -40,6 +43,7 @@ struct Module { // std::vector using_namespaces; ///< all default namespaces std::vector forward_declarations; std::vector includes; ///< Include statements + GlobalFunctions global_functions; /// constructor that parses interface file Module(const std::string& interfacePath, diff --git a/wrap/tests/geometry.h b/wrap/tests/geometry.h index 5dfe07b8d..2e92043b2 100644 --- a/wrap/tests/geometry.h +++ b/wrap/tests/geometry.h @@ -82,6 +82,9 @@ class Test { // even more comments at the end! }; + +Vector aGlobalFunction(); + // comments at the end! // even more comments at the end! From e7e564268d67b6976ccd0f9b7a623951b41c4fc5 Mon Sep 17 00:00:00 2001 From: Alex Cunningham Date: Mon, 23 Jul 2012 14:09:42 +0000 Subject: [PATCH 04/11] global function parsing now tested and working --- wrap/Module.cpp | 2 +- wrap/tests/testNamespaces.h | 6 ++++++ wrap/tests/testWrap.cpp | 38 ++++++++++++++++++++++++++++++++++++- 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/wrap/Module.cpp b/wrap/Module.cpp index 786a4de78..241371b0b 100644 --- a/wrap/Module.cpp +++ b/wrap/Module.cpp @@ -294,7 +294,7 @@ Module::Module(const string& interfacePath, (str_p("namespace") >> namespace_name_p[push_back_a(namespaces)] >> ch_p('{') - >> *(include_p | class_p | templateSingleInstantiation_p | namespace_def_p | comments_p) + >> *(include_p | class_p | templateSingleInstantiation_p | global_function_p | namespace_def_p | comments_p) >> str_p("}///\\namespace") // end namespace, avoid confusion with classes // FIXME: check for absense of semicolon to disambiguate >> !namespace_name_p) [pop_a(namespaces)]; diff --git a/wrap/tests/testNamespaces.h b/wrap/tests/testNamespaces.h index 644fdb3ea..68b6e041e 100644 --- a/wrap/tests/testNamespaces.h +++ b/wrap/tests/testNamespaces.h @@ -14,6 +14,9 @@ class ClassB { ClassB(); }; +// check namespace handling +Vector aGlobalFunction(); + }///\namespace ns1 #include @@ -41,6 +44,9 @@ class ClassC { ClassC(); }; +// separate namespace global function, same name +Vector aGlobalFunction(); + }///\namespace ns2 class ClassD { diff --git a/wrap/tests/testWrap.cpp b/wrap/tests/testWrap.cpp index 0ed1f84ef..2de19f6e4 100644 --- a/wrap/tests/testWrap.cpp +++ b/wrap/tests/testWrap.cpp @@ -88,6 +88,8 @@ TEST( wrap, parse_geometry ) { strvec exp_includes; exp_includes += "folder/path/to/Test.h"; EXPECT(assert_equal(exp_includes, module.includes)); + LONGS_EQUAL(3, module.classes.size()); + // check first class, Point2 { Class cls = module.classes.at(0); @@ -133,7 +135,6 @@ TEST( wrap, parse_geometry ) { // Test class is the third one { - LONGS_EQUAL(3, module.classes.size()); Class testCls = module.classes.at(2); EXPECT_LONGS_EQUAL( 2, testCls.constructor.args_list.size()); EXPECT_LONGS_EQUAL(19, testCls.methods.size()); @@ -149,6 +150,20 @@ TEST( wrap, parse_geometry ) { EXPECT(m2.returnVals.front().category1 == ReturnValue::EIGEN); EXPECT(m2.returnVals.front().category2 == ReturnValue::EIGEN); } + + // evaluate global functions +// Vector aGlobalFunction(); + LONGS_EQUAL(1, module.global_functions.size()); + CHECK(module.global_functions.find("aGlobalFunction") != module.global_functions.end()); + { + GlobalFunction gfunc = module.global_functions.at("aGlobalFunction"); + EXPECT(assert_equal("aGlobalFunction", gfunc.name)); + LONGS_EQUAL(1, gfunc.returnVals.size()); + EXPECT(assert_equal("Vector", gfunc.returnVals.front().type1)); + EXPECT_LONGS_EQUAL(1, gfunc.argLists.size()); + LONGS_EQUAL(1, gfunc.namespaces.size()); + EXPECT(gfunc.namespaces.front().empty()); + } } /* ************************************************************************* */ @@ -208,6 +223,27 @@ TEST( wrap, parse_namespaces ) { strvec exp_namespaces; EXPECT(assert_equal(exp_namespaces, cls.namespaces)); } + + // evaluate global functions +// Vector ns1::aGlobalFunction(); +// Vector ns2::aGlobalFunction(); + LONGS_EQUAL(1, module.global_functions.size()); + CHECK(module.global_functions.find("aGlobalFunction") != module.global_functions.end()); + { + GlobalFunction gfunc = module.global_functions.at("aGlobalFunction"); + EXPECT(assert_equal("aGlobalFunction", gfunc.name)); + LONGS_EQUAL(2, gfunc.returnVals.size()); + EXPECT(assert_equal("Vector", gfunc.returnVals.front().type1)); + EXPECT_LONGS_EQUAL(2, gfunc.argLists.size()); + + // check namespaces + LONGS_EQUAL(2, gfunc.namespaces.size()); + strvec exp_namespaces1; exp_namespaces1 += "ns1"; + EXPECT(assert_equal(exp_namespaces1, gfunc.namespaces.at(0))); + + strvec exp_namespaces2; exp_namespaces2 += "ns2"; + EXPECT(assert_equal(exp_namespaces2, gfunc.namespaces.at(1))); + } } /* ************************************************************************* */ From ece5888cacebdc940e479263ea91e0490bbc7f14 Mon Sep 17 00:00:00 2001 From: Alex Cunningham Date: Mon, 23 Jul 2012 14:09:44 +0000 Subject: [PATCH 05/11] Removed need in wrap to end namespaces in special non-standard tag - can now just use } --- gtsam.h | 15 +++++++-------- wrap/Module.cpp | 3 +-- wrap/tests/testNamespaces.h | 6 +++--- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/gtsam.h b/gtsam.h index 4a2cbb66c..5661cb520 100644 --- a/gtsam.h +++ b/gtsam.h @@ -36,8 +36,7 @@ * Namespace definitions * - Names of namespaces must start with a lowercase letter * - start a namespace with "namespace {" - * - end a namespace with exactly "}///\namespace [namespace_name]", optionally adding the name of the namespace - * - This ending is not C++ standard, and must contain "}///\namespace" to parse + * - end a namespace with exactly "}" * - Namespaces can be nested * Namespace usage * - Namespaces can be specified for classes in arguments and return values @@ -1363,7 +1362,7 @@ virtual class GenericProjectionFactor : gtsam::NonlinearFactor { typedef gtsam::GenericProjectionFactor GenericProjectionFactorCal3_S2; typedef gtsam::GenericProjectionFactor GenericProjectionFactorCal3DS2; -}///\namespace gtsam +} //\namespace gtsam //************************************************************************* // Pose2SLAM @@ -1418,7 +1417,7 @@ class Graph { gtsam::Marginals marginals(const pose2SLAM::Values& solution) const; }; -}///\namespace pose2SLAM +} //\namespace pose2SLAM //************************************************************************* // Pose3SLAM @@ -1473,7 +1472,7 @@ class Graph { gtsam::Marginals marginals(const pose3SLAM::Values& solution) const; }; -}///\namespace pose3SLAM +} //\namespace pose3SLAM //************************************************************************* // planarSLAM @@ -1561,7 +1560,7 @@ class Odometry { const gtsam::Ordering& ordering) const; }; -}///\namespace planarSLAM +} //\namespace planarSLAM //************************************************************************* // VisualSLAM @@ -1686,7 +1685,7 @@ class LevenbergMarquardtOptimizer { visualSLAM::Values values() const; }; -}///\namespace visualSLAM +} //\namespace visualSLAM //************************************************************************ // sparse BA @@ -1767,5 +1766,5 @@ class LevenbergMarquardtOptimizer { sparseBA::Values optimizeSafely(); sparseBA::Values values() const; }; -}///\namespace sparseBA +} //\namespace sparseBA diff --git a/wrap/Module.cpp b/wrap/Module.cpp index 241371b0b..757241ca2 100644 --- a/wrap/Module.cpp +++ b/wrap/Module.cpp @@ -295,8 +295,7 @@ Module::Module(const string& interfacePath, >> namespace_name_p[push_back_a(namespaces)] >> ch_p('{') >> *(include_p | class_p | templateSingleInstantiation_p | global_function_p | namespace_def_p | comments_p) - >> str_p("}///\\namespace") // end namespace, avoid confusion with classes // FIXME: check for absense of semicolon to disambiguate - >> !namespace_name_p) + >> ch_p('}')) [pop_a(namespaces)]; Rule using_namespace_p = diff --git a/wrap/tests/testNamespaces.h b/wrap/tests/testNamespaces.h index 68b6e041e..2c12686c0 100644 --- a/wrap/tests/testNamespaces.h +++ b/wrap/tests/testNamespaces.h @@ -17,7 +17,7 @@ class ClassB { // check namespace handling Vector aGlobalFunction(); -}///\namespace ns1 +} #include namespace ns2 { @@ -38,7 +38,7 @@ class ClassB { ClassB(); }; -}///\namespace ns3 +} class ClassC { ClassC(); @@ -47,7 +47,7 @@ class ClassC { // separate namespace global function, same name Vector aGlobalFunction(); -}///\namespace ns2 +} //\namespace ns2 class ClassD { ClassD(); From b7c2177f0bfd5bd8858b06826194a401c11c396e Mon Sep 17 00:00:00 2001 From: Alex Cunningham Date: Mon, 23 Jul 2012 18:24:35 +0000 Subject: [PATCH 06/11] Generating code for global functions now works --- wrap/Class.cpp | 14 +- wrap/GlobalFunction.cpp | 142 ++++++++++++++++++ wrap/GlobalFunction.h | 16 ++ wrap/Module.cpp | 5 + wrap/StaticMethod.cpp | 1 + wrap/tests/expected/aGlobalFunction.m | 7 + wrap/tests/expected/geometry_wrapper.cpp | 8 + .../+ns1/aGlobalFunction.m | 7 + .../+ns2/aGlobalFunction.m | 7 + .../testNamespaces_wrapper.cpp | 17 +++ wrap/tests/testWrap.cpp | 1 + wrap/utilities.cpp | 16 ++ wrap/utilities.h | 3 + 13 files changed, 231 insertions(+), 13 deletions(-) create mode 100644 wrap/tests/expected/aGlobalFunction.m create mode 100644 wrap/tests/expected_namespaces/+ns1/aGlobalFunction.m create mode 100644 wrap/tests/expected_namespaces/+ns2/aGlobalFunction.m diff --git a/wrap/Class.cpp b/wrap/Class.cpp index 8e04543e4..749a61707 100644 --- a/wrap/Class.cpp +++ b/wrap/Class.cpp @@ -24,7 +24,6 @@ #include // works on Linux GCC #include -#include #include #include "Class.h" @@ -40,18 +39,7 @@ void Class::matlab_proxy(const string& toolboxPath, const string& wrapperName, FileWriter& wrapperFile, vector& functionNames) const { // Create namespace folders - { - using namespace boost::filesystem; - path curPath = toolboxPath; - BOOST_FOREACH(const string& subdir, namespaces) { - curPath /= "+" + subdir; - if(!is_directory(curPath)) - if(exists("+" + subdir)) - throw OutputError("Need to write files to directory " + curPath.string() + ", which already exists as a file but is not a directory"); - else - boost::filesystem::create_directory(curPath); - } - } + createNamespaceStructure(namespaces, toolboxPath); // open destination classFile string classFile = toolboxPath; diff --git a/wrap/GlobalFunction.cpp b/wrap/GlobalFunction.cpp index e20a1f2f2..14bb824d2 100644 --- a/wrap/GlobalFunction.cpp +++ b/wrap/GlobalFunction.cpp @@ -6,9 +6,15 @@ */ #include "GlobalFunction.h" +#include "utilities.h" + +#include +#include namespace wrap { +using namespace std; + /* ************************************************************************* */ void GlobalFunction::addOverload(bool verbose, const std::string& name, const ArgumentList& args, const ReturnValue& retVal, const StrVec& ns_stack) { @@ -19,6 +25,142 @@ void GlobalFunction::addOverload(bool verbose, const std::string& name, this->namespaces.push_back(ns_stack); } +/* ************************************************************************* */ +void GlobalFunction::matlab_proxy(const std::string& toolboxPath, const std::string& wrapperName, + const TypeAttributesTable& typeAttributes, FileWriter& wrapperFile, + std::vector& functionNames) const { + + // cluster overloads with same namespace + // create new GlobalFunction structures around namespaces - same namespaces and names are overloads + // map of namespace to global function + typedef map GlobalFunctionMap; + GlobalFunctionMap grouped_functions; + for (size_t i=0; i& functionNames) const { + + // create the folder for the namespace + const StrVec& ns = namespaces.front(); + createNamespaceStructure(ns, toolboxPath); + + // open destination mfunctionFileName + string mfunctionFileName = toolboxPath; + if(!ns.empty()) + mfunctionFileName += "/+" + wrap::qualifiedName("/+", ns); + mfunctionFileName += "/" + name + ".m"; + FileWriter mfunctionFile(mfunctionFileName, verbose_, "%"); + + // get the name of actual matlab object + const string + matlabQualName = qualifiedName(".", ns, name), + matlabUniqueName = qualifiedName("", ns, name), + cppName = qualifiedName("::", ns, name); + + mfunctionFile.oss << "function varargout = " << name << "(varargin)\n"; + + for(size_t overload = 0; overload < argLists.size(); ++overload) { + const ArgumentList& args = argLists[overload]; + const ReturnValue& returnVal = returnVals[overload]; + size_t nrArgs = args.size(); + + const int id = functionNames.size(); + + // Output proxy matlab code + + // check for number of arguments... + mfunctionFile.oss << (overload==0?"":"else") << "if length(varargin) == " << nrArgs; + if (nrArgs>0) mfunctionFile.oss << " && "; + // ...and their types + bool first = true; + for(size_t i=0;i(id); + + // call + wrapperFile.oss << "void " << wrapFunctionName << "(int nargout, mxArray *out[], int nargin, const mxArray *in[])\n"; + // start + wrapperFile.oss << "{\n"; + + if(returnVal.isPair) + { + if(returnVal.category1 == ReturnValue::CLASS) + wrapperFile.oss << " typedef boost::shared_ptr<" << returnVal.qualifiedType1("::") << "> Shared" << returnVal.type1 << ";"<< endl; + if(returnVal.category2 == ReturnValue::CLASS) + wrapperFile.oss << " typedef boost::shared_ptr<" << returnVal.qualifiedType2("::") << "> Shared" << returnVal.type2 << ";"<< endl; + } + else { + if (returnVal.category1 == ReturnValue::CLASS) + wrapperFile.oss << " typedef boost::shared_ptr<" << returnVal.qualifiedType1("::") << "> Shared" << returnVal.type1 << ";"<< endl; + } + + // check arguments + // NOTE: for static functions, there is no object passed + wrapperFile.oss << " checkArguments(\"" << matlabUniqueName << "\",nargout,nargin," << args.size() << ");\n"; + + // unwrap arguments, see Argument.cpp + args.matlab_unwrap(wrapperFile,0); // We start at 0 because there is no self object + + // call method with default type and wrap result + if (returnVal.type1!="void") + returnVal.wrap_result(cppName+"("+args.names()+")", wrapperFile, typeAttributes); + else + wrapperFile.oss << cppName+"("+args.names()+");\n"; + + // finish + wrapperFile.oss << "}\n"; + + // Add to function list + functionNames.push_back(wrapFunctionName); + } + + mfunctionFile.oss << "else\n"; + mfunctionFile.oss << " error('Arguments do not match any overload of function " << matlabQualName << "');" << endl; + mfunctionFile.oss << "end" << endl; + + // Close file + mfunctionFile.emit(true); +} + /* ************************************************************************* */ diff --git a/wrap/GlobalFunction.h b/wrap/GlobalFunction.h index 0899bbdc9..e281e6a6d 100644 --- a/wrap/GlobalFunction.h +++ b/wrap/GlobalFunction.h @@ -29,10 +29,26 @@ struct GlobalFunction { // Constructor only used in Module GlobalFunction(bool verbose = true) : verbose_(verbose) {} + // Used to reconstruct + GlobalFunction(const std::string& name_, bool verbose = true) + : verbose_(verbose), name(name_) {} + // adds an overloaded version of this function void addOverload(bool verbose, const std::string& name, const ArgumentList& args, const ReturnValue& retVal, const StrVec& ns_stack); + // codegen function called from Module to build the cpp and matlab versions of the function + void matlab_proxy(const std::string& toolboxPath, const std::string& wrapperName, + const TypeAttributesTable& typeAttributes, FileWriter& wrapperFile, + std::vector& functionNames) const; + +private: + + // Creates a single global function - all in same namespace + void generateSingleFunction(const std::string& toolboxPath, const std::string& wrapperName, + const TypeAttributesTable& typeAttributes, FileWriter& wrapperFile, + std::vector& functionNames) const; + }; } // \namespace wrap diff --git a/wrap/Module.cpp b/wrap/Module.cpp index 757241ca2..35b0d2ff8 100644 --- a/wrap/Module.cpp +++ b/wrap/Module.cpp @@ -464,6 +464,11 @@ void Module::matlab_code(const string& toolboxPath, const string& headerPath) co cls.matlab_proxy(toolboxPath, wrapperName, typeAttributes, wrapperFile, functionNames); } + // create matlab files and wrapper code for global functions + BOOST_FOREACH(const GlobalFunctions::value_type& p, global_functions) { + p.second.matlab_proxy(toolboxPath, wrapperName, typeAttributes, wrapperFile, functionNames); + } + // finish wrapper file wrapperFile.oss << "\n"; finish_wrapper(wrapperFile, functionNames); diff --git a/wrap/StaticMethod.cpp b/wrap/StaticMethod.cpp index fcef79857..f123a31ac 100644 --- a/wrap/StaticMethod.cpp +++ b/wrap/StaticMethod.cpp @@ -38,6 +38,7 @@ void StaticMethod::addOverload(bool verbose, const std::string& name, this->returnVals.push_back(retVal); } +/* ************************************************************************* */ void StaticMethod::proxy_wrapper_fragments(FileWriter& proxyFile, FileWriter& wrapperFile, const string& cppClassName, const std::string& matlabQualName, diff --git a/wrap/tests/expected/aGlobalFunction.m b/wrap/tests/expected/aGlobalFunction.m new file mode 100644 index 000000000..80d6b1f6b --- /dev/null +++ b/wrap/tests/expected/aGlobalFunction.m @@ -0,0 +1,7 @@ +% automatically generated by wrap +function varargout = aGlobalFunction(varargin) +if length(varargin) == 0 + varargout{1} = geometry_wrapper(40, varargin{:}); +else + error('Arguments do not match any overload of function aGlobalFunction'); +end diff --git a/wrap/tests/expected/geometry_wrapper.cpp b/wrap/tests/expected/geometry_wrapper.cpp index a520803ee..d403073d4 100644 --- a/wrap/tests/expected/geometry_wrapper.cpp +++ b/wrap/tests/expected/geometry_wrapper.cpp @@ -495,6 +495,11 @@ using namespace geometry; out[0] = wrap< Vector >(obj->return_vector2(value)); } +void aGlobalFunction_40(int nargout, mxArray *out[], int nargin, const mxArray *in[]) +{ + checkArguments("aGlobalFunction",nargout,nargin,0); + out[0] = wrap< Vector >(aGlobalFunction()); +} void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { @@ -626,6 +631,9 @@ void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) case 39: Test_return_vector2_39(nargout, out, nargin-1, in+1); break; + case 40: + aGlobalFunction_40(nargout, out, nargin-1, in+1); + break; } std::cout.rdbuf(outbuf); diff --git a/wrap/tests/expected_namespaces/+ns1/aGlobalFunction.m b/wrap/tests/expected_namespaces/+ns1/aGlobalFunction.m new file mode 100644 index 000000000..fc1e780af --- /dev/null +++ b/wrap/tests/expected_namespaces/+ns1/aGlobalFunction.m @@ -0,0 +1,7 @@ +% automatically generated by wrap +function varargout = aGlobalFunction(varargin) +if length(varargin) == 0 + varargout{1} = testNamespaces_wrapper(22, varargin{:}); +else + error('Arguments do not match any overload of function ns1.aGlobalFunction'); +end diff --git a/wrap/tests/expected_namespaces/+ns2/aGlobalFunction.m b/wrap/tests/expected_namespaces/+ns2/aGlobalFunction.m new file mode 100644 index 000000000..2bdf45dd6 --- /dev/null +++ b/wrap/tests/expected_namespaces/+ns2/aGlobalFunction.m @@ -0,0 +1,7 @@ +% automatically generated by wrap +function varargout = aGlobalFunction(varargin) +if length(varargin) == 0 + varargout{1} = testNamespaces_wrapper(23, varargin{:}); +else + error('Arguments do not match any overload of function ns2.aGlobalFunction'); +end diff --git a/wrap/tests/expected_namespaces/testNamespaces_wrapper.cpp b/wrap/tests/expected_namespaces/testNamespaces_wrapper.cpp index 3eb0b0311..c75c6a388 100644 --- a/wrap/tests/expected_namespaces/testNamespaces_wrapper.cpp +++ b/wrap/tests/expected_namespaces/testNamespaces_wrapper.cpp @@ -332,6 +332,17 @@ void ClassD_deconstructor_21(int nargout, mxArray *out[], int nargin, const mxAr } } +void ns1aGlobalFunction_22(int nargout, mxArray *out[], int nargin, const mxArray *in[]) +{ + checkArguments("ns1aGlobalFunction",nargout,nargin,0); + out[0] = wrap< Vector >(ns1::aGlobalFunction()); +} + +void ns2aGlobalFunction_23(int nargout, mxArray *out[], int nargin, const mxArray *in[]) +{ + checkArguments("ns2aGlobalFunction",nargout,nargin,0); + out[0] = wrap< Vector >(ns2::aGlobalFunction()); +} void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { @@ -409,6 +420,12 @@ void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) case 21: ClassD_deconstructor_21(nargout, out, nargin-1, in+1); break; + case 22: + ns1aGlobalFunction_22(nargout, out, nargin-1, in+1); + break; + case 23: + ns2aGlobalFunction_23(nargout, out, nargin-1, in+1); + break; } std::cout.rdbuf(outbuf); diff --git a/wrap/tests/testWrap.cpp b/wrap/tests/testWrap.cpp index 2de19f6e4..29fc1891a 100644 --- a/wrap/tests/testWrap.cpp +++ b/wrap/tests/testWrap.cpp @@ -291,6 +291,7 @@ TEST( wrap, matlab_code_geometry ) { EXPECT(files_equal(epath + "Point2.m" , apath + "Point2.m" )); EXPECT(files_equal(epath + "Point3.m" , apath + "Point3.m" )); EXPECT(files_equal(epath + "Test.m" , apath + "Test.m" )); + EXPECT(files_equal(epath + "aGlobalFunction.m" , apath + "aGlobalFunction.m" )); } /* ************************************************************************* */ diff --git a/wrap/utilities.cpp b/wrap/utilities.cpp index 6eb47c55d..6b6e57094 100644 --- a/wrap/utilities.cpp +++ b/wrap/utilities.cpp @@ -20,6 +20,7 @@ #include #include +#include #include "utilities.h" @@ -137,6 +138,21 @@ string qualifiedName(const string& separator, const vector& names, const return result; } +/* ************************************************************************* */ +void createNamespaceStructure(const std::vector& namespaces, const std::string& toolboxPath) { + using namespace boost::filesystem; + path curPath = toolboxPath; + BOOST_FOREACH(const string& subdir, namespaces) { + curPath /= "+" + subdir; + if(!is_directory(curPath)) { + if(exists("+" + subdir)) + throw OutputError("Need to write files to directory " + curPath.string() + ", which already exists as a file but is not a directory"); + else + boost::filesystem::create_directory(curPath); + } + } +} + /* ************************************************************************* */ } // \namespace wrap diff --git a/wrap/utilities.h b/wrap/utilities.h index 7e28d6793..2eaf5397a 100644 --- a/wrap/utilities.h +++ b/wrap/utilities.h @@ -133,4 +133,7 @@ void generateUsingNamespace(FileWriter& file, const std::vector& us */ std::string qualifiedName(const std::string& separator, const std::vector& names, const std::string& finalName = ""); +/** creates the necessary folders for namespaces, as specified by a namespace stack */ +void createNamespaceStructure(const std::vector& namespaces, const std::string& toolboxPath); + } // \namespace wrap From 5d008d43faa83cac64e1de7ce38e7b0e417baa51 Mon Sep 17 00:00:00 2001 From: Alex Cunningham Date: Mon, 23 Jul 2012 18:24:37 +0000 Subject: [PATCH 07/11] Added example namespace function to gtsam - works in matlab --- gtsam.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gtsam.h b/gtsam.h index 5661cb520..120d585aa 100644 --- a/gtsam.h +++ b/gtsam.h @@ -85,6 +85,9 @@ namespace gtsam { // base //************************************************************************* +/** gtsam namespace functions */ +bool linear_independent(Matrix A, Matrix B, double tol); + virtual class Value { // No constructors because this is an abstract class From 79c9bc99ffc71540d61176f2b07d57969300ad5b Mon Sep 17 00:00:00 2001 From: Alex Cunningham Date: Mon, 23 Jul 2012 18:24:39 +0000 Subject: [PATCH 08/11] Some additional cleanup in wrap --- gtsam.h | 5 ++++- wrap/Class.cpp | 2 +- wrap/GlobalFunction.cpp | 12 +----------- wrap/GlobalFunction.h | 2 +- wrap/Module.h | 1 - wrap/ReturnValue.cpp | 14 ++++++++++++++ wrap/ReturnValue.h | 2 ++ wrap/StaticMethod.cpp | 11 +---------- 8 files changed, 24 insertions(+), 25 deletions(-) diff --git a/gtsam.h b/gtsam.h index 120d585aa..04d6b7e9b 100644 --- a/gtsam.h +++ b/gtsam.h @@ -48,6 +48,10 @@ * - All includes will be collected and added in a single file * - All namespaces must have angle brackets: * - No default includes will be added + * Global/Namespace functions + * - Functions specified outside of a class are global + * - Can be overloaded with different arguments + * - Can have multiple functions of the same name in different namespaces * Using classes defined in other modules * - If you are using a class 'OtherClass' not wrapped in this definition file, add "class OtherClass;" to avoid a dependency error * Virtual inheritance @@ -74,7 +78,6 @@ /** * Status: - * - TODO: global functions * - TODO: default values for arguments * - TODO: Handle gtsam::Rot3M conversions to quaternions */ diff --git a/wrap/Class.cpp b/wrap/Class.cpp index 749a61707..5110ab6cd 100644 --- a/wrap/Class.cpp +++ b/wrap/Class.cpp @@ -308,7 +308,7 @@ std::string Class::getTypedef() const { result += ("namespace " + namesp + " { "); } result += ("typedef " + typedefName + " " + name + ";"); - BOOST_FOREACH(const string& namesp, namespaces) { + for (size_t i = 0; i Shared" << returnVal.type1 << ";"<< endl; - if(returnVal.category2 == ReturnValue::CLASS) - wrapperFile.oss << " typedef boost::shared_ptr<" << returnVal.qualifiedType2("::") << "> Shared" << returnVal.type2 << ";"<< endl; - } - else { - if (returnVal.category1 == ReturnValue::CLASS) - wrapperFile.oss << " typedef boost::shared_ptr<" << returnVal.qualifiedType1("::") << "> Shared" << returnVal.type1 << ";"<< endl; - } + returnVal.wrapTypeUnwrap(wrapperFile); // check arguments // NOTE: for static functions, there is no object passed diff --git a/wrap/GlobalFunction.h b/wrap/GlobalFunction.h index e281e6a6d..37a70df2a 100644 --- a/wrap/GlobalFunction.h +++ b/wrap/GlobalFunction.h @@ -24,7 +24,7 @@ struct GlobalFunction { // each overload, regardless of namespace std::vector argLists; ///< arugments for each overload std::vector returnVals; ///< returnVals for each overload - std::vector namespaces; ///< Stack of namespaces + std::vector namespaces; ///< Stack of namespaces // Constructor only used in Module GlobalFunction(bool verbose = true) : verbose_(verbose) {} diff --git a/wrap/Module.h b/wrap/Module.h index a2c77bc9e..ca8b0bb1a 100644 --- a/wrap/Module.h +++ b/wrap/Module.h @@ -40,7 +40,6 @@ struct Module { std::vector classes; ///< list of classes std::vector templateInstantiationTypedefs; ///< list of template instantiations bool verbose; ///< verbose flag -// std::vector using_namespaces; ///< all default namespaces std::vector forward_declarations; std::vector includes; ///< Include statements GlobalFunctions global_functions; diff --git a/wrap/ReturnValue.cpp b/wrap/ReturnValue.cpp index c209a3131..37e6b15ff 100644 --- a/wrap/ReturnValue.cpp +++ b/wrap/ReturnValue.cpp @@ -122,5 +122,19 @@ void ReturnValue::wrap_result(const string& result, FileWriter& file, const Type } /* ************************************************************************* */ +void ReturnValue::wrapTypeUnwrap(FileWriter& wrapperFile) const { + if(isPair) + { + if(category1 == ReturnValue::CLASS) + wrapperFile.oss << " typedef boost::shared_ptr<" << qualifiedType1("::") << "> Shared" << type1 << ";"<< endl; + if(category2 == ReturnValue::CLASS) + wrapperFile.oss << " typedef boost::shared_ptr<" << qualifiedType2("::") << "> Shared" << type2 << ";"<< endl; + } + else { + if (category1 == ReturnValue::CLASS) + wrapperFile.oss << " typedef boost::shared_ptr<" << qualifiedType1("::") << "> Shared" << type1 << ";"<< endl; + } +} +/* ************************************************************************* */ diff --git a/wrap/ReturnValue.h b/wrap/ReturnValue.h index 8ff5d712b..2bffef680 100644 --- a/wrap/ReturnValue.h +++ b/wrap/ReturnValue.h @@ -52,6 +52,8 @@ struct ReturnValue { void wrap_result(const std::string& result, FileWriter& file, const TypeAttributesTable& typeAttributes) const; + void wrapTypeUnwrap(FileWriter& wrapperFile) const; + }; } // \namespace wrap diff --git a/wrap/StaticMethod.cpp b/wrap/StaticMethod.cpp index f123a31ac..ed80d7890 100644 --- a/wrap/StaticMethod.cpp +++ b/wrap/StaticMethod.cpp @@ -123,16 +123,7 @@ string StaticMethod::wrapper_fragment(FileWriter& file, file.oss << "{\n"; generateUsingNamespace(file, using_namespaces); - if(returnVal.isPair) - { - if(returnVal.category1 == ReturnValue::CLASS) - file.oss << " typedef boost::shared_ptr<" << returnVal.qualifiedType1("::") << "> Shared" << returnVal.type1 << ";"<< endl; - if(returnVal.category2 == ReturnValue::CLASS) - file.oss << " typedef boost::shared_ptr<" << returnVal.qualifiedType2("::") << "> Shared" << returnVal.type2 << ";"<< endl; - } - else - if(returnVal.category1 == ReturnValue::CLASS) - file.oss << " typedef boost::shared_ptr<" << returnVal.qualifiedType1("::") << "> Shared" << returnVal.type1 << ";"<< endl; + returnVal.wrapTypeUnwrap(file); file.oss << " typedef boost::shared_ptr<" << cppClassName << "> Shared;" << endl; From 656f573c0a54fee32ce0101c21a325e494accbc9 Mon Sep 17 00:00:00 2001 From: Alex Cunningham Date: Mon, 23 Jul 2012 18:24:43 +0000 Subject: [PATCH 09/11] Removed from wrap the use of "using namespace xxx" statements - wasn't fully supported before, and now we have real namespace support --- gtsam.h | 3 --- wrap/Class.cpp | 10 ++++---- wrap/Class.h | 1 - wrap/Constructor.cpp | 2 -- wrap/Constructor.h | 1 - wrap/Deconstructor.cpp | 4 +--- wrap/Deconstructor.h | 3 +-- wrap/Method.cpp | 5 +--- wrap/Method.h | 4 +--- wrap/Module.cpp | 10 ++------ wrap/StaticMethod.cpp | 5 +--- wrap/StaticMethod.h | 4 +--- wrap/tests/expected/geometry_wrapper.cpp | 29 ------------------------ wrap/tests/geometry.h | 3 --- wrap/tests/testWrap.cpp | 6 ----- wrap/utilities.cpp | 7 ------ wrap/utilities.h | 5 ---- 17 files changed, 12 insertions(+), 90 deletions(-) diff --git a/gtsam.h b/gtsam.h index 04d6b7e9b..35975f710 100644 --- a/gtsam.h +++ b/gtsam.h @@ -41,9 +41,6 @@ * Namespace usage * - Namespaces can be specified for classes in arguments and return values * - In each case, the namespace must be fully specified, e.g., "namespace1::namespace2::ClassName" - * Using namespace: FIXME: this functionality is currently broken - * - To use a namespace (e.g., generate a "using namespace x" line in cpp files), add "using namespace x;" - * - This declaration applies to all classes *after* the declaration, regardless of brackets * Includes in C++ wrappers * - All includes will be collected and added in a single file * - All namespaces must have angle brackets: diff --git a/wrap/Class.cpp b/wrap/Class.cpp index 5110ab6cd..00fdba011 100644 --- a/wrap/Class.cpp +++ b/wrap/Class.cpp @@ -79,7 +79,7 @@ void Class::matlab_proxy(const string& toolboxPath, const string& wrapperName, const int id = (int)functionNames.size(); constructor.proxy_fragment(proxyFile, wrapperName, !qualifiedParent.empty(), id, a); const string wrapFunctionName = constructor.wrapper_fragment(wrapperFile, - cppName, matlabUniqueName, cppBaseName, id, using_namespaces, a); + cppName, matlabUniqueName, cppBaseName, id, a); wrapperFile.oss << "\n"; functionNames.push_back(wrapFunctionName); } @@ -96,7 +96,7 @@ void Class::matlab_proxy(const string& toolboxPath, const string& wrapperName, const int id = (int)functionNames.size(); deconstructor.proxy_fragment(proxyFile, wrapperName, matlabUniqueName, id); proxyFile.oss << "\n"; - const string functionName = deconstructor.wrapper_fragment(wrapperFile, cppName, matlabUniqueName, id, using_namespaces); + const string functionName = deconstructor.wrapper_fragment(wrapperFile, cppName, matlabUniqueName, id); wrapperFile.oss << "\n"; functionNames.push_back(functionName); } @@ -106,7 +106,7 @@ void Class::matlab_proxy(const string& toolboxPath, const string& wrapperName, // Methods BOOST_FOREACH(const Methods::value_type& name_m, methods) { const Method& m = name_m.second; - m.proxy_wrapper_fragments(proxyFile, wrapperFile, cppName, matlabQualName, matlabUniqueName, wrapperName, using_namespaces, typeAttributes, functionNames); + m.proxy_wrapper_fragments(proxyFile, wrapperFile, cppName, matlabQualName, matlabUniqueName, wrapperName, typeAttributes, functionNames); proxyFile.oss << "\n"; wrapperFile.oss << "\n"; } @@ -118,7 +118,7 @@ void Class::matlab_proxy(const string& toolboxPath, const string& wrapperName, // Static methods BOOST_FOREACH(const StaticMethods::value_type& name_m, static_methods) { const StaticMethod& m = name_m.second; - m.proxy_wrapper_fragments(proxyFile, wrapperFile, cppName, matlabQualName, matlabUniqueName, wrapperName, using_namespaces, typeAttributes, functionNames); + m.proxy_wrapper_fragments(proxyFile, wrapperFile, cppName, matlabQualName, matlabUniqueName, wrapperName, typeAttributes, functionNames); proxyFile.oss << "\n"; wrapperFile.oss << "\n"; } @@ -183,7 +183,6 @@ void Class::pointer_constructor_fragments(FileWriter& proxyFile, FileWriter& wra wrapperFile.oss << "void " << collectorInsertFunctionName << "(int nargout, mxArray *out[], int nargin, const mxArray *in[])" << endl; wrapperFile.oss << "{\n"; wrapperFile.oss << " mexAtExit(&_deleteAllObjects);\n"; - generateUsingNamespace(wrapperFile, using_namespaces); // Typedef boost::shared_ptr wrapperFile.oss << " typedef boost::shared_ptr<" << cppName << "> Shared;\n"; wrapperFile.oss << "\n"; @@ -273,7 +272,6 @@ Class expandClassTemplate(const Class& cls, const string& templateArg, const vec inst.methods = expandMethodTemplate(cls.methods, templateArg, instName); inst.static_methods = expandMethodTemplate(cls.static_methods, templateArg, instName); inst.namespaces = cls.namespaces; - inst.using_namespaces = cls.using_namespaces; inst.constructor = cls.constructor; inst.constructor.args_list = expandArgumentListsTemplate(cls.constructor.args_list, templateArg, instName); inst.constructor.name = inst.name; diff --git a/wrap/Class.h b/wrap/Class.h index c41cbb470..2d10d691a 100644 --- a/wrap/Class.h +++ b/wrap/Class.h @@ -47,7 +47,6 @@ struct Class { Methods methods; ///< Class methods StaticMethods static_methods; ///< Static methods std::vector namespaces; ///< Stack of namespaces - std::vector using_namespaces;///< default namespaces Constructor constructor; ///< Class constructors Deconstructor deconstructor; ///< Deconstructor to deallocate C++ object bool verbose_; ///< verbose flag diff --git a/wrap/Constructor.cpp b/wrap/Constructor.cpp index 274180e08..7d18cb8db 100644 --- a/wrap/Constructor.cpp +++ b/wrap/Constructor.cpp @@ -70,7 +70,6 @@ string Constructor::wrapper_fragment(FileWriter& file, const string& matlabUniqueName, const string& cppBaseClassName, int id, - const vector& using_namespaces, const ArgumentList& al) const { const string wrapFunctionName = matlabUniqueName + "_constructor_" + boost::lexical_cast(id); @@ -78,7 +77,6 @@ string Constructor::wrapper_fragment(FileWriter& file, file.oss << "void " << wrapFunctionName << "(int nargout, mxArray *out[], int nargin, const mxArray *in[])" << endl; file.oss << "{\n"; file.oss << " mexAtExit(&_deleteAllObjects);\n"; - generateUsingNamespace(file, using_namespaces); //Typedef boost::shared_ptr file.oss << " typedef boost::shared_ptr<" << cppClassName << "> Shared;\n"; file.oss << "\n"; diff --git a/wrap/Constructor.h b/wrap/Constructor.h index e2eca1291..fe8a96ccd 100644 --- a/wrap/Constructor.h +++ b/wrap/Constructor.h @@ -58,7 +58,6 @@ struct Constructor { const std::string& matlabUniqueName, const std::string& cppBaseClassName, int id, - const std::vector& using_namespaces, const ArgumentList& al) const; /// constructor function diff --git a/wrap/Deconstructor.cpp b/wrap/Deconstructor.cpp index c9239ee74..b2355f20e 100644 --- a/wrap/Deconstructor.cpp +++ b/wrap/Deconstructor.cpp @@ -48,8 +48,7 @@ void Deconstructor::proxy_fragment(FileWriter& file, string Deconstructor::wrapper_fragment(FileWriter& file, const string& cppClassName, const string& matlabUniqueName, - int id, - const vector& using_namespaces) const { + int id) const { const string matlabName = matlab_wrapper_name(matlabUniqueName); @@ -57,7 +56,6 @@ string Deconstructor::wrapper_fragment(FileWriter& file, file.oss << "void " << wrapFunctionName << "(int nargout, mxArray *out[], int nargin, const mxArray *in[])" << endl; file.oss << "{" << endl; - generateUsingNamespace(file, using_namespaces); file.oss << " typedef boost::shared_ptr<" << cppClassName << "> Shared;" << endl; //Deconstructor takes 1 arg, the mxArray obj file.oss << " checkArguments(\"" << matlabName << "\",nargout,nargin," << "1" << ");" << endl; diff --git a/wrap/Deconstructor.h b/wrap/Deconstructor.h index 0d7dadaad..a3b71b04e 100644 --- a/wrap/Deconstructor.h +++ b/wrap/Deconstructor.h @@ -54,8 +54,7 @@ struct Deconstructor { std::string wrapper_fragment(FileWriter& file, const std::string& cppClassName, const std::string& matlabUniqueName, - int id, - const std::vector& using_namespaces) const; + int id) const; }; } // \namespace wrap diff --git a/wrap/Method.cpp b/wrap/Method.cpp index eb143b4dc..cc7c5a865 100644 --- a/wrap/Method.cpp +++ b/wrap/Method.cpp @@ -42,7 +42,6 @@ void Method::proxy_wrapper_fragments(FileWriter& proxyFile, FileWriter& wrapperF const std::string& matlabQualName, const std::string& matlabUniqueName, const string& wrapperName, - const vector& using_namespaces, const TypeAttributesTable& typeAttributes, vector& functionNames) const { @@ -82,7 +81,7 @@ void Method::proxy_wrapper_fragments(FileWriter& proxyFile, FileWriter& wrapperF // Output C++ wrapper code const string wrapFunctionName = wrapper_fragment( - wrapperFile, cppClassName, matlabUniqueName, overload, id, using_namespaces, typeAttributes); + wrapperFile, cppClassName, matlabUniqueName, overload, id, typeAttributes); // Add to function list functionNames.push_back(wrapFunctionName); @@ -103,7 +102,6 @@ string Method::wrapper_fragment(FileWriter& file, const string& matlabUniqueName, int overload, int id, - const vector& using_namespaces, const TypeAttributesTable& typeAttributes) const { // generate code @@ -117,7 +115,6 @@ string Method::wrapper_fragment(FileWriter& file, file.oss << "void " << wrapFunctionName << "(int nargout, mxArray *out[], int nargin, const mxArray *in[])\n"; // start file.oss << "{\n"; - generateUsingNamespace(file, using_namespaces); if(returnVal.isPair) { diff --git a/wrap/Method.h b/wrap/Method.h index e23a24186..4185732cf 100644 --- a/wrap/Method.h +++ b/wrap/Method.h @@ -51,8 +51,7 @@ struct Method { // classPath is class directory, e.g., ../matlab/@Point2 void proxy_wrapper_fragments(FileWriter& proxyFile, FileWriter& wrapperFile, const std::string& cppClassName, const std::string& matlabQualName, const std::string& matlabUniqueName, - const std::string& wrapperName, const std::vector& using_namespaces, - const TypeAttributesTable& typeAttributes, + const std::string& wrapperName, const TypeAttributesTable& typeAttributes, std::vector& functionNames) const; private: @@ -61,7 +60,6 @@ private: const std::string& matlabUniqueName, int overload, int id, - const std::vector& using_namespaces, const TypeAttributesTable& typeAttributes) const; ///< cpp wrapper }; diff --git a/wrap/Module.cpp b/wrap/Module.cpp index 35b0d2ff8..8c564e92f 100644 --- a/wrap/Module.cpp +++ b/wrap/Module.cpp @@ -84,8 +84,7 @@ Module::Module(const string& interfacePath, GlobalFunction globalFunc0(enable_verbose), globalFunc(enable_verbose); ForwardDeclaration fwDec0, fwDec; vector namespaces, /// current namespace tag - namespaces_return, /// namespace for current return type - using_namespace_current; /// All namespaces from "using" declarations + namespaces_return; /// namespace for current return type string templateArgument; vector templateInstantiationNamespace; vector > templateInstantiations; @@ -264,7 +263,6 @@ Module::Module(const string& interfacePath, [assign_a(constructor.name, cls.name)] [assign_a(cls.constructor, constructor)] [assign_a(cls.namespaces, namespaces)] - [assign_a(cls.using_namespaces, using_namespace_current)] [assign_a(deconstructor.name,cls.name)] [assign_a(cls.deconstructor, deconstructor)] [bl::bind(&handle_possible_template, bl::var(classes), bl::var(cls), bl::var(templateArgument), bl::var(templateInstantiations))] @@ -298,10 +296,6 @@ Module::Module(const string& interfacePath, >> ch_p('}')) [pop_a(namespaces)]; - Rule using_namespace_p = - str_p("using") >> str_p("namespace") - >> namespace_name_p[push_back_a(using_namespace_current)] >> ch_p(';'); - Rule forward_declaration_p = !(str_p("virtual")[assign_a(fwDec.isVirtual, true)]) >> str_p("class") @@ -310,7 +304,7 @@ Module::Module(const string& interfacePath, [push_back_a(forward_declarations, fwDec)] [assign_a(fwDec, fwDec0)]; - Rule module_content_p = comments_p | using_namespace_p | include_p | class_p | templateSingleInstantiation_p | forward_declaration_p | global_function_p | namespace_def_p; + Rule module_content_p = comments_p | include_p | class_p | templateSingleInstantiation_p | forward_declaration_p | global_function_p | namespace_def_p; Rule module_p = *module_content_p >> !end_p; diff --git a/wrap/StaticMethod.cpp b/wrap/StaticMethod.cpp index ed80d7890..3def66b0f 100644 --- a/wrap/StaticMethod.cpp +++ b/wrap/StaticMethod.cpp @@ -44,7 +44,6 @@ void StaticMethod::proxy_wrapper_fragments(FileWriter& proxyFile, FileWriter& wr const std::string& matlabQualName, const std::string& matlabUniqueName, const string& wrapperName, - const vector& using_namespaces, const TypeAttributesTable& typeAttributes, vector& functionNames) const { @@ -86,7 +85,7 @@ void StaticMethod::proxy_wrapper_fragments(FileWriter& proxyFile, FileWriter& wr // Output C++ wrapper code const string wrapFunctionName = wrapper_fragment( - wrapperFile, cppClassName, matlabUniqueName, overload, id, using_namespaces, typeAttributes); + wrapperFile, cppClassName, matlabUniqueName, overload, id, typeAttributes); // Add to function list functionNames.push_back(wrapFunctionName); @@ -107,7 +106,6 @@ string StaticMethod::wrapper_fragment(FileWriter& file, const string& matlabUniqueName, int overload, int id, - const vector& using_namespaces, const TypeAttributesTable& typeAttributes) const { // generate code @@ -121,7 +119,6 @@ string StaticMethod::wrapper_fragment(FileWriter& file, file.oss << "void " << wrapFunctionName << "(int nargout, mxArray *out[], int nargin, const mxArray *in[])\n"; // start file.oss << "{\n"; - generateUsingNamespace(file, using_namespaces); returnVal.wrapTypeUnwrap(file); diff --git a/wrap/StaticMethod.h b/wrap/StaticMethod.h index 55d9f3e99..fc82105f0 100644 --- a/wrap/StaticMethod.h +++ b/wrap/StaticMethod.h @@ -51,8 +51,7 @@ struct StaticMethod { // classPath is class directory, e.g., ../matlab/@Point2 void proxy_wrapper_fragments(FileWriter& proxyFile, FileWriter& wrapperFile, const std::string& cppClassName, const std::string& matlabQualName, const std::string& matlabUniqueName, - const std::string& wrapperName, const std::vector& using_namespaces, - const TypeAttributesTable& typeAttributes, + const std::string& wrapperName, const TypeAttributesTable& typeAttributes, std::vector& functionNames) const; private: @@ -61,7 +60,6 @@ private: const std::string& matlabUniqueName, int overload, int id, - const std::vector& using_namespaces, const TypeAttributesTable& typeAttributes) const; ///< cpp wrapper }; diff --git a/wrap/tests/expected/geometry_wrapper.cpp b/wrap/tests/expected/geometry_wrapper.cpp index d403073d4..93fde1ca4 100644 --- a/wrap/tests/expected/geometry_wrapper.cpp +++ b/wrap/tests/expected/geometry_wrapper.cpp @@ -180,7 +180,6 @@ void Point2_y_10(int nargout, mxArray *out[], int nargin, const mxArray *in[]) void Point3_collectorInsertAndMakeBase_11(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { mexAtExit(&_deleteAllObjects); -using namespace geometry; typedef boost::shared_ptr Shared; Shared *self = *reinterpret_cast (mxGetData(in[0])); @@ -190,7 +189,6 @@ using namespace geometry; void Point3_constructor_12(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { mexAtExit(&_deleteAllObjects); -using namespace geometry; typedef boost::shared_ptr Shared; double x = unwrap< double >(in[0]); @@ -204,7 +202,6 @@ using namespace geometry; void Point3_deconstructor_13(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { -using namespace geometry; typedef boost::shared_ptr Shared; checkArguments("delete_Point3",nargout,nargin,1); Shared *self = *reinterpret_cast(mxGetData(in[0])); @@ -218,7 +215,6 @@ using namespace geometry; void Point3_norm_14(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { -using namespace geometry; typedef boost::shared_ptr Shared; checkArguments("norm",nargout,nargin-1,0); Shared obj = unwrap_shared_ptr(in[0], "ptr_Point3"); @@ -227,7 +223,6 @@ using namespace geometry; void Point3_StaticFunctionRet_15(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { -using namespace geometry; typedef boost::shared_ptr SharedPoint3; typedef boost::shared_ptr Shared; checkArguments("Point3.StaticFunctionRet",nargout,nargin,1); @@ -237,7 +232,6 @@ using namespace geometry; void Point3_staticFunction_16(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { -using namespace geometry; typedef boost::shared_ptr Shared; checkArguments("Point3.staticFunction",nargout,nargin,0); out[0] = wrap< double >(Point3::staticFunction()); @@ -246,7 +240,6 @@ using namespace geometry; void Test_collectorInsertAndMakeBase_17(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { mexAtExit(&_deleteAllObjects); -using namespace geometry; typedef boost::shared_ptr Shared; Shared *self = *reinterpret_cast (mxGetData(in[0])); @@ -256,7 +249,6 @@ using namespace geometry; void Test_constructor_18(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { mexAtExit(&_deleteAllObjects); -using namespace geometry; typedef boost::shared_ptr Shared; Shared *self = new Shared(new Test()); @@ -268,7 +260,6 @@ using namespace geometry; void Test_constructor_19(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { mexAtExit(&_deleteAllObjects); -using namespace geometry; typedef boost::shared_ptr Shared; double a = unwrap< double >(in[0]); @@ -281,7 +272,6 @@ using namespace geometry; void Test_deconstructor_20(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { -using namespace geometry; typedef boost::shared_ptr Shared; checkArguments("delete_Test",nargout,nargin,1); Shared *self = *reinterpret_cast(mxGetData(in[0])); @@ -295,7 +285,6 @@ using namespace geometry; void Test_arg_EigenConstRef_21(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { -using namespace geometry; typedef boost::shared_ptr Shared; checkArguments("arg_EigenConstRef",nargout,nargin-1,1); Shared obj = unwrap_shared_ptr(in[0], "ptr_Test"); @@ -305,7 +294,6 @@ using namespace geometry; void Test_create_MixedPtrs_22(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { -using namespace geometry; typedef boost::shared_ptr SharedTest; typedef boost::shared_ptr SharedTest; typedef boost::shared_ptr Shared; @@ -317,7 +305,6 @@ using namespace geometry; void Test_create_ptrs_23(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { -using namespace geometry; typedef boost::shared_ptr SharedTest; typedef boost::shared_ptr SharedTest; typedef boost::shared_ptr Shared; @@ -329,7 +316,6 @@ using namespace geometry; void Test_print_24(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { -using namespace geometry; typedef boost::shared_ptr Shared; checkArguments("print",nargout,nargin-1,0); Shared obj = unwrap_shared_ptr(in[0], "ptr_Test"); @@ -338,7 +324,6 @@ using namespace geometry; void Test_return_Point2Ptr_25(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { -using namespace geometry; typedef boost::shared_ptr SharedPoint2; typedef boost::shared_ptr Shared; checkArguments("return_Point2Ptr",nargout,nargin-1,1); @@ -349,7 +334,6 @@ using namespace geometry; void Test_return_Test_26(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { -using namespace geometry; typedef boost::shared_ptr SharedTest; typedef boost::shared_ptr Shared; checkArguments("return_Test",nargout,nargin-1,1); @@ -360,7 +344,6 @@ using namespace geometry; void Test_return_TestPtr_27(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { -using namespace geometry; typedef boost::shared_ptr SharedTest; typedef boost::shared_ptr Shared; checkArguments("return_TestPtr",nargout,nargin-1,1); @@ -371,7 +354,6 @@ using namespace geometry; void Test_return_bool_28(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { -using namespace geometry; typedef boost::shared_ptr Shared; checkArguments("return_bool",nargout,nargin-1,1); Shared obj = unwrap_shared_ptr(in[0], "ptr_Test"); @@ -381,7 +363,6 @@ using namespace geometry; void Test_return_double_29(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { -using namespace geometry; typedef boost::shared_ptr Shared; checkArguments("return_double",nargout,nargin-1,1); Shared obj = unwrap_shared_ptr(in[0], "ptr_Test"); @@ -391,7 +372,6 @@ using namespace geometry; void Test_return_field_30(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { -using namespace geometry; typedef boost::shared_ptr Shared; checkArguments("return_field",nargout,nargin-1,1); Shared obj = unwrap_shared_ptr(in[0], "ptr_Test"); @@ -401,7 +381,6 @@ using namespace geometry; void Test_return_int_31(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { -using namespace geometry; typedef boost::shared_ptr Shared; checkArguments("return_int",nargout,nargin-1,1); Shared obj = unwrap_shared_ptr(in[0], "ptr_Test"); @@ -411,7 +390,6 @@ using namespace geometry; void Test_return_matrix1_32(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { -using namespace geometry; typedef boost::shared_ptr Shared; checkArguments("return_matrix1",nargout,nargin-1,1); Shared obj = unwrap_shared_ptr(in[0], "ptr_Test"); @@ -421,7 +399,6 @@ using namespace geometry; void Test_return_matrix2_33(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { -using namespace geometry; typedef boost::shared_ptr Shared; checkArguments("return_matrix2",nargout,nargin-1,1); Shared obj = unwrap_shared_ptr(in[0], "ptr_Test"); @@ -431,7 +408,6 @@ using namespace geometry; void Test_return_pair_34(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { -using namespace geometry; typedef boost::shared_ptr Shared; checkArguments("return_pair",nargout,nargin-1,2); Shared obj = unwrap_shared_ptr(in[0], "ptr_Test"); @@ -443,7 +419,6 @@ using namespace geometry; void Test_return_ptrs_35(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { -using namespace geometry; typedef boost::shared_ptr SharedTest; typedef boost::shared_ptr SharedTest; typedef boost::shared_ptr Shared; @@ -457,7 +432,6 @@ using namespace geometry; void Test_return_size_t_36(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { -using namespace geometry; typedef boost::shared_ptr Shared; checkArguments("return_size_t",nargout,nargin-1,1); Shared obj = unwrap_shared_ptr(in[0], "ptr_Test"); @@ -467,7 +441,6 @@ using namespace geometry; void Test_return_string_37(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { -using namespace geometry; typedef boost::shared_ptr Shared; checkArguments("return_string",nargout,nargin-1,1); Shared obj = unwrap_shared_ptr(in[0], "ptr_Test"); @@ -477,7 +450,6 @@ using namespace geometry; void Test_return_vector1_38(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { -using namespace geometry; typedef boost::shared_ptr Shared; checkArguments("return_vector1",nargout,nargin-1,1); Shared obj = unwrap_shared_ptr(in[0], "ptr_Test"); @@ -487,7 +459,6 @@ using namespace geometry; void Test_return_vector2_39(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { -using namespace geometry; typedef boost::shared_ptr Shared; checkArguments("return_vector2",nargout,nargin-1,1); Shared obj = unwrap_shared_ptr(in[0], "ptr_Test"); diff --git a/wrap/tests/geometry.h b/wrap/tests/geometry.h index 2e92043b2..54694a1cf 100644 --- a/wrap/tests/geometry.h +++ b/wrap/tests/geometry.h @@ -15,9 +15,6 @@ class Point2 { VectorNotEigen vectorConfusion(); }; -// flag a namespace as in use - only applies *after* the declaration -using namespace geometry; - class Point3 { Point3(double x, double y, double z); double norm() const; diff --git a/wrap/tests/testWrap.cpp b/wrap/tests/testWrap.cpp index 29fc1891a..844281775 100644 --- a/wrap/tests/testWrap.cpp +++ b/wrap/tests/testWrap.cpp @@ -76,9 +76,6 @@ TEST( wrap, parse_geometry ) { Module module(markup_header_path.c_str(), "geometry",enable_verbose); EXPECT_LONGS_EQUAL(3, module.classes.size()); - // check using declarations - strvec exp_using1, exp_using2; exp_using2 += "geometry"; - // forward declarations LONGS_EQUAL(2, module.forward_declarations.size()); EXPECT(assert_equal("VectorNotEigen", module.forward_declarations[0].name)); @@ -98,7 +95,6 @@ TEST( wrap, parse_geometry ) { EXPECT_LONGS_EQUAL(7, cls.methods.size()); EXPECT_LONGS_EQUAL(0, cls.static_methods.size()); EXPECT_LONGS_EQUAL(0, cls.namespaces.size()); - EXPECT(assert_equal(exp_using1, cls.using_namespaces)); } // check second class, Point3 @@ -109,7 +105,6 @@ TEST( wrap, parse_geometry ) { EXPECT_LONGS_EQUAL(1, cls.methods.size()); EXPECT_LONGS_EQUAL(2, cls.static_methods.size()); EXPECT_LONGS_EQUAL(0, cls.namespaces.size()); - EXPECT(assert_equal(exp_using2, cls.using_namespaces)); // first constructor takes 3 doubles ArgumentList c1 = cls.constructor.args_list.front(); @@ -140,7 +135,6 @@ TEST( wrap, parse_geometry ) { EXPECT_LONGS_EQUAL(19, testCls.methods.size()); EXPECT_LONGS_EQUAL( 0, testCls.static_methods.size()); EXPECT_LONGS_EQUAL( 0, testCls.namespaces.size()); - EXPECT(assert_equal(exp_using2, testCls.using_namespaces)); // function to parse: pair return_pair (Vector v, Matrix A) const; CHECK(testCls.methods.find("return_pair") != testCls.methods.end()); diff --git a/wrap/utilities.cpp b/wrap/utilities.cpp index 6b6e57094..52ed3c750 100644 --- a/wrap/utilities.cpp +++ b/wrap/utilities.cpp @@ -115,13 +115,6 @@ string maybe_shared_ptr(bool add, const string& qtype, const string& type) { return str; } -/* ************************************************************************* */ -void generateUsingNamespace(FileWriter& file, const vector& using_namespaces) { - if (using_namespaces.empty()) return; - BOOST_FOREACH(const string& s, using_namespaces) - file.oss << "using namespace " << s << ";" << endl; -} - /* ************************************************************************* */ string qualifiedName(const string& separator, const vector& names, const string& finalName) { string result; diff --git a/wrap/utilities.h b/wrap/utilities.h index 2eaf5397a..85a2246a2 100644 --- a/wrap/utilities.h +++ b/wrap/utilities.h @@ -122,11 +122,6 @@ bool assert_equal(const std::vector& expected, const std::vector& using_namespaces); - /** * Return a qualified name, if finalName is empty, only the names vector will * be used (i.e. there won't be a trailing separator on the qualified name). From c32d1c7e027f4b6dc7505fd6fe3de26a49e09481 Mon Sep 17 00:00:00 2001 From: Richard Roberts Date: Mon, 23 Jul 2012 19:29:52 +0000 Subject: [PATCH 10/11] Fixed dimensions bug in Marginals and added unit test --- gtsam/inference/GenericSequentialSolver-inl.h | 2 +- gtsam/nonlinear/Marginals.cpp | 13 +++-- tests/testMarginals.cpp | 55 +++++++++++++++++++ 3 files changed, 64 insertions(+), 6 deletions(-) diff --git a/gtsam/inference/GenericSequentialSolver-inl.h b/gtsam/inference/GenericSequentialSolver-inl.h index 53dee3dcd..368aae831 100644 --- a/gtsam/inference/GenericSequentialSolver-inl.h +++ b/gtsam/inference/GenericSequentialSolver-inl.h @@ -88,7 +88,7 @@ namespace gtsam { GenericSequentialSolver::jointFactorGraph( const std::vector& js, Eliminate function) const { - // Compute a COLAMD permutation with the marginal variable constrained to the end. + // Compute a COLAMD permutation with the marginal variables constrained to the end. Permutation::shared_ptr permutation(inference::PermutationCOLAMD(*structure_, js)); Permutation::shared_ptr permutationInverse(permutation->inverse()); diff --git a/gtsam/nonlinear/Marginals.cpp b/gtsam/nonlinear/Marginals.cpp index f7f1aa00f..52c507374 100644 --- a/gtsam/nonlinear/Marginals.cpp +++ b/gtsam/nonlinear/Marginals.cpp @@ -110,11 +110,11 @@ JointMarginal Marginals::jointMarginalInformation(const std::vector& variab return JointMarginal(info, dims, indices); } else { - // Convert keys to linear indices + // Obtain requested variables as ordered indices vector indices(variables.size()); for(size_t i=0; i& variab jointFG = *GaussianSequentialSolver(graph_, true).jointFactorGraph(indices); } - // Conversion from variable keys to position in factor graph variables, + // Build map from variable keys to position in factor graph variables, // which are sorted in index order. Ordering variableConversion; { + // First build map from index to key FastMap usedIndices; for(size_t i=0; i Index_Key; BOOST_FOREACH(const Index_Key& index_key, usedIndices) { @@ -145,8 +147,9 @@ JointMarginal Marginals::jointMarginalInformation(const std::vector& variab // Get dimensions from factor graph std::vector dims(indices.size(), 0); - for(size_t i = 0; i < variables.size(); ++i) - dims[i] = values_.at(variables[i]).dim(); + BOOST_FOREACH(Key key, variables) { + dims[variableConversion[key]] = values_.at(key).dim(); + } // Get information matrix Matrix augmentedInfo = jointFG.denseHessian(); diff --git a/tests/testMarginals.cpp b/tests/testMarginals.cpp index da7157a1e..c9bd43b27 100644 --- a/tests/testMarginals.cpp +++ b/tests/testMarginals.cpp @@ -180,7 +180,62 @@ TEST(Marginals, planarSLAMmarginals) { EXPECT(assert_equal(expectedx1, Matrix(joint_l2x1(x1,x1)), 1e-6)); } +/* ************************************************************************* */ +TEST(Marginals, order) { + NonlinearFactorGraph fg; + fg.add(PriorFactor(0, Pose2(), noiseModel::Unit::Create(3))); + fg.add(BetweenFactor(0, 1, Pose2(1,0,0), noiseModel::Unit::Create(3))); + fg.add(BetweenFactor(1, 2, Pose2(1,0,0), noiseModel::Unit::Create(3))); + fg.add(BetweenFactor(2, 3, Pose2(1,0,0), noiseModel::Unit::Create(3))); + Values vals; + vals.insert(0, Pose2()); + vals.insert(1, Pose2(1,0,0)); + vals.insert(2, Pose2(2,0,0)); + vals.insert(3, Pose2(3,0,0)); + + vals.insert(100, Point2(0,1)); + vals.insert(101, Point2(1,1)); + + fg.add(BearingRangeFactor(0, 100, + vals.at(0).bearing(vals.at(100)), + vals.at(0).range(vals.at(100)), noiseModel::Unit::Create(2))); + fg.add(BearingRangeFactor(0, 101, + vals.at(0).bearing(vals.at(101)), + vals.at(0).range(vals.at(101)), noiseModel::Unit::Create(2))); + + fg.add(BearingRangeFactor(1, 100, + vals.at(1).bearing(vals.at(100)), + vals.at(1).range(vals.at(100)), noiseModel::Unit::Create(2))); + fg.add(BearingRangeFactor(1, 101, + vals.at(1).bearing(vals.at(101)), + vals.at(1).range(vals.at(101)), noiseModel::Unit::Create(2))); + + fg.add(BearingRangeFactor(2, 100, + vals.at(2).bearing(vals.at(100)), + vals.at(2).range(vals.at(100)), noiseModel::Unit::Create(2))); + fg.add(BearingRangeFactor(2, 101, + vals.at(2).bearing(vals.at(101)), + vals.at(2).range(vals.at(101)), noiseModel::Unit::Create(2))); + + fg.add(BearingRangeFactor(3, 100, + vals.at(3).bearing(vals.at(100)), + vals.at(3).range(vals.at(100)), noiseModel::Unit::Create(2))); + fg.add(BearingRangeFactor(3, 101, + vals.at(3).bearing(vals.at(101)), + vals.at(3).range(vals.at(101)), noiseModel::Unit::Create(2))); + + Marginals marginals(fg, vals); + FastVector keys(fg.keys()); + JointMarginal joint = marginals.jointMarginalCovariance(keys); + + LONGS_EQUAL(3, joint(0,0).rows()); + LONGS_EQUAL(3, joint(1,1).rows()); + LONGS_EQUAL(3, joint(2,2).rows()); + LONGS_EQUAL(3, joint(3,3).rows()); + LONGS_EQUAL(2, joint(100,100).rows()); + LONGS_EQUAL(2, joint(101,101).rows()); +} /* ************************************************************************* */ int main() { TestResult tr; return TestRegistry::runAllTests(tr);} From 065b7ee1e6dff19eaf2a6be2cc7e8a6d42f9913c Mon Sep 17 00:00:00 2001 From: Richard Roberts Date: Mon, 23 Jul 2012 19:29:57 +0000 Subject: [PATCH 11/11] In wrap tests, read file in text mode to translate line endings --- wrap/utilities.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wrap/utilities.cpp b/wrap/utilities.cpp index 52ed3c750..973778d71 100644 --- a/wrap/utilities.cpp +++ b/wrap/utilities.cpp @@ -30,7 +30,7 @@ using namespace std; /* ************************************************************************* */ string file_contents(const string& filename, bool skipheader) { - ifstream ifs(filename.c_str(), ios::binary); // Do not do LF/CRLF translation - we always write in binary mode too + ifstream ifs(filename.c_str()); if(!ifs) throw CantOpenFile(filename); // read file into stringstream