tutorials/tut03_gravity_compensation.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 
00046 #include "tutsim.hpp"
00047 #include <opspace/Task.hpp>
00048 #include <jspace/test/sai_util.hpp>
00049 #include <boost/shared_ptr.hpp>
00050 #include <err.h>
00051 
00052 
00053 namespace tut03 {
00054   
00055   class JTask : public opspace::Task {
00056   public:
00057     JTask() : opspace::Task("tut03::JTask"), enable_gravity_compensation_(false) {}
00058     
00059     virtual jspace::Status init(jspace::Model const & model)
00060     {
00062       // The Jacobian is not really required for pure jspace control,
00063       // but will become very important for operational-space control.
00064       
00065       jacobian_ = jspace::Matrix::Identity(model.getNDOF(), model.getNDOF());
00066       
00068       // Initialize our PD parameters.
00069       
00070       kp_ = 100.0;
00071       kd_ = 20.0;
00072       
00074       // Initialize our goal to the current configuration.
00075       
00076       goal_ = model.getState().position_;
00077       
00079       // No initialization problems to report: the default constructor
00080       // of jspace::Status yields an instance that signifies success.
00081       
00082       jspace::Status ok;
00083       return ok;
00084     }
00085     
00086     
00087     virtual jspace::Status update(jspace::Model const & model)
00088     {
00090       // Update the state of our task. Again, this is not critical
00091       // here, but important later when we want to integrate several
00092       // operational space tasks into a hierarchy.
00093       
00094       actual_ = model.getState().position_;
00095       
00097       // Compute PD control torques and store them in command_ for
00098       // later retrieval. If enabled, add the estimated effect of
00099       // gravity in order to make the robot behave as if was
00100       // weightless.
00101       
00102       command_ = kp_ * (goal_ - actual_) - kd_ * model.getState().velocity_;
00103       if (enable_gravity_compensation_) {
00104   jspace::Vector gg;
00105   if ( ! model.getGravity(gg)) {
00106     return jspace::Status(false, "failed to retrieve gravity torque");
00107   }
00108   command_ += gg;
00109       }
00110       
00111       jspace::Status ok;
00112       return ok;
00113     }
00114     
00115     bool enable_gravity_compensation_;
00116     double kp_, kd_;
00117     jspace::Vector goal_;
00118   };
00119   
00120 }
00121 
00122 
00123 static std::string model_filename(TUTROB_XML_PATH_STR);
00124 static boost::shared_ptr<jspace::Model> model;
00125 static boost::shared_ptr<tut03::JTask> jtask;
00126 static size_t mode(0);
00127 
00128 
00129 static bool servo_cb(size_t toggle_count,
00130          double wall_time_ms,
00131          double sim_time_ms,
00132          jspace::State & state,
00133          jspace::Vector & command)
00134 {
00135   mode = toggle_count % 3;
00136   static size_t prevmode(0);
00137   
00138   if (0 == mode) {
00139     
00141     // Re-initialize simulator with a configuration so we can test the
00142     // task from various starting states.
00143     
00144     for (int ii(0); ii < state.position_.rows(); ++ii) {
00145       static double const amplitude(0.5 * M_PI);
00146       double const omega(1.0 + 0.1 * ii);
00147       double const phase(omega * 1e-3 * wall_time_ms);
00148       state.position_[ii] =         amplitude * sin(phase);
00149       state.velocity_[ii] = omega * amplitude * cos(phase);
00150     }
00151     prevmode = 0;
00152     return false;
00153     
00154   }
00155   
00157   // Update the model to reflect the current robot state.
00158   
00159   model->update(state);
00160   
00162   // Run the jtask, but re-initialize it whenever we start a new
00163   // cycle of trials, and switch gravity compensation on/off to
00164   // illustrate its effects.
00165   
00166   if (mode != prevmode) {
00167     if (0 == prevmode) {
00168       jtask->init(*model);
00169     }
00170     if (1 == mode) {
00171       jtask->enable_gravity_compensation_ = true;
00172     }
00173     else {
00174       jtask->enable_gravity_compensation_ = false;
00175     }
00176   }
00177   prevmode = mode;
00178   
00179   jtask->update(*model);
00180   command = jtask->getCommand();
00181   
00183   // Print debug info from time to time.
00184   
00185   static size_t iteration(0);
00186   if (0 == (iteration % 100)) {
00187     switch (mode) {
00188     case 0:
00189       std::cerr << "mode: re-init simul\n";
00190       break;
00191     case 1:
00192       std::cerr << "mode: jtask with gravity compensation\n";
00193       jspace::pretty_print(jtask->goal_, std::cerr, "  goal", "    ");
00194       break;
00195     default:
00196       std::cerr << "mode: jtask without gravity compensation\n";
00197       jspace::pretty_print(jtask->goal_, std::cerr, "  goal", "    ");
00198       break;
00199     }
00200     jspace::pretty_print(state.position_, std::cerr, "  jpos", "    ");
00201     jspace::pretty_print(state.velocity_, std::cerr, "  jvel", "    ");
00202     jspace::pretty_print(command, std::cerr, "  command", "    ");
00203   }
00204   ++iteration;
00205   
00206   return true;
00207 }
00208 
00209 
00210 static void draw_cb(double x0, double y0, double scale)
00211 {
00212   if (0 != mode) {
00213     tutsim::draw_robot(jtask->goal_, 2, 100, 80, 80, x0, y0, scale);
00214     tutsim::draw_delta_jpos(jtask->goal_, 1, 120, 120, 80, x0, y0, scale);
00215   }
00216 }
00217 
00218 
00219 int main(int argc, char ** argv)
00220 {
00221   try {
00222     model.reset(jspace::test::parse_sai_xml_file(model_filename, true));
00223     jtask.reset(new tut03::JTask());
00224   }
00225   catch (std::runtime_error const & ee) {
00226     errx(EXIT_FAILURE, "%s", ee.what());
00227   }
00228   tutsim::set_draw_cb(draw_cb);
00229   return tutsim::run(servo_cb);
00230 }

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