simple_transmission_for_muscle.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2008, 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  * Author: Stuart Glaser
00036  *
00037  * modified by Ugo Cupcic
00038  */
00039 
00040 #include <math.h>
00041 #include <pluginlib/class_list_macros.h>
00042 #include "pr2_mechanism_model/robot.h"
00043 #include "sr_mechanism_model/simple_transmission_for_muscle.hpp"
00044 
00045 #include <sr_hardware_interface/sr_actuator.hpp>
00046 
00047 using namespace pr2_hardware_interface;
00048 
00049 PLUGINLIB_DECLARE_CLASS(sr_mechanism_model, SimpleTransmissionForMuscle,
00050                         sr_mechanism_model::SimpleTransmissionForMuscle,
00051                         pr2_mechanism_model::Transmission)
00052 
00053 
00054 namespace sr_mechanism_model
00055 {
00056   bool SimpleTransmissionForMuscle::initXml(TiXmlElement *elt, pr2_mechanism_model::Robot *robot)
00057   {
00058     const char *name = elt->Attribute("name");
00059     name_ = name ? name : "";
00060 
00061     TiXmlElement *jel = elt->FirstChildElement("joint");
00062     const char *joint_name = jel ? jel->Attribute("name") : NULL;
00063     if (!joint_name)
00064     {
00065       ROS_ERROR("SimpleTransmissionForMuscle did not specify joint name");
00066       return false;
00067     }
00068 
00069     const boost::shared_ptr<const urdf::Joint> joint = robot->robot_model_.getJoint(joint_name);
00070     if (!joint)
00071     {
00072       ROS_ERROR("SimpleTransmissionForMuscle could not find joint named \"%s\"", joint_name);
00073       return false;
00074     }
00075     joint_names_.push_back(joint_name);
00076 
00077     TiXmlElement *ael = elt->FirstChildElement("actuator");
00078     const char *actuator_name = ael ? ael->Attribute("name") : NULL;
00079     pr2_hardware_interface::Actuator *a;
00080     if (!actuator_name || (a = robot->getActuator(actuator_name)) == NULL )
00081     {
00082       ROS_ERROR("SimpleTransmissionForMuscle could not find actuator named \"%s\"", actuator_name);
00083       return false;
00084     }
00085     a->command_.enable_ = true;
00086     actuator_names_.push_back(actuator_name);
00087 
00088     mechanical_reduction_ = atof(elt->FirstChildElement("mechanicalReduction")->GetText());
00089 
00090     return true;
00091   }
00092 
00093   bool SimpleTransmissionForMuscle::initXml(TiXmlElement *elt)
00094   {
00095     const char *name = elt->Attribute("name");
00096     name_ = name ? name : "";
00097 
00098     TiXmlElement *jel = elt->FirstChildElement("joint");
00099     const char *joint_name = jel ? jel->Attribute("name") : NULL;
00100     if (!joint_name)
00101     {
00102       ROS_ERROR("SimpleTransmissionForMuscle did not specify joint name");
00103       return false;
00104     }
00105     joint_names_.push_back(joint_name);
00106 
00107     TiXmlElement *ael = elt->FirstChildElement("actuator");
00108     const char *actuator_name = ael ? ael->Attribute("name") : NULL;
00109     if (!actuator_name)
00110     {
00111       ROS_ERROR("SimpleTransmissionForMuscle could not find actuator named \"%s\"", actuator_name);
00112       return false;
00113     }
00114     actuator_names_.push_back(actuator_name);
00115 
00116     mechanical_reduction_ = atof(elt->FirstChildElement("mechanicalReduction")->GetText());
00117 
00118     return true;
00119   }
00120 
00121   void SimpleTransmissionForMuscle::propagatePosition(
00122     std::vector<pr2_hardware_interface::Actuator*>& as, std::vector<pr2_mechanism_model::JointState*>& js)
00123   {
00124     ROS_DEBUG(" propagate position");
00125 
00126     assert(as.size() == 1);
00127     assert(js.size() == 1);
00128     js[0]->position_ = static_cast<sr_actuator::SrMuscleActuator*>(as[0])->state_.position_;
00129     js[0]->velocity_ = static_cast<sr_actuator::SrMuscleActuator*>(as[0])->state_.velocity_;
00130     //We don't want to define a modified version of JointState, as that would imply using a modified version of robot.h, controller manager,
00131     //ethercat_hardware and pr2_etherCAT main loop
00132     // So we will encode the two uint16 that contain the data from the muscle pressure sensors into the double measured_effort_. (We don't
00133     // have any measured effort in the muscle hand anyway).
00134     // Then in the joint controller we will decode that back into uint16.
00135     js[0]->measured_effort_ = (static_cast<double>(static_cast<sr_actuator::SrMuscleActuator*>(as[0])->state_.pressure_[1]) * 0x10000) +
00136                               static_cast<double>(static_cast<sr_actuator::SrMuscleActuator*>(as[0])->state_.pressure_[0]);
00137 
00138     ROS_DEBUG("end propagate position");
00139   }
00140 
00141   void SimpleTransmissionForMuscle::propagatePositionBackwards(
00142     std::vector<pr2_mechanism_model::JointState*>& js, std::vector<pr2_hardware_interface::Actuator*>& as)
00143   {
00144     ROS_DEBUG(" propagate position bw");
00145 
00146     assert(as.size() == 1);
00147     assert(js.size() == 1);
00148     static_cast<sr_actuator::SrMuscleActuator*>(as[0])->state_.position_ = js[0]->position_;
00149     static_cast<sr_actuator::SrMuscleActuator*>(as[0])->state_.velocity_ = js[0]->velocity_;
00150     static_cast<sr_actuator::SrMuscleActuator*>(as[0])->state_.last_measured_effort_ = js[0]->measured_effort_;
00151 
00152     // Update the timing (making sure it's initialized).
00153     if (! simulated_actuator_timestamp_initialized_)
00154     {
00155       // Set the time stamp to zero (it is measured relative to the start time).
00156       static_cast<sr_actuator::SrMuscleActuator*>(as[0])->state_.sample_timestamp_ = ros::Duration(0);
00157 
00158       // Try to set the start time.  Only then do we claim initialized.
00159       if (ros::isStarted())
00160       {
00161         simulated_actuator_start_time_ = ros::Time::now();
00162         simulated_actuator_timestamp_initialized_ = true;
00163       }
00164     }
00165     else
00166     {
00167       // Measure the time stamp relative to the start time.
00168       static_cast<sr_actuator::SrMuscleActuator*>(as[0])->state_.sample_timestamp_ = ros::Time::now() - simulated_actuator_start_time_;
00169     }
00170     // Set the historical (double) timestamp accordingly.
00171     static_cast<sr_actuator::SrMuscleActuator*>(as[0])->state_.timestamp_ = static_cast<sr_actuator::SrMuscleActuator*>(as[0])->state_.sample_timestamp_.toSec();
00172 
00173     // simulate calibration sensors by filling out actuator states
00174     this->joint_calibration_simulator_.simulateJointCalibration(js[0],static_cast<sr_actuator::SrMuscleActuator*>(as[0]));
00175 
00176     ROS_DEBUG(" end propagate position bw");
00177   }
00178 
00179   void SimpleTransmissionForMuscle::propagateEffort(
00180     std::vector<pr2_mechanism_model::JointState*>& js, std::vector<pr2_hardware_interface::Actuator*>& as)
00181   {
00182     ROS_DEBUG(" propagate effort");
00183 
00184     assert(as.size() == 1);
00185     assert(js.size() == 1);
00186     static_cast<sr_actuator::SrMuscleActuator*>(as[0])->command_.enable_ = true;
00187     //We don't want to define a modified version of JointState, as that would imply using a modified version of robot.h, controller manager,
00188     //ethercat_hardware and pr2_etherCAT main loop
00189     // So the controller encodes the two int16 that contain the valve commands into the double effort_. (We don't
00190     // have any real commanded_effort_ in the muscle hand anyway).
00191     // Here we decode them back into two int16.
00192     double valve_0 = fmod(js[0]->commanded_effort_, 0x10);
00193     int8_t valve_0_tmp = static_cast<int8_t>(valve_0 + 0.5);
00194     if (valve_0_tmp >= 8)
00195     {
00196       valve_0_tmp -= 8;
00197       valve_0_tmp *= (-1);
00198     }
00199 
00200     int8_t valve_1_tmp = static_cast<int8_t>(((fmod(js[0]->commanded_effort_, 0x100) - valve_0) / 0x10) + 0.5);
00201     if (valve_1_tmp >= 8)
00202     {
00203       valve_1_tmp -= 8;
00204       valve_1_tmp *= (-1);
00205     }
00206 
00207     static_cast<sr_actuator::SrMuscleActuator*>(as[0])->command_.valve_[0] = valve_0_tmp;
00208     static_cast<sr_actuator::SrMuscleActuator*>(as[0])->command_.valve_[1] = valve_1_tmp;
00209 
00210     ROS_DEBUG("end propagate effort");
00211   }
00212 
00213   void SimpleTransmissionForMuscle::propagateEffortBackwards(
00214     std::vector<pr2_hardware_interface::Actuator*>& as, std::vector<pr2_mechanism_model::JointState*>& js)
00215   {
00216     ROS_DEBUG(" propagate effort bw");
00217 
00218     assert(as.size() == 1);
00219     assert(js.size() == 1);
00220     js[0]->commanded_effort_ = static_cast<sr_actuator::SrMuscleActuator*>(as[0])->command_.effort_;
00221 
00222     ROS_DEBUG("end propagate effort bw");
00223   }
00224 
00225 } //end namespace
00226 
00227 /* For the emacs weenies in the crowd.
00228 Local Variables:
00229    c-basic-offset: 2
00230 End:
00231 */


sr_mechanism_model
Author(s): Ugo Cupcic / ugo@shadowrobot.com , contact@shadowrobot.com
autogenerated on Mon Oct 6 2014 07:47:50