tutorials/tut02_jtask.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 
00044 #include "tutsim.hpp"
00045 #include <opspace/Task.hpp>
00046 #include <jspace/test/sai_util.hpp>
00047 #include <boost/shared_ptr.hpp>
00048 #include <err.h>
00049 
00050 
00051 namespace tut02 {
00052   
00053   class JTask : public opspace::Task {
00054   public:
00055     JTask() : opspace::Task("tut02::JTask") {}
00056     
00057     virtual jspace::Status init(jspace::Model const & model)
00058     {
00060       // The Jacobian is not really required for pure jspace control,
00061       // but will become very important for operational-space control.
00062       
00063       jacobian_ = jspace::Matrix::Identity(model.getNDOF(), model.getNDOF());
00064       
00066       // Initialize our PD parameters.
00067       
00068       kp_ = 400.0;
00069       kd_ = 40.0;
00070       
00072       // Initialize our goal to a configuration that is the current
00073       // one +/- 45 degrees on each joint.
00074       
00075       goal_ = model.getState().position_;
00076       for (int ii(0); ii < goal_.rows(); ++ii) {
00077   if (0 == (ii % 2)) {
00078     goal_[ii] += M_PI / 4.0;
00079   }
00080   else {
00081     goal_[ii] -= M_PI / 4.0;
00082   }
00083       }
00084       
00086       // No initialization problems to report: the default constructor
00087       // of jspace::Status yields an instance that signifies success.
00088       
00089       jspace::Status ok;
00090       return ok;
00091     }
00092     
00093     
00094     virtual jspace::Status update(jspace::Model const & model)
00095     {
00097       // Update the state of our task. Again, this is not critical
00098       // here, but important later when we want to integrate several
00099       // operational space tasks into a hierarchy.
00100       
00101       actual_ = model.getState().position_;
00102       
00104       // Compute PD control torques and store them in command_ for
00105       // later retrieval.
00106 
00107       command_ = kp_ * (goal_ - actual_) - kd_ * model.getState().velocity_;
00108       
00109       jspace::Status ok;
00110       return ok;
00111     }
00112     
00113     double kp_, kd_;
00114     jspace::Vector goal_;
00115   };
00116   
00117 }
00118 
00119 
00120 static std::string model_filename(TUTROB_XML_PATH_STR);
00121 static boost::shared_ptr<jspace::Model> model;
00122 static boost::shared_ptr<tut02::JTask> jtask;
00123 static size_t mode(0);
00124 
00125 
00126 static bool servo_cb(size_t toggle_count,
00127          double wall_time_ms,
00128          double sim_time_ms,
00129          jspace::State & state,
00130          jspace::Vector & command)
00131 {
00132   static size_t prev_toggle(1234);
00133   mode = toggle_count % 2;
00134   
00135   if (0 == mode) {
00136     
00138     // Send torques that make the robot sway around.
00139     
00140     command = -3.0 * state.velocity_;
00141     command[0] = 40.0 * sin(1e-3 * sim_time_ms);
00142     
00143   }
00144   else {
00145     
00146     model->update(state);
00147     
00149     // Use our JTask to compute the command, re-initializing it
00150     // whenever we switch here from the "swaying" mode, and setting
00151     // the goal to zero every other time.
00152     
00153     if (prev_toggle != toggle_count) {
00154       jtask->init(*model);
00155     }
00156     jtask->update(*model);
00157     command = jtask->getCommand();
00158     
00159   }
00160   
00161   prev_toggle = toggle_count;
00162   
00164   // Print debug info from time to time.
00165   
00166   static size_t iteration(0);
00167   if (0 == (iteration % 100)) {
00168     std::cerr << "toggle: " << toggle_count << "  sim_time_ms: " << sim_time_ms << "\n";
00169     if (0 != (toggle_count % 2)) {
00170       jspace::pretty_print(jtask->goal_, std::cerr, "goal", "  ");
00171     }
00172     jspace::pretty_print(state.position_, std::cerr, "jpos", "  ");
00173     jspace::pretty_print(state.velocity_, std::cerr, "jvel", "  ");
00174     jspace::pretty_print(command, std::cerr, "command", "  ");
00175   }
00176   ++iteration;
00177   
00178   return true;
00179 }
00180 
00181 
00182 static void draw_cb(double x0, double y0, double scale)
00183 {
00184   if (0 != mode) {
00185     tutsim::draw_robot(jtask->goal_, 2, 100, 80, 80, x0, y0, scale);
00186     tutsim::draw_delta_jpos(jtask->goal_, 1, 120, 120, 80, x0, y0, scale);
00187   }
00188 }
00189 
00190 
00191 int main(int argc, char ** argv)
00192 {
00193   try {
00194     model.reset(jspace::test::parse_sai_xml_file(model_filename, true));
00195     jtask.reset(new tut02::JTask());
00196   }
00197   catch (std::runtime_error const & ee) {
00198     errx(EXIT_FAILURE, "%s", ee.what());
00199   }
00200   tutsim::set_draw_cb(draw_cb);
00201   return tutsim::run(servo_cb);
00202 }

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