InverseDynamicsSolverWBC.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2010, Willow Garage, Inc.
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *   * Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *   * Redistributions in binary form must reproduce the above
00014  *     copyright notice, this list of conditions and the following
00015  *     disclaimer in the documentation and/or other materials provided
00016  *     with the distribution.
00017  *   * Neither the name of the Willow Garage nor the names of its
00018  *     contributors may be used to endorse or promote products derived
00019  *     from this software without specific prior written permission.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  *  POSSIBILITY OF SUCH DAMAGE.
00033  *********************************************************************/
00034 
00035 /*
00036   Author: Daniel Hennes
00037  */
00038 
00039 #include "collision_detection/InverseDynamicsSolverWBC.h"
00040 
00041 InverseDynamicsSolverWBC::InverseDynamicsSolverWBC(std::string fname) {
00042   // load sai model
00043   try {
00044     jspace::test::BRParser brp;
00045     jspace::test::BranchingRepresentation * brep(brp.parse(fname));
00046     jspace::tao_tree_info_s * tree(brep->createTreeInfo());
00047     if (0 != model.init(tree, 0, &std::cout)) {
00048       ROS_ERROR("failed to load jspace model from %s!", fname.c_str());
00049       exit(-1);
00050     }
00051   } catch (std::exception const & ee) {
00052     ROS_ERROR("failed to parse sai model from %s! (%s)", fname.c_str(), ee.what());
00053     exit(-1);
00054   }
00055   ndof = model.getNDOF(); // set DOF
00056   last_time = ros::Time::now().toSec();
00057   r = jspace::Vector::Zero(7);
00058   nh_priv = new ros::NodeHandle("~");
00059   js_sub = nh.subscribe("/joint_states", 1, 
00060                         &InverseDynamicsSolverWBC::jsCallback, this);
00061   ros::Rate r(100);
00062   first_call = false;
00063   while(ros::ok()) {
00064     // Call callbacks to get most recent data
00065     ros::spinOnce();
00066     if(first_call)
00067       break;
00068     r.sleep();
00069   }
00070   pub = nh.advertise<collision_detection::Residual>("residual", 2);
00071   last_grav = jspace::Vector::Zero(7);
00072   E0 = -10100.0;
00073   sig_int = 0;
00074 
00075   zero_srv = nh.advertiseService("zero_sigma", &InverseDynamicsSolverWBC::srvZeroSigma, this);
00076   ROS_INFO("[collision_monitor] Service advertised at r_start_detection");
00077   
00078   ROS_DEBUG("wbc inverse dynamics solver initalized (%zu DOF).", ndof);
00079 }
00080 
00081 bool InverseDynamicsSolverWBC::srvZeroSigma(std_srvs::Empty::Request&, std_srvs::Empty::Response&) {
00082   sigma = 0;
00083   return true;
00084 }
00085 
00086 void InverseDynamicsSolverWBC::jsCallback(sensor_msgs::JointState::ConstPtr message) {
00087   j_state = message;
00088   first_call = true;
00089 }
00090 
00091 void InverseDynamicsSolverWBC::updateState(std::vector<double>& pos, 
00092                                            std::vector<double>& vel, 
00093                                            std::vector<double>& acc) {
00094 
00095 
00096   if (ndof != pos.size())
00097     ROS_ERROR("dimensions do not agree, expected %zu DOF, pos vector has length %zu.",
00098               ndof, pos.size());
00099 
00100   if (ndof != vel.size())
00101     ROS_ERROR("dimensions do not agree, expected %zu DOF, vel vector has length %zu.",
00102               ndof, vel.size());
00103 
00104   if (ndof != acc.size())
00105     ROS_ERROR("dimensions do not agree, expected %zu DOF, acc vector has length %zu.",
00106               ndof, acc.size());
00107 
00108   jspace::convert(&pos[0], ndof, state.position_);
00109   jspace::convert(&vel[0], ndof, state.velocity_);
00110   jspace::convert(&acc[0], ndof, q_dotdot);
00111 
00112   model.update(state);
00113         
00114 }
00115 
00116 int JOINTSTATE_INDS_L[] = {29, 30, 28, 32, 31, 33, 34};
00117 
00118 bool InverseDynamicsSolverWBC::getTorques(std::vector<double>& torques) {
00119   ros::spinOnce();
00120   double delta_time = ros::Time::now().toSec() - last_time;
00121   last_time = ros::Time::now().toSec();
00122   if (!model.getMassInertia(M)) {
00123     ROS_ERROR("jspace::Model::getMassInertia() failed!");
00124     return false;
00125   }
00126 
00127   model.getGravity(grav);
00128   jspace::State s = model.getState();
00129   double delta[7] = {0.01, 0.001, 0.01, 0.01, 0.01, 0.01, 0.01};
00130   jspace::Vector K(7);
00131   K << 90.0, 0.0080, 20.0, 22.0, 7.0, 27.0, 20.0;  
00132   jspace::Vector p = M * s.velocity_;
00133   jspace::Matrix M1, M2, DM;
00134   jspace::Vector alpha = jspace::Vector::Zero(7); //grav;
00135   jspace::Vector eff = grav;
00136   collision_detection::Residual res;
00137   for(int i=0;i<7;i++) {
00138     s.position_[i] += delta[i];
00139     if (!model.getMassInertia(M1)) {
00140       ROS_ERROR("jspace::Model::getMassInertia() failed!");
00141       return false;
00142     }
00143     s.position_[i] -= 2*delta[i];
00144     if (!model.getMassInertia(M2)) {
00145       ROS_ERROR("jspace::Model::getMassInertia() failed!");
00146       return false;
00147     }
00148     DM = (M1 - M2) / (2*delta[i]);
00149     alpha(i) = alpha(i) - 0.5 * (s.velocity_.transpose() * (DM * s.velocity_))(0,0);
00150     eff(i) = j_state->effort[JOINTSTATE_INDS_L[i]];
00151 
00152     s.position_[i] += delta[i];
00153   }
00154   r = K.cwise() * (delta_time * (alpha - eff - r) + p);
00155 
00156   double T = 0.5 * (s.velocity_.transpose() * (M * s.velocity_))(0,0);
00157   double g_delta = 0.0001;
00158   jspace::Vector g1, g2, q1, q2;
00159   for(int i=0;i<7;i++) 
00160     s.position_(i) += g_delta;
00161   q1 = s.position_;
00162   model.getGravity(g1);
00163   for(int i=0;i<7;i++) 
00164     s.position_(i) -= 2*g_delta;
00165   q2 = s.position_;
00166   model.getGravity(g2);
00167   for(int i=0;i<7;i++) 
00168     s.position_(i) += g_delta;
00169 
00170   double U = 0.5 * (g1 + g2).dot(q1 - q2);
00171   //U = 0.0;
00172   double E = T + U;
00173   if(E0 < -10000.0) {
00174     E0 += 1;
00175     if(E0 == -10000.0)
00176       E0 = E;
00177   }
00178   double k_sig = 50.0;
00179   //eff = jspace::Vector::Zero(7);
00180   sig_int += delta_time * ((s.velocity_.transpose() * eff)(0,0) + sigma);
00181   sigma = k_sig * (E - sig_int - E0);
00182   res.data.resize(8);
00183   for(int i=0;i<7;i++) 
00184     res.data[i] = r(i);
00185   res.data[7] = sigma;
00186   pub.publish(res);
00187   
00188   //if(std::abs(sigma) > 1.5)
00189   //  std::cout << sigma << std::endl;
00190   //std::cout << E << E0 << std::endl;
00191   //std::cout << grav.transpose() << std::endl;
00192   //std::cout << alpha.transpose() << std::endl;
00193   //std::cout << delta_time << std::endl;
00194   //std::cout << r.transpose() << std::endl;
00195   // std::cout << jspace::pretty_string(state.position_) << "   "
00196   //           << jspace::pretty_string(state.velocity_) << "   "
00197   //           << jspace::pretty_string(q_dotdot) << "   "
00198   //           << jspace::pretty_string(tau) << "\n";
00199   last_grav = grav;
00200 
00201   torques.resize(ndof);
00202   //jspace::convert(tau, torques);
00203 
00204   return true;
00205 }
00206 
00207 size_t InverseDynamicsSolverWBC::getNumDOF() {
00208   return ndof;
00209 }
00210 
00211 // int main(int argc, char ** argv)
00212 // {
00213 //   InverseDynamicsSolverWBC solver = InverseDynamicsSolverWBC("./config/pr2_left_arm_wbc.sai.xml");
00214 //   std::vector<double> pos(7);
00215 //   std::vector<double> vel(7);
00216 //   std::vector<double> acc(7);
00217 //   std::vector<double> torques(7);
00218 
00219 //   acc[1] = 0.1;
00220 
00221 //   solver.updateState(pos, vel, acc);
00222 //   solver.getTorques(torques);
00223 
00224 //   for (std::vector<double>::iterator it = torques.begin(); it != torques.end(); it++)
00225 //     printf("%6.3f ", *it);
00226 //   printf("\n");
00227 // }


kelsey_sandbox
Author(s): kelsey
autogenerated on Wed Nov 27 2013 11:52:04