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
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
00077
00078
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
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));
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
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
00110 if(order %2 != 0)
00111 {
00112 backward_coeffs*= -1.0;
00113 }
00114
00115
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