00001 /* 00002 * robot_state.hpp 00003 * 00004 * Created on: 7 Jan 2014 00005 * Author: Manos Nikolaidis 00006 * 00007 * Software License Agreement (BSD License) 00008 * 00009 * Copyright (c) 2014, Shadow Robot Company Ltd. 00010 * All rights reserved. 00011 * 00012 * Redistribution and use in source and binary forms, with or without 00013 * modification, are permitted provided that the following conditions 00014 * are met: 00015 * 00016 * * Redistributions of source code must retain the above copyright 00017 * notice, this list of conditions and the following disclaimer. 00018 * * Redistributions in binary form must reproduce the above 00019 * copyright notice, this list of conditions and the following 00020 * disclaimer in the documentation and/or other materials provided 00021 * with the distribution. 00022 * * Neither the name of the Willow Garage nor the names of its 00023 * contributors may be used to endorse or promote products derived 00024 * from this software without specific prior written permission. 00025 * 00026 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00027 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00028 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00029 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00030 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00031 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00032 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00033 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00034 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00035 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00036 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00037 * POSSIBILITY OF SUCH DAMAGE. 00038 *********************************************************************/ 00039 00040 #ifndef ROS_ETHERCAT_MODEL_ROBOTSTATE_HPP 00041 #define ROS_ETHERCAT_MODEL_ROBOTSTATE_HPP 00042 00043 #include <urdf/model.h> 00044 #include <pluginlib/class_loader.h> 00045 #include <boost/ptr_container/ptr_unordered_map.hpp> 00046 #include <boost/ptr_container/ptr_vector.hpp> 00047 #include <hardware_interface/hardware_interface.h> 00048 #include "ros_ethercat_model/joint.hpp" 00049 #include "ros_ethercat_model/transmission.hpp" 00050 #include "ros_ethercat_model/hardware_interface.hpp" 00051 #include <map> 00052 #include <string> 00053 00054 namespace ros_ethercat_model 00055 { 00056 00063 class RobotState : public hardware_interface::HardwareInterface 00064 { 00065 public: 00066 RobotState(TiXmlElement *root=NULL) 00067 : transmission_loader_("ros_ethercat_model", "ros_ethercat_model::Transmission") 00068 { 00069 if (root) 00070 initXml(root); 00071 } 00072 00073 void initXml(TiXmlElement *root) 00074 { 00075 try 00076 { 00077 if (!robot_model_.initXml(root)) 00078 throw std::runtime_error("Failed to load robot_model_"); 00079 00080 for (std::map<std::string, boost::shared_ptr<urdf::Joint> >::const_iterator it = robot_model_.joints_.begin(); 00081 it != robot_model_.joints_.end(); 00082 ++it) 00083 { 00084 // we are only loading joints that can be controlled 00085 if (it->second->type == urdf::Joint::PRISMATIC || it->second->type == urdf::Joint::REVOLUTE) 00086 joint_states_[it->first].joint_ = it->second; 00087 } 00088 00089 for (TiXmlElement *xit = root->FirstChildElement("transmission"); 00090 xit; 00091 xit = xit->NextSiblingElement("transmission")) 00092 { 00093 std::string type; 00094 00095 if (xit->Attribute("type")) 00096 { 00097 type = xit->Attribute("type"); 00098 } // new transmissions have type as an element instead of attribute 00099 else if (xit->FirstChildElement("type")) 00100 { 00101 type = std::string(xit->FirstChildElement("type")->GetText()); 00102 } 00103 00104 if (!type.empty()) 00105 { 00106 Transmission *t = transmission_loader_.createUnmanagedInstance(type); 00107 if (!t || !t->initXml(xit, this)) 00108 throw std::runtime_error(std::string("Failed to initialize transmission type: ") + type); 00109 transmissions_.push_back(t); 00110 } 00111 } 00112 } 00113 catch (const std::runtime_error &ex) 00114 { 00115 ROS_FATAL_STREAM("ros_ethercat_model failed to parse the URDF xml into a robot model\n" << ex.what()); 00116 } 00117 } 00118 00120 void propagateActuatorPositionToJointPosition() 00121 { 00122 for (size_t i = 0; i < transmissions_.size(); ++i) 00123 transmissions_[i].propagatePosition(); 00124 } 00125 00127 void propagateJointEffortToActuatorEffort() 00128 { 00129 for (size_t i = 0; i < transmissions_.size(); ++i) 00130 transmissions_[i].propagateEffort(); 00131 } 00132 00134 Actuator* getActuator(const std::string &name) 00135 { 00136 for (size_t i = 0; i < transmissions_.size(); ++i) 00137 if (transmissions_[i].actuator_->name_ == name) 00138 return transmissions_[i].actuator_; 00139 return NULL; 00140 } 00141 00143 CustomHW* getCustomHW(const std::string &name) 00144 { 00145 return custom_hws_.count(name) ? &custom_hws_[name] : NULL; 00146 } 00147 00149 JointState* getJointState(const std::string &name) 00150 { 00151 return joint_states_.count(name) ? &joint_states_[name] : NULL; 00152 } 00153 00155 ros::Time getTime() 00156 { 00157 return current_time_; 00158 } 00159 00161 ros::Time current_time_; 00162 00164 boost::ptr_unordered_map<std::string, JointState> joint_states_; 00165 00167 boost::ptr_unordered_map<std::string, CustomHW> custom_hws_; 00168 00170 urdf::Model robot_model_; 00171 00173 boost::ptr_vector<Transmission> transmissions_; 00174 00176 pluginlib::ClassLoader<Transmission> transmission_loader_; 00177 00178 // map between the hardware name and its product code 00179 std::map<std::string, std::string> device_to_name_map_; 00180 }; 00181 } 00182 #endif