GCC Code Coverage Report


Directory: ./
File: benchmark/all_robots.cpp
Date: 2025-01-16 08:47:40
Exec Total Coverage
Lines: 0 184 0.0%
Branches: 0 696 0.0%

Line Branch Exec Source
1 ///////////////////////////////////////////////////////////////////////////////
2 // BSD 3-Clause License
3 //
4 // Copyright (C) 2019-2021, LAAS-CNRS, University of Edinburgh
5 // Copyright note valid unless otherwise stated in individual files.
6 // All rights reserved.
7 ///////////////////////////////////////////////////////////////////////////////
8
9 #ifdef CROCODDYL_WITH_MULTITHREADING
10 #include <omp.h>
11 #endif
12 #ifndef CROCODDYL_WITH_NTHREADS
13 #define CROCODDYL_WITH_NTHREADS 1
14 #endif
15
16 #ifdef CROCODDYL_WITH_CODEGEN
17 #include "crocoddyl/core/codegen/action-base.hpp"
18 #endif
19
20 #include "crocoddyl/core/solvers/fddp.hpp"
21 #include "crocoddyl/core/utils/file-io.hpp"
22 #include "crocoddyl/core/utils/timer.hpp"
23 #include "factory/arm-kinova.hpp"
24 #include "factory/arm.hpp"
25 #include "factory/legged-robots.hpp"
26
27 #define STDDEV(vec) \
28 std::sqrt(((vec - vec.mean())).square().sum() / \
29 (static_cast<double>(vec.size()) - 1))
30 #define AVG(vec) (vec.mean())
31
32 void print_benchmark(RobotEENames robot) {
33 unsigned int N = 100; // number of nodes
34 unsigned int T = 1e3; // number of trials
35
36 // Building the running and terminal models
37 boost::shared_ptr<crocoddyl::ActionModelAbstract> runningModel, terminalModel;
38 if (robot.robot_name == "Talos_arm") {
39 crocoddyl::benchmark::build_arm_action_models(runningModel, terminalModel);
40 } else if (robot.robot_name == "Kinova_arm") {
41 crocoddyl::benchmark::build_arm_kinova_action_models(runningModel,
42 terminalModel);
43 } else {
44 crocoddyl::benchmark::build_contact_action_models(robot, runningModel,
45 terminalModel);
46 }
47
48 // Get the initial state
49 boost::shared_ptr<crocoddyl::StateMultibody> state =
50 boost::static_pointer_cast<crocoddyl::StateMultibody>(
51 runningModel->get_state());
52 std::cout << "NQ: " << state->get_nq() << std::endl;
53 std::cout << "Number of nodes: " << N << std::endl << std::endl;
54
55 Eigen::VectorXd default_state(state->get_nq() + state->get_nv());
56 boost::shared_ptr<crocoddyl::IntegratedActionModelEulerTpl<double> > rm =
57 boost::static_pointer_cast<
58 crocoddyl::IntegratedActionModelEulerTpl<double> >(runningModel);
59 if (robot.robot_name == "Talos_arm" || robot.robot_name == "Kinova_arm") {
60 boost::shared_ptr<
61 crocoddyl::DifferentialActionModelFreeFwdDynamicsTpl<double> >
62 dm = boost::static_pointer_cast<
63 crocoddyl::DifferentialActionModelFreeFwdDynamicsTpl<double> >(
64 rm->get_differential());
65 default_state
66 << dm->get_pinocchio().referenceConfigurations[robot.reference_conf],
67 Eigen::VectorXd::Zero(state->get_nv());
68 } else {
69 boost::shared_ptr<
70 crocoddyl::DifferentialActionModelContactFwdDynamicsTpl<double> >
71 dm = boost::static_pointer_cast<
72 crocoddyl::DifferentialActionModelContactFwdDynamicsTpl<double> >(
73 rm->get_differential());
74 default_state
75 << dm->get_pinocchio().referenceConfigurations[robot.reference_conf],
76 Eigen::VectorXd::Zero(state->get_nv());
77 }
78 Eigen::VectorXd x0(default_state);
79 std::vector<boost::shared_ptr<crocoddyl::ActionModelAbstract> > runningModels(
80 N, runningModel);
81 boost::shared_ptr<crocoddyl::ShootingProblem> problem =
82 boost::make_shared<crocoddyl::ShootingProblem>(x0, runningModels,
83 terminalModel);
84 // Computing the warm-start
85 std::vector<Eigen::VectorXd> xs(N + 1, x0);
86 std::vector<Eigen::VectorXd> us(
87 N, Eigen::VectorXd::Zero(runningModel->get_nu()));
88 for (unsigned int i = 0; i < N; ++i) {
89 const boost::shared_ptr<crocoddyl::ActionModelAbstract>& model =
90 problem->get_runningModels()[i];
91 const boost::shared_ptr<crocoddyl::ActionDataAbstract>& data =
92 problem->get_runningDatas()[i];
93 model->quasiStatic(data, us[i], x0);
94 }
95 crocoddyl::SolverFDDP ddp(problem);
96 ddp.setCandidate(xs, us, false);
97 boost::shared_ptr<crocoddyl::ActionDataAbstract> runningData =
98 runningModel->createData();
99
100 #ifdef CROCODDYL_WITH_CODEGEN
101 // Code generation of the running an terminal models
102 typedef CppAD::AD<CppAD::cg::CG<double> > ADScalar;
103 boost::shared_ptr<crocoddyl::ActionModelAbstractTpl<ADScalar> >
104 ad_runningModel, ad_terminalModel;
105 if (robot.robot_name == "Talos_arm") {
106 crocoddyl::benchmark::build_arm_action_models(ad_runningModel,
107 ad_terminalModel);
108 } else if (robot.robot_name == "Kinova_arm") {
109 crocoddyl::benchmark::build_arm_kinova_action_models(ad_runningModel,
110 ad_terminalModel);
111 } else {
112 crocoddyl::benchmark::build_contact_action_models(robot, ad_runningModel,
113 ad_terminalModel);
114 }
115
116 boost::shared_ptr<crocoddyl::ActionModelAbstract> cg_runningModel =
117 boost::make_shared<crocoddyl::ActionModelCodeGen>(
118 ad_runningModel, runningModel, robot.robot_name + "_running_cg");
119 boost::shared_ptr<crocoddyl::ActionModelAbstract> cg_terminalModel =
120 boost::make_shared<crocoddyl::ActionModelCodeGen>(
121 ad_terminalModel, terminalModel, robot.robot_name + "_terminal_cg");
122
123 // Defining the shooting problem for both cases: with and without code
124 // generation
125 std::vector<boost::shared_ptr<crocoddyl::ActionModelAbstract> >
126 cg_runningModels(N, cg_runningModel);
127 boost::shared_ptr<crocoddyl::ShootingProblem> cg_problem =
128 boost::make_shared<crocoddyl::ShootingProblem>(x0, cg_runningModels,
129 cg_terminalModel);
130
131 // Check that code-generated action model is the same as original.
132 /**************************************************************************/
133 crocoddyl::SolverFDDP cg_ddp(cg_problem);
134 cg_ddp.setCandidate(xs, us, false);
135 boost::shared_ptr<crocoddyl::ActionDataAbstract> cg_runningData =
136 cg_runningModel->createData();
137 Eigen::VectorXd x_rand = cg_runningModel->get_state()->rand();
138 Eigen::VectorXd u_rand = Eigen::VectorXd::Random(cg_runningModel->get_nu());
139 runningModel->calc(runningData, x_rand, u_rand);
140 runningModel->calcDiff(runningData, x_rand, u_rand);
141 cg_runningModel->calc(cg_runningData, x_rand, u_rand);
142 cg_runningModel->calcDiff(cg_runningData, x_rand, u_rand);
143 assert_pretty(cg_runningData->xnext.isApprox(runningData->xnext),
144 "Problem in xnext");
145 assert_pretty(std::abs(cg_runningData->cost - runningData->cost) < 1e-10,
146 "Problem in cost");
147 assert_pretty(cg_runningData->Lx.isApprox(runningData->Lx), "Problem in Lx");
148 assert_pretty(cg_runningData->Lu.isApprox(runningData->Lu), "Problem in Lu");
149 assert_pretty(cg_runningData->Lxx.isApprox(runningData->Lxx),
150 "Problem in Lxx");
151 assert_pretty(cg_runningData->Lxu.isApprox(runningData->Lxu),
152 "Problem in Lxu");
153 assert_pretty(cg_runningData->Luu.isApprox(runningData->Luu),
154 "Problem in Luu");
155 assert_pretty(cg_runningData->Fx.isApprox(runningData->Fx), "Problem in Fx");
156 assert_pretty(cg_runningData->Fu.isApprox(runningData->Fu), "Problem in Fu");
157 #endif // CROCODDYL_WITH_CODEGEN
158
159 /******************************* create csv file
160 * *******************************/
161 const std::string csv_filename = "/tmp/" + robot.robot_name + "_" +
162 std::to_string(state->get_nq()) +
163 "DoF.bench";
164 CsvStream csv(csv_filename);
165 csv << "fn_name"
166 << "nthreads"
167 << "with_cg"
168 << "mean"
169 << "stddev"
170 << "max"
171 << "min"
172 << "mean_per_nodes"
173 << "stddev_per_nodes" << csv.endl;
174
175 /*******************************************************************************/
176 /*********************************** TIMINGS
177 * ***********************************/
178 Eigen::ArrayXd duration(T);
179 Eigen::ArrayXd avg(CROCODDYL_WITH_NTHREADS);
180 Eigen::ArrayXd stddev(CROCODDYL_WITH_NTHREADS);
181
182 /*******************************************************************************/
183 /****************************** ACTION MODEL TIMINGS
184 * ***************************/
185 std::cout << "Without Code Generation:" << std::endl;
186 problem->calc(xs, us);
187 // calcDiff timings
188 for (int ithread = 0; ithread < CROCODDYL_WITH_NTHREADS; ++ithread) {
189 duration.setZero();
190 for (unsigned int i = 0; i < T; ++i) {
191 crocoddyl::Timer timer;
192 #ifdef CROCODDYL_WITH_MULTITHREADING
193 #pragma omp parallel for num_threads(ithread + 1)
194 #endif
195 for (unsigned int j = 0; j < N; ++j) {
196 runningModels[j]->calcDiff(problem->get_runningDatas()[j], xs[j],
197 us[j]);
198 }
199 duration[i] = timer.get_us_duration();
200 }
201 avg[ithread] = AVG(duration);
202 stddev[ithread] = STDDEV(duration);
203 std::cout << ithread + 1 << " threaded calcDiff [us]:\t" << avg[ithread]
204 << " +- " << stddev[ithread] << " (max: " << duration.maxCoeff()
205 << ", min: " << duration.minCoeff()
206 << ", per nodes: " << avg[ithread] * (ithread + 1) / N << " +- "
207 << stddev[ithread] * (ithread + 1) / N << ")" << std::endl;
208 csv << "calcDiff" << (ithread + 1) << false << avg[ithread]
209 << stddev[ithread] << duration.maxCoeff() << duration.minCoeff()
210 << avg[ithread] * (ithread + 1) / N
211 << stddev[ithread] * (ithread + 1) / N << csv.endl;
212 }
213
214 // calc timings
215 for (int ithread = 0; ithread < CROCODDYL_WITH_NTHREADS; ++ithread) {
216 duration.setZero();
217 for (unsigned int i = 0; i < T; ++i) {
218 crocoddyl::Timer timer;
219 #ifdef CROCODDYL_WITH_MULTITHREADING
220 #pragma omp parallel for num_threads(ithread + 1)
221 #endif
222 for (unsigned int j = 0; j < N; ++j) {
223 runningModels[j]->calc(problem->get_runningDatas()[j], xs[j], us[j]);
224 }
225 duration[i] = timer.get_us_duration();
226 }
227 avg[ithread] = AVG(duration);
228 stddev[ithread] = STDDEV(duration);
229 std::cout << ithread + 1 << " threaded calc [us]: \t" << avg[ithread]
230 << " +- " << stddev[ithread] << " (max: " << duration.maxCoeff()
231 << ", min: " << duration.minCoeff()
232 << ", per nodes: " << avg[ithread] * (ithread + 1) / N << " +- "
233 << stddev[ithread] * (ithread + 1) / N << ")" << std::endl;
234 csv << "calc" << (ithread + 1) << false << avg[ithread] << stddev[ithread]
235 << duration.maxCoeff() << duration.minCoeff()
236 << avg[ithread] * (ithread + 1) / N
237 << stddev[ithread] * (ithread + 1) / N << csv.endl;
238 }
239
240 /*******************************************************************************/
241 /******************* DDP BACKWARD AND FORWARD PASSES TIMINGS
242 * *******************/
243 // Backward pass timings
244 ddp.calcDiff();
245 duration.setZero();
246 for (unsigned int i = 0; i < T; ++i) {
247 crocoddyl::Timer timer;
248 ddp.backwardPass();
249 duration[i] = timer.get_us_duration();
250 }
251 double avg_bp = AVG(duration);
252 double stddev_bp = STDDEV(duration);
253 std::cout << "backwardPass [us]:\t\t" << avg_bp << " +- " << stddev_bp
254 << " (max: " << duration.maxCoeff()
255 << ", min: " << duration.minCoeff() << ", per nodes: " << avg_bp / N
256 << " +- " << stddev_bp / N << ")" << std::endl;
257
258 csv << "backwardPass" << 1 << false << avg_bp << stddev_bp
259 << duration.maxCoeff() << duration.minCoeff() << avg_bp / N
260 << stddev_bp / N << csv.endl;
261
262 // Forward pass timings
263 duration.setZero();
264 for (unsigned int i = 0; i < T; ++i) {
265 crocoddyl::Timer timer;
266 ddp.forwardPass(0.005);
267 duration[i] = timer.get_us_duration();
268 }
269 double avg_fp = AVG(duration);
270 double stddev_fp = STDDEV(duration);
271 std::cout << "forwardPass [us]: \t\t" << avg_fp << " +- " << stddev_fp
272 << " (max: " << duration.maxCoeff()
273 << ", min: " << duration.minCoeff() << ", per nodes: " << avg_fp / N
274 << " +- " << stddev_fp / N << ")" << std::endl;
275
276 csv << "forwardPass" << 1 << false << avg_fp << stddev_fp
277 << duration.maxCoeff() << duration.minCoeff() << avg_fp / N
278 << stddev_fp / N << csv.endl;
279
280 #ifdef CROCODDYL_WITH_CODEGEN
281
282 /*******************************************************************************/
283 /*************************** CODE GENERATION TIMINGS
284 * ***************************/
285 /*******************************************************************************/
286
287 /*******************************************************************************/
288 /****************************** ACTION MODEL TIMINGS
289 * ***************************/
290 std::cout << std::endl << "With Code Generation:" << std::endl;
291 // calcDiff timings
292 cg_problem->calc(xs, us);
293 for (int ithread = 0; ithread < CROCODDYL_WITH_NTHREADS; ++ithread) {
294 duration.setZero();
295 for (unsigned int i = 0; i < T; ++i) {
296 crocoddyl::Timer timer;
297 #ifdef CROCODDYL_WITH_MULTITHREADING
298 #pragma omp parallel for num_threads(ithread + 1)
299 #endif
300 for (unsigned int j = 0; j < N; ++j) {
301 cg_runningModels[j]->calcDiff(cg_problem->get_runningDatas()[j], xs[j],
302 us[j]);
303 }
304 duration[i] = timer.get_us_duration();
305 }
306 avg[ithread] = AVG(duration);
307 stddev[ithread] = STDDEV(duration);
308 std::cout << ithread + 1 << " threaded calcDiff [us]:\t" << avg[ithread]
309 << " +- " << stddev[ithread] << " (max: " << duration.maxCoeff()
310 << ", min: " << duration.minCoeff()
311 << ", per nodes: " << avg[ithread] * (ithread + 1) / N << " +- "
312 << stddev[ithread] * (ithread + 1) / N << ")" << std::endl;
313 csv << "calcDiff" << (ithread + 1) << true << avg[ithread]
314 << stddev[ithread] << duration.maxCoeff() << duration.minCoeff()
315 << avg[ithread] * (ithread + 1) / N
316 << stddev[ithread] * (ithread + 1) / N << csv.endl;
317 }
318
319 // calc timings
320 for (int ithread = 0; ithread < CROCODDYL_WITH_NTHREADS; ++ithread) {
321 duration.setZero();
322 for (unsigned int i = 0; i < T; ++i) {
323 crocoddyl::Timer timer;
324 #ifdef CROCODDYL_WITH_MULTITHREADING
325 #pragma omp parallel for num_threads(ithread + 1)
326 #endif
327 for (unsigned int j = 0; j < N; ++j) {
328 cg_runningModels[j]->calc(cg_problem->get_runningDatas()[j], xs[j],
329 us[j]);
330 }
331 duration[i] = timer.get_us_duration();
332 }
333 avg[ithread] = AVG(duration);
334 stddev[ithread] = STDDEV(duration);
335 std::cout << ithread + 1 << " threaded calc [us]: \t" << avg[ithread]
336 << " +- " << stddev[ithread] << " (max: " << duration.maxCoeff()
337 << ", min: " << duration.minCoeff()
338 << ", per nodes: " << avg[ithread] * (ithread + 1) / N << " +- "
339 << stddev[ithread] * (ithread + 1) / N << ")" << std::endl;
340 csv << "calc" << (ithread + 1) << true << avg[ithread] << stddev[ithread]
341 << duration.maxCoeff() << duration.minCoeff()
342 << avg[ithread] * (ithread + 1) / N
343 << stddev[ithread] * (ithread + 1) / N << csv.endl;
344 }
345
346 /*******************************************************************************/
347 /******************* DDP BACKWARD AND FORWARD PASSES TIMINGS
348 * *******************/
349 // Backward pass timings
350 cg_ddp.calcDiff();
351 for (unsigned int i = 0; i < T; ++i) {
352 crocoddyl::Timer timer;
353 cg_ddp.backwardPass();
354 duration[i] = timer.get_us_duration();
355 }
356 avg_bp = AVG(duration);
357 stddev_bp = STDDEV(duration);
358 std::cout << "backwardPass [us]:\t\t" << avg_bp << " +- " << stddev_bp
359 << " (max: " << duration.maxCoeff()
360 << ", min: " << duration.minCoeff() << ", per nodes: " << avg_bp / N
361 << " +- " << stddev_bp / N << ")" << std::endl;
362 csv << "backwardPass" << 1 << true << avg_bp << stddev_bp
363 << duration.maxCoeff() << duration.minCoeff() << avg_bp / N
364 << stddev_bp / N << csv.endl;
365
366 // Forward pass timings
367 for (unsigned int i = 0; i < T; ++i) {
368 crocoddyl::Timer timer;
369 cg_ddp.forwardPass(0.005);
370 duration[i] = timer.get_us_duration();
371 }
372 avg_fp = AVG(duration);
373 stddev_fp = STDDEV(duration);
374 std::cout << "forwardPass [us]: \t\t" << avg_fp << " +- " << stddev_fp
375 << " (max: " << duration.maxCoeff()
376 << ", min: " << duration.minCoeff() << ", per nodes: " << avg_fp / N
377 << " +- " << stddev_fp / N << ")" << std::endl;
378
379 csv << "forwardPass" << 1 << true << avg_fp << stddev_fp
380 << duration.maxCoeff() << duration.minCoeff() << avg_fp / N
381 << stddev_fp / N << csv.endl;
382
383 #endif // CROCODDYL_WITH_CODEGEN
384 }
385
386 int main() {
387 // Arm Manipulation Benchmarks
388 std::cout << "********************Talos 4DoF Arm******************"
389 << std::endl;
390 std::vector<std::string> contact_names;
391 std::vector<crocoddyl::ContactType> contact_types;
392 RobotEENames talosArm4Dof(
393 "Talos_arm", contact_names, contact_types,
394 EXAMPLE_ROBOT_DATA_MODEL_DIR "/talos_data/robots/talos_left_arm.urdf",
395 EXAMPLE_ROBOT_DATA_MODEL_DIR "/talos_data/srdf/talos.srdf",
396 "gripper_left_joint", "half_sitting");
397
398 print_benchmark(talosArm4Dof);
399 // Arm Manipulation Benchmarks
400 std::cout << "******************** Kinova Arm ******************"
401 << std::endl;
402 RobotEENames kinovaArm(
403 "Kinova_arm", contact_names, contact_types,
404 EXAMPLE_ROBOT_DATA_MODEL_DIR "/kinova_description/robots/kinova.urdf",
405 EXAMPLE_ROBOT_DATA_MODEL_DIR "/kinova_description/srdf/kinova.srdf",
406 "gripper_left_joint", "arm_up");
407
408 print_benchmark(kinovaArm);
409
410 // Quadruped Solo Benchmarks
411 std::cout << "********************Quadruped Solo******************"
412 << std::endl;
413 contact_names.clear();
414 contact_types.clear();
415 contact_names.push_back("FR_KFE");
416 contact_names.push_back("HL_KFE");
417 contact_types.push_back(crocoddyl::Contact3D);
418 contact_types.push_back(crocoddyl::Contact3D);
419 RobotEENames quadrupedSolo(
420 "Solo", contact_names, contact_types,
421 EXAMPLE_ROBOT_DATA_MODEL_DIR "/solo_description/robots/solo.urdf",
422 EXAMPLE_ROBOT_DATA_MODEL_DIR "/solo_description/srdf/solo.srdf", "HL_KFE",
423 "standing");
424
425 print_benchmark(quadrupedSolo);
426
427 // Quadruped Anymal Benchmarks
428 std::cout << "********************Quadruped Anymal******************"
429 << std::endl;
430 contact_names.clear();
431 contact_types.clear();
432 contact_names.push_back("RF_KFE");
433 contact_names.push_back("LF_KFE");
434 contact_names.push_back("LH_KFE");
435 contact_types.push_back(crocoddyl::Contact3D);
436 contact_types.push_back(crocoddyl::Contact3D);
437 contact_types.push_back(crocoddyl::Contact3D);
438 RobotEENames quadrupedAnymal(
439 "Anymal", contact_names, contact_types,
440 EXAMPLE_ROBOT_DATA_MODEL_DIR
441 "/anymal_b_simple_description/robots/anymal.urdf",
442 EXAMPLE_ROBOT_DATA_MODEL_DIR
443 "/anymal_b_simple_description/srdf/anymal.srdf",
444 "RH_KFE", "standing");
445
446 print_benchmark(quadrupedAnymal);
447
448 // Quadruped HyQ Benchmarks
449 std::cout << "******************** Quadruped HyQ ******************"
450 << std::endl;
451 contact_names.clear();
452 contact_types.clear();
453 contact_names.push_back("rf_kfe_joint");
454 contact_names.push_back("lf_kfe_joint");
455 contact_names.push_back("lh_kfe_joint");
456 contact_types.push_back(crocoddyl::Contact3D);
457 contact_types.push_back(crocoddyl::Contact3D);
458 contact_types.push_back(crocoddyl::Contact3D);
459 RobotEENames quadrupedHyQ("HyQ", contact_names, contact_types,
460 EXAMPLE_ROBOT_DATA_MODEL_DIR
461 "/hyq_description/robots/hyq_no_sensors.urdf",
462 EXAMPLE_ROBOT_DATA_MODEL_DIR
463 "/hyq_description/srdf/hyq.srdf",
464 "rh_kfe_joint", "standing");
465
466 print_benchmark(quadrupedHyQ);
467
468 // Biped icub Benchmarks
469 std::cout << "********************Biped iCub ***********************"
470 << std::endl;
471 contact_names.clear();
472 contact_types.clear();
473 contact_names.push_back("r_ankle_roll");
474 contact_names.push_back("l_ankle_roll");
475 contact_types.push_back(crocoddyl::Contact6D);
476 contact_types.push_back(crocoddyl::Contact6D);
477
478 RobotEENames bipedIcub(
479 "iCub", contact_names, contact_types,
480 EXAMPLE_ROBOT_DATA_MODEL_DIR "/icub_description/robots/icub_reduced.urdf",
481 EXAMPLE_ROBOT_DATA_MODEL_DIR "/icub_description/srdf/icub.srdf",
482 "r_wrist_yaw", "half_sitting");
483 print_benchmark(bipedIcub);
484
485 // Biped icub Benchmarks
486 std::cout << "********************Biped Talos***********************"
487 << std::endl;
488 contact_names.clear();
489 contact_types.clear();
490 contact_names.push_back("leg_right_6_joint");
491 contact_names.push_back("leg_left_6_joint");
492 contact_types.push_back(crocoddyl::Contact6D);
493 contact_types.push_back(crocoddyl::Contact6D);
494
495 RobotEENames bipedTalos(
496 "Talos", contact_names, contact_types,
497 EXAMPLE_ROBOT_DATA_MODEL_DIR "/talos_data/robots/talos_reduced.urdf",
498 EXAMPLE_ROBOT_DATA_MODEL_DIR "/talos_data/srdf/talos.srdf",
499 "arm_right_7_joint", "half_sitting");
500 print_benchmark(bipedTalos);
501
502 return 0;
503 }
504