DMP_BBO library
DmpContextualOneStep.cpp
Go to the documentation of this file.
1 
25 
26 #include <iomanip>
27 #include <iostream>
28 #include <eigen3/Eigen/Core>
29 
30 #include "dmp/Trajectory.hpp"
32 
33 using namespace std;
34 using namespace Eigen;
35 
36 namespace DmpBbo {
37 
38 DmpContextualOneStep::DmpContextualOneStep(int n_dims_dmp, std::vector<FunctionApproximator*> function_approximators,
39  DmpType dmp_type)
40 : DmpContextual(n_dims_dmp, function_approximators, dmp_type)
41 {
42 }
43 
44 // Overloads in DMP computeFunctionApproximatorOutput
46  const Eigen::Ref<const Eigen::MatrixXd>& phase_state, Eigen::MatrixXd& fa_output) const
47 {
48  int n_time_steps = phase_state.rows();
49  fa_output.resize(n_time_steps,dim_orig());
50  fa_output.fill(0.0);
51 
52  MatrixXd task_parameters = task_parameters_;
53  if (task_parameters.rows()==1)
54  {
55  task_parameters = task_parameters.row(0).replicate(n_time_steps,1).eval();
56  }
57  else if (task_parameters.cols()==1)
58  {
59  task_parameters = task_parameters.col(0).transpose().replicate(n_time_steps,1).eval();
60  }
61 
62 
63 
64  assert(n_time_steps==task_parameters.rows());
65 
66  int n_task_parameters = task_parameters.cols();
67  MatrixXd fa_input(n_time_steps,n_task_parameters+1);
68  fa_input << phase_state, task_parameters;
69 
70 
71  MatrixXd output(n_time_steps,1);
72  for (int dd=0; dd<dim_orig(); dd++)
73  {
74  if (function_approximator(dd)!=NULL)
75  {
76  if (function_approximator(dd)->isTrained())
77  {
78  function_approximator(dd)->predict(fa_input,output);
79  if (output.size()>0)
80  {
81  fa_output.col(dd) = output;
82  }
83  }
84  }
85  }
86 }
87 
88 void DmpContextualOneStep::train(const vector<Trajectory>& trajectories, const vector<MatrixXd>& task_parameters, string save_directory, bool overwrite)
89 {
90  // Check if inputs are of the right size.
91  unsigned int n_demonstrations = trajectories.size();
92  assert(n_demonstrations==task_parameters.size());
93 
94  // Then check if the trajectories have the same duration and initial/final state
95  // Later on, if they are not the same, they should be learned also.
96  checkTrainTrajectories(trajectories);
97 
98  // Set tau, initial_state and attractor_state from the trajectories
99  set_tau(trajectories[0].duration());
100  set_initial_state(trajectories[0].initial_y());
101  set_attractor_state(trajectories[0].final_y());
102 
103  MatrixXd all_fa_inputs(0,0);
104  MatrixXd all_fa_targets(0,0);
105  int n_task_parameters = -1;
106  int n_time_steps_total = 0;
107 
108  VectorXd cur_fa_input_phase;
109  MatrixXd cur_fa_target;
110  MatrixXd cur_task_parameters;
111  for (unsigned int i_demo=0; i_demo<n_demonstrations; i_demo++)
112  {
113  cur_task_parameters = task_parameters[i_demo];
114  if (i_demo==0)
115  {
116  n_task_parameters = cur_task_parameters.cols();
117 
118  // This is the first time task_parameters_ is set, because this is the first time we know
119  // n_task_parameters.
120  // We set it so that set_task_parameters can check if task_parameters_.cols()==n_task_parameters
121  task_parameters_ = MatrixXd::Zero(1,n_task_parameters);
122  }
123  else
124  {
125  assert(n_task_parameters==cur_task_parameters.cols());
126  }
127 
128  int n_time_steps = trajectories[i_demo].length();
129  n_time_steps_total += n_time_steps;
130 
131  // Make sure cur_task_parameters has n_time_steps. Copy if it doesn't.
132  if (cur_task_parameters.rows()==1 && n_time_steps>1) {
133  MatrixXd cur_task_parameters_tmp = cur_task_parameters.replicate(n_time_steps,1);
134  cur_task_parameters = cur_task_parameters_tmp;
135  }
136  assert(n_time_steps==cur_task_parameters.rows());
137 
138  computeFunctionApproximatorInputsAndTargets(trajectories[i_demo], cur_fa_input_phase, cur_fa_target);
139 
140  all_fa_inputs.conservativeResize(n_time_steps_total,1+n_task_parameters);
141 
142  all_fa_inputs.bottomLeftCorner(n_time_steps,1) = cur_fa_input_phase;
143  all_fa_inputs.bottomRightCorner(n_time_steps,n_task_parameters) = cur_task_parameters;
144 
145  all_fa_targets.conservativeResize(n_time_steps_total,dim_orig());
146  all_fa_targets.bottomRows(n_time_steps) = cur_fa_target;
147 
148  }
149 
150  // We have all inputs and targets. Now train the function approximator for each dimension.
151 
152  for (int dd=0; dd<dim_orig(); dd++)
153  {
154  // This is just boring stuff to figure out if and where to store the results of training
155  string save_directory_dim;
156  if (!save_directory.empty())
157  {
158  if (dim_orig()==1)
159  save_directory_dim = save_directory;
160  else
161  save_directory_dim = save_directory + "/dim" + to_string(dd);
162  }
163 
164  VectorXd fa_target = all_fa_targets.col(dd);
165  function_approximator(dd)->train(all_fa_inputs,fa_target,save_directory_dim,overwrite);
166  }
167 
168 }
169 
170 }
virtual void set_attractor_state(const Eigen::VectorXd &y_attr)
Accessor function for the attractor state of the system.
Definition: Dmp.cpp:873
Contextual Dmp class header file.
Trajectory class header file.
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.
void computeFunctionApproximatorInputsAndTargets(const Trajectory &trajectory, Eigen::VectorXd &fa_inputs_phase, Eigen::MatrixXd &fa_targets) const
Given a trajectory, compute the inputs and targets for the function approximators.
Definition: Dmp.cpp:583
void train(const std::vector< Trajectory > &trajectories, const std::vector< Eigen::MatrixXd > &task_parameters, std::string save_directory="", bool overwrite=false)
Train a contextual Dmp with a set of trajectories (and save results to file) This function is useful ...
bool isTrained(void) const
Determine whether the function approximator has already been trained with data or not...
Implementation of Contextual Dynamical Movement Primitives.
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
void computeFunctionApproximatorOutput(const Eigen::Ref< const Eigen::MatrixXd > &phase_state, Eigen::MatrixXd &fa_output) const
Compute the outputs of the function approximators.
FunctionApproximator * function_approximator(int i_dim) const
Get a pointer to the function approximator for a certain dimension.
Definition: Dmp.hpp:345
Eigen::MatrixXd task_parameters_
The current task parameters.
virtual void set_initial_state(const Eigen::VectorXd &y_init)
Accessor function for the initial state of the system.
Definition: Dmp.cpp:864
void checkTrainTrajectories(const std::vector< Trajectory > &trajectories)
Check if several trajectories have the same duration and initial/final states.