/** Main function * \param[in] n_args Number of arguments * \param[in] args Arguments themselves * \return Success of exection. 0 if successful. */ int main(int n_args, char** args) { if (n_args<3 || n_args>5) { help(args[0]); return -1; } if (string(args[1]).compare("--help")==0) { help(args[0]); return 0; } string dmp_filename = string(args[1]); string traj_filename = string(args[2]); string sample_filename = ""; if (n_args>3) sample_filename = string(args[3]); string dmp_output_filename = ""; if (n_args>4) dmp_output_filename = string(args[4]); cout << "C++ | Executing "; for (int ii=0; ii<n_args; ii++) cout << " " << args[ii]; cout << endl; // Read dmp from xml file cout << "C++ | Reading dmp from file '" << dmp_filename << "'" << endl; std::ifstream ifs(dmp_filename); boost::archive::xml_iarchive ia(ifs); Dmp* dmp; ia >> BOOST_SERIALIZATION_NVP(dmp); ifs.close(); cout << "C++ | " << *dmp << endl; // Read sample file, if necessary if (!sample_filename.empty()) { cout << "C++ | Reading sample from file '" << sample_filename << "'" << endl; VectorXd sample; if (!loadMatrix(sample_filename, sample)) { cerr << "C++ | WARNING: Could not read sample file. Executing default DMP instead." << endl; } else { // Set DMP parameters to sample dmp->setParameterVectorSelected(sample); // Save dmp whose parameters have been perturbed, if necessary if (!dmp_output_filename.empty()) { cout << "C++ | Saving dmp to file '" << dmp_output_filename << "'" << endl; std::ofstream ofs(dmp_output_filename); boost::archive::xml_oarchive oa(ofs); oa << boost::serialization::make_nvp("dmp",dmp); ofs.close(); } } } // Integrate DMP longer than the tau with which it was trained double integration_time = 1.5*dmp->tau(); double frequency_Hz = 100.0; cout << "C++ | Integrating dmp for " << integration_time << "s at " << (int)frequency_Hz << "Hz" << endl; int n_time_steps = floor(frequency_Hz*integration_time); VectorXd ts = VectorXd::LinSpaced(n_time_steps,0,integration_time); // Time steps // Save trajectory cout << "C++ | Saving trajectory to file '" << traj_filename << "'" << endl; Trajectory trajectory; dmp->analyticalSolution(ts,trajectory); // Now we have the end-effector trajectory. Compute the ball trajectory. MatrixXd y_endeff = trajectory.ys(); MatrixXd yd_endeff = trajectory.yds(); MatrixXd ydd_endeff = trajectory.ydds(); MatrixXd y_ball(n_time_steps,2); MatrixXd yd_ball(n_time_steps,2); MatrixXd ydd_ball(n_time_steps,2); double dt = 1.0/frequency_Hz; bool ball_in_hand = true; for (int ii=0; ii<n_time_steps; ii++) { if (ball_in_hand) { // If the ball is in your hand, it moves along with your hand y_ball.row(ii) = y_endeff.row(ii); yd_ball.row(ii) = yd_endeff.row(ii); ydd_ball.row(ii) = ydd_endeff.row(ii); if (ts(ii)>0.6) { // Release the ball to throw it! ball_in_hand = false; } } else // ball_in_hand is false => ball is flying through the air { ydd_ball(ii,0) = 0.0; ydd_ball(ii,1) = -9.81; // Gravity // Euler integration yd_ball.row(ii) = yd_ball.row(ii-1) + dt*ydd_ball.row(ii); y_ball.row(ii) = y_ball.row(ii-1) + dt*yd_ball.row(ii); if (y_ball(ii,1)<-0.3) { // Ball hits the floor (floor is at -0.3) y_ball(ii,1) = -0.3; yd_ball.row(ii) = VectorXd::Zero(2); ydd_ball.row(ii) = VectorXd::Zero(2); } } //if x(t_i-1,BALL_IN_CUP) // % If the ball is in the cup, it does not move // x(t_i,BALL_X:BALL_Y) = x(t_i-1,BALL_X:BALL_Y); // x(t_i,BALL_IN_CUP) = 1; % Once in the cup, always in the cup // //else // // if x(t_i,HOLD_BALL) // % If the ball is in your hand, it moves along with your hand // x(t_i,BALL_X:BALL_Y) = x(t_i,REF_X:REF_Y); // x(t_i,BALL_XD) = diff(x([t_i-1 t_i],BALL_X))/dt; // x(t_i,BALL_YD) = diff(x([t_i-1 t_i],BALL_Y))/dt; // // else // % If the ball is not in your hand, it simply falls // x(t_i,BALL_XDD) = 0; // x(t_i,BALL_YDD) = -g; // // % Euler integration // x(t_i,BALL_XD:BALL_YD) = x(t_i-1,BALL_XD:BALL_YD) + dt*x(t_i,BALL_XDD:BALL_YDD); // x(t_i,BALL_X:BALL_Y) = x(t_i-1,BALL_X:BALL_Y) + dt*x(t_i,BALL_XD:BALL_YD); // // end } trajectory.set_misc(y_ball); bool overwrite = true; trajectory.saveToFile(traj_filename, overwrite); delete dmp; return 0; }
/** Main function * \param[in] n_args Number of arguments * \param[in] args Arguments themselves * \return Success of exection. 0 if successful. */ int main(int n_args, char** args) { string save_directory; if (n_args!=2) { cerr << "Usage: " << args[0] << " <directory>" << endl; return -1; } save_directory = string(args[1]); // GENERATE A TRAJECTORY double tau = 0.5; int n_time_steps = 51; VectorXd ts = VectorXd::LinSpaced(n_time_steps,0,tau); // Time steps Trajectory trajectory = getDemoTrajectory(ts); // getDemoTrajectory() is implemented below main() int n_dims = trajectory.dim(); // MAKE THE FUNCTION APPROXIMATORS // Initialize some meta parameters for training LWR function approximator int n_basis_functions = 25; int input_dim = 1; double intersection = 0.5; MetaParametersLWR* meta_parameters = new MetaParametersLWR(input_dim,n_basis_functions,intersection); FunctionApproximatorLWR* fa_lwr = new FunctionApproximatorLWR(meta_parameters); // Clone the function approximator for each dimension of the DMP vector<FunctionApproximator*> function_approximators(n_dims); for (int dd=0; dd<n_dims; dd++) function_approximators[dd] = fa_lwr->clone(); // CONSTRUCT AND TRAIN THE DMP cout << "** Initialize DMP." << endl; // Initialize the DMP Dmp::DmpType dmp_type = Dmp::KULVICIUS_2012_JOINING; //dmp_type = Dmp::IJSPEERT_2002_MOVEMENT; Dmp* dmp_tmp = new Dmp(n_dims, function_approximators, dmp_type); cout << "** Initialize DmpWithGainSchedules." << endl; int n_gains = trajectory.dim_misc(); // Clone the function approximator for each extra dimension of the DMP vector<FunctionApproximator*> function_approximators_gains(n_gains); for (int dd=0; dd<n_gains; dd++) function_approximators_gains[dd] = fa_lwr->clone(); DmpWithGainSchedules* dmp_gains = new DmpWithGainSchedules(dmp_tmp,function_approximators_gains); cout << "** Train DmpWithGainSchedules." << endl; // And train it. Passing the save_directory will make sure the results are saved to file. bool overwrite = true; dmp_gains->train(trajectory,save_directory,overwrite); // INTEGRATE DMP TO GET REPRODUCED TRAJECTORY cout << "** Integrate DMP analytically." << endl; Trajectory traj_reproduced; tau = 0.9; n_time_steps = 91; ts = VectorXd::LinSpaced(n_time_steps,0,tau); // Time steps dmp_gains->analyticalSolution(ts,traj_reproduced); // Integrate again, but this time get more information MatrixXd xs_ana, xds_ana, forcing_terms_ana, fa_output_ana, fa_gains; dmp_gains->analyticalSolution(ts,xs_ana,xds_ana,forcing_terms_ana,fa_output_ana,fa_gains); // WRITE THINGS TO FILE trajectory.saveToFile(save_directory,"demonstration_traj.txt",overwrite); traj_reproduced.saveToFile(save_directory,"reproduced_traj.txt",overwrite); MatrixXd output_ana(ts.size(),1+xs_ana.cols()+xds_ana.cols()); output_ana << ts, xs_ana, xds_ana; saveMatrix(save_directory,"reproduced_ts_xs_xds.txt",output_ana,overwrite); saveMatrix(save_directory,"reproduced_forcing_terms.txt",forcing_terms_ana,overwrite); saveMatrix(save_directory,"reproduced_fa_output.txt",fa_output_ana,overwrite); saveMatrix(save_directory,"reproduced_fa_gains.txt",fa_gains,overwrite); // INTEGRATE STEP BY STEP cout << "** Integrate DMP step-by-step." << endl; VectorXd x(dmp_gains->dim(),1); VectorXd xd(dmp_gains->dim(),1); VectorXd x_updated(dmp_gains->dim(),1); VectorXd gains(dmp_gains->dim_gains(),1); MatrixXd xs_step(n_time_steps,x.size()); MatrixXd xds_step(n_time_steps,xd.size()); MatrixXd gains_all(n_time_steps,gains.size()); cout << std::setprecision(3) << std::fixed << std::showpos; double dt = ts[1]; dmp_gains->integrateStart(x,xd,gains); xs_step.row(0) = x; xds_step.row(0) = xd; gains_all.row(0) = gains; for (int t=1; t<n_time_steps; t++) { dmp_gains->integrateStep(dt,x,x_updated,xd,gains); x = x_updated; xs_step.row(t) = x; xds_step.row(t) = xd; gains_all.row(t) = gains; if (save_directory.empty()) { // Not writing to file, output on cout instead. //cout << x.transpose() << " | " << xd.transpose() << endl; } } MatrixXd output_step(ts.size(),1+xs_ana.cols()+xds_ana.cols()+gains_all.cols()); output_step << ts, xs_step, xds_step, gains_all; saveMatrix(save_directory,"reproduced_step_ts_xs_xds_gains.txt",output_step,overwrite); delete meta_parameters; delete fa_lwr; delete dmp_gains; return 0; }