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


sr_mechanism_model
Author(s): Ugo Cupcic
autogenerated on Fri Aug 28 2015 13:09:16