DMP_BBO library
DmpContextual.cpp
Go to the documentation of this file.
1 
24 #include "dmp/DmpContextual.hpp"
25 
26 #include "dmp/Trajectory.hpp"
28 
29 #include <assert.h>
30 #include <iostream>
31 #include <eigen3/Eigen/Core>
32 
33 
34 using namespace std;
35 using namespace Eigen;
36 
37 namespace DmpBbo {
38 
39 DmpContextual::DmpContextual(int n_dims_dmp, std::vector<FunctionApproximator*> function_approximators, DmpType dmp_type)
40 : Dmp(n_dims_dmp, function_approximators, dmp_type)
41 {
42  policy_parameter_function_goal_ = std::vector<FunctionApproximator*>(0);
44 }
45 
47 {
48  // Make clones, one for each of the dimensions of the goal
49  policy_parameter_function_goal_ = vector<FunctionApproximator*>(dim_orig());
50  for (int dd=0; dd<dim_orig(); dd++)
51  {
52  policy_parameter_function_goal_[dd] = function_approximator->clone();
53  }
54 }
55 
57 {
58  // Output of this function approximator should always be 1D (duration is time is 1D)
59  assert(function_approximator->getExpectedOutputDim()==1);
60 
61  policy_parameter_function_duration_ = function_approximator->clone();
62 }
63 
64 // In the end, all of the below train(...) variants call the pure virtual function
65 // virtual void train(const std::vector<Trajectory>& trajectories, const std::vector<Eigen::MatrixXd>& task_parameters, std::string save_directory, bool overwrite) = 0;
66 
67 
68 void DmpContextual::train(const std::vector<Trajectory>& trajectories, const std::vector<Eigen::MatrixXd>& task_parameters, std::string save_directory)
69 {
70  bool overwrite = false;
71  train(trajectories, task_parameters, save_directory, overwrite);
72 }
73 
74 void DmpContextual::train(const std::vector<Trajectory>& trajectories, const std::vector<Eigen::MatrixXd>& task_parameters)
75 {
76  bool overwrite=false;
77  string save_directory("");
78  train(trajectories, task_parameters, save_directory, overwrite);
79 }
80 
81 
82 void DmpContextual::trainLocal(const std::vector<Trajectory>& trajectories, const std::vector<Eigen::MatrixXd>& task_parameters, std::string save_directory, bool overwrite)
83 {
85  {
86  unsigned int n_demonstrations = trajectories.size();
87  assert(n_demonstrations==task_parameters.size());
88 
89  // Gather task parameters in a matrix
90  int n_task_parameters = task_parameters[0].cols();
91  MatrixXd inputs(n_demonstrations,n_task_parameters);
92  for (unsigned int i_demo=0; i_demo<n_demonstrations; i_demo++)
93  // Take the first row, i.e. at time_i = 0.
94  inputs.row(i_demo) = task_parameters[i_demo].row(0);
95 
97  {
98  // Gather goals (target values for approximation) in one matrix
99  MatrixXd targets(n_demonstrations,dim_orig());
100  for (unsigned int i_demo=0; i_demo<n_demonstrations; i_demo++)
101  targets.row(i_demo) = trajectories[i_demo].final_y();
102 
103  //cout << " inputs=" << inputs << endl;
104  //cout << " targets=" << targets << endl;
105  //cout << " targets.col(0)=" << targets.col(0) << endl;
106 
107  for (int i_dim=0; i_dim<dim_orig(); i_dim++)
108  {
109  string save_directory_cur;
110  if (!save_directory.empty())
111  save_directory_cur = save_directory + "/dim" + to_string(i_dim) + "_goal";
112 
113  policy_parameter_function_goal_[i_dim]->train(inputs,targets.col(i_dim),save_directory_cur,overwrite);
114  }
115  }
116 
118  {
119  // Gather durations (target values for approximation) in one matrix
120  VectorXd targets(n_demonstrations);
121  for (unsigned int i_demo=0; i_demo<n_demonstrations; i_demo++)
122  targets(i_demo) = trajectories[i_demo].duration();
123 
124  //cout << " inputs=" << inputs << endl;
125  //cout << " targets=" << targets << endl;
126 
127  string save_directory_cur;
128  if (!save_directory.empty())
129  save_directory_cur = save_directory + "/_duration";
130 
131  policy_parameter_function_duration_->train(inputs,targets,save_directory_cur,overwrite);
132  }
133 
134  }
135 
136  // Train the rest, i.e. the parameters for the forcing term.
137  train(trajectories, task_parameters, save_directory, overwrite);
138 }
139 
140 void DmpContextual::set_task_parameters(const MatrixXd& task_parameters)
141 {
142  assert(task_parameters_.cols()==task_parameters.cols());
143  task_parameters_ = task_parameters; // This will be used for the forcing term later
144 
145  // Compute new attractor state now, if necessary.
146  if (policy_parameter_function_goal_.size()>0)
147  {
148  // TODO: Check size of task_parameters
149  VectorXd goal(dim_orig());
150  MatrixXd outputs;
151  for (int i_dim=0; i_dim<dim_orig(); i_dim++)
152  {
153  policy_parameter_function_goal_[i_dim]->predict(task_parameters,outputs);
154  goal(i_dim) = outputs(0,0);
155  }
156  set_attractor_state(goal);
157  }
158 
159  // Compute new duration now, if necessary.
161  {
162  // TODO: Check size of task_parameters
163  MatrixXd duration_as_matrix;
164  policy_parameter_function_duration_->predict(task_parameters,duration_as_matrix);
165  set_tau(duration_as_matrix(0,0));
166  }
167 
168 }
169 
170 void DmpContextual::train(const std::vector<Trajectory>& trajectories, std::string save_directory, bool overwrite)
171 {
172  vector<MatrixXd> task_parameters(trajectories.size());
173  for (unsigned int i_traj=0; i_traj<trajectories.size(); i_traj++)
174  {
175  task_parameters[i_traj] = trajectories[i_traj].misc();
176  assert(task_parameters[i_traj].cols()>0);
177  if (i_traj>0)
178  assert(task_parameters[i_traj].cols() == task_parameters[i_traj].cols());
179  }
180  trainLocal(trajectories, task_parameters, save_directory, overwrite);
181 }
182 
183 void DmpContextual::train(const std::vector<Trajectory>& trajectories, std::string save_directory)
184 {
185  bool overwrite=false;
186  train(trajectories, save_directory, overwrite);
187 }
188 
189 void DmpContextual::train(const std::vector<Trajectory>& trajectories)
190 {
191  bool overwrite=false;
192  string save_directory("");
193  train(trajectories, save_directory, overwrite);
194 }
195 
196 
197 void DmpContextual::checkTrainTrajectories(const vector<Trajectory>& trajectories)
198 {
199  // Check if inputs are of the right size.
200  unsigned int n_demonstrations = trajectories.size();
201 
202  // Then check if the trajectories have the same duration and initial/final state
203  double first_duration = trajectories[0].duration();
204  VectorXd first_y_init = trajectories[0].initial_y();
205  VectorXd first_y_attr = trajectories[0].final_y();
206  for (unsigned int i_demo=1; i_demo<n_demonstrations; i_demo++)
207  {
208  // Difference in tau
209  if (fabs(first_duration-trajectories[i_demo].duration())>10e-4)
210  {
212  {
213  cerr << __FILE__ << ":" << __LINE__ << ":";
214  cerr << "WARNING: Duration of demonstrations differ (" << first_duration << "!=" << trajectories[i_demo].duration() << ")" << endl;
215  cerr << " See DmpContextual::set_policy_parameter_function_duration(...) on how to fix this. " << endl;
216  }
217  }
218 
219  // Difference between initial states
220  double sum_abs_diff = (first_y_init.array()-trajectories[i_demo].initial_y().array()).abs().sum();
221  if (sum_abs_diff>10e-7)
222  {
223  cerr << __FILE__ << ":" << __LINE__ << ":";
224  cerr << "WARNING: Initial states of demonstrations differ ( [" << first_y_init.transpose() << "] != [ " << trajectories[i_demo].initial_y().transpose() << "] )" << endl;
225  }
226 
227  // Difference between final states
228  sum_abs_diff = (first_y_attr.array()-trajectories[i_demo].final_y().array()).abs().sum();
229  if (sum_abs_diff>10e-7 && policy_parameter_function_goal_.size()==0)
230  {
231  cerr << __FILE__ << ":" << __LINE__ << ":";
232  cerr << "WARNING: Final states of demonstrations differ ( [" << first_y_attr.transpose() << "] != [ " << trajectories[i_demo].final_y().transpose() << "] )" << endl;
233  cerr << " See DmpContextual::set_policy_parameter_function_goal(...) on how to fix this. " << endl;
234  }
235 
236  }
237 }
238 
239 }
virtual void set_attractor_state(const Eigen::VectorXd &y_attr)
Accessor function for the attractor state of the system.
Definition: Dmp.cpp:873
Trajectory class header file.
Implementation of Dynamical Movement Primitives.
Definition: Dmp.hpp:56
int dim_orig(void) const
Get the dimensionality of the dynamical system, i.e.
FunctionApproximator class header file.
virtual void set_tau(double tau)
Accessor function for the time constant.
Definition: Dmp.cpp:853
virtual void train(const Eigen::Ref< const Eigen::MatrixXd > &inputs, const Eigen::Ref< const Eigen::MatrixXd > &targets)=0
Train the function approximator with corresponding input and target examples.
std::vector< FunctionApproximator * > policy_parameter_function_goal_
FunctionApproximators that relate task parameters the goal of the DMP.
FunctionApproximator * policy_parameter_function_duration_
FunctionApproximator that relates task parameters the duration of the DMP.
void set_policy_parameter_function_goal(FunctionApproximator *function_approximator)
Set a function approximator to predict the goal from the task parameters.
virtual void train(const std::vector< Trajectory > &trajectories, const std::vector< Eigen::MatrixXd > &task_parameters, std::string save_directory, bool overwrite)=0
Train a contextual Dmp with a set of trajectories (and save results to file) This function is useful ...
int getExpectedOutputDim(void) const
The expected dimensionality of the output data.
Base class for all function approximators.
void trainLocal(const std::vector< Trajectory > &trajectories, const std::vector< Eigen::MatrixXd > &task_parameters, std::string save_directory, bool overwrite)
Train a contextual DMP.
virtual void predict(const Eigen::Ref< const Eigen::MatrixXd > &inputs, Eigen::MatrixXd &outputs)=0
Query the function approximator to make a prediction.
DmpType
Different types of DMPs that can be initialized.
Definition: Dmp.hpp:61
Contextual Dmp class header file.
void set_policy_parameter_function_duration(FunctionApproximator *function_approximator)
Set a function approximator to predict the duration from the task parameters.
FunctionApproximator * function_approximator(int i_dim) const
Get a pointer to the function approximator for a certain dimension.
Definition: Dmp.hpp:345
virtual FunctionApproximator * clone(void) const =0
Return a pointer to a deep copy of the FunctionApproximator object.
Eigen::MatrixXd task_parameters_
The current task parameters.
void checkTrainTrajectories(const std::vector< Trajectory > &trajectories)
Check if several trajectories have the same duration and initial/final states.
void set_task_parameters(const Eigen::MatrixXd &task_parameters)
Set the current task parameters.