Git Product home page Git Product logo

dmpbbo's People

Contributors

ahoarau avatar avm99963 avatar bvgvgv avatar danielskatz avatar dlsuser avatar eurobin-project avatar graiola avatar stulp avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dmpbbo's Issues

Error when building

I got compilation error when building on Ubuntu 18.04

In file included from /home/yuriy/Documents/dmpbbo/src/dmpbbo_io/EigenBoostSerialization.hpp:114:0,
                 from /home/yuriy/Documents/dmpbbo/src/dynamicalsystems/DynamicalSystem.hpp:33,
                 from /home/yuriy/Documents/dmpbbo/src/dynamicalsystems/DynamicalSystem.cpp:24:
/home/yuriy/Documents/dmpbbo/src/dmpbbo_io/EigenBoostSerialization.tpp: In function ‘void boost::serialization::load(Archive&, Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>&, unsigned int)’:
/home/yuriy/Documents/dmpbbo/src/dmpbbo_io/EigenBoostSerialization.tpp:100:12: error: ‘cerr’ is not a member of ‘std’
       std::cerr << __FILE__ << ":" << __LINE__ << ":";
            ^~~~
/home/yuriy/Documents/dmpbbo/src/dmpbbo_io/EigenBoostSerialization.tpp:100:12: note: suggested alternative: ‘errc’
       std::cerr << __FILE__ << ":" << __LINE__ << ":";
            ^~~~
            errc
/home/yuriy/Documents/dmpbbo/src/dmpbbo_io/EigenBoostSerialization.tpp:101:12: error: ‘cerr’ is not a member of ‘std’
       std::cerr << "WARNING: Unexpected character '" << c << "' when deserializing Eigen::Matrix." << std::endl;
            ^~~~
/home/yuriy/Documents/dmpbbo/src/dmpbbo_io/EigenBoostSerialization.tpp:101:12: note: suggested alternative: ‘errc’
       std::cerr << "WARNING: Unexpected character '" << c << "' when deserializing Eigen::Matrix." << std::endl;
            ^~~~
            errc
/home/yuriy/Documents/dmpbbo/src/dmpbbo_io/EigenBoostSerialization.tpp:131:18: error: ‘cerr’ is not a member of ‘std’
             std::cerr << __FILE__ << ":" << __LINE__ << ":";
                  ^~~~
/home/yuriy/Documents/dmpbbo/src/dmpbbo_io/EigenBoostSerialization.tpp:131:18: note: suggested alternative: ‘errc’
             std::cerr << __FILE__ << ":" << __LINE__ << ":";
                  ^~~~
                  errc
/home/yuriy/Documents/dmpbbo/src/dmpbbo_io/EigenBoostSerialization.tpp:132:18: error: ‘cerr’ is not a member of ‘std’
             std::cerr << "WARNING: Unexpected character '" << c << "' when deserializing Eigen::Matrix." << std::endl;
                  ^~~~
/home/yuriy/Documents/dmpbbo/src/dmpbbo_io/EigenBoostSerialization.tpp:132:18: note: suggested alternative: ‘errc’
             std::cerr << "WARNING: Unexpected character '" << c << "' when deserializing Eigen::Matrix." << std::endl;
                  ^~~~
                  errc
src/dynamicalsystems/CMakeFiles/dynamicalsystems.dir/build.make:62: recipe for target 'src/dynamicalsystems/CMakeFiles/dynamicalsystems.dir/DynamicalSystem.cpp.o' failed
make[2]: *** [src/dynamicalsystems/CMakeFiles/dynamicalsystems.dir/DynamicalSystem.cpp.o] Error 1
CMakeFiles/Makefile2:223: recipe for target 'src/dynamicalsystems/CMakeFiles/dynamicalsystems.dir/all' failed
make[1]: *** [src/dynamicalsystems/CMakeFiles/dynamicalsystems.dir/all] Error 2
Makefile:129: recipe for target 'all' failed
make: *** [all] Error 2

Adding #include <iostream> before

#include <boost/archive/text_oarchive.hpp>
solves the issue.

Limit checks are missing

I found that this library does not consider constraints such as acceleration, velocity or position limits. I did find the forcing term scaling here:

https://github.com/stulp/dmpbbo/blob/master/src/dmp/Dmp.cpp#L629

But it doesn't seem to prevent the system from breaching its limits. I'm currently unsure whether the feature is not implemented yet or whether I just didn't find it.

I think that such a (optional) feature can be easily implemented by introducing a limits_ member in DynamicalSystem and performing an element-wise std::max in integrateStep. Do you think that's something we should implement? If so I will create a PR for this.

Implement robot_demo_traj

Many researchers do not run the DMP in the real-time control loop, but rather use dmpbbo to generate trajectories off-line, and then execute those trajectories on the robot. See for instance #61.

For these users, it would be much better to have a robot_demo_traj implementation, where everything is done in Python. This is related to #60, but can be done independently of #60 (which is a massive refactoring of the entire code base)

Seg fault in deserialized dmp->analyticalSolution

I serialize and deserialize a Dmp similar to testDmpSerialization.cpp. Then, calling dmp->analyticalSolution() leads to a sigsegv error.

Crash occurs at 560th line of Dmp.cpp:
perturbation(i_dim) = (*analytical_solution_perturber_)();

Apparently, after deserialization analytical_solution_perturber_ is not NULL anymore. But I didn't set it before serialization. Also, there is no perturbation property in a serialized dmp.xml file.

As a workaround, calling dmp->set_perturbation_analytical_solution() after deserialization solves the problem:

{
    // create and open an archive for input
    ifstream ifs;
    ifs.open(dmp_filename.c_str());
    boost::archive::xml_iarchive ia(ifs);
    // read class state from archive
    ia >> BOOST_SERIALIZATION_NVP(dmp_);
  } // brackets for auto-closing streams

  // to avoid seg fault in analyticalSolution
  dmp_->set_perturbation_analytical_solution(0.0);

Built with static libraries, debug mode. Ubuntu 16.04.

memory leak in FunctionApproximatorLWR

There is a memory leak in FunctionApproximatorLWR.cpp because the constructor clones meta_params and model_params. I fixed it applying the following changes:

@@ -67,15 +68,21 @@ FunctionApproximator* FunctionApproximatorLWR::clone(void) const {
   if (getModelParameters()!=NULL)
     model_params = dynamic_cast<ModelParametersLWR*>(getModelParameters()->clone());

+  FunctionApproximatorLWR* falwr;
   if (meta_params==NULL)
-    return new FunctionApproximatorLWR(model_params);
-  else
-    return new FunctionApproximatorLWR(meta_params,model_params);
+    falwr = new FunctionApproximatorLWR(model_params);
+  else {
+    falwr = new FunctionApproximatorLWR(meta_params,model_params);
+    delete meta_params;
+  }
+  delete model_params;
+
+  return falwr;
 };

I did not check other approximators, but if the code is similar, the problem might be more widespread.

Issues with Demos and Tests

It would be nice to add some instructions on how to call the demos. This is mentioned for demoDynamicalSystems in the tutorial, however the corresponding plotDynamicalSystem.py does not seem to exist.
The Python Wrappers are nice, but it is also not 100% clear how to call them. You need to "make install" and then call them from the original source directory, which I didn't find very intuitive.

The help for semoDynamicalSystems is quite nice, for the dmp demos I'd suggest changing it to the same format (with a complete example of a call)

If you call demoDmpChangeGoal or similar with a relative path for the output, the python files don't work if called from a different location then from which they were generated. E.g.
./demoDmpChangeGoal output/ and then going to the directory where the Python script resides and trying to call is there

Some of the demos cause a core dump if they don't find the correct file rather than existing nicely
I found demoDmpTrainFromTrajFile and demoOptimizationDmp

related note demoFunctionApproxTrainingWrapper.py crashes if lwpr is not installed while the C++ handles that correctly

I also got core dumps for
functionapproximator/tests/testTrainingCompareCppPython
and
dmp_bbo/tests/testTaskViapoint

Refactoring Python/C++ redundancy

Rationale for removing bbo C++ implementation

There is obvious code redunancy due to the parallel Python and C++ implementations. This is because there are two different purposes.

  • C++ for real-time implementation, and completeness (implements many more features)
  • Python better for scripting and didactic purposes.

The modules bbo and dmp_bbo need not be real-time, and therefore the C++ implementation is not really necessary.

Planned refactoring steps

  1. Port functionality from src/bbo to python/bbo (and dmp_bbo also)
  2. Add docstrings in Python from C++ code
  3. Apply consistent formatting in Python with black
  4. Remove src/dmp_bbo, src/bbo

Further steps along the way:

  • Rename dmpbbo_io => eigen_tools
  • Get rid of boost::serialization, which is very annoying, and replace with a YAML/JSON library?

Comparison to None in python

At the moment there are a few comparisons to None and when running I just get:

FutureWarning: comparison to None will result in an elementwise object comparison in the future.
if samples==None:

But in the latest numpy version it is treated as an error.
ValueError: the truth value of an array with more than one element is ambiguous.
Use a.any() or a.all()

Not compiling due to boost::serialization (again!)

Since the following commit, dmpbbo no longer compiles on travis (it does on Ubuntu 18.04 using boost 1.65 though)
d2fe4cb

The commit only involves documentation, so the broken build must be due to a change in the boost libraries, perhaps similar to this issue:
freeorion/freeorion#445

I need to read this:
https://freeorion.org/forum/viewtopic.php?t=10671

Or perhaps one of these:
esa/pagmo#174
esa/pagmo#69
esa/pagmo#68

It's very easy to find people that have strange linking issues with boost serialization...

scaling to new goals

In the document, I find this repo still not provide the function for scaling towards new goals.
$$\begin{bmatrix} \dot{z} \ \dot{y} \end{bmatrix} = \begin{bmatrix} (\alpha_y(\beta_y (y^{g_d} - y) -z) + v \cdot f(x))/\tau \ z / \tau  \end{bmatrix}  $$

Is it possible to use the traditional method for scaling towards novel goals like the following equation?

$$\begin{bmatrix} \dot{z} \ \dot{y} \end{bmatrix} = \begin{bmatrix} (\alpha_y(\beta_y (y^{g_d} - y) -z) + v \cdot f(x) \cdot (g-y_0)))/\tau \ z / \tau  \end{bmatrix}  $$

Implement UpdaterCovarAdaptation::setSubMatrices to mimic parallel optimization

The parallel optimization is no longer needed if the covariance matrix updates updates the matrix in submatrices. The simple solution to this would be to have a function UpdaterCovarAdaptation::setSubMatrices(VectorXi), in which the sizes of the submatrices are set, rather than derived from the array of distributions:

covar_block_sizes[pp] = distributions[pp].mean().size();

The following functions can then be deleted:

/** \todo Get rid of runOptimizationParallelDeprecated(), and implement in UpdaterCovarAdapation

bool saveToDirectory(

A bug about "/dmp_bbo/demoImitationAndOptimization.cpp"

#when I run the "/dmp_bbo/demoImitationAndOptimization.cpp", there is an error. After printing out the "breakpoint", I find the return of the function "Trajectory::getRangePerDim()" wrong. Indeed, the return should be transposed so that it is a vector. I change the code like this:
111
And it works well.

Unclear how to call Python wrappers

The Python Wrappers are nice, but it is also not 100% clear how to call them. You need to "make install" and then call them from the original source directory, which I didn't find very intuitive.

(splitting #31 into several separate issues)

License LGPL or GPL?

Hi, I noticed your library has 2 different license files (LGPL and GPL) checked in -- under what license is this library licensed?

Thank you!

Something went wrong when compiling the code

Hey bro! Something went wrong when I compiled the code.
The compilation process is as follows:

scu@pisoso:~/workspace/ws_lhj/opensource/dmpbbo$ mkdir -p build_dir; cd build_dir; cmake .. -DCMAKE_BUILD_TYPE=Release; make -j16
CMake Deprecation Warning at CMakeLists.txt:2 (cmake_minimum_required):
  Compatibility with CMake < 2.8.12 will be removed from a future version of
  CMake.

  Update the VERSION argument <min> value or use a ...<max> suffix to tell
  CMake that the project does not need compatibility with older versions.


-- The C compiler identification is GNU 7.5.0
-- The CXX compiler identification is GNU 7.5.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found PkgConfig: /usr/bin/pkg-config (found version "0.29.1") 
-- Could NOT find LWPR (missing: LWPR_LIBRARY LWPR_INCLUDE_DIR) 
-- Found Boost: /usr/local/lib/cmake/Boost-1.74.0/BoostConfig.cmake (found suitable version "1.74.0", minimum required is "1.34") found components: filesystem system serialization 

-- Could NOT find Doxygen (missing: DOXYGEN_EXECUTABLE) 
CMake Warning at CMakeLists.txt:83 (message):
  Doxygen is needed to build the documentation.  Please install it correctly


-- Configuring done
-- Generating done
-- Build files have been written to: /home/scu/workspace/ws_lhj/opensource/dmpbbo/build_dir
[  5%] Building CXX object src/dynamicalsystems/CMakeFiles/dynamicalsystems.dir/DynamicalSystem.cpp.o
[  5%] Building CXX object src/dmp/CMakeFiles/dmp.dir/DmpContextual.cpp.o
[  5%] Building CXX object src/eigen/CMakeFiles/eigen.dir/eigen_json.cpp.o
[  5%] Building CXX object src/dynamicalsystems/CMakeFiles/dynamicalsystems.dir/DynamicalSystemFactory.cpp.o
[  5%] Building CXX object src/dmp/CMakeFiles/dmp.dir/Dmp.cpp.o
[  5%] Building CXX object src/bbo/CMakeFiles/bbo.dir/DistributionGaussian.cpp.o
[  7%] Building CXX object src/dmp_bbo/CMakeFiles/dmp_bbo.dir/ExperimentBBO.cpp.o
[  7%] Building CXX object src/dynamicalsystems/CMakeFiles/dynamicalsystems.dir/ExponentialSystem.cpp.o
[  8%] Building CXX object src/bbo/CMakeFiles/bbo.dir/runOptimization.cpp.o
[  9%] Building CXX object src/dynamicalsystems/CMakeFiles/dynamicalsystems.dir/SigmoidSystem.cpp.o
[ 10%] Building CXX object src/dmp_bbo/tasks/CMakeFiles/tasksolverdmparm2d.dir/TaskSolverDmpArm2D.cpp.o
[ 11%] Building CXX object src/dmp_bbo/CMakeFiles/dmp_bbo.dir/Rollout.cpp.o
[ 13%] Building CXX object src/dmp/CMakeFiles/dmp.dir/DmpContextualOneStep.cpp.o
[ 13%] Building CXX object src/dmp_bbo/tasks/CMakeFiles/taskviapoint.dir/TaskViapoint.cpp.o
[ 14%] Building CXX object src/dmp_bbo/tasks/CMakeFiles/taskviapointarm2d.dir/TaskViapointArm2D.cpp.o
[ 15%] Building CXX object src/functionapproximators/CMakeFiles/functionapproximators.dir/BasisFunction.cpp.o
[ 16%] Building CXX object src/bbo/CMakeFiles/bbo.dir/updaters/UpdaterCovarAdaptation.cpp.o
[ 17%] Building CXX object src/dmp_bbo/CMakeFiles/dmp_bbo.dir/Task.cpp.o
[ 18%] Linking CXX static library libeigen.a
[ 18%] Built target eigen
[ 19%] Building CXX object src/dmp/CMakeFiles/dmp.dir/DmpContextualTwoStep.cpp.o
[ 20%] Building CXX object src/dynamicalsystems/CMakeFiles/dynamicalsystems.dir/SpringDamperSystem.cpp.o
[ 21%] Linking CXX static library libtaskviapointarm2d.a
[ 21%] Built target taskviapointarm2d
[ 22%] Building CXX object src/bbo/CMakeFiles/bbo.dir/updaters/UpdaterCovarDecay.cpp.o
[ 23%] Linking CXX static library libtasksolverdmparm2d.a
[ 23%] Built target tasksolverdmparm2d
[ 24%] Building CXX object src/dmp_bbo/CMakeFiles/dmp_bbo.dir/TaskSolver.cpp.o
In file included from /usr/include/c++/7/bits/stl_algobase.h:67:0,
                 from /usr/include/c++/7/bits/char_traits.h:39,
                 from /usr/include/c++/7/string:40,
                 from /home/scu/workspace/ws_lhj/opensource/dmpbbo/src/dynamicalsystems/DynamicalSystem.hpp:29,
                 from /home/scu/workspace/ws_lhj/opensource/dmpbbo/src/dynamicalsystems/ExponentialSystem.hpp:27,
                 from /home/scu/workspace/ws_lhj/opensource/dmpbbo/src/dynamicalsystems/ExponentialSystem.cpp:24:
/usr/include/c++/7/bits/stl_iterator.h: In instantiation of ‘std::insert_iterator<_Container>& std::insert_iterator<_Container>::operator=(typename _Container::value_type&&) [with _Container = Eigen::Matrix<double, -1, 1>; typename _Container::value_type = double]’:
/usr/include/c++/7/bits/stl_algo.h:4306:12:   required from ‘_OIter std::transform(_IIter, _IIter, _OIter, _UnaryOperation) [with _IIter = nlohmann::detail::iter_impl<const nlohmann::basic_json<> >; _OIter = std::insert_iterator<Eigen::Matrix<double, -1, 1> >; _UnaryOperation = nlohmann::detail::from_json_array_impl(const BasicJsonType&, ConstructibleArrayType&, nlohmann::detail::priority_tag<0>) [with BasicJsonType = nlohmann::basic_json<>; ConstructibleArrayType = Eigen::Matrix<double, -1, 1>]::<lambda(const nlohmann::basic_json<>&)>]/usr/include/nlohmann/detail/conversions/from_json.hpp:215:19:   required from ‘void nlohmann::detail::from_json_array_impl(const BasicJsonType&, ConstructibleArrayType&, nlohmann::detail::priority_tag<0>) [with BasicJsonType = nlohmann::basic_json<>; ConstructibleArrayType = Eigen::Matrix<double, -1, 1>]/usr/include/nlohmann/detail/conversions/from_json.hpp:245:25:   required from ‘decltype (((nlohmann::detail::from_json_array_impl(j, arr, nlohmann::detail::priority_tag<3>{}), j.get<typename ConstructibleArrayType::value_type>()), void())) nlohmann::detail::from_json(const BasicJsonType&, ConstructibleArrayType&) [with BasicJsonType = nlohmann::basic_json<>; ConstructibleArrayType = Eigen::Matrix<double, -1, 1>; typename std::enable_if<(((nlohmann::detail::is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value && (! nlohmann::detail::is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value)) && (! nlohmann::detail::is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value)) && (! nlohmann::detail::is_basic_json<T>::value)), int>::type <anonymous> = 0; decltype (((nlohmann::detail::from_json_array_impl(j, arr, nlohmann::detail::priority_tag<3>{}), j.get<typename ConstructibleArrayType::value_type>()), void())) = void; typename ConstructibleArrayType::value_type = double]/usr/include/nlohmann/detail/conversions/from_json.hpp:377:25:   required from ‘decltype ((nlohmann::detail::from_json(j, val), void())) nlohmann::detail::from_json_fn::operator()(const BasicJsonType&, T&) const [with BasicJsonType = nlohmann::basic_json<>; T = Eigen::Matrix<double, -1, 1>; decltype ((nlohmann::detail::from_json(j, val), void())) = void]/usr/include/nlohmann/adl_serializer.hpp:28:30:   required from ‘static decltype ((nlohmann::{anonymous}::from_json(forward<BasicJsonType>(j), val), void())) nlohmann::adl_serializer<T, SFINAE>::from_json(BasicJsonType&&, ValueType&) [with BasicJsonType = const nlohmann::basic_json<>&; ValueType = Eigen::Matrix<double, -1, 1>; <template-parameter-1-1> = Eigen::Matrix<double, -1, 1>; <template-parameter-1-2> = void; decltype ((nlohmann::{anonymous}::from_json(forward<BasicJsonType>(j), val), void())) = void]/usr/include/nlohmann/json.hpp:2643:45:   required from ‘ValueType nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>::get() const [with ValueTypeCV = Eigen::Matrix<double, -1, 1>; ValueType = Eigen::Matrix<double, -1, 1>; typename std::enable_if<(((! nlohmann::detail::is_basic_json<U>::value) && nlohmann::detail::has_from_json<nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>, ValueType>::value) && (! nlohmann::detail::has_non_default_from_json<nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>, ValueType>::value)), int>::type <anonymous> = 0; ObjectType = std::map; ArrayType = std::vector; StringType = std::__cxx11::basic_string<char>; BooleanType = bool; NumberIntegerType = long int; NumberUnsignedType = long unsigned int; NumberFloatType = double; AllocatorType = std::allocator; JSONSerializer = nlohmann::adl_serializer]/usr/include/nlohmann/json.hpp:2936:30:   required from ‘nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>::operator ValueType() const [with ValueType = Eigen::Matrix<double, -1, 1>; typename std::enable_if<((((((! std::is_pointer<_Ptr>::value) && (! std::is_same<ValueType, nlohmann::detail::json_ref<nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer> > >::value)) && (! std::is_same<ValueType, typename StringType::value_type>::value)) && (! nlohmann::detail::is_basic_json<BasicJsonType>::value)) && (! std::is_same<ValueType, std::initializer_list<typename StringType::value_type> >::value)) && typename nlohmann::detail::detector<nlohmann::detail::nonesuch, void, nlohmann::detail::get_template_function, const nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>&, ValueType>::value_t:: value), int>::type <anonymous> = 0; ObjectType = std::map; ArrayType = std::vector; StringType = std::__cxx11::basic_string<char>; BooleanType = bool; NumberIntegerType = long int; NumberUnsignedType = long unsigned int; NumberFloatType = double; AllocatorType = std::allocator; JSONSerializer = nlohmann::adl_serializer]/home/scu/workspace/ws_lhj/opensource/dmpbbo/src/dynamicalsystems/ExponentialSystem.cpp:110:58:   required from here
/usr/include/c++/7/bits/stl_iterator.h:703:20: error: class Eigen::Matrix<double, -1, 1>’ has no member named ‘insert’; did you mean ‘_set’?
  iter = container->insert(iter, std::move(__value));
         ~~~~~~~~~~~^~~~~~
         _set
In file included from /usr/include/c++/7/bits/stl_algobase.h:67:0,
                 from /usr/include/c++/7/bits/char_traits.h:39,
                 from /usr/include/c++/7/string:40,
                 from /home/scu/workspace/ws_lhj/opensource/dmpbbo/src/dynamicalsystems/DynamicalSystem.hpp:29,
                 from /home/scu/workspace/ws_lhj/opensource/dmpbbo/src/dynamicalsystems/SigmoidSystem.hpp:27,
                 from /home/scu/workspace/ws_lhj/opensource/dmpbbo/src/dynamicalsystems/SigmoidSystem.cpp:31:
/usr/include/c++/7/bits/stl_iterator.h: In instantiation of ‘std::insert_iterator<_Container>& std::insert_iterator<_Container>::operator=(typename _Container::value_type&&) [with _Container = Eigen::Matrix<double, -1, 1>; typename _Container::value_type = double]’:
/usr/include/c++/7/bits/stl_algo.h:4306:12:   required from ‘_OIter std::transform(_IIter, _IIter, _OIter, _UnaryOperation) [with _IIter = nlohmann::detail::iter_impl<const nlohmann::basic_json<> >; _OIter = std::insert_iterator<Eigen::Matrix<double, -1, 1> >; _UnaryOperation = nlohmann::detail::from_json_array_impl(const BasicJsonType&, ConstructibleArrayType&, nlohmann::detail::priority_tag<0>) [with BasicJsonType = nlohmann::basic_json<>; ConstructibleArrayType = Eigen::Matrix<double, -1, 1>]::<lambda(const nlohmann::basic_json<>&)>]/usr/include/nlohmann/detail/conversions/from_json.hpp:215:19:   required from ‘void nlohmann::detail::from_json_array_impl(const BasicJsonType&, ConstructibleArrayType&, nlohmann::detail::priority_tag<0>) [with BasicJsonType = nlohmann::basic_json<>; ConstructibleArrayType = Eigen::Matrix<double, -1, 1>]/usr/include/nlohmann/detail/conversions/from_json.hpp:245:25:   required from ‘decltype (((nlohmann::detail::from_json_array_impl(j, arr, nlohmann::detail::priority_tag<3>{}), j.get<typename ConstructibleArrayType::value_type>()), void())) nlohmann::detail::from_json(const BasicJsonType&, ConstructibleArrayType&) [with BasicJsonType = nlohmann::basic_json<>; ConstructibleArrayType = Eigen::Matrix<double, -1, 1>; typename std::enable_if<(((nlohmann::detail::is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value && (! nlohmann::detail::is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value)) && (! nlohmann::detail::is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value)) && (! nlohmann::detail::is_basic_json<T>::value)), int>::type <anonymous> = 0; decltype (((nlohmann::detail::from_json_array_impl(j, arr, nlohmann::detail::priority_tag<3>{}), j.get<typename ConstructibleArrayType::value_type>()), void())) = void; typename ConstructibleArrayType::value_type = double]/usr/include/nlohmann/detail/conversions/from_json.hpp:377:25:   required from ‘decltype ((nlohmann::detail::from_json(j, val), void())) nlohmann::detail::from_json_fn::operator()(const BasicJsonType&, T&) const [with BasicJsonType = nlohmann::basic_json<>; T = Eigen::Matrix<double, -1, 1>; decltype ((nlohmann::detail::from_json(j, val), void())) = void]/usr/include/nlohmann/adl_serializer.hpp:28:30:   required from ‘static decltype ((nlohmann::{anonymous}::from_json(forward<BasicJsonType>(j), val), void())) nlohmann::adl_serializer<T, SFINAE>::from_json(BasicJsonType&&, ValueType&) [with BasicJsonType = const nlohmann::basic_json<>&; ValueType = Eigen::Matrix<double, -1, 1>; <template-parameter-1-1> = Eigen::Matrix<double, -1, 1>; <template-parameter-1-2> = void; decltype ((nlohmann::{anonymous}::from_json(forward<BasicJsonType>(j), val), void())) = void]/usr/include/nlohmann/json.hpp:2643:45:   required from ‘ValueType nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>::get() const [with ValueTypeCV = Eigen::Matrix<double, -1, 1>; ValueType = Eigen::Matrix<double, -1, 1>; typename std::enable_if<(((! nlohmann::detail::is_basic_json<U>::value) && nlohmann::detail::has_from_json<nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>, ValueType>::value) && (! nlohmann::detail::has_non_default_from_json<nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>, ValueType>::value)), int>::type <anonymous> = 0; ObjectType = std::map; ArrayType = std::vector; StringType = std::__cxx11::basic_string<char>; BooleanType = bool; NumberIntegerType = long int; NumberUnsignedType = long unsigned int; NumberFloatType = double; AllocatorType = std::allocator; JSONSerializer = nlohmann::adl_serializer]/usr/include/nlohmann/json.hpp:2936:30:   required from ‘nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>::operator ValueType() const [with ValueType = Eigen::Matrix<double, -1, 1>; typename std::enable_if<((((((! std::is_pointer<_Ptr>::value) && (! std::is_same<ValueType, nlohmann::detail::json_ref<nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer> > >::value)) && (! std::is_same<ValueType, typename StringType::value_type>::value)) && (! nlohmann::detail::is_basic_json<BasicJsonType>::value)) && (! std::is_same<ValueType, std::initializer_list<typename StringType::value_type> >::value)) && typename nlohmann::detail::detector<nlohmann::detail::nonesuch, void, nlohmann::detail::get_template_function, const nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>&, ValueType>::value_t:: value), int>::type <anonymous> = 0; ObjectType = std::map; ArrayType = std::vector; StringType = std::__cxx11::basic_string<char>; BooleanType = bool; NumberIntegerType = long int; NumberUnsignedType = long unsigned int; NumberFloatType = double; AllocatorType = std::allocator; JSONSerializer = nlohmann::adl_serializer]/home/scu/workspace/ws_lhj/opensource/dmpbbo/src/dynamicalsystems/SigmoidSystem.cpp:183:58:   required from here
/usr/include/c++/7/bits/stl_iterator.h:703:20: error: class Eigen::Matrix<double, -1, 1>’ has no member named ‘insert’; did you mean ‘_set’?
  iter = container->insert(iter, std::move(__value));
         ~~~~~~~~~~~^~~~~~
         _set
[ 48%] Building CXX object src/functionapproximators/CMakeFiles/functionapproximators.dir/ModelParametersRBFN.cpp.o
[ 49%] Linking CXX static library libdmp_bbo.a
[ 49%] Built target dmp_bbo
[ 50%] Building CXX object src/functionapproximators/CMakeFiles/functionapproximators.dir/ModelParametersRRRFF.cpp.o
src/functionapproximators/CMakeFiles/functionapproximators.dir/build.make:243: recipe for target 'src/functionapproximators/CMakeFiles/functionapproximators.dir/MetaParametersRBFN.cpp.o' failed
make[2]: *** [src/functionapproximators/CMakeFiles/functionapproximators.dir/MetaParametersRBFN.cpp.o] Error 1
make[2]: *** 正在等待未完成的任务....
[ 51%] Linking CXX static library libdmp.a
[ 51%] Built target dmp
In file included from /usr/include/nlohmann/adl_serializer.hpp:6:0,
                 from /usr/include/nlohmann/json.hpp:51,
                 from /home/scu/workspace/ws_lhj/opensource/dmpbbo/src/eigen/eigen_json.hpp:26,
                 from /home/scu/workspace/ws_lhj/opensource/dmpbbo/src/functionapproximators/ModelParametersRBFN.cpp:30:
/usr/include/nlohmann/detail/conversions/to_json.hpp: In instantiation of ‘static void nlohmann::detail::external_constructor<(nlohmann::detail::value_t)2>::construct(BasicJsonType&, const CompatibleArrayType&) [with BasicJsonType = nlohmann::basic_json<>; CompatibleArrayType = Eigen::Matrix<double, -1, -1>; typename std::enable_if<(! std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value), int>::type <anonymous> = 0]’:
/usr/include/nlohmann/detail/conversions/to_json.hpp:266:52:   required from ‘void nlohmann::detail::to_json(BasicJsonType&, const CompatibleArrayType&) [with BasicJsonType = nlohmann::basic_json<>; CompatibleArrayType = Eigen::Matrix<double, -1, -1>; typename std::enable_if<(((nlohmann::detail::is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value && (! nlohmann::detail::is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value)) && (! nlohmann::detail::is_compatible_string_type<BasicJsonType, ConstructibleStringType>::value)) && (! nlohmann::detail::is_basic_json<T>::value)), int>::type <anonymous> = 0]/usr/include/nlohmann/detail/conversions/to_json.hpp:337:23:   required from ‘decltype ((nlohmann::detail::to_json(j, forward<T>(val)), void())) nlohmann::detail::to_json_fn::operator()(BasicJsonType&, T&&) const [with BasicJsonType = nlohmann::basic_json<>; T = const Eigen::Matrix<double, -1, -1>&; decltype ((nlohmann::detail::to_json(j, forward<T>(val)), void())) = void]/usr/include/nlohmann/adl_serializer.hpp:45:28:   required from ‘static decltype ((nlohmann::{anonymous}::to_json(j, forward<ValueType>(val)), void())) nlohmann::adl_serializer<T, SFINAE>::to_json(BasicJsonType&, ValueType&&) [with BasicJsonType = nlohmann::basic_json<>; ValueType = const Eigen::Matrix<double, -1, -1>&; <template-parameter-1-1> = Eigen::Matrix<double, -1, -1>; <template-parameter-1-2> = void; decltype ((nlohmann::{anonymous}::to_json(j, forward<ValueType>(val)), void())) = void]/usr/include/nlohmann/json.hpp:1304:35:   required from ‘nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>::basic_json(CompatibleType&&) [with CompatibleType = const Eigen::Matrix<double, -1, -1>&; U = Eigen::Matrix<double, -1, -1>; typename std::enable_if<((! nlohmann::detail::is_basic_json<U>::value) && nlohmann::detail::is_compatible_type<nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>, U>::value), int>::type <anonymous> = 0; ObjectType = std::map; ArrayType = std::vector; StringType = std::__cxx11::basic_string<char>; BooleanType = bool; NumberIntegerType = long int; NumberUnsignedType = long unsigned int; NumberFloatType = double; AllocatorType = std::allocator; JSONSerializer = nlohmann::adl_serializer]/home/scu/workspace/ws_lhj/opensource/dmpbbo/src/functionapproximators/ModelParametersRBFN.cpp:233:23:   required from here
/usr/include/nlohmann/detail/conversions/to_json.hpp:133:25: error: invalid use of void expression
         j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
In file included from /usr/include/nlohmann/adl_serializer.hpp:5:0,
                 from /usr/include/nlohmann/json.hpp:51,
                 from /home/scu/workspace/ws_lhj/opensource/dmpbbo/src/eigen/eigen_json.hpp:26,
                 from /home/scu/workspace/ws_lhj/opensource/dmpbbo/src/functionapproximators/ModelParametersRBFN.cpp:30:
/usr/include/nlohmann/detail/conversions/from_json.hpp: In instantiation of ‘void nlohmann::detail::from_json_array_impl(const BasicJsonType&, ConstructibleArrayType&, nlohmann::detail::priority_tag<0>) [with BasicJsonType = nlohmann::basic_json<>; ConstructibleArrayType = Eigen::Matrix<double, -1, -1>]’:
/usr/include/nlohmann/detail/conversions/from_json.hpp:245:25:   required from ‘decltype (((nlohmann::detail::from_json_array_impl(j, arr, nlohmann::detail::priority_tag<3>{}), j.get<typename ConstructibleArrayType::value_type>()), void())) nlohmann::detail::from_json(const BasicJsonType&, ConstructibleArrayType&) [with BasicJsonType = nlohmann::basic_json<>; ConstructibleArrayType = Eigen::Matrix<double, -1, -1>; typename std::enable_if<(((nlohmann::detail::is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value && (! nlohmann::detail::is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value)) && (! nlohmann::detail::is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value)) && (! nlohmann::detail::is_basic_json<T>::value)), int>::type <anonymous> = 0; decltype (((nlohmann::detail::from_json_array_impl(j, arr, nlohmann::detail::priority_tag<3>{}), j.get<typename ConstructibleArrayType::value_type>()), void())) = void; typename ConstructibleArrayType::value_type = double]/usr/include/nlohmann/detail/conversions/from_json.hpp:377:25:   required from ‘decltype ((nlohmann::detail::from_json(j, val), void())) nlohmann::detail::from_json_fn::operator()(const BasicJsonType&, T&) const [with BasicJsonType = nlohmann::basic_json<>; T = Eigen::Matrix<double, -1, -1>; decltype ((nlohmann::detail::from_json(j, val), void())) = void]/usr/include/nlohmann/adl_serializer.hpp:28:30:   required from ‘static decltype ((nlohmann::{anonymous}::from_json(forward<BasicJsonType>(j), val), void())) nlohmann::adl_serializer<T, SFINAE>::from_json(BasicJsonType&&, ValueType&) [with BasicJsonType = const nlohmann::basic_json<>&; ValueType = Eigen::Matrix<double, -1, -1>; <template-parameter-1-1> = Eigen::Matrix<double, -1, -1>; <template-parameter-1-2> = void; decltype ((nlohmann::{anonymous}::from_json(forward<BasicJsonType>(j), val), void())) = void]/usr/include/nlohmann/json.hpp:2643:45:   required from ‘ValueType nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>::get() const [with ValueTypeCV = Eigen::Matrix<double, -1, -1>; ValueType = Eigen::Matrix<double, -1, -1>; typename std::enable_if<(((! nlohmann::detail::is_basic_json<U>::value) && nlohmann::detail::has_from_json<nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>, ValueType>::value) && (! nlohmann::detail::has_non_default_from_json<nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>, ValueType>::value)), int>::type <anonymous> = 0; ObjectType = std::map; ArrayType = std::vector; StringType = std::__cxx11::basic_string<char>; BooleanType = bool; NumberIntegerType = long int; NumberUnsignedType = long unsigned int; NumberFloatType = double; AllocatorType = std::allocator; JSONSerializer = nlohmann::adl_serializer]/usr/include/nlohmann/json.hpp:2936:30:   required from ‘nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>::operator ValueType() const [with ValueType = Eigen::Matrix<double, -1, -1>; typename std::enable_if<((((((! std::is_pointer<_Ptr>::value) && (! std::is_same<ValueType, nlohmann::detail::json_ref<nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer> > >::value)) && (! std::is_same<ValueType, typename StringType::value_type>::value)) && (! nlohmann::detail::is_basic_json<BasicJsonType>::value)) && (! std::is_same<ValueType, std::initializer_list<typename StringType::value_type> >::value)) && typename nlohmann::detail::detector<nlohmann::detail::nonesuch, void, nlohmann::detail::get_template_function, const nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>&, ValueType>::value_t:: value), int>::type <anonymous> = 0; ObjectType = std::map; ArrayType = std::vector; StringType = std::__cxx11::basic_string<char>; BooleanType = bool; NumberIntegerType = long int; NumberUnsignedType = long unsigned int; NumberFloatType = double; AllocatorType = std::allocator; JSONSerializer = nlohmann::adl_serializer]/home/scu/workspace/ws_lhj/opensource/dmpbbo/src/functionapproximators/ModelParametersRBFN.cpp:224:52:   required from here
/usr/include/nlohmann/detail/conversions/from_json.hpp:216:42: error: invalid use of void expression
         j.begin(), j.end(), std::inserter(ret, end(ret)),
                             ~~~~~~~~~~~~~^~~~~~~~~~~~~~~
In file included from /usr/include/nlohmann/adl_serializer.hpp:6:0,
                 from /usr/include/nlohmann/json.hpp:51,
                 from /home/scu/workspace/ws_lhj/opensource/dmpbbo/src/eigen/eigen_json.hpp:26,
                 from /home/scu/workspace/ws_lhj/opensource/dmpbbo/src/functionapproximators/ModelParametersLWR.cpp:30:
/usr/include/nlohmann/detail/conversions/to_json.hpp: In instantiation of ‘static void nlohmann::detail::external_constructor<(nlohmann::detail::value_t)2>::construct(BasicJsonType&, const CompatibleArrayType&) [with BasicJsonType = nlohmann::basic_json<>; CompatibleArrayType = Eigen::Matrix<double, -1, -1>; typename std::enable_if<(! std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value), int>::type <anonymous> = 0]’:
/usr/include/nlohmann/detail/conversions/to_json.hpp:266:52:   required from ‘void nlohmann::detail::to_json(BasicJsonType&, const CompatibleArrayType&) [with BasicJsonType = nlohmann::basic_json<>; CompatibleArrayType = Eigen::Matrix<double, -1, -1>; typename std::enable_if<(((nlohmann::detail::is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value && (! nlohmann::detail::is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value)) && (! nlohmann::detail::is_compatible_string_type<BasicJsonType, ConstructibleStringType>::value)) && (! nlohmann::detail::is_basic_json<T>::value)), int>::type <anonymous> = 0]/usr/include/nlohmann/detail/conversions/to_json.hpp:337:23:   required from ‘decltype ((nlohmann::detail::to_json(j, forward<T>(val)), void())) nlohmann::detail::to_json_fn::operator()(BasicJsonType&, T&&) const [with BasicJsonType = nlohmann::basic_json<>; T = const Eigen::Matrix<double, -1, -1>&; decltype ((nlohmann::detail::to_json(j, forward<T>(val)), void())) = void]/usr/include/nlohmann/adl_serializer.hpp:45:28:   required from ‘static decltype ((nlohmann::{anonymous}::to_json(j, forward<ValueType>(val)), void())) nlohmann::adl_serializer<T, SFINAE>::to_json(BasicJsonType&, ValueType&&) [with BasicJsonType = nlohmann::basic_json<>; ValueType = const Eigen::Matrix<double, -1, -1>&; <template-parameter-1-1> = Eigen::Matrix<double, -1, -1>; <template-parameter-1-2> = void; decltype ((nlohmann::{anonymous}::to_json(j, forward<ValueType>(val)), void())) = void]/usr/include/nlohmann/json.hpp:1304:35:   required from ‘nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>::basic_json(CompatibleType&&) [with CompatibleType = const Eigen::Matrix<double, -1, -1>&; U = Eigen::Matrix<double, -1, -1>; typename std::enable_if<((! nlohmann::detail::is_basic_json<U>::value) && nlohmann::detail::is_compatible_type<nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>, U>::value), int>::type <anonymous> = 0; ObjectType = std::map; ArrayType = std::vector; StringType = std::__cxx11::basic_string<char>; BooleanType = bool; NumberIntegerType = long int; NumberUnsignedType = long unsigned int; NumberFloatType = double; AllocatorType = std::allocator; JSONSerializer = nlohmann::adl_serializer]/home/scu/workspace/ws_lhj/opensource/dmpbbo/src/functionapproximators/ModelParametersLWR.cpp:444:23:   required from here
/usr/include/nlohmann/detail/conversions/to_json.hpp:133:25: error: invalid use of void expression
         j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
In file included from /usr/include/nlohmann/adl_serializer.hpp:5:0,
                 from /usr/include/nlohmann/json.hpp:51,
                 from /home/scu/workspace/ws_lhj/opensource/dmpbbo/src/eigen/eigen_json.hpp:26,
                 from /home/scu/workspace/ws_lhj/opensource/dmpbbo/src/functionapproximators/ModelParametersLWR.cpp:30:
/usr/include/nlohmann/detail/conversions/from_json.hpp: In instantiation of ‘void nlohmann::detail::from_json_array_impl(const BasicJsonType&, ConstructibleArrayType&, nlohmann::detail::priority_tag<0>) [with BasicJsonType = nlohmann::basic_json<>; ConstructibleArrayType = Eigen::Matrix<double, -1, -1>]’:
/usr/include/nlohmann/detail/conversions/from_json.hpp:245:25:   required from ‘decltype (((nlohmann::detail::from_json_array_impl(j, arr, nlohmann::detail::priority_tag<3>{}), j.get<typename ConstructibleArrayType::value_type>()), void())) nlohmann::detail::from_json(const BasicJsonType&, ConstructibleArrayType&) [with BasicJsonType = nlohmann::basic_json<>; ConstructibleArrayType = Eigen::Matrix<double, -1, -1>; typename std::enable_if<(((nlohmann::detail::is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value && (! nlohmann::detail::is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value)) && (! nlohmann::detail::is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value)) && (! nlohmann::detail::is_basic_json<T>::value)), int>::type <anonymous> = 0; decltype (((nlohmann::detail::from_json_array_impl(j, arr, nlohmann::detail::priority_tag<3>{}), j.get<typename ConstructibleArrayType::value_type>()), void())) = void; typename ConstructibleArrayType::value_type = double]/usr/include/nlohmann/detail/conversions/from_json.hpp:377:25:   required from ‘decltype ((nlohmann::detail::from_json(j, val), void())) nlohmann::detail::from_json_fn::operator()(const BasicJsonType&, T&) const [with BasicJsonType = nlohmann::basic_json<>; T = Eigen::Matrix<double, -1, -1>; decltype ((nlohmann::detail::from_json(j, val), void())) = void]/usr/include/nlohmann/adl_serializer.hpp:28:30:   required from ‘static decltype ((nlohmann::{anonymous}::from_json(forward<BasicJsonType>(j), val), void())) nlohmann::adl_serializer<T, SFINAE>::from_json(BasicJsonType&&, ValueType&) [with BasicJsonType = const nlohmann::basic_json<>&; ValueType = Eigen::Matrix<double, -1, -1>; <template-parameter-1-1> = Eigen::Matrix<double, -1, -1>; <template-parameter-1-2> = void; decltype ((nlohmann::{anonymous}::from_json(forward<BasicJsonType>(j), val), void())) = void]/usr/include/nlohmann/json.hpp:2643:45:   required from ‘ValueType nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>::get() const [with ValueTypeCV = Eigen::Matrix<double, -1, -1>; ValueType = Eigen::Matrix<double, -1, -1>; typename std::enable_if<(((! nlohmann::detail::is_basic_json<U>::value) && nlohmann::detail::has_from_json<nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>, ValueType>::value) && (! nlohmann::detail::has_non_default_from_json<nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>, ValueType>::value)), int>::type <anonymous> = 0; ObjectType = std::map; ArrayType = std::vector; StringType = std::__cxx11::basic_string<char>; BooleanType = bool; NumberIntegerType = long int; NumberUnsignedType = long unsigned int; NumberFloatType = double; AllocatorType = std::allocator; JSONSerializer = nlohmann::adl_serializer]/usr/include/nlohmann/json.hpp:2936:30:   required from ‘nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>::operator ValueType() const [with ValueType = Eigen::Matrix<double, -1, -1>; typename std::enable_if<((((((! std::is_pointer<_Ptr>::value) && (! std::is_same<ValueType, nlohmann::detail::json_ref<nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer> > >::value)) && (! std::is_same<ValueType, typename StringType::value_type>::value)) && (! nlohmann::detail::is_basic_json<BasicJsonType>::value)) && (! std::is_same<ValueType, std::initializer_list<typename StringType::value_type> >::value)) && typename nlohmann::detail::detector<nlohmann::detail::nonesuch, void, nlohmann::detail::get_template_function, const nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>&, ValueType>::value_t:: value), int>::type <anonymous> = 0; ObjectType = std::map; ArrayType = std::vector; StringType = std::__cxx11::basic_string<char>; BooleanType = bool; NumberIntegerType = long int; NumberUnsignedType = long unsigned int; NumberFloatType = double; AllocatorType = std::allocator; JSONSerializer = nlohmann::adl_serializer]/home/scu/workspace/ws_lhj/opensource/dmpbbo/src/functionapproximators/ModelParametersLWR.cpp:434:52:   required from here
/usr/include/nlohmann/detail/conversions/from_json.hpp:216:42: error: invalid use of void expression
         j.begin(), j.end(), std::inserter(ret, end(ret)),
                             ~~~~~~~~~~~~~^~~~~~~~~~~~~~~
In file included from /usr/local/include/eigen3/Eigen/Core:152:0,
                 from /home/scu/workspace/ws_lhj/opensource/dmpbbo/src/dmpbbo_io/EigenBoostSerialization.hpp:29,
                 from /home/scu/workspace/ws_lhj/opensource/dmpbbo/src/functionapproximators/Parameterizable.hpp:29,
                 from /home/scu/workspace/ws_lhj/opensource/dmpbbo/src/functionapproximators/ModelParameters.hpp:27,
                 from /home/scu/workspace/ws_lhj/opensource/dmpbbo/src/functionapproximators/ModelParametersLWR.hpp:27,
                 from /home/scu/workspace/ws_lhj/opensource/dmpbbo/src/functionapproximators/ModelParametersLWR.cpp:24:
/usr/local/include/eigen3/Eigen/src/Core/StlIterators.h: In instantiation of ‘Eigen::DenseBase<Derived>::iterator Eigen::DenseBase<Derived>::end() [with Derived = Eigen::Matrix<double, -1, -1>; Eigen::DenseBase<Derived>::iterator = void]’:
/usr/include/c++/7/bits/range_access.h:69:25:   required from ‘decltype (__cont.end()) std::end(_Container&) [with _Container = Eigen::Matrix<double, -1, -1>; decltype (__cont.end()) = void]/usr/include/nlohmann/detail/conversions/from_json.hpp:216:51:   required from ‘void nlohmann::detail::from_json_array_impl(const BasicJsonType&, ConstructibleArrayType&, nlohmann::detail::priority_tag<0>) [with BasicJsonType = nlohmann::basic_json<>; ConstructibleArrayType = Eigen::Matrix<double, -1, -1>]/usr/include/nlohmann/detail/conversions/from_json.hpp:245:25:   required from ‘decltype (((nlohmann::detail::from_json_array_impl(j, arr, nlohmann::detail::priority_tag<3>{}), j.get<typename ConstructibleArrayType::value_type>()), void())) nlohmann::detail::from_json(const BasicJsonType&, ConstructibleArrayType&) [with BasicJsonType = nlohmann::basic_json<>; ConstructibleArrayType = Eigen::Matrix<double, -1, -1>; typename std::enable_if<(((nlohmann::detail::is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value && (! nlohmann::detail::is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value)) && (! nlohmann::detail::is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value)) && (! nlohmann::detail::is_basic_json<T>::value)), int>::type <anonymous> = 0; decltype (((nlohmann::detail::from_json_array_impl(j, arr, nlohmann::detail::priority_tag<3>{}), j.get<typename ConstructibleArrayType::value_type>()), void())) = void; typename ConstructibleArrayType::value_type = double]/usr/include/nlohmann/detail/conversions/from_json.hpp:377:25:   required from ‘decltype ((nlohmann::detail::from_json(j, val), void())) nlohmann::detail::from_json_fn::operator()(const BasicJsonType&, T&) const [with BasicJsonType = nlohmann::basic_json<>; T = Eigen::Matrix<double, -1, -1>; decltype ((nlohmann::detail::from_json(j, val), void())) = void]/usr/include/nlohmann/adl_serializer.hpp:28:30:   required from ‘static decltype ((nlohmann::{anonymous}::from_json(forward<BasicJsonType>(j), val), void())) nlohmann::adl_serializer<T, SFINAE>::from_json(BasicJsonType&&, ValueType&) [with BasicJsonType = const nlohmann::basic_json<>&; ValueType = Eigen::Matrix<double, -1, -1>; <template-parameter-1-1> = Eigen::Matrix<double, -1, -1>; <template-parameter-1-2> = void; decltype ((nlohmann::{anonymous}::from_json(forward<BasicJsonType>(j), val), void())) = void]/usr/include/nlohmann/json.hpp:2643:45:   required from ‘ValueType nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>::get() const [with ValueTypeCV = Eigen::Matrix<double, -1, -1>; ValueType = Eigen::Matrix<double, -1, -1>; typename std::enable_if<(((! nlohmann::detail::is_basic_json<U>::value) && nlohmann::detail::has_from_json<nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>, ValueType>::value) && (! nlohmann::detail::has_non_default_from_json<nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>, ValueType>::value)), int>::type <anonymous> = 0; ObjectType = std::map; ArrayType = std::vector; StringType = std::__cxx11::basic_string<char>; BooleanType = bool; NumberIntegerType = long int; NumberUnsignedType = long unsigned int; NumberFloatType = double; AllocatorType = std::allocator; JSONSerializer = nlohmann::adl_serializer]/usr/include/nlohmann/json.hpp:2936:30:   required from ‘nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>::operator ValueType() const [with ValueType = Eigen::Matrix<double, -1, -1>; typename std::enable_if<((((((! std::is_pointer<_Ptr>::value) && (! std::is_same<ValueType, nlohmann::detail::json_ref<nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer> > >::value)) && (! std::is_same<ValueType, typename StringType::value_type>::value)) && (! nlohmann::detail::is_basic_json<BasicJsonType>::value)) && (! std::is_same<ValueType, std::initializer_list<typename StringType::value_type> >::value)) && typename nlohmann::detail::detector<nlohmann::detail::nonesuch, void, nlohmann::detail::get_template_function, const nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer>&, ValueType>::value_t:: value), int>::type <anonymous> = 0; ObjectType = std::map; ArrayType = std::vector; StringType = std::__cxx11::basic_string<char>; BooleanType = bool; NumberIntegerType = long int; NumberUnsignedType = long unsigned int; NumberFloatType = double; AllocatorType = std::allocator; JSONSerializer = nlohmann::adl_serializer]/home/scu/workspace/ws_lhj/opensource/dmpbbo/src/functionapproximators/ModelParametersLWR.cpp:434:52:   required from here
/usr/local/include/eigen3/Eigen/src/Core/StlIterators.h:309:3: error: static assertion failed: YOU_TRIED_CALLING_A_VECTOR_METHOD_ON_A_MATRIX
   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
   ^
In file included from /usr/local/include/eigen3/Eigen/Core:340:0,
                 from /home/scu/workspace/ws_lhj/opensource/dmpbbo/src/dmpbbo_io/EigenBoostSerialization.hpp:29,
                 from /home/scu/workspace/ws_lhj/opensource/dmpbbo/src/functionapproximators/Parameterizable.hpp:29,
                 from /home/scu/workspace/ws_lhj/opensource/dmpbbo/src/functionapproximators/ModelParameters.hpp:27,
                 from /home/scu/workspace/ws_lhj/opensource/dmpbbo/src/functionapproximators/ModelParametersRBFN.hpp:27,
                 from /home/scu/workspace/ws_lhj/opensource/dmpbbo/src/functionapproximators/ModelParametersRBFN.cpp:24:
/usr/local/include/eigen3/Eigen/src/Core/StlIterators.h:328:10: error: expression list treated as compound expression in functional cast [-fpermissive]
   return const_iterator(derived(), size());
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/functionapproximators/CMakeFiles/functionapproximators.dir/build.make:313: recipe for target 'src/functionapproximators/CMakeFiles/functionapproximators.dir/ModelParametersLWR.cpp.o' failed
make[2]: *** [src/functionapproximators/CMakeFiles/functionapproximators.dir/ModelParametersLWR.cpp.o] Error 1
src/functionapproximators/CMakeFiles/functionapproximators.dir/build.make:327: recipe for target 'src/functionapproximators/CMakeFiles/functionapproximators.dir/ModelParametersRBFN.cpp.o' failed
make[2]: *** [src/functionapproximators/CMakeFiles/functionapproximators.dir/ModelParametersRBFN.cpp.o] Error 1
[ 52%] Linking CXX static library libbbo.a
[ 52%] Built target bbo
CMakeFiles/Makefile2:496: recipe for target 'src/functionapproximators/CMakeFiles/functionapproximators.dir/all' failed
make[1]: *** [src/functionapproximators/CMakeFiles/functionapproximators.dir/all] Error 2
Makefile:135: recipe for target 'all' failed
make: *** [all] Error 2

Thank you for your reply

(minor) compile error on OS X

#include <vector> is missing on branch master in functionapproximators.dir/Parameterizable.hpp. It generates an error when compiled with clang on OS X 10.9.

Integrating gains in demo_robot

The problem that I see in your task is that you are not using an impedance controller. Therefore, I am not sure how the gains can play a role, for example, in the cost function. We can check that the exploration takes place but not the optimization. The alternative is to integrate the gains in the rollout function.

Demo instructions

It would be nice to add some instructions on how to call the demos. This is mentioned for demoDynamicalSystems in the tutorial, however the corresponding plotDynamicalSystem.py does not seem to exist.

(splitting #31 into several separate issues)

Serializing old archives after updating the library

I have been using older versions of DMPBBO (~2018). Recently I updated to the latest and observed that I can't save or load serialized DMPs anymore. After some debugging, I noticed that adding the #include "dmp/serialization.hpp" line solves the saving issue. It is hard to spot since the program still builds without this header and it used to work without the header in the older versions. I suggest mentioning this in the documentation.

I still can't load the old DMP archives with the following error:

terminate called after throwing an instance of 'boost::archive::archive_exception'
what():  unregistered class

Probably, I will need to do some changes in the old XML files. I will send the updates.

demoOptimizationDmp exits with core dump

Some of the demos cause a core dump if they don't find the correct file rather than existing nicely
I found demoOptimizationDmp

(splitting #31 into several separate issues)

Refactor Parameterizable in C++

Due to the use of the "mask", the Parameterizable implementation is complex and inefficient (the main design decision behind it was to keep the implementations in its subclasses simple; now I see it makes Parameterizable itself too complex).

It should be refactored so that:

  • Subclasses return a vector of the right size, as is done in the Python implementation (rather than vector_all)
  • Subclasses must return min_values/max_values, and be smart about which block of parameters they belong to.

That should make the code easier to debug. The current complexity is the bottleneck for allowing DmpWithGainSchedules to inherit from Parameterizable (see #61)

Installation Requirements

I installed/compiled dmpbbo on a VirtualBox of fresh Ubuntu 16.04 (desktop) install.

Eigen3 is still required but went missing after a recent commit (Ubuntu now contains a high enough version, so custom install is not required) but should be added to apt-get list, i.e., libeigen3-dev

For the Python part tkinter (python3-tk) was not included by default when installing python3 via apt-get but also required.

In general it would be nice to mention which versions of Debian/Ubuntu this has been tested with.

openjournals/joss-reviews#1225

DMP Implementation for PDFF Exploration

These questions are specifically about utilizing discrete DMPs (implemented in this repository) for the reaching task, especially in the context of this paper (https://onlinelibrary.wiley.com/doi/abs/10.1111/desc.12638).

  • For multi-joint arms, what is the input trajectory for training?
    • We noticed the code (in the above repository) and your proximodistal learning paper seem to follow different approaches. The code involves trajectories in world coordinates and the paper involves trajectories in joint angles. Therefore, in order to use your code, is it accurate if we provide joint angles as inputs? We would not like to use inverse kinematics during the movement of the robot (output) since the purpose of our project is to develop an alternative method for arm reach, based on human-learning processes.
  • We were assuming that only the end-effector trajectory is passed in for training the DMPs. However, in that case, when are joint trajectories calculated? Or are joint trajectories known initially?
  • Is the forcing function in the paper (and its MATLAB code) the same as joint acceleration in the paper, section 3.1.3? If so, then can we integrate the output and send joint positions (angles) to the robot to follow?

Any help or pointers on this will be highly appreciated!

Installing serialization headers

When I install DMPBBO in a new PC using the release build:

mkdir -p build_dir; cd build_dir; cmake .. -DCMAKE_BUILD_TYPE=Release; make; make Docs
sudo make install

It does not copy the serialization.hpp headers into /usr/local/include/.. directories. So it gives fatal error: dmp/serialization.hpp: No such file or directory at compilation.

It works fine when doing the debug build:

mkdir -p build_dir; cd build_dir; cmake .. -DCMAKE_BUILD_TYPE=Release; make; make Docs
sudo make install

Eorror when compile on Ubuntu 16.04

I compile on Ubuntu 16.04, but there are errors. I don't know how to figure it out. Would you please give me some suggestion. Thanks for your kindly help.
Following is the screenshot of the error.
image

Error in Rollout.py

Hello Freek,

I encountered the following problem after the first rollouts :
python3 david_one_update.py optimization/

  File "david_one_update.py", line 148, in <module>
    oneUpdate(args.directory,args.plot)
  File "david_one_update.py", line 72, in oneUpdate
    i_update = runOptimizationTaskOneUpdate(directory, task, initial_distribution, updater, n_samples_per_update)
  File "/home/beng_wi/git_repo_david_optimization/dmpbbo/python/dmp_bbo/run_one_update.py", line 130, in runOptimizationTaskOneUpdate
    saveUpdateRollouts(directory, i_update, distribution, rollout_eval, rollouts, weights, distribution_new)
  File "/home/beng_wi/git_repo_david_optimization/dmpbbo/python/dmp_bbo/dmp_bbo_plotting.py", line 187, in saveUpdateRollouts
    if rollouts[0].total_cost():
  File "/home/beng_wi/git_repo_david_optimization/dmpbbo/python/dmp_bbo/Rollout.py", line 39, in total_cost
    if self.cost:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

I am using Python 3.6.4

Make install doesn't install eigen_realtime header

Make install doesn't install eigen_realtime header. Building a code that includes Dmpbbo fails with fatal error: eigen_realtime/eigen_realtime_check.hpp no such file or directory .

Copying the header into /usr/local/include manually solves the problem:

mkdir /usr/local/include/eigen_realtime
cp path-to-dmpbbo/src/eigen_realtime/eigen_realtime_check.hpp /usr/local/include/eigen_realtime/

System: Ubuntu 16.04

robot demos README typo

just a small typo
python3 step1_defineTask.py results/
should be
python3 step2_defineTask.py results/

Compile issues on Ubuntu 16.04

I am getting some compile issues on Ubuntu 16.04 concerning boost::serialization. Not sure what's going on here, but any help would be appreciated!

Screenshot shows error when compiling with debug symbols, but this was recreated on two computers in normal compile mode as well.
screenshot from 2017-06-15 10-11-15

Error on executing demoDmpDbo.py

Hi

I have the following error when I execute the demo:

$python2 demoDmpBbo.py

../../../bin/demoDmpBbo /tmp/demoDmpBbo/

/home/marie-morgane/ensStage/dmpbbo/src/dynamicalsystems/SigmoidSystem.cpp:116:In function SigmoidSystem::computeKs(), Ks is too close to N_0s. This may lead to errors during numerical integration. Recommended solution: choose a lower magnitude for the maximum rate of change (currently it is -40)
Couldn't make directory '/tmp/demoDmpBbo/'. Not saving data.
Traceback (most recent call last):
  File "demoDmpBbo.py", line 36, in <module>
    plotEvolutionaryOptimization(directory,axs)
  File "/home/marie-morgane/ensStage/dmpbbo/src/bbo/plotting/plotEvolutionaryOptimization.py", line 188, in plotEvolutionaryOptimization
    plotLearningCurve(eval_at_samples,costs_eval,ax,costs_all)
  File "/home/marie-morgane/ensStage/dmpbbo/src/bbo/plotting/plotEvolutionaryOptimization.py", line 151, in plotLearningCurve
    y_limits = [0,1.2*max(costs_eval)];
ValueError: max() arg is an empty sequence

Could you please tell me if this problem comes from my install or if this is a more general issue?

Thank you.

Hints on DmpWithGainSchedules does not yet override Parameterizable interface

I am using the DmpWithGainSchedules class to optimize the gains of a DMP. However, the impedance gains are not modified during the rollouts. In line 171 of DmpWithGainSchedules.hpp, there is a TODO left to do. Its description is to override the Parameterizable interface. Thus, the function approximators for gains can not yet be parametrized. This TODO is probably causing the bug of the optimization of the gains. I would appreciate any hint or help on how to tackle the task.

Thanks,

demoDynamicalSystem has default test for nonsense entries

I accidentally typo'd on a call to demoDynamicalSystem and found out that it runs with any text after the call, e.g. python demoDynamicalSystem.py a b. I don't think there needs to be testing for valid user entry but it might be helpful if the demo printed out which test was being run when an invalid entry was made.

Making C++/Python implementation of Dmp interchangeable

First implement these in Python

enum DmpType { IJSPEERT_2002_MOVEMENT, KULVICIUS_2012_JOINING, COUNTDOWN_2013 };

Dmp(int n_dims_dmp, std::vector<FunctionApproximator*> function_approximators,

Check if same results

dmp_bb_robot readme

It would be helpful if there could be a one liner be added about the use of the demo_one_update and demo_perform_rollouts be added in the readme on what the input directory is expected to contain. I didn't see anything in the referenced section of the docs about use of those files specifically.

Suggest adding in start / end markers to demoOptimizationDmp.py

something like

    # Plot start / end markers on trajectory
    ax_rollout.plot(h[0].get_xdata()[0], h[0].get_ydata()[0], 'rx', mew=3, label='start')
    ax_rollout.plot(h[0].get_xdata()[-1], h[0].get_ydata()[-1], 'bx', mew=3, label='end')
    plt.legend()

after line 107 in runOptimizationTask.py just adds a start and end marker to the demo. Just a suggestion to make it a little easier to parse on first glance:

Optimization_with_covar_update=decay

Problem with demoDmpChangeGoal and relative paths

If you call demoDmpChangeGoal or similar with a relative path for the output, the python files don't work if called from a different location then from which they were generated. E.g.
./demoDmpChangeGoal output/ and then going to the directory where the Python script resides and trying to call is there

(splitting #31 into several separate issues)

process for contributors

What is the process to become a contributor to the code? Is it just making a PR, or is there a contributors list that names should be appended to (or anything along these lines)? Could you add a sentence in the README on what the process for submitting code to this repo is?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.