#include #include #include #include #include #include #include #include #include "rbdl/rbdl.h" #include "model_generator.h" #include "Human36Model.h" #include "SampleData.h" #include "Timer.h" #ifdef RBDL_BUILD_ADDON_LUAMODEL #include "../addons/luamodel/luamodel.h" bool have_luamodel = true; #else bool have_luamodel = false; #endif #ifdef RBDL_BUILD_ADDON_URDFREADER #include "../addons/urdfreader/urdfreader.h" bool have_urdfreader = true; bool urdf_floating_base = false; #else bool have_urdfreader = false; #endif using namespace std; using namespace RigidBodyDynamics; using namespace RigidBodyDynamics::Math; int benchmark_sample_count = 1000; int benchmark_model_max_depth = 5; bool benchmark_run_fd_aba = true; bool benchmark_run_fd_lagrangian = true; bool benchmark_run_id_rnea = true; bool benchmark_run_crba = true; bool benchmark_run_nle = true; bool benchmark_run_calc_minv_times_tau = true; bool benchmark_run_contacts = false; bool benchmark_run_ik = false; bool json_output = false; string model_name; enum ContactsMethod { ConstraintsMethodDirect = 0, ConstraintsMethodRangeSpaceSparse, ConstraintsMethodNullSpace, ConstraintsMethodKokkevis }; struct BenchmarkRun { string model_name; int model_dof; string benchmark; int sample_count; double duration; double avg; double min; double max; }; vector benchmark_runs; void report_section (const char* section_name) { if (!json_output) { cout << "= " << section_name << " =" << endl; } } void register_run(const Model &model, const SampleData &data, const char *run_name) { BenchmarkRun run; run.benchmark = run_name; run.model_name = model_name; run.model_dof = model.dof_count; run.sample_count = data.count; run.duration = data.durations.sum(); run.avg = data.durations.mean(); run.min = data.durations.minCoeff(); run.max = data.durations.maxCoeff(); benchmark_runs.push_back(run); } void report_run(const Model &model, const SampleData &data, const char *run_name) { register_run(model, data, run_name); if (!json_output) { cout << "#DOF: " << setw(3) << model.dof_count << " #samples: " << data.count << " duration = " << setw(10) << data.durations.sum() << "(s)" << " (~" << setw(10) << data.durations.mean() << "(s) per call)" << endl; } } void report_constraints_run(const Model &model, const SampleData &data, const char *run_name) { register_run(model, data, run_name); if (!json_output) { cout << model_name << ": " << " duration = " << setw(10) << data.durations.sum() << "(s)" << " (~" << setw(10) << data.durations.mean() << "(s) per call)" << endl; } } /** Parses /proc/cpuinfo for the CPU model name. */ string get_cpu_model_name () { ifstream proc_cpu ("/proc/cpuinfo", ios_base::in); if (!proc_cpu) { cerr << "Cannot determine cpu model: could not open /proc/cpuinfo for reading." << endl; abort(); } ostringstream content; content << proc_cpu.rdbuf(); proc_cpu.close(); string content_str = content.str(); std::size_t model_name_pos = content_str.find("model name"); if (model_name_pos != string::npos) { std::size_t start = content_str.find(':', model_name_pos + strlen("model name")) + 2; std::size_t end = content_str.find('\n', model_name_pos + strlen("model name")); return content_str.substr(start, end - start); } return "unknown"; } string get_utc_time_string () { time_t current_time; struct tm* timeinfo; time(¤t_time); timeinfo = gmtime(¤t_time); char time_buf[80]; std::size_t UNUSED(time_len) = strftime(&time_buf[0], 80, "%a %b %d %T %Y", timeinfo); assert(time_len <= 80 & "violating buffer size for utc time conversion"); return time_buf; } double run_forward_dynamics_ABA_benchmark (Model *model, int sample_count) { SampleData sample_data; sample_data.fillRandom(model->dof_count, sample_count); TimerInfo tinfo; for (int i = 0; i < sample_count; i++) { timer_start (&tinfo); ForwardDynamics (*model, sample_data.q[i], sample_data.qdot[i], sample_data.tau[i], sample_data.qddot[i]); sample_data.durations[i] = timer_stop (&tinfo); } report_run(*model, sample_data, "ForwardDynamics"); return sample_data.durations.sum(); } double run_forward_dynamics_lagrangian_benchmark (Model *model, int sample_count) { SampleData sample_data; sample_data.fillRandom(model->dof_count, sample_count); TimerInfo tinfo; MatrixNd H (MatrixNd::Zero(model->dof_count, model->dof_count)); VectorNd C (VectorNd::Zero(model->dof_count)); for (int i = 0; i < sample_count; i++) { timer_start (&tinfo); ForwardDynamicsLagrangian (*model, sample_data.q[i], sample_data.qdot[i], sample_data.tau[i], sample_data.qddot[i], Math::LinearSolverPartialPivLU, NULL, &H, &C ); sample_data.durations[i] = timer_stop (&tinfo); } report_run(*model, sample_data, "ForwardDynamicsLagrangian_PivLU"); return sample_data.durations.sum(); } double run_inverse_dynamics_RNEA_benchmark (Model *model, int sample_count) { SampleData sample_data; sample_data.fillRandom(model->dof_count, sample_count); TimerInfo tinfo; timer_start (&tinfo); for (int i = 0; i < sample_count; i++) { timer_start (&tinfo); InverseDynamics (*model, sample_data.q[i], sample_data.qdot[i], sample_data.qddot[i], sample_data.tau[i] ); sample_data.durations[i] = timer_stop (&tinfo); } report_run(*model, sample_data, "InverseDynamics"); return sample_data.durations.sum(); } double run_CRBA_benchmark (Model *model, int sample_count) { SampleData sample_data; sample_data.fillRandom(model->dof_count, sample_count); Math::MatrixNd H = Math::MatrixNd::Zero(model->dof_count, model->dof_count); Math::MatrixNd identity = Math::MatrixNd::Identity(model->dof_count, model->dof_count); Math::MatrixNd Hinv = Math::MatrixNd::Zero(model->dof_count, model->dof_count); TimerInfo tinfo; for (int i = 0; i < sample_count; i++) { timer_start (&tinfo); CompositeRigidBodyAlgorithm (*model, sample_data.q[i], H, true); sample_data.durations[i] = timer_stop (&tinfo); } report_run(*model, sample_data, "CompositeRigidBodyAlgorithm"); return sample_data.durations.sum(); } double run_nle_benchmark (Model *model, int sample_count) { SampleData sample_data; sample_data.fillRandom(model->dof_count, sample_count); TimerInfo tinfo; for (int i = 0; i < sample_count; i++) { timer_start (&tinfo); NonlinearEffects (*model, sample_data.q[i], sample_data.qdot[i], sample_data.tau[i] ); sample_data.durations[i] = timer_stop (&tinfo); } report_run(*model, sample_data, "NonlinearEffects"); return sample_data.durations.sum(); } double run_calc_minv_times_tau_benchmark (Model *model, int sample_count) { SampleData sample_data; sample_data.fillRandom(model->dof_count, sample_count); CalcMInvTimesTau (*model, sample_data.q[0], sample_data.tau[0], sample_data.qddot[0]); TimerInfo tinfo; for (int i = 0; i < sample_count; i++) { timer_start (&tinfo); CalcMInvTimesTau (*model, sample_data.q[i], sample_data.tau[i], sample_data.qddot[i]); sample_data.durations[i] = timer_stop (&tinfo); } report_run(*model, sample_data, "NonlinearEffects"); return sample_data.durations.sum(); } double run_contacts_lagrangian_benchmark (Model *model, ConstraintSet *constraint_set, int sample_count) { SampleData sample_data; sample_data.fillRandom(model->dof_count, sample_count); TimerInfo tinfo; for (int i = 0; i < sample_count; i++) { timer_start (&tinfo); ForwardDynamicsConstraintsDirect (*model, sample_data.q[i], sample_data.qdot[i], sample_data.tau[i], *constraint_set, sample_data.qddot[i]); sample_data.durations[i] = timer_stop (&tinfo); } report_constraints_run(*model, sample_data, "ForwardDynamicsConstraintsDirect"); return sample_data.durations.sum(); } double run_contacts_lagrangian_sparse_benchmark (Model *model, ConstraintSet *constraint_set, int sample_count) { SampleData sample_data; sample_data.fillRandom(model->dof_count, sample_count); TimerInfo tinfo; for (int i = 0; i < sample_count; i++) { timer_start (&tinfo); ForwardDynamicsConstraintsRangeSpaceSparse (*model, sample_data.q[i], sample_data.qdot[i], sample_data.tau[i], *constraint_set, sample_data.qddot[i]); sample_data.durations[i] = timer_stop (&tinfo); } report_constraints_run(*model, sample_data, "ForwardDynamicsConstraintsRangeSpaceSparse"); return sample_data.durations.sum(); } double run_contacts_null_space (Model *model, ConstraintSet *constraint_set, int sample_count) { SampleData sample_data; sample_data.fillRandom(model->dof_count, sample_count); TimerInfo tinfo; for (int i = 0; i < sample_count; i++) { timer_start (&tinfo); ForwardDynamicsConstraintsNullSpace (*model, sample_data.q[i], sample_data.qdot[i], sample_data.tau[i], *constraint_set, sample_data.qddot[i]); sample_data.durations[i] = timer_stop (&tinfo); } report_constraints_run(*model, sample_data, "ForwardDynamicsConstraintsNullSpace"); return sample_data.durations.sum(); } double run_contacts_kokkevis_benchmark (Model *model, ConstraintSet *constraint_set, int sample_count) { SampleData sample_data; sample_data.fillRandom(model->dof_count, sample_count); TimerInfo tinfo; for (int i = 0; i < sample_count; i++) { timer_start (&tinfo); ForwardDynamicsContactsKokkevis(*model, sample_data.q[i], sample_data.qdot[i], sample_data.tau[i], *constraint_set, sample_data.qddot[i]); sample_data.durations[i] = timer_stop (&tinfo); } report_constraints_run(*model, sample_data, "ForwardDynamicsContactsKokkevis"); return sample_data.durations.sum(); } void contacts_benchmark (int sample_count, ContactsMethod contacts_method) { // initialize the human model Model *model = new Model(); generate_human36model(model); // initialize the constraint sets unsigned int foot_r = model->GetBodyId ("foot_r"); unsigned int foot_l = model->GetBodyId ("foot_l"); unsigned int hand_r = model->GetBodyId ("hand_r"); unsigned int hand_l = model->GetBodyId ("hand_l"); ConstraintSet one_body_one_constraint; ConstraintSet two_bodies_one_constraint; ConstraintSet four_bodies_one_constraint; ConstraintSet one_body_four_constraints; ConstraintSet two_bodies_four_constraints; ConstraintSet four_bodies_four_constraints; LinearSolver linear_solver = LinearSolverPartialPivLU; one_body_one_constraint.linear_solver = linear_solver; two_bodies_one_constraint.linear_solver = linear_solver; four_bodies_one_constraint.linear_solver = linear_solver; one_body_four_constraints.linear_solver = linear_solver; two_bodies_four_constraints.linear_solver = linear_solver; four_bodies_four_constraints.linear_solver = linear_solver; // one_body_one one_body_one_constraint.AddContactConstraint (foot_r, Vector3d (0.1, 0., -0.05), Vector3d (1., 0., 0.)); one_body_one_constraint.Bind (*model); // two_bodies_one two_bodies_one_constraint.AddContactConstraint (foot_r, Vector3d (0.1, 0., -0.05), Vector3d (1., 0., 0.)); two_bodies_one_constraint.AddContactConstraint (foot_l, Vector3d (0.1, 0., -0.05), Vector3d (1., 0., 0.)); two_bodies_one_constraint.Bind (*model); // four_bodies_one four_bodies_one_constraint.AddContactConstraint (foot_r, Vector3d (0.1, 0., -0.05), Vector3d (1., 0., 0.)); four_bodies_one_constraint.AddContactConstraint (foot_l, Vector3d (0.1, 0., -0.05), Vector3d (1., 0., 0.)); four_bodies_one_constraint.AddContactConstraint (hand_r, Vector3d (0.1, 0., -0.05), Vector3d (1., 0., 0.)); four_bodies_one_constraint.AddContactConstraint (hand_l, Vector3d (0.1, 0., -0.05), Vector3d (1., 0., 0.)); four_bodies_one_constraint.Bind (*model); // one_body_four one_body_four_constraints.AddContactConstraint (foot_r, Vector3d (0.1, 0., -0.05), Vector3d (1., 0., 0.)); one_body_four_constraints.AddContactConstraint (foot_r, Vector3d (0.1, 0., -0.05), Vector3d (0., 1., 0.)); one_body_four_constraints.AddContactConstraint (foot_r, Vector3d (0.1, 0., -0.05), Vector3d (0., 0., 1.)); one_body_four_constraints.AddContactConstraint (foot_r, Vector3d (-0.1, 0., -0.05), Vector3d (1., 0., 0.)); one_body_four_constraints.Bind (*model); // two_bodies_four two_bodies_four_constraints.AddContactConstraint (foot_r, Vector3d (0.1, 0., -0.05), Vector3d (1., 0., 0.)); two_bodies_four_constraints.AddContactConstraint (foot_r, Vector3d (0.1, 0., -0.05), Vector3d (0., 1., 0.)); two_bodies_four_constraints.AddContactConstraint (foot_r, Vector3d (0.1, 0., -0.05), Vector3d (0., 0., 1.)); two_bodies_four_constraints.AddContactConstraint (foot_r, Vector3d (-0.1, 0., -0.05), Vector3d (1., 0., 0.)); two_bodies_four_constraints.AddContactConstraint (foot_l, Vector3d (0.1, 0., -0.05), Vector3d (1., 0., 0.)); two_bodies_four_constraints.AddContactConstraint (foot_l, Vector3d (0.1, 0., -0.05), Vector3d (0., 1., 0.)); two_bodies_four_constraints.AddContactConstraint (foot_l, Vector3d (0.1, 0., -0.05), Vector3d (0., 0., 1.)); two_bodies_four_constraints.AddContactConstraint (foot_l, Vector3d (-0.1, 0., -0.05), Vector3d (1., 0., 0.)); two_bodies_four_constraints.Bind (*model); // four_bodies_four four_bodies_four_constraints.AddContactConstraint (foot_r, Vector3d (0.1, 0., -0.05), Vector3d (1., 0., 0.)); four_bodies_four_constraints.AddContactConstraint (foot_r, Vector3d (0.1, 0., -0.05), Vector3d (0., 1., 0.)); four_bodies_four_constraints.AddContactConstraint (foot_r, Vector3d (0.1, 0., -0.05), Vector3d (0., 0., 1.)); four_bodies_four_constraints.AddContactConstraint (foot_r, Vector3d (-0.1, 0., -0.05), Vector3d (1., 0., 0.)); four_bodies_four_constraints.AddContactConstraint (foot_l, Vector3d (0.1, 0., -0.05), Vector3d (1., 0., 0.)); four_bodies_four_constraints.AddContactConstraint (foot_l, Vector3d (0.1, 0., -0.05), Vector3d (0., 1., 0.)); four_bodies_four_constraints.AddContactConstraint (foot_l, Vector3d (0.1, 0., -0.05), Vector3d (0., 0., 1.)); four_bodies_four_constraints.AddContactConstraint (foot_l, Vector3d (-0.1, 0., -0.05), Vector3d (1., 0., 0.)); four_bodies_four_constraints.AddContactConstraint (hand_r, Vector3d (0.1, 0., -0.05), Vector3d (1., 0., 0.)); four_bodies_four_constraints.AddContactConstraint (hand_r, Vector3d (0.1, 0., -0.05), Vector3d (0., 1., 0.)); four_bodies_four_constraints.AddContactConstraint (hand_r, Vector3d (0.1, 0., -0.05), Vector3d (0., 0., 1.)); four_bodies_four_constraints.AddContactConstraint (hand_r, Vector3d (-0.1, 0., -0.05), Vector3d (1., 0., 0.)); four_bodies_four_constraints.AddContactConstraint (hand_l, Vector3d (0.1, 0., -0.05), Vector3d (1., 0., 0.)); four_bodies_four_constraints.AddContactConstraint (hand_l, Vector3d (0.1, 0., -0.05), Vector3d (0., 1., 0.)); four_bodies_four_constraints.AddContactConstraint (hand_l, Vector3d (0.1, 0., -0.05), Vector3d (0., 0., 1.)); four_bodies_four_constraints.AddContactConstraint (hand_l, Vector3d (-0.1, 0., -0.05), Vector3d (1., 0., 0.)); four_bodies_four_constraints.Bind (*model); model_name = "Human36"; if (!json_output) { cout << "= #DOF: " << setw(3) << model->dof_count << endl; cout << "= #samples: " << sample_count << endl; cout << "= No constraints (Articulated Body Algorithm):" << endl; run_forward_dynamics_ABA_benchmark(model, sample_count); } // one body one model_name = "Human36_1Bodies1Constraints"; if (contacts_method == ConstraintsMethodDirect) { run_contacts_lagrangian_benchmark (model, &one_body_one_constraint, sample_count); } else if (contacts_method == ConstraintsMethodRangeSpaceSparse) { run_contacts_lagrangian_sparse_benchmark (model, &one_body_one_constraint, sample_count); } else if (contacts_method == ConstraintsMethodNullSpace) { run_contacts_null_space (model, &one_body_one_constraint, sample_count); } else { run_contacts_kokkevis_benchmark (model, &one_body_one_constraint, sample_count); } // two_bodies_one model_name = "Human36_2Bodies1Constraints"; if (contacts_method == ConstraintsMethodDirect) { run_contacts_lagrangian_benchmark (model, &two_bodies_one_constraint, sample_count); } else if (contacts_method == ConstraintsMethodRangeSpaceSparse) { run_contacts_lagrangian_sparse_benchmark (model, &two_bodies_one_constraint, sample_count); } else if (contacts_method == ConstraintsMethodNullSpace) { run_contacts_null_space (model, &two_bodies_one_constraint, sample_count); } else { run_contacts_kokkevis_benchmark (model, &two_bodies_one_constraint, sample_count); } // four_bodies_one model_name = "Human36_4Bodies1Constraints"; if (contacts_method == ConstraintsMethodDirect) { run_contacts_lagrangian_benchmark (model, &four_bodies_one_constraint, sample_count); } else if (contacts_method == ConstraintsMethodRangeSpaceSparse) { run_contacts_lagrangian_sparse_benchmark (model, &four_bodies_one_constraint, sample_count); } else if (contacts_method == ConstraintsMethodNullSpace) { run_contacts_null_space (model, &four_bodies_one_constraint, sample_count); } else { run_contacts_kokkevis_benchmark (model, &four_bodies_one_constraint, sample_count); } // one_body_four model_name = "Human36_1Bodies4Constraints"; if (contacts_method == ConstraintsMethodDirect) { run_contacts_lagrangian_benchmark (model, &one_body_four_constraints, sample_count); } else if (contacts_method == ConstraintsMethodRangeSpaceSparse) { run_contacts_lagrangian_sparse_benchmark (model, &one_body_four_constraints, sample_count); } else if (contacts_method == ConstraintsMethodNullSpace) { run_contacts_null_space (model, &one_body_four_constraints, sample_count); } else { run_contacts_kokkevis_benchmark (model, &one_body_four_constraints, sample_count); } // two_bodies_four model_name = "Human36_2Bodies4Constraints"; if (contacts_method == ConstraintsMethodDirect) { run_contacts_lagrangian_benchmark (model, &two_bodies_four_constraints, sample_count); } else if (contacts_method == ConstraintsMethodRangeSpaceSparse) { run_contacts_lagrangian_sparse_benchmark (model, &two_bodies_four_constraints, sample_count); } else if (contacts_method == ConstraintsMethodNullSpace) { run_contacts_null_space (model, &two_bodies_four_constraints, sample_count); } else { run_contacts_kokkevis_benchmark (model, &two_bodies_four_constraints, sample_count); } // four_bodies_four model_name = "Human36_4Bodies4Constraints"; if (contacts_method == ConstraintsMethodDirect) { run_contacts_lagrangian_benchmark (model, &four_bodies_four_constraints, sample_count); } else if (contacts_method == ConstraintsMethodRangeSpaceSparse) { run_contacts_lagrangian_sparse_benchmark (model, &four_bodies_four_constraints, sample_count); } else if (contacts_method == ConstraintsMethodNullSpace) { run_contacts_null_space (model, &four_bodies_four_constraints, sample_count); } else { run_contacts_kokkevis_benchmark (model, &four_bodies_four_constraints, sample_count); } delete model; } double run_single_inverse_kinematics_benchmark(Model *model, std::vector &CS, int sample_count){ TimerInfo tinfo; timer_start (&tinfo); VectorNd qinit = VectorNd::Zero(model->dof_count); VectorNd qres = VectorNd::Zero(model->dof_count); VectorNd failures = VectorNd::Zero(model->dof_count); for (int i = 0; i < sample_count; i++) { if (!InverseKinematics(*model, qinit, CS[i], qres)){ failures[i] = 1; } } double duration = timer_stop (&tinfo); std::cout << "Success Rate: " << (1-failures.mean())*100 << "% for: "; return duration; } double run_all_inverse_kinematics_benchmark (unsigned int sample_count){ //initialize the human model Model *model = new Model(); generate_human36model(model); unsigned int foot_r = model->GetBodyId ("foot_r"); unsigned int foot_l = model->GetBodyId ("foot_l"); unsigned int hand_r = model->GetBodyId ("hand_r"); unsigned int hand_l = model->GetBodyId ("hand_l"); unsigned int head = model->GetBodyId ("head"); Vector3d foot_r_point (1., 0., 0.); Vector3d foot_l_point (-1., 0., 0.); Vector3d hand_r_point (0., 1., 0.); Vector3d hand_l_point (1., 0., 1.); Vector3d head_point (0.,0.,-1.); SampleData sample_data; sample_data.fillRandom(model->dof_count, sample_count); //create constraint sets std::vector cs_one_point; std::vector cs_two_point_one_orientation; std::vector cs_two_full_one_point; std::vector cs_two_full_two_point_one_orientation; std::vector cs_five_full; for (unsigned int i = 0; i < sample_count; i++){ Vector3d foot_r_position = CalcBodyToBaseCoordinates (*model, sample_data.q[i], foot_r, foot_r_point); Vector3d foot_l_position = CalcBodyToBaseCoordinates (*model, sample_data.q[i], foot_l, foot_l_point); Vector3d hand_r_position = CalcBodyToBaseCoordinates (*model, sample_data.q[i], hand_r, hand_r_point); Vector3d hand_l_position = CalcBodyToBaseCoordinates (*model, sample_data.q[i], hand_l, hand_l_point); Vector3d head_position = CalcBodyToBaseCoordinates (*model, sample_data.q[i], head , head_point); Matrix3d foot_r_orientation = CalcBodyWorldOrientation (*model, sample_data.q[i], foot_r, false); Matrix3d foot_l_orientation = CalcBodyWorldOrientation (*model, sample_data.q[i], foot_l, false); Matrix3d hand_r_orientation = CalcBodyWorldOrientation (*model, sample_data.q[i], hand_r, false); Matrix3d hand_l_orientation = CalcBodyWorldOrientation (*model, sample_data.q[i], hand_l, false); Matrix3d head_orientation = CalcBodyWorldOrientation (*model, sample_data.q[i], head , false); //single point InverseKinematicsConstraintSet one_point; one_point.AddPointConstraint(foot_r, foot_r_point, foot_r_position); one_point.step_tol = 1e-12; cs_one_point.push_back(one_point); //two point and one orientation InverseKinematicsConstraintSet two_point_one_orientation; two_point_one_orientation.AddPointConstraint(foot_l,foot_l_point, foot_l_position); two_point_one_orientation.AddPointConstraint(foot_r, foot_r_point, foot_r_position); two_point_one_orientation.AddOrientationConstraint(head, head_orientation); two_point_one_orientation.step_tol = 1e-12; cs_two_point_one_orientation.push_back(two_point_one_orientation); //two full and one point InverseKinematicsConstraintSet two_full_one_point; two_full_one_point.AddFullConstraint(hand_r, hand_r_point, hand_r_position, hand_r_orientation); two_full_one_point.AddFullConstraint(hand_l, hand_l_point, hand_l_position, hand_l_orientation); two_full_one_point.AddPointConstraint(head, head_point, head_position); two_full_one_point.step_tol = 1e-12; cs_two_full_one_point.push_back(two_full_one_point); //two full, two points and one orienation InverseKinematicsConstraintSet two_full_two_point_one_orientation; two_full_two_point_one_orientation.AddPointConstraint(foot_r, foot_r_point, foot_r_position); two_full_two_point_one_orientation.AddPointConstraint(foot_l, foot_l_point, foot_l_position); two_full_two_point_one_orientation.AddFullConstraint(hand_r, hand_r_point, hand_r_position, hand_r_orientation); two_full_two_point_one_orientation.AddFullConstraint(hand_l, hand_l_point, hand_l_position, hand_l_orientation); two_full_two_point_one_orientation.AddOrientationConstraint(head, head_orientation); two_full_two_point_one_orientation.step_tol = 1e-12; cs_two_full_two_point_one_orientation.push_back(two_full_two_point_one_orientation); //five points 5 orientations InverseKinematicsConstraintSet five_full; five_full.AddFullConstraint(foot_r, foot_r_point, foot_r_position, foot_r_orientation); five_full.AddFullConstraint(foot_l, foot_l_point, foot_l_position, foot_l_orientation); five_full.AddFullConstraint(hand_r, hand_r_point, hand_r_position, hand_r_orientation); five_full.AddFullConstraint(hand_l, hand_l_point, hand_l_position, hand_l_orientation); five_full.AddFullConstraint(head, head_point, head_position, head_orientation); five_full.step_tol = 1e-12; cs_five_full.push_back(five_full); } cout << "= #DOF: " << setw(3) << model->dof_count << endl; cout << "= #samples: " << sample_count << endl; double duration; duration = run_single_inverse_kinematics_benchmark(model, cs_one_point, sample_count); cout << "Constraints: 1 Body: 1 Point : " << " duration = " << setw(10) << duration << "(s)" << " (~" << setw(10) << duration / sample_count << "(s) per call)" << endl; duration = run_single_inverse_kinematics_benchmark(model, cs_two_point_one_orientation, sample_count); cout << "Constraints: 3 Bodies: 2 Points 1 Orienation : " << " duration = " << setw(10) << duration << "(s)" << " (~" << setw(10) << duration / sample_count << "(s) per call)" << endl; duration = run_single_inverse_kinematics_benchmark(model, cs_two_full_one_point, sample_count); cout << "Constraints: 3 Bodies: 2 Full 1 Point : " << " duration = " << setw(10) << duration << "(s)" << " (~" << setw(10) << duration / sample_count << "(s) per call)" << endl; duration = run_single_inverse_kinematics_benchmark(model, cs_two_full_two_point_one_orientation, sample_count); cout << "Constraints: 5 Bodies: 2 Full 2 Points 1 Orienation : " << " duration = " << setw(10) << duration << "(s)" << " (~" << setw(10) << duration / sample_count << "(s) per call)" << endl; duration = run_single_inverse_kinematics_benchmark(model, cs_five_full, sample_count); cout << "Constraints: 5 Bodies: 5 Full : " << " duration = " << setw(10) << duration << "(s)" << " (~" << setw(10) << duration / sample_count << "(s) per call)" << endl; return duration; } void print_usage () { #if defined (RBDL_BUILD_ADDON_LUAMODEL) || defined (RBDL_BUILD_ADDON_URDFREADER) cout << "Usage: benchmark [--count|-c ] [--depth|-d ] " << endl; #else cout << "Usage: benchmark [--count|-c ] [--depth|-d ]" << endl; #endif cout << "Simple benchmark tool for the Rigid Body Dynamics Library." << endl; cout << " --count | -c : sets the number of sample states that should" << endl; cout << " be calculated (default: 1000)" << endl; cout << " --depth | -d : sets maximum depth for the branched test model" << endl; cout << " which is created increased from 1 to (default: 5)." << endl; #if defined RBDL_BUILD_ADDON_URDFREADER cout << " --floating-base | -f : the specified URDF model is a floating base model." << endl; #endif cout << " --json : prints output in json format." << endl; cout << " --no-fd : disables benchmarking of forward dynamics." << endl; cout << " --no-fd-aba : disables benchmark for forwards dynamics using" << endl; cout << " the Articulated Body Algorithm" << endl; cout << " --no-fd-lagrangian : disables benchmark for forward dynamics via" << endl; cout << " solving the lagrangian equation." << endl; cout << " --no-id-rnea : disables benchmark for inverse dynamics using" << endl; cout << " the recursive newton euler algorithm." << endl; cout << " --no-crba : disables benchmark for joint space inertia" << endl; cout << " matrix computation using the composite rigid" << endl; cout << " body algorithm." << endl; cout << " --no-nle : disables benchmark for the nonlinear effects." << endl; cout << " --no-calc-minv : disables benchmark M^-1 * tau benchmark." << endl; cout << " --only-contacts | -C : only runs contact model benchmarks." << endl; cout << " --only-ik : only runs inverse kinematics benchmarks." << endl; cout << " --help | -h : prints this help." << endl; } void disable_all_benchmarks () { benchmark_run_fd_aba = false; benchmark_run_fd_lagrangian = false; benchmark_run_id_rnea = false; benchmark_run_crba = false; benchmark_run_nle = false; benchmark_run_calc_minv_times_tau = false; benchmark_run_contacts = false; } void parse_args (int argc, char* argv[]) { int argi = 1; while (argi < argc) { string arg = argv[argi]; if (arg == "--help" || arg == "-h") { print_usage(); exit (1); } else if (arg == "--count" || arg == "-c" ) { if (argi == argc - 1) { print_usage(); cerr << "Error: missing number of samples!" << endl; exit (1); } argi++; stringstream count_stream (argv[argi]); count_stream >> benchmark_sample_count; } else if (arg == "--depth" || arg == "-d" ) { if (argi == argc - 1) { print_usage(); cerr << "Error: missing number for model depth!" << endl; exit (1); } argi++; stringstream depth_stream (argv[argi]); depth_stream >> benchmark_model_max_depth; #ifdef RBDL_BUILD_ADDON_URDFREADER } else if (arg == "--floating-base" || arg == "-f") { urdf_floating_base = true; #endif } else if (arg == "--json") { json_output = true; } else if (arg == "--no-fd" ) { benchmark_run_fd_aba = false; benchmark_run_fd_lagrangian = false; } else if (arg == "--no-fd-aba" ) { benchmark_run_fd_aba = false; } else if (arg == "--no-fd-lagrangian" ) { benchmark_run_fd_lagrangian = false; } else if (arg == "--no-id-rnea" ) { benchmark_run_id_rnea = false; } else if (arg == "--no-crba" ) { benchmark_run_crba = false; } else if (arg == "--no-nle" ) { benchmark_run_nle = false; } else if (arg == "--no-calc-minv" ) { benchmark_run_calc_minv_times_tau = false; } else if (arg == "--only-contacts" || arg == "-C") { disable_all_benchmarks(); benchmark_run_contacts = true; } else if (arg == "--only-ik") { disable_all_benchmarks(); benchmark_run_ik = true; #if defined (RBDL_BUILD_ADDON_LUAMODEL) || defined (RBDL_BUILD_ADDON_URDFREADER) } else if (model_name == "") { model_name = arg; #endif } else { print_usage(); cerr << "Invalid argument '" << arg << "'." << endl; exit(1); } argi++; } } int main (int argc, char *argv[]) { parse_args (argc, argv); Model *model = NULL; model = new Model(); if (model_name != "") { if (model_name.substr (model_name.size() - 4, 4) == ".lua") { #ifdef RBDL_BUILD_ADDON_LUAMODEL RigidBodyDynamics::Addons::LuaModelReadFromFile (model_name.c_str(), model); #else cerr << "Could not load Lua model: LuaModel addon not enabled!" << endl; abort(); #endif } if (model_name.substr (model_name.size() - 5, 5) == ".urdf") { #ifdef RBDL_BUILD_ADDON_URDFREADER RigidBodyDynamics::Addons::URDFReadFromFile(model_name.c_str(), model, urdf_floating_base); #else cerr << "Could not load URDF model: urdfreader addon not enabled!" << endl; abort(); #endif } if (benchmark_run_fd_aba) { report_section("Forward Dynamics: ABA"); run_forward_dynamics_ABA_benchmark (model, benchmark_sample_count); } if (benchmark_run_fd_lagrangian) { report_section("Forward Dynamics: Lagrangian (Piv. LU decomposition)"); run_forward_dynamics_lagrangian_benchmark (model, benchmark_sample_count); } if (benchmark_run_id_rnea) { report_section("Inverse Dynamics: RNEA"); run_inverse_dynamics_RNEA_benchmark (model, benchmark_sample_count); } if (benchmark_run_crba) { report_section("Joint Space Inertia Matrix: CRBA"); run_CRBA_benchmark (model, benchmark_sample_count); } if (benchmark_run_nle) { report_section("Nonlinear Effects"); run_nle_benchmark (model, benchmark_sample_count); } delete model; return 0; } if (!json_output) { rbdl_print_version(); cout << endl; } if (benchmark_run_fd_aba) { report_section("Forward Dynamics: ABA"); for (int depth = 1; depth <= benchmark_model_max_depth; depth++) { ostringstream model_name_stream; model_name_stream << "planar_model_depth_" << depth; model_name = model_name_stream.str(); model = new Model(); model->gravity = Vector3d (0., -9.81, 0.); generate_planar_tree (model, depth); run_forward_dynamics_ABA_benchmark (model, benchmark_sample_count); delete model; } } if (benchmark_run_fd_lagrangian) { report_section("Forward Dynamics: Lagrangian (Piv. LU decomposition)"); for (int depth = 1; depth <= benchmark_model_max_depth; depth++) { model = new Model(); model->gravity = Vector3d (0., -9.81, 0.); generate_planar_tree (model, depth); run_forward_dynamics_lagrangian_benchmark (model, benchmark_sample_count); delete model; } } if (benchmark_run_id_rnea) { report_section("Inverse Dynamics: RNEA"); for (int depth = 1; depth <= benchmark_model_max_depth; depth++) { model = new Model(); model->gravity = Vector3d (0., -9.81, 0.); generate_planar_tree (model, depth); run_inverse_dynamics_RNEA_benchmark (model, benchmark_sample_count); delete model; } } if (benchmark_run_crba) { report_section("Joint Space Inertia Matrix: CRBA"); for (int depth = 1; depth <= benchmark_model_max_depth; depth++) { model = new Model(); model->gravity = Vector3d (0., -9.81, 0.); generate_planar_tree (model, depth); run_CRBA_benchmark (model, benchmark_sample_count); delete model; } } if (benchmark_run_nle) { report_section("Nonlinear Effects"); for (int depth = 1; depth <= benchmark_model_max_depth; depth++) { model = new Model(); model->gravity = Vector3d (0., -9.81, 0.); generate_planar_tree (model, depth); run_nle_benchmark (model, benchmark_sample_count); delete model; } } if (benchmark_run_calc_minv_times_tau) { report_section("CalcMInvTimesTau"); for (int depth = 1; depth <= benchmark_model_max_depth; depth++) { model = new Model(); model->gravity = Vector3d (0., -9.81, 0.); generate_planar_tree (model, depth); run_calc_minv_times_tau_benchmark (model, benchmark_sample_count); delete model; } } if (benchmark_run_contacts) { report_section("Contacts: ForwardDynamicsConstraintsDirect"); contacts_benchmark (benchmark_sample_count, ConstraintsMethodDirect); report_section("Contacts: ForwardDynamicsConstraintsRangeSpaceSparse"); contacts_benchmark (benchmark_sample_count, ConstraintsMethodRangeSpaceSparse); report_section("Contacts: ForwardDynamicsConstraintsNullSpace"); contacts_benchmark (benchmark_sample_count, ConstraintsMethodNullSpace); report_section("Contacts: ForwardDynamicsContactsKokkevis"); contacts_benchmark (benchmark_sample_count, ConstraintsMethodKokkevis); } if (benchmark_run_ik) { report_section("Inverse Kinematics"); run_all_inverse_kinematics_benchmark(benchmark_sample_count); } if (json_output) { cout.precision(15); cout << "{" << endl; cout << " \"rbdl_info\" : {" << endl; int compile_version = rbdl_get_api_version(); int compile_major = (compile_version & 0xff0000) >> 16; int compile_minor = (compile_version & 0x00ff00) >> 8; int compile_patch = (compile_version & 0x0000ff); std::ostringstream compile_version_string(""); compile_version_string << compile_major << "." << compile_minor << "." << compile_patch; cout << " \"version_str\" : \"" << compile_version_string.str() << "\"," << endl; cout << " \"major\" : " << compile_major << "," << endl; cout << " \"minor\" : " << compile_minor << "," << endl; cout << " \"patch\" : " << compile_patch << "," << endl; #if defined RBDL_USE_SIMPLE_MATH cout << " \"simple_math\" : " << "true," << endl; #else cout << " \"simple_math\" : " << "false," << endl; #endif cout << " \"build_type\" : \"" << RBDL_BUILD_TYPE << "\"," << endl; cout << " \"commit\" : \"" << RBDL_BUILD_COMMIT << "\"," << endl; cout << " \"branch\" : \"" << RBDL_BUILD_BRANCH << "\"," << endl; cout << " \"compiler_id\" : \"" << RBDL_BUILD_COMPILER_ID << "\"," << endl; cout << " \"compiler_version\" : \"" << RBDL_BUILD_COMPILER_VERSION << "\"" << endl; cout << " }," << endl; cout << " \"host_info\" : {" << endl; cout << " \"cpu_model_name\" : \"" << get_cpu_model_name() << "\"," << endl; cout << " \"time_utc\" : " << "\"" << get_utc_time_string() << "\"" << endl; cout << " }," << endl; cout << " \"runs\" : "; cout << "[" << endl; for (unsigned int i=0; i < benchmark_runs.size(); i++) { const BenchmarkRun& run = benchmark_runs[i]; const char* indent = " "; cout << " " << "{" << endl; cout << indent << "\"model\" : \"" << run.model_name << "\"," << endl; cout << indent << "\"dof\" : " << run.model_dof << "," << endl; cout << indent << "\"benchmark\" : \"" << run.benchmark << "\"," << endl; cout << indent << "\"duration\" : " << run.duration << "," << endl; cout << indent << "\"sample_count\" : " << run.sample_count << "," << endl; cout << indent << "\"avg\" : " << run.avg << "," << endl; cout << indent << "\"min\" : " << run.min << "," << endl; cout << indent << "\"max\" : " << run.max << endl; cout << " " << "}"; if (i != benchmark_runs.size() - 1) { cout << ","; } cout << endl; } cout << " ]" << endl; cout << "}" << endl; } return 0; }