opspace/src/testTask.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2011 The Board of Trustees of The Leland Stanford Junior University. All rights reserved.
00003  *
00004  * Author: Roland Philippsen
00005  *         http://cs.stanford.edu/group/manips/
00006  *
00007  * This program is free software: you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public License
00009  * as published by the Free Software Foundation, either version 3 of
00010  * the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful, but
00013  * WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this program.  If not, see
00019  * <http://www.gnu.org/licenses/>
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 }

Generated on Fri Aug 26 01:31:17 2011 for Stanford Whole-Body Control Framework by  doxygen 1.5.4