Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00024 #include "sr_ronex_transmissions/mapping/general_io/command_to_pwm.hpp"
00025 #include <ros_ethercat_model/robot_state.hpp>
00026 #include <boost/lexical_cast.hpp>
00027 #include <math.h>
00028
00029 namespace ronex
00030 {
00031 namespace mapping
00032 {
00033 namespace general_io
00034 {
00035 CommandToPWM::CommandToPWM(TiXmlElement* mapping_el, ros_ethercat_model::RobotState* robot)
00036 : RonexMapping(), pin_out_of_bound_(true)
00037 {
00038 const char *ronex_name = mapping_el ? mapping_el->Attribute("ronex") : NULL;
00039 if (!ronex_name)
00040 {
00041 ROS_ERROR("RonexTransmission transmission did not specify the ronex name");
00042 return;
00043 }
00044
00045 init_timer_ = nh_.createTimer(ros::Duration(0.01),
00046 boost::bind(&CommandToPWM::try_init_cb_, this, _1, mapping_el, robot, ronex_name));
00047 }
00048
00049 bool CommandToPWM::try_init_cb_(const ros::TimerEvent&, TiXmlElement* mapping_el, ros_ethercat_model::RobotState* robot, const char* ronex_name)
00050 {
00051
00052 if( robot->getCustomHW(ronex_name) == NULL )
00053 return false;
00054
00055 general_io_ = static_cast<ronex::GeneralIO*>( robot->getCustomHW(ronex_name) );
00056 if(!general_io_)
00057 {
00058 ROS_ERROR_STREAM("The RoNeX: " << ronex_name << " was not found on the system.");
00059 return false;
00060 }
00061
00062
00063 const char *pwm_module = mapping_el ? mapping_el->Attribute("pwm_module") : NULL;
00064 if (!pwm_module)
00065 {
00066 ROS_ERROR("RonexTransmission transmission did not specify the pwm module.");
00067 return false;
00068 }
00069
00070 try
00071 {
00072 pwm_module_ = boost::lexical_cast<size_t>( pwm_module );
00073 }
00074 catch( boost::bad_lexical_cast const& )
00075 {
00076 ROS_ERROR("RonexTransmission: Couldn't parse pwm_module to a size_t.");
00077 return false;
00078 }
00079
00080
00081 const char *pin = mapping_el ? mapping_el->Attribute("pwm_pin") : NULL;
00082 if (!pin)
00083 {
00084 ROS_ERROR("RonexTransmission transmission did not specify the pwm pin.");
00085 return false;
00086 }
00087
00088 try
00089 {
00090 pwm_pin_index_ = boost::lexical_cast<size_t>( pin );
00091 }
00092 catch( boost::bad_lexical_cast const& )
00093 {
00094 ROS_ERROR("RonexTransmission: Couldn't parse pwm_pin to a size_t.");
00095 return false;
00096 }
00097
00098
00099 const char *d_pin = mapping_el ? mapping_el->Attribute("direction_pin") : NULL;
00100 if (!d_pin)
00101 {
00102 ROS_ERROR("RonexTransmission transmission did not specify the direction pin.");
00103 return false;
00104 }
00105
00106 try
00107 {
00108 digital_pin_index_ = boost::lexical_cast<size_t>( d_pin );
00109 }
00110 catch( boost::bad_lexical_cast const& )
00111 {
00112 ROS_ERROR("RonexTransmission: Couldn't parse direction_pin to a size_t.");
00113 return false;
00114 }
00115
00116 ROS_DEBUG_STREAM("RoNeX" << ronex_name << " is initialised now.");
00117
00118 init_timer_.stop();
00119
00120 is_initialized_ = true;
00121 return true;
00122 }
00123
00124 bool CommandToPWM::check_pins_in_bound_()
00125 {
00126
00127 if( first_iteration_ )
00128 {
00129 pin_out_of_bound_ = true;
00130 first_iteration_ = false;
00131 return false;
00132 }
00133
00134
00135 if( pin_out_of_bound_ )
00136 {
00137 if( pwm_module_ >= general_io_->command_.pwm_.size() )
00138 {
00139
00140 ROS_ERROR_STREAM("Specified PWM module index is out of bound: " << pwm_pin_index_ << " / max = " << general_io_->command_.pwm_.size() << ", not propagating the command to the RoNeX.");
00141 pin_out_of_bound_ = true;
00142 return false;
00143 }
00144 if( pwm_pin_index_ > 1 )
00145 {
00146
00147 ROS_ERROR_STREAM("Specified PWM pin is out of bound: " << pwm_pin_index_ << " / max = 1, not propagating the command to the RoNeX.");
00148 pin_out_of_bound_ = true;
00149 return false;
00150 }
00151 if( digital_pin_index_ > general_io_->command_.digital_.size() )
00152 {
00153
00154 ROS_ERROR_STREAM("Specified direction pin is out of bound: " << digital_pin_index_ << " / max = " << general_io_->command_.digital_.size() << " , not propagating the command to the RoNeX.");
00155 pin_out_of_bound_ = true;
00156 return false;
00157 }
00158 }
00159
00160 pin_out_of_bound_ = false;
00161 return true;
00162 }
00163
00164 void CommandToPWM::propagateToRonex(ros_ethercat_model::JointState *js)
00165 {
00166 if( !is_initialized_ )
00167 return;
00168
00169 if( check_pins_in_bound_() )
00170 {
00171 if( pwm_pin_index_ == 0 )
00172 general_io_->command_.pwm_[pwm_module_].on_time_0 = static_cast<unsigned short int>((static_cast<double>(general_io_->command_.pwm_[pwm_module_].period) * js->commanded_effort_ ) / 100);
00173 else
00174 general_io_->command_.pwm_[pwm_module_].on_time_1 = static_cast<unsigned short int>((static_cast<double>(general_io_->command_.pwm_[pwm_module_].period) * js->commanded_effort_ ) / 100);
00175
00176
00177 general_io_->command_.digital_[digital_pin_index_] = (js->commanded_effort_ < 0.0);
00178 }
00179 }
00180 }
00181 }
00182 }
00183
00184
00185
00186
00187