diff --git a/hello_plugin/CMakeLists.txt b/hello_plugin/CMakeLists.txt index 75722dccbde1b387a589a419b75be6a9d146fbe9..4582cc4090cd73d4e19f2a66cb9140df2c4d47b7 100644 --- a/hello_plugin/CMakeLists.txt +++ b/hello_plugin/CMakeLists.txt @@ -4,7 +4,9 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) # ADD_EXECUTABLE(hello_plugin hello_plugin.cpp sensor_odom_2D.cpp processor_odom_2D.cpp) ADD_EXECUTABLE(hello_plugin hello_plugin.cpp) +ADD_EXECUTABLE(params_autoconf params_autoconf.cpp) target_link_libraries(hello_plugin class_loader boost_system console_bridge wolf yaml-cpp ${CERES_LIBRARIES}) +target_link_libraries(params_autoconf class_loader boost_system console_bridge wolf yaml-cpp ) # These lines always at the end SET(HDRS_PLUGIN ${HDRS_PLUGIN} PARENT_SCOPE ) SET(SRCS_PLUGIN ${SRCS_PLUGIN} PARENT_SCOPE ) diff --git a/hello_plugin/hello_plugin.cpp b/hello_plugin/hello_plugin.cpp index 86baf7eb83c957293828e3a10f98d5a5f083b7b1..9077d04f300a9bcd9c52677a8992c04716144013 100644 --- a/hello_plugin/hello_plugin.cpp +++ b/hello_plugin/hello_plugin.cpp @@ -56,6 +56,7 @@ int main(int argc, char** argv) { cout << s._name << " " << s._type << " " << s._name_assoc_sensor << endl; procesorMap.insert(pair<string, ProcessorBasePtr>(s._name,problem->installProcessor(s._type, s._name, s._name_assoc_sensor, server))); } + problem->print(4,1,1,1); Vector2s motion_data(1.0, 0.0); // Will advance 1m at each keyframe, will not turn. Matrix2s motion_cov = 0.1 * Matrix2s::Identity(); diff --git a/hello_plugin/params.yaml b/hello_plugin/params.yaml index ff190b7334b2cd1941da436b0846499bf965446a..db5fab3faaa036d7ba02f7f30c6a21468098330f 100644 --- a/hello_plugin/params.yaml +++ b/hello_plugin/params.yaml @@ -20,6 +20,11 @@ config: type: "RANGE BEARING" name: "rb_processor" sensorname: "rb" + - + type: "ODOM 2D" + name: "my_proc_test" + sensorname: "odom" + follow: "../hello_plugin/params_conf.yaml" files: - "/home/jcasals/workspace/wip/wolf/lib/libsensor_odo.so" - "/home/jcasals/workspace/wip/wolf/lib/librange_bearing.so" \ No newline at end of file diff --git a/hello_plugin/params_autoconf.cpp b/hello_plugin/params_autoconf.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cf95715f84451676b6ad36a477c68a8c9a57a405 --- /dev/null +++ b/hello_plugin/params_autoconf.cpp @@ -0,0 +1,71 @@ +/* + * params_autoconf.cpp + * + * Created on: Feb 15, 2019 + * Author: jcasals + */ +#include <class_loader/class_loader.hpp> +#include "base/sensor/sensor_base.h" +#include "base/wolf.h" +// #include "sensor_odom_2D.cpp" +#include <yaml-cpp/yaml.h> +#include "parser_yaml.hpp" +#include "base/params_server.hpp" + +#include "../hello_wolf/capture_range_bearing.h" +#include "../hello_wolf/feature_range_bearing.h" +#include "../hello_wolf/constraint_range_bearing.h" +#include "../hello_wolf/landmark_point_2D.h" +#include "base/processor/processor_odom_2D.h" + +#include "base/solver/solver_factory.h" +#include "base/ceres_wrapper/ceres_manager.h" + +using namespace std; +using namespace class_loader; +using namespace wolf; +using namespace Eigen; + +int main(int argc, char** argv) { + string file = ""; + if(argc > 1) file = argv[1]; + parserYAML parser = parserYAML(file); + parser.parse(); + paramsServer server = paramsServer(parser.getParams(), parser.sensorsSerialization(), parser.processorsSerialization()); + cout << "PRINTING SERVER MAP" << endl; + server.print(); + cout << "-----------------------------------" << endl; + /** + It seems to be a requirement that each file is loaded by its own ClassLoader object, otherwise I get + a segmentation fault. Likewise, it seems that these ClassLoaders must be allocated at the heap, because + the constructor refuses to build an object if I try to do local (stack) allocation, i.e `ClassLoader(it)` is not allowed but `new ClassLoader(it)` is. + **/ + vector<ClassLoader*> class_loaders = vector<ClassLoader*>(); + for(auto it : parser.getFiles()) { + auto c = new ClassLoader(it); + class_loaders.push_back(c); + } + ProblemPtr problem = Problem::create("PO 2D"); + auto sensorMap = map<string, SensorBasePtr>(); + auto procesorMap = map<string, ProcessorBasePtr>(); + for(auto s : server.getSensors()){ + cout << s._name << " " << s._type << endl; + sensorMap.insert(pair<string, SensorBasePtr>(s._name,problem->installSensor(s._type, s._name, server))); + } + for(auto s : server.getProcessors()){ + cout << s._name << " " << s._type << " " << s._name_assoc_sensor << endl; + procesorMap.insert(pair<string, ProcessorBasePtr>(s._name,problem->installProcessor(s._type, s._name, s._name_assoc_sensor, server))); + } + auto prc = ProcessorParamsOdom2D("my_proc_test", server); + + std::cout << "prc.cov_det " << prc.cov_det << std::endl; + std::cout << "prc.unmeasured_perturbation_std " << prc.unmeasured_perturbation_std << std::endl; + std::cout << "prc.angle_turned " << prc.angle_turned << std::endl; + std::cout << "prc.dist_traveled " << prc.dist_traveled << std::endl; + std::cout << "prc.max_buff_length " << prc.max_buff_length << std::endl; + std::cout << "prc.max_time_span " << prc.max_time_span << std::endl; + std::cout << "prc.time_tolerance " << prc.time_tolerance << std::endl; + std::cout << "prc.voting_active " << prc.voting_active << std::endl; + + return 0; +} diff --git a/hello_plugin/params_conf.yaml b/hello_plugin/params_conf.yaml new file mode 100644 index 0000000000000000000000000000000000000000..0d80a5802f5da772f59c29adf12257c8f79663d3 --- /dev/null +++ b/hello_plugin/params_conf.yaml @@ -0,0 +1,8 @@ +cov_det: 100 +unmeasured_perturbation_std: 100 +angle_turned: 100 +dist_traveled: 100 +max_buff_length: 100 +max_time_span: 100 +time_tolerance: 100 +voting_active: false \ No newline at end of file diff --git a/hello_plugin/parser_yaml.hpp b/hello_plugin/parser_yaml.hpp index 455561e01219fed6a80ea41118ed787af92fc6e7..ffe2adc5f5f5779dd91fd500ca9573d90564376a 100644 --- a/hello_plugin/parser_yaml.hpp +++ b/hello_plugin/parser_yaml.hpp @@ -140,13 +140,20 @@ void parserYAML::walkTreeR(YAML::Node n, vector<string>& tags, string hdr){ } case YAML::NodeType::Map : { for(const auto& kv : n){ + // If the key's value starts with a $ (i.e. $key) then its value is parsed as a literal map, + //otherwise the parser recursively parses the map regex r("^\\$.*"); if(not regex_match(kv.first.as<string>(), r)){ - tags.push_back(kv.first.as<string>()); - if(tags.size() == 2) this->updateActiveName(kv.first.as<string>()); - walkTreeR(kv.second, tags, hdr +"/"+ kv.first.as<string>()); - tags.pop_back(); - if(tags.size() == 1) this->updateActiveName(""); + regex rr("follow"); + if(not regex_match(kv.first.as<string>(), rr)) { + tags.push_back(kv.first.as<string>()); + if(tags.size() == 2) this->updateActiveName(kv.first.as<string>()); + walkTreeR(kv.second, tags, hdr +"/"+ kv.first.as<string>()); + tags.pop_back(); + if(tags.size() == 1) this->updateActiveName(""); + }else{ + walkTree(kv.second.as<string>(), tags, hdr); + } }else{ string key = kv.first.as<string>(); key = key.substr(1,key.size() - 1); diff --git a/include/base/converter.h b/include/base/converter.h index 357a5f81d9fa31f014353317b445e5d61b586e4d..2bff920a96c853c460a6aabc3fd863ecc1c6212c 100644 --- a/include/base/converter.h +++ b/include/base/converter.h @@ -116,6 +116,12 @@ struct converter<int>{ } }; template<> +struct converter<unsigned int>{ + static unsigned int convert(std::string val){ + return stod(val); + } +}; +template<> struct converter<double>{ static double convert(std::string val){ return stod(val); diff --git a/include/base/processor/processor_IMU.h b/include/base/processor/processor_IMU.h index 98c7cffeef534a179e2127eb4b775e437a92c8d6..64d97861c8915db1e1ea5b29f9022c8361cc2b46 100644 --- a/include/base/processor/processor_IMU.h +++ b/include/base/processor/processor_IMU.h @@ -11,7 +11,12 @@ WOLF_STRUCT_PTR_TYPEDEFS(ProcessorParamsIMU); struct ProcessorParamsIMU : public ProcessorParamsMotion { - // + ProcessorParamsIMU() = default; + ProcessorParamsIMU(std::string _unique_name, const paramsServer& _server): + ProcessorParamsMotion(_unique_name, _server) + { + // + } }; WOLF_PTR_TYPEDEFS(ProcessorIMU); diff --git a/include/base/processor/processor_base.h b/include/base/processor/processor_base.h index 23ac82daa6ff6ea65bc3172d4fa0726890e5dff1..fb5c9e64739ec1b68190c2bc719d2772f241ae23 100644 --- a/include/base/processor/processor_base.h +++ b/include/base/processor/processor_base.h @@ -11,6 +11,7 @@ class SensorBase; #include "base/node_base.h" #include "base/time_stamp.h" #include "base/frame_base.h" +#include "base/params_server.hpp" // std #include <memory> @@ -108,7 +109,6 @@ class PackKeyFrameBuffer struct ProcessorParamsBase { ProcessorParamsBase() = default; - ProcessorParamsBase(bool _voting_active, Scalar _time_tolerance) : voting_active(_voting_active) @@ -116,6 +116,11 @@ struct ProcessorParamsBase { // } + ProcessorParamsBase(std::string _unique_name, const paramsServer& _server) + { + voting_active = _server.getParam<bool>(_unique_name + "/voting_active", "false"); + time_tolerance = _server.getParam<Scalar>(_unique_name + "/time_tolerance", "0"); + } virtual ~ProcessorParamsBase() = default; diff --git a/include/base/processor/processor_diff_drive.h b/include/base/processor/processor_diff_drive.h index e219b552f566153659b3f3643ce9a3210b89efe4..dc7f77c80855097907585f2689e4b8d093d6d82d 100644 --- a/include/base/processor/processor_diff_drive.h +++ b/include/base/processor/processor_diff_drive.h @@ -10,6 +10,7 @@ #include "base/processor/processor_motion.h" #include "base/diff_drive_tools.h" +#include "base/params_server.hpp" namespace wolf { @@ -17,19 +18,13 @@ WOLF_STRUCT_PTR_TYPEDEFS(ProcessorParamsDiffDrive); struct ProcessorParamsDiffDrive : public ProcessorParamsMotion { -// ProcessorParamsDiffDrive(const Scalar _time_tolerance, -// const Scalar _dist_travel_th, -// const Scalar _theta_traveled_th, -// const Scalar _cov_det_th, -// const Scalar _unmeasured_perturbation_std = 0.0001) : -// dist_traveled_th_(_dist_travel_th), -// theta_traveled_th_(_theta_traveled_th), -// cov_det_th_(_cov_det_th), -// unmeasured_perturbation_std_(_unmeasured_perturbation_std) -// { -// time_tolerance = _time_tolerance; -// } Scalar unmeasured_perturbation_std = 0.0001; + ProcessorParamsDiffDrive(); + ProcessorParamsDiffDrive(std::string _unique_name, const paramsServer& _server): + ProcessorParamsMotion(_unique_name, _server) + { + unmeasured_perturbation_std = _server.getParam<Scalar>(_unique_name + "/unmeasured_perturbation_std", "0.0001"); + } }; /** diff --git a/include/base/processor/processor_motion.h b/include/base/processor/processor_motion.h index df43f9f841e51c7d8d0cae06354b04c0752b159d..cb7957e1a713b89a52213dffad45c1d5bd2069f9 100644 --- a/include/base/processor/processor_motion.h +++ b/include/base/processor/processor_motion.h @@ -12,6 +12,7 @@ #include "base/capture/capture_motion.h" #include "base/processor/processor_base.h" #include "base/time_stamp.h" +#include "base/params_server.hpp" // std #include <iomanip> @@ -27,6 +28,15 @@ struct ProcessorParamsMotion : public ProcessorParamsBase unsigned int max_buff_length = 10; Scalar dist_traveled = 5; Scalar angle_turned = 0.5; + ProcessorParamsMotion() = default; + ProcessorParamsMotion(std::string _unique_name, const paramsServer& _server): + ProcessorParamsBase(_unique_name, _server) + { + max_time_span = _server.getParam<Scalar>(_unique_name + "/max_time_span", "0.5"); + max_buff_length = _server.getParam<unsigned int>(_unique_name + "/max_buff_length", "10"); + dist_traveled = _server.getParam<Scalar>(_unique_name + "/dist_traveled", "5"); + angle_turned = _server.getParam<Scalar>(_unique_name + "/angle_turned", "0.5"); + } }; /** \brief class for Motion processors diff --git a/include/base/processor/processor_odom_2D.h b/include/base/processor/processor_odom_2D.h index af8856455ae55f9269f95e7b7ca8bd796db242e3..a8a8942c73218571677b6653fdbf994645fba84f 100644 --- a/include/base/processor/processor_odom_2D.h +++ b/include/base/processor/processor_odom_2D.h @@ -23,6 +23,14 @@ struct ProcessorParamsOdom2D : public ProcessorParamsMotion { Scalar cov_det = 1.0; // 1 rad^2 Scalar unmeasured_perturbation_std = 0.001; // no particular dimension: the same for displacement and angle + + ProcessorParamsOdom2D() = default; + ProcessorParamsOdom2D(std::string _unique_name, const paramsServer& _server): + ProcessorParamsMotion(_unique_name, _server) + { + cov_det = _server.getParam<Scalar>(_unique_name + "/cov_det", "1.0"); + unmeasured_perturbation_std = _server.getParam<Scalar>(_unique_name + "/unmeasured_perturbation_std", "0.001"); + } }; class ProcessorOdom2D : public ProcessorMotion diff --git a/include/base/processor/processor_odom_3D.h b/include/base/processor/processor_odom_3D.h index 491ae23c7593d2b9c13ad52ed2b90f046a91274a..21bad23eac1aab6c455f1eba5edd098fd25ccb20 100644 --- a/include/base/processor/processor_odom_3D.h +++ b/include/base/processor/processor_odom_3D.h @@ -21,7 +21,12 @@ WOLF_STRUCT_PTR_TYPEDEFS(ProcessorParamsOdom3D); struct ProcessorParamsOdom3D : public ProcessorParamsMotion { - // + ProcessorParamsOdom3D() = default; + ProcessorParamsOdom3D(std::string _unique_name, const paramsServer& _server): + ProcessorParamsMotion(_unique_name, _server) + { + // + } }; WOLF_PTR_TYPEDEFS(ProcessorOdom3D); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 37859c19ea9713f5ca503c3b9fd9ac7abb7441db..c4e1ce8bee30236fa0ba79626d2588898a4f2b15 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -84,6 +84,10 @@ target_link_libraries(gtest_motion_buffer ${PROJECT_NAME}) wolf_add_gtest(gtest_pack_KF_buffer gtest_pack_KF_buffer.cpp) target_link_libraries(gtest_pack_KF_buffer ${PROJECT_NAME}) +# YAML parser +wolf_add_gtest(gtest_parser_yaml gtest_parser_yaml.cpp) +target_link_libraries(gtest_parser_yaml ${PROJECT_NAME}) + # Problem class test wolf_add_gtest(gtest_problem gtest_problem.cpp) target_link_libraries(gtest_problem ${PROJECT_NAME}) diff --git a/test/gtest_parser_yaml.cpp b/test/gtest_parser_yaml.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b25e7a4b30e303c3f76c4e7196e431d0a4bbd79b --- /dev/null +++ b/test/gtest_parser_yaml.cpp @@ -0,0 +1,24 @@ +#include "utils_gtest.h" +#include "base/converter.h" +#include "../hello_plugin/parser_yaml.hpp" + +using namespace std; +using namespace wolf; + +TEST(ParserYAML, RegularParse) +{ + string file = ""; + file = "../test/params1.yaml"; + parserYAML parser = parserYAML(file); + parser.parse(); + auto params = parser.getParams(); + for(auto it : params) + cout << it.first << " %% " << it.second << endl; + ASSERT_EQ(params["odom/intrinsic/k_rot_to_rot"], "0.1"); +} + +int main(int argc, char **argv) +{ + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/params1.yaml b/test/params1.yaml new file mode 100644 index 0000000000000000000000000000000000000000..db5fab3faaa036d7ba02f7f30c6a21468098330f --- /dev/null +++ b/test/params1.yaml @@ -0,0 +1,30 @@ +config: + sensors: + - + type: "ODOM 2D" + name: "odom" + intrinsic: + k_disp_to_disp: 0.1 + k_rot_to_rot: 0.1 + extrinsic: + pos: [1,2,3] + - + type: "RANGE BEARING" + name: "rb" + processors: + - + type: "ODOM 2D" + name: "processor1" + sensorname: "odom" + - + type: "RANGE BEARING" + name: "rb_processor" + sensorname: "rb" + - + type: "ODOM 2D" + name: "my_proc_test" + sensorname: "odom" + follow: "../hello_plugin/params_conf.yaml" +files: + - "/home/jcasals/workspace/wip/wolf/lib/libsensor_odo.so" + - "/home/jcasals/workspace/wip/wolf/lib/librange_bearing.so" \ No newline at end of file