00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <gtest/gtest.h>
00023 #include <opspace/task_library.hpp>
00024 #include <opspace/skill_library.hpp>
00025 #include <opspace/ClassicTaskPostureController.hpp>
00026 #include <jspace/test/model_library.hpp>
00027 #include <err.h>
00028
00029 using jspace::Model;
00030 using jspace::State;
00031 using jspace::pretty_print;
00032 using namespace opspace;
00033 using boost::shared_ptr;
00034 using namespace std;
00035
00036
00037 static Model * get_puma()
00038 {
00039 static Model * puma(0);
00040 if ( ! puma) {
00041 puma = jspace::test::create_puma_model();
00042 }
00043 size_t const ndof(puma->getNDOF());
00044 State state(ndof, ndof, 0);
00045 for (size_t ii(0); ii < ndof; ++ii) {
00046 state.position_[ii] = 0.01 * ii + 0.08;
00047 state.velocity_[ii] = 0.02 - 0.005 * ii;
00048 }
00049 puma->update(state);
00050 return puma;
00051 }
00052
00053
00054 TEST (task, basics)
00055 {
00056 Model * puma(get_puma());
00057 SelectedJointPostureTask odd("odd");
00058 Status st;
00059
00060 st = odd.update(*puma);
00061 EXPECT_FALSE (st.ok) << "update before init should have failed";
00062
00063 st = odd.init(*puma);
00064 EXPECT_FALSE (st.ok) << "init before selection setting should have failed";
00065
00066 Parameter * selection(odd.lookupParameter("selection", PARAMETER_TYPE_VECTOR));
00067 ASSERT_NE ((void*)0, selection) << "failed to retrieve selection parameter";
00068
00069 Vector sel(Vector::Zero(puma->getNDOF()));
00070 for (size_t ii(0); ii < puma->getNDOF(); ii += 2) {
00071 sel[ii] = 1.0;
00072 }
00073 st = selection->set(sel);
00074 EXPECT_TRUE (st.ok) << "failed to set selection: " << st.errstr;
00075
00076 st = odd.init(*puma);
00077 EXPECT_TRUE (st.ok) << "init failed: " << st.errstr;
00078
00079 st = odd.update(*puma);
00080 EXPECT_TRUE (st.ok) << "update failed: " << st.errstr;
00081 }
00082
00083
00084 static shared_ptr<Task> create_sel_jp_task(string const & name, Vector const & selection)
00085 throw(runtime_error)
00086 {
00087 SelectedJointPostureTask * task(new SelectedJointPostureTask(name));
00088 Parameter * sel_p(task->lookupParameter("selection", PARAMETER_TYPE_VECTOR));
00089 if ( ! sel_p) {
00090 delete task;
00091 throw runtime_error("failed to retrieve selection parameter");
00092 }
00093 Status const st(sel_p->set(selection));
00094 if ( ! st) {
00095 delete task;
00096 throw runtime_error("failed to set selection: " + st.errstr);
00097 }
00098 return shared_ptr<Task>(task);
00099 }
00100
00101
00102 static void append_odd_even_tasks(GenericSkill gb, size_t ndof)
00103 {
00104 vector<shared_ptr<Task> > task;
00105 Vector sel_odd(Vector::Zero(ndof));
00106 Vector sel_even(Vector::Zero(ndof));
00107 for (size_t ii(0); ii < ndof; ++ii) {
00108 if (0 == (ii % 2)) {
00109 sel_even[ii] = 1.0;
00110 }
00111 else {
00112 sel_odd[ii] = 1.0;
00113 }
00114 }
00115 task.push_back(create_sel_jp_task("odd", sel_odd));
00116 task.push_back(create_sel_jp_task("even", sel_even));
00117 for (size_t ii(0); ii < task.size(); ++ii) {
00118 gb.appendTask(task[ii]);
00119 }
00120 }
00121
00122
00123 static void append_odd_full_tasks(GenericSkill gb, size_t ndof)
00124 {
00125 vector<shared_ptr<Task> > task;
00126 Vector sel_odd(Vector::Zero(ndof));
00127 Vector sel_full(Vector::Ones(ndof));
00128 for (size_t ii(1); ii < ndof; ii += 2) {
00129 sel_odd[ii] = 1.0;
00130 }
00131 task.push_back(create_sel_jp_task("odd", sel_odd));
00132 task.push_back(create_sel_jp_task("full", sel_full));
00133 for (size_t ii(0); ii < task.size(); ++ii) {
00134 gb.appendTask(task[ii]);
00135 }
00136 }
00137
00138
00139 TEST (controller, odd_even)
00140 {
00141 shared_ptr<Task> jpos;
00142 Vector gamma_jpos;
00143
00144 vector<shared_ptr<ClassicTaskPostureController> > ctrl;
00145 vector<shared_ptr<GenericSkill> > gb;
00146 vector<Vector> gamma;
00147
00148 try {
00149 Model * puma(get_puma());
00150 Matrix aa;
00151 Vector gg;
00152 ASSERT_TRUE (puma->getMassInertia(aa)) << "failed to get mass inertia";
00153 ASSERT_TRUE (puma->getGravity(gg)) << "failed to get gravity";
00154
00155 jpos = create_sel_jp_task("all", Vector::Ones(puma->getNDOF()));
00156 Status st;
00157 st = jpos->init(*puma);
00158 EXPECT_TRUE (st.ok) << "failed to init jpos task: " << st.errstr;
00159 st = jpos->update(*puma);
00160 EXPECT_TRUE (st.ok) << "failed to update jpos task: " << st.errstr;
00161 gamma_jpos = aa * jpos->getCommand() + gg;
00162
00163 ctrl.push_back(shared_ptr<ClassicTaskPostureController>(new ClassicTaskPostureController("blah")));
00164 gb.push_back(shared_ptr<GenericSkill>(new GenericSkill("blah")));
00165 gamma.push_back(Vector::Zero(puma->getNDOF()));
00166
00167 for (size_t ii(0); ii < ctrl.size(); ++ii) {
00168
00169 append_odd_even_tasks(*gb[ii], puma->getNDOF());
00170 st = gb[ii]->init(*puma);
00171 EXPECT_TRUE (st.ok) << "failed to init generic skill #"
00172 << ii << ": " << st.errstr;
00173 st = ctrl[ii]->init(*puma);
00174 EXPECT_TRUE (st.ok) << "failed to init controller #"
00175 << ii << " `" << ctrl[ii]->getName() << "': " << st.errstr;
00176 st = ctrl[ii]->computeCommand(*puma, *gb[ii], gamma[ii]);
00177 EXPECT_TRUE (st.ok) << "failed to compute torques #"
00178 << ii << " `" << ctrl[ii]->getName() << "': " << st.errstr;
00179 }
00180
00181 cout << "==================================================\n"
00182 << "whole-body torque comparison:\n";
00183 pretty_print(gamma_jpos, cout, " reference jpos task", " ");
00184 for (size_t ii(0); ii < ctrl.size(); ++ii) {
00185 pretty_print(gamma[ii], cout, " controller `" + ctrl[ii]->getName() + "'", " ");
00186 Vector const delta(gamma_jpos - gamma[ii]);
00187 pretty_print(delta, cout, " delta", " ");
00188 }
00189
00190 }
00191 catch (exception const & ee) {
00192 ADD_FAILURE () << "exception " << ee.what();
00193 }
00194 }
00195
00196
00197 TEST (controller, odd_full)
00198 {
00199 shared_ptr<Task> jpos;
00200 Vector gamma_jpos;
00201
00202 vector<shared_ptr<ClassicTaskPostureController> > ctrl;
00203 vector<shared_ptr<GenericSkill> > gb;
00204 vector<Vector> gamma;
00205
00206 try {
00207 Model * puma(get_puma());
00208 Matrix aa;
00209 Vector gg;
00210 ASSERT_TRUE (puma->getMassInertia(aa)) << "failed to get mass inertia";
00211 ASSERT_TRUE (puma->getGravity(gg)) << "failed to get gravity";
00212
00213 jpos = create_sel_jp_task("all", Vector::Ones(puma->getNDOF()));
00214 Status st;
00215 st = jpos->init(*puma);
00216 EXPECT_TRUE (st.ok) << "failed to init jpos task: " << st.errstr;
00217 st = jpos->update(*puma);
00218 EXPECT_TRUE (st.ok) << "failed to update jpos task: " << st.errstr;
00219 gamma_jpos = aa * jpos->getCommand() + gg;
00220
00221 ctrl.push_back(shared_ptr<ClassicTaskPostureController>(new ClassicTaskPostureController("blah")));
00222 gb.push_back(shared_ptr<GenericSkill>(new GenericSkill("blah")));
00223 gamma.push_back(Vector::Zero(puma->getNDOF()));
00224
00225 for (size_t ii(0); ii < ctrl.size(); ++ii) {
00226
00227 append_odd_full_tasks(*gb[ii], puma->getNDOF());
00228 st = gb[ii]->init(*puma);
00229 EXPECT_TRUE (st.ok) << "failed to init generic skill #"
00230 << ii << ": " << st.errstr;
00231 st = ctrl[ii]->init(*puma);
00232 EXPECT_TRUE (st.ok) << "failed to init controller #"
00233 << ii << " `" << ctrl[ii]->getName() << "': " << st.errstr;
00234 st = ctrl[ii]->computeCommand(*puma, *gb[ii], gamma[ii]);
00235 EXPECT_TRUE (st.ok) << "failed to compute torques #"
00236 << ii << " `" << ctrl[ii]->getName() << "': " << st.errstr;
00237 }
00238
00239 cout << "==================================================\n"
00240 << "whole-body torque comparison:\n";
00241 pretty_print(gamma_jpos, cout, " reference jpos task", " ");
00242 for (size_t ii(0); ii < ctrl.size(); ++ii) {
00243 pretty_print(gamma[ii], cout, " controller `" + ctrl[ii]->getName() + "'", " ");
00244 Vector const delta(gamma_jpos - gamma[ii]);
00245 pretty_print(delta, cout, " delta", " ");
00246 }
00247
00248 }
00249 catch (exception const & ee) {
00250 ADD_FAILURE () << "exception " << ee.what();
00251 }
00252 }
00253
00254
00255
00256
00257 TEST (task, jlimit)
00258 {
00259 shared_ptr<JointLimitTask> jlimit(new JointLimitTask("jlimit"));
00260
00261 try {
00262 Model * puma(get_puma());
00263 size_t const ndof(puma->getNDOF());
00264
00265 Parameter * param(jlimit->lookupParameter("dt_seconds", PARAMETER_TYPE_REAL));
00266 ASSERT_NE ((void*)0, param) << "failed to get dt_seconds param";
00267 Status st(param->set(0.1));
00268 ASSERT_TRUE (st.ok) << "failed to set dt_seconds: " << st.errstr;
00269
00270 param = jlimit->lookupParameter("upper_stop_deg", PARAMETER_TYPE_VECTOR);
00271 ASSERT_NE ((void*)0, param) << "failed to get upper_stop_deg param";
00272 Vector foo(30.0 * Vector::Ones(ndof));
00273 st = param->set(foo);
00274 ASSERT_TRUE (st.ok) << "failed to set upper_stop_deg: " << st.errstr;
00275
00276 param = jlimit->lookupParameter("upper_trigger_deg", PARAMETER_TYPE_VECTOR);
00277 ASSERT_NE ((void*)0, param) << "failed to get upper_trigger_deg param";
00278 foo = 20.0 * Vector::Ones(ndof);
00279 st = param->set(foo);
00280 ASSERT_TRUE (st.ok) << "failed to set upper_trigger_deg: " << st.errstr;
00281
00282 param = jlimit->lookupParameter("lower_stop_deg", PARAMETER_TYPE_VECTOR);
00283 ASSERT_NE ((void*)0, param) << "failed to get lower_stop_deg param";
00284 foo = -30.0 * Vector::Ones(ndof);
00285 st = param->set(foo);
00286 ASSERT_TRUE (st.ok) << "failed to set lower_stop_deg: " << st.errstr;
00287
00288 param = jlimit->lookupParameter("lower_trigger_deg", PARAMETER_TYPE_VECTOR);
00289 ASSERT_NE ((void*)0, param) << "failed to get lower_trigger_deg param";
00290 foo = -20.0 * Vector::Ones(ndof);
00291 st = param->set(foo);
00292 ASSERT_TRUE (st.ok) << "failed to set lower_trigger_deg: " << st.errstr;
00293
00294 param = jlimit->lookupParameter("kp", PARAMETER_TYPE_VECTOR);
00295 ASSERT_NE ((void*)0, param) << "failed to get kp param";
00296 foo = 100.0 * Vector::Ones(ndof);
00297 st = param->set(foo);
00298 ASSERT_TRUE (st.ok) << "failed to set kp: " << st.errstr;
00299
00300 param = jlimit->lookupParameter("kd", PARAMETER_TYPE_VECTOR);
00301 ASSERT_NE ((void*)0, param) << "failed to get kd param";
00302 foo = 20.0 * Vector::Ones(ndof);
00303 st = param->set(foo);
00304 ASSERT_TRUE (st.ok) << "failed to set kd: " << st.errstr;
00305
00306 param = jlimit->lookupParameter("maxvel", PARAMETER_TYPE_VECTOR);
00307 ASSERT_NE ((void*)0, param) << "failed to get maxvel param";
00308 foo = 10.0 * M_PI / 180.0 * Vector::Ones(ndof);
00309 st = param->set(foo);
00310 ASSERT_TRUE (st.ok) << "failed to set maxvel: " << st.errstr;
00311
00312 param = jlimit->lookupParameter("maxacc", PARAMETER_TYPE_VECTOR);
00313 ASSERT_NE ((void*)0, param) << "failed to get maxacc param";
00314 foo = 25.0 * M_PI / 180.0 * Vector::Ones(ndof);
00315 st = param->set(foo);
00316 ASSERT_TRUE (st.ok) << "failed to set maxacc: " << st.errstr;
00317
00318 ClassicTaskPostureController ctrl("ctrl");
00319 GenericSkill gb("gb");
00320 gb.appendTask(jlimit);
00321
00322 State state(ndof, ndof, 0);
00323 state.position_ = Vector::Zero(ndof);
00324 state.velocity_ = Vector::Zero(ndof);
00325 puma->update(state);
00326 st = gb.init(*puma);
00327 EXPECT_TRUE (st.ok) << "failed to init generic skill: " << st.errstr;
00328 st = ctrl.init(*puma);
00329 EXPECT_TRUE (st.ok) << "failed to init controller: " << st.errstr;
00330 Vector gamma;
00331 st = ctrl.computeCommand(*puma, gb, gamma);
00332 EXPECT_FALSE (st.ok) << "computeCommand should have failed due to empty Jacobians";
00333
00334 for (size_t ii(0); ii < ndof; ++ii) {
00335 if (0 == ii % 2) {
00336 state.position_[ii] = 4.0 * M_PI;
00337 }
00338 else {
00339 state.position_[ii] = -4.0 * M_PI;
00340 }
00341 puma->update(state);
00342 st = gb.update(*puma);
00343 EXPECT_TRUE (st.ok) << "failed to update generic skill: " << st.errstr;
00344 st = ctrl.computeCommand(*puma, gb, gamma);
00345 EXPECT_TRUE (st.ok) << "failed to computeCommand: " << st.errstr;
00346 }
00347
00348 }
00349 catch (exception const & ee) {
00350 ADD_FAILURE () << "exception " << ee.what();
00351 }
00352 }
00353
00354
00355 int main(int argc, char ** argv)
00356 {
00357 testing::InitGoogleTest(&argc, argv);
00358 return RUN_ALL_TESTS ();
00359 }