utils.cpp
00001 
00026 #include <stomp_core/utils.h>
00027 #include <cmath>
00028 #include <iostream>
00029 #include <Eigen/Dense>
00030 
00031 namespace stomp_core
00032 {
00033 
00034 
00035 
00036 void generateFiniteDifferenceMatrix(int num_time_steps,
00037                                              DerivativeOrders::DerivativeOrder order,
00038                                              double dt, Eigen::MatrixXd& diff_matrix)
00039 {
00040 
00041   diff_matrix = Eigen::MatrixXd::Zero(num_time_steps, num_time_steps);
00042   double multiplier = 1.0/pow(dt,(int)order);
00043   for (int i=0; i<num_time_steps; ++i)
00044   {
00045     for (int j=-FINITE_DIFF_RULE_LENGTH/2; j<=FINITE_DIFF_RULE_LENGTH/2; ++j)
00046     {
00047       int index = i+j;
00048       if (index < 0)
00049       {
00050         index = 0;
00051         continue;
00052       }
00053       if (index >= num_time_steps)
00054       {
00055         index = num_time_steps-1;
00056         continue;
00057       }
00058 
00059       diff_matrix(i,index) = multiplier * FINITE_CENTRAL_DIFF_COEFFS[order][j+FINITE_DIFF_RULE_LENGTH/2];
00060     }
00061   }
00062 }
00063 
00064 void generateSmoothingMatrix(int num_timesteps,double dt, Eigen::MatrixXd& projection_matrix_M)
00065 {
00066   using namespace Eigen;
00067 
00068   // generate augmented finite differencing matrix
00069   int start_index_padded = FINITE_DIFF_RULE_LENGTH-1;
00070   int num_timesteps_padded = num_timesteps + 2*(FINITE_DIFF_RULE_LENGTH-1);
00071   MatrixXd finite_diff_matrix_A_padded;
00072   generateFiniteDifferenceMatrix(num_timesteps_padded,DerivativeOrders::STOMP_ACCELERATION,
00073                                  dt,finite_diff_matrix_A_padded);
00074 
00075 
00076   /* computing control cost matrix (R = A_transpose * A):
00077    * Note: Original code multiplies the A product by the time interval.  However this is not
00078    * what was described in the literature
00079    */
00080   MatrixXd control_cost_matrix_R_padded = dt*finite_diff_matrix_A_padded.transpose() * finite_diff_matrix_A_padded;
00081   MatrixXd control_cost_matrix_R = control_cost_matrix_R_padded.block(
00082       start_index_padded,start_index_padded,num_timesteps,num_timesteps);
00083   MatrixXd inv_control_cost_matrix_R = control_cost_matrix_R.fullPivLu().inverse();
00084 
00085   // computing projection matrix M
00086   projection_matrix_M = inv_control_cost_matrix_R;
00087   double max = 0;
00088   for(auto t = 0u; t < num_timesteps; t++)
00089   {
00090     max = projection_matrix_M(t,t);
00091     projection_matrix_M.col(t)*= (1.0/(num_timesteps*max)); // scaling such that the maximum value is 1/num_timesteps
00092   }
00093 }
00094 
00095 void differentiate(const Eigen::VectorXd& parameters, DerivativeOrders::DerivativeOrder order,
00096                           double dt, Eigen::VectorXd& derivatives )
00097 {
00098 
00099   using namespace Eigen;
00100 
00101   derivatives = Eigen::VectorXd::Zero(parameters.size());
00102 
00103 
00104   // coefficient arrays
00105   VectorXd central_coeffs = VectorXd::Map(&FINITE_CENTRAL_DIFF_COEFFS[order][0],FINITE_DIFF_RULE_LENGTH);
00106   VectorXd forward_coeffs = VectorXd::Map(&FINITE_FORWARD_DIFF_COEFFS[order][0],FINITE_DIFF_RULE_LENGTH);
00107   VectorXd backward_coeffs = forward_coeffs.reverse();
00108 
00109   // check order eveness
00110   if(order %2 != 0)
00111   {
00112     backward_coeffs*= -1.0;
00113   }
00114 
00115   // creating difference matrix
00116   int rule_length = FINITE_DIFF_RULE_LENGTH;
00117   int size = parameters.size();
00118   int skip = FINITE_DIFF_RULE_LENGTH/2;
00119   Eigen::MatrixXd A = Eigen::MatrixXd::Zero(size,size);
00120   int start_ind, end_ind;
00121   for(auto i = 0; i < size; i++)
00122   {
00123     if(i < skip)
00124     {
00125       start_ind = i;
00126       A.row(i).segment(start_ind,rule_length) = forward_coeffs;
00127     }
00128     else if(i >= skip && i < size - skip)
00129     {
00130       start_ind = i - skip;
00131       A.row(i).segment(start_ind,rule_length) = central_coeffs;
00132     }
00133     else
00134     {
00135       start_ind = i - rule_length+1;
00136       A.row(i).segment(start_ind,rule_length) = backward_coeffs;
00137     }
00138   }
00139 
00140   derivatives = A*parameters/std::pow(dt,2);
00141 }
00142 
00143 void toVector(const Eigen::MatrixXd& m,std::vector<Eigen::VectorXd>& v)
00144 {
00145   v.resize(m.rows(),Eigen::VectorXd::Zero(m.cols()));
00146   for(auto d = 0u; d < m.rows();d++)
00147   {
00148     v[d] = m.row(d);
00149   }
00150 }
00151 
00152 std::string toString(const std::vector<Eigen::VectorXd>& data)
00153 {
00154   Eigen::IOFormat clean_format(4, 0, ", ", "\n", "[", "]");
00155   Eigen::MatrixXd m = Eigen::MatrixXd::Zero(data.size(),data.front().size());
00156   std::stringstream ss;
00157   for(auto d = 0u; d < data.size(); d++)
00158   {
00159     m.row(d) = data[d].transpose();
00160   }
00161 
00162   ss<<m.format(clean_format);
00163   return ss.str();
00164 }
00165 
00166 std::string toString(const Eigen::MatrixXd& data)
00167 {
00168   Eigen::IOFormat clean_format(4, 0, ", ", "\n", "[", "]");
00169   std::stringstream ss;
00170   ss<<data.format(clean_format);
00171   return ss.str();
00172 }
00173 
00174 std::string toString(const Eigen::VectorXd& data)
00175 {
00176   Eigen::IOFormat clean_format(4, 0, ", ", "\n", "[", "]");
00177   std::stringstream ss;
00178   ss<<data.transpose().format(clean_format);
00179   return ss.str();
00180 }
00181 
00182 }
00183 
00184 
00185 
00186 
00187 


stomp_core
Author(s): Jorge Nicho
autogenerated on Sat Jun 8 2019 19:23:57