00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00024 
00025 
00026 #include <ros/ros.h>
00027 #include <string>
00028 
00029 
00030 #include "SVHNode.h"
00031 #include <icl_core/EnumHelper.h>
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 SVHNode::SVHNode(const ros::NodeHandle & nh)
00040 {
00041 
00042   
00043   
00044   
00045 
00046   bool autostart,use_internal_logging;
00047   int reset_timeout;
00048   std::vector<bool> disable_flags(driver_svh::eSVH_DIMENSION, false);
00049   
00050   std::string logging_config_file;
00051 
00052 
00053   try
00054   {
00055     nh.param<bool>("autostart",autostart,false);
00056     nh.param<bool>("use_internal_logging",use_internal_logging,false);
00057     nh.param<std::string>("serial_device",serial_device_name_,"/dev/ttyUSB0");
00058     
00059     nh.getParam("disable_flags",disable_flags);
00060     nh.param<int>("reset_timeout",reset_timeout,5);
00061     nh.getParam("logging_config",logging_config_file);
00062     nh.param<std::string>("name_prefix",name_prefix,"left_hand");
00063     nh.param<int>("connect_retry_count",connect_retry_count,3);
00064   }
00065   catch (ros::InvalidNameException e)
00066   {
00067     ROS_ERROR("Parameter Error!");
00068   }
00069 
00070   
00071   ROS_INFO("Name prefix for this Hand was set to :%s",name_prefix.c_str());
00072 
00073   
00074   if (use_internal_logging)
00075   {
00076     
00077 
00078     
00079     
00080     char * argv[]= {
00081       strdup("Logging"),
00082       strdup("-c"),
00083       strdup(logging_config_file.c_str())
00084     };
00085     int argc = 3; 
00086 
00087     
00088     
00089     
00090     if (icl_core::logging::initialize(argc,argv))
00091       ROS_INFO("Internal logging was activated, output will be written as configured in logging.xml (default to ~/.ros/log)");
00092     else
00093       ROS_WARN("Internal logging was enabled but config file could not be read. Please make sure the provided path to the config file is correct.");
00094   }
00095   else
00096   {
00097     icl_core::logging::initialize();
00098   }
00099 
00100 
00101 
00102 
00103   for (size_t i = 0; i < 9; ++i)
00104   {
00105     if(disable_flags[i])
00106     {
00107       ROS_WARN("svh_controller disabling channel nr %i", i);
00108     }
00109   }
00110 
00111   
00112   fm_.reset(new driver_svh::SVHFingerManager(disable_flags,reset_timeout));
00113 
00114   
00115   std::vector< std::vector<float> > position_settings(driver_svh::eSVH_DIMENSION);
00116   std::vector<bool> postion_settings_given(driver_svh::eSVH_DIMENSION,false);
00117 
00118   std::vector< std::vector<float> > current_settings(driver_svh::eSVH_DIMENSION);
00119   std::vector<bool> current_settings_given(driver_svh::eSVH_DIMENSION,false);
00120 
00121   std::vector< std::vector<float> > home_settings(driver_svh::eSVH_DIMENSION);
00122   std::vector<bool> home_settings_given(driver_svh::eSVH_DIMENSION,false);
00123 
00124 
00125   
00126   
00127   try
00128   {
00129     postion_settings_given[driver_svh::eSVH_THUMB_FLEXION] = nh.getParam("THUMB_FLEXION/position_controller",position_settings[driver_svh::eSVH_THUMB_FLEXION]);
00130     current_settings_given[driver_svh::eSVH_THUMB_FLEXION] = nh.getParam("THUMB_FLEXION/current_controller",current_settings[driver_svh::eSVH_THUMB_FLEXION]);
00131     home_settings_given[driver_svh::eSVH_THUMB_FLEXION]    = nh.getParam("THUMB_FLEXION/home_settings",home_settings[driver_svh::eSVH_THUMB_FLEXION]);
00132 
00133     postion_settings_given[driver_svh::eSVH_THUMB_OPPOSITION] = nh.getParam("THUMB_OPPOSITION/position_controller",position_settings[driver_svh::eSVH_THUMB_OPPOSITION]);
00134     current_settings_given[driver_svh::eSVH_THUMB_OPPOSITION] = nh.getParam("THUMB_OPPOSITION/current_controller",current_settings[driver_svh::eSVH_THUMB_OPPOSITION]);
00135     home_settings_given[driver_svh::eSVH_THUMB_OPPOSITION]    = nh.getParam("THUMB_OPPOSITION/home_settings",home_settings[driver_svh::eSVH_THUMB_OPPOSITION]);
00136 
00137     postion_settings_given[driver_svh::eSVH_INDEX_FINGER_DISTAL] = nh.getParam("INDEX_FINGER_DISTAL/position_controller",position_settings[driver_svh::eSVH_INDEX_FINGER_DISTAL]);
00138     current_settings_given[driver_svh::eSVH_INDEX_FINGER_DISTAL] = nh.getParam("INDEX_FINGER_DISTAL/current_controller",current_settings[driver_svh::eSVH_INDEX_FINGER_DISTAL]);
00139     home_settings_given[driver_svh::eSVH_INDEX_FINGER_DISTAL]    = nh.getParam("INDEX_FINGER_DISTAL/home_settings",home_settings[driver_svh::eSVH_INDEX_FINGER_DISTAL]);
00140 
00141     postion_settings_given[driver_svh::eSVH_INDEX_FINGER_PROXIMAL] = nh.getParam("INDEX_FINGER_PROXIMAL/position_controller",position_settings[driver_svh::eSVH_INDEX_FINGER_PROXIMAL]);
00142     current_settings_given[driver_svh::eSVH_INDEX_FINGER_PROXIMAL] = nh.getParam("INDEX_FINGER_PROXIMAL/current_controller",current_settings[driver_svh::eSVH_INDEX_FINGER_PROXIMAL]);
00143     home_settings_given[driver_svh::eSVH_INDEX_FINGER_PROXIMAL]    = nh.getParam("INDEX_FINGER_PROXIMAL/home_settings",home_settings[driver_svh::eSVH_INDEX_FINGER_PROXIMAL]);
00144 
00145     postion_settings_given[driver_svh::eSVH_MIDDLE_FINGER_DISTAL] = nh.getParam("MIDDLE_FINGER_DISTAL/position_controller",position_settings[driver_svh::eSVH_MIDDLE_FINGER_DISTAL]);
00146     current_settings_given[driver_svh::eSVH_MIDDLE_FINGER_DISTAL] = nh.getParam("MIDDLE_FINGER_DISTAL/current_controller",current_settings[driver_svh::eSVH_MIDDLE_FINGER_DISTAL]);
00147     home_settings_given[driver_svh::eSVH_MIDDLE_FINGER_DISTAL]    = nh.getParam("MIDDLE_FINGER_DISTAL/home_settings",home_settings[driver_svh::eSVH_MIDDLE_FINGER_DISTAL]);
00148 
00149     postion_settings_given[driver_svh::eSVH_MIDDLE_FINGER_PROXIMAL] = nh.getParam("MIDDLE_FINGER_PROXIMAL/position_controller",position_settings[driver_svh::eSVH_MIDDLE_FINGER_PROXIMAL]);
00150     current_settings_given[driver_svh::eSVH_MIDDLE_FINGER_PROXIMAL] = nh.getParam("MIDDLE_FINGER_PROXIMAL/current_controller",current_settings[driver_svh::eSVH_MIDDLE_FINGER_PROXIMAL]);
00151     home_settings_given[driver_svh::eSVH_MIDDLE_FINGER_PROXIMAL]    = nh.getParam("MIDDLE_FINGER_PROXIMAL/home_settings",home_settings[driver_svh::eSVH_MIDDLE_FINGER_PROXIMAL]);
00152 
00153     postion_settings_given[driver_svh::eSVH_RING_FINGER] = nh.getParam("RING_FINGER/position_controller",position_settings[driver_svh::eSVH_RING_FINGER]);
00154     current_settings_given[driver_svh::eSVH_RING_FINGER] = nh.getParam("RING_FINGER/current_controller",current_settings[driver_svh::eSVH_RING_FINGER]);
00155     home_settings_given[driver_svh::eSVH_RING_FINGER]    = nh.getParam("RING_FINGER/home_settings",home_settings[driver_svh::eSVH_RING_FINGER]);
00156 
00157     postion_settings_given[driver_svh::eSVH_PINKY] = nh.getParam("PINKY/position_controller",position_settings[driver_svh::eSVH_PINKY]);
00158     current_settings_given[driver_svh::eSVH_PINKY] = nh.getParam("PINKY/current_controller",current_settings[driver_svh::eSVH_PINKY]);
00159     home_settings_given[driver_svh::eSVH_PINKY]    = nh.getParam("PINKY/home_settings",home_settings[driver_svh::eSVH_PINKY]);
00160 
00161     postion_settings_given[driver_svh::eSVH_FINGER_SPREAD] = nh.getParam("FINGER_SPREAD/position_controller",position_settings[driver_svh::eSVH_FINGER_SPREAD]);
00162     current_settings_given[driver_svh::eSVH_FINGER_SPREAD] = nh.getParam("FINGER_SPREAD/current_controller",current_settings[driver_svh::eSVH_FINGER_SPREAD]);
00163     home_settings_given[driver_svh::eSVH_FINGER_SPREAD]    = nh.getParam("FINGER_SPREAD/home_settings",home_settings[driver_svh::eSVH_FINGER_SPREAD]);
00164 
00165     for (size_t channel = 0; channel < driver_svh::eSVH_DIMENSION; ++channel)
00166     {
00167       
00168       if (current_settings_given[channel])
00169       {
00170         fm_->setCurrentSettings(static_cast<driver_svh::SVHChannel>(channel),driver_svh::SVHCurrentSettings(current_settings[channel]));
00171       }
00172       if (postion_settings_given[channel])
00173       {
00174         fm_->setPositionSettings(static_cast<driver_svh::SVHChannel>(channel),driver_svh::SVHPositionSettings(position_settings[channel]));
00175       }
00176       if (home_settings_given[channel])
00177       {
00178         fm_->setHomeSettings(static_cast<driver_svh::SVHChannel>(channel),driver_svh::SVHHomeSettings(home_settings[channel]));
00179       }
00180     }
00181   }
00182   catch (ros::InvalidNameException e)
00183   {
00184     ROS_ERROR("Parameter Error! While reading the controller settings. Will use default settings");
00185   }
00186 
00187   
00188   channel_pos_.name.resize(driver_svh::eSVH_DIMENSION);
00189   channel_pos_.position.resize(driver_svh::eSVH_DIMENSION, 0.0);
00190   channel_pos_.effort.resize(driver_svh::eSVH_DIMENSION, 0.0);
00191   for (size_t channel = 0; channel < driver_svh::eSVH_DIMENSION; ++channel)
00192   {
00193     channel_pos_.name[channel] = name_prefix + "_" + driver_svh::SVHController::m_channel_description[channel];
00194   }
00195 
00196   
00197   channel_currents.data.clear();
00198   channel_currents.data.resize(driver_svh::eSVH_DIMENSION, 0.0);
00199   channel_currents.layout.data_offset = 0;
00200   std_msgs::MultiArrayDimension dim ;
00201   dim.label ="channel currents";
00202   dim.size = 9;
00203   dim.stride = 0;
00204   channel_currents.layout.dim.push_back(dim);
00205 
00206   
00207   if (autostart && fm_->connect(serial_device_name_,connect_retry_count))
00208   {
00209     fm_->resetChannel(driver_svh::eSVH_ALL);
00210     ROS_INFO("Driver was autostarted! Input can now be sent. Have a safe and productive day!");
00211   }
00212   else
00213   {
00214     ROS_INFO("SVH Driver Ready, you will need to connect and reset the fingers before you can use the hand.");
00215   }
00216 
00217 }
00218 
00219 SVHNode::~SVHNode()
00220 {
00221   
00222   fm_->disconnect();
00223 }
00224 
00225 
00226 void SVHNode::dynamic_reconfigure_callback(svh_controller::svhConfig &config, uint32_t level)
00227 {
00228   serial_device_name_ = config.serial_device;
00229 
00230   fm_->setResetSpeed(config.finger_reset_speed);
00231   fm_->setResetTimeout(config.reset_timeout);
00232 }
00233 
00234 
00235 void SVHNode::connectCallback(const std_msgs::Empty&)
00236 {
00237   if (fm_->isConnected())
00238   {
00239     fm_->disconnect();
00240   }
00241 
00242   if (!fm_->connect(serial_device_name_,connect_retry_count))
00243   {
00244     ROS_ERROR("Could not connect to SCHUNK five finger hand with serial device %s, and retry count %i", serial_device_name_.c_str(),connect_retry_count);
00245   }
00246 }
00247 
00248 
00249 void SVHNode::resetChannelCallback(const std_msgs::Int8ConstPtr& channel)
00250 {
00251   
00252   driver_svh::SVHChannel svh_channel = static_cast<driver_svh::SVHChannel>(channel->data);
00253 
00254   if (fm_->resetChannel(svh_channel))
00255   {
00256     ROS_INFO("Channel %i successfully homed!", svh_channel);
00257   }
00258   else
00259   {
00260     ROS_ERROR("Could not reset channel %i !", svh_channel);
00261   }
00262 }
00263 
00264 
00265 void SVHNode::enableChannelCallback(const std_msgs::Int8ConstPtr& channel)
00266 {
00267   fm_->enableChannel(static_cast<driver_svh::SVHChannel>(channel->data));
00268 }
00269 
00270 
00271 void SVHNode::jointStateCallback(const sensor_msgs::JointStateConstPtr& input )
00272 {
00273   
00274   std::vector<double> target_positions(driver_svh::eSVH_DIMENSION, 0.0);
00275   
00276   std::vector<bool> pos_read(driver_svh::eSVH_DIMENSION, false);
00277   
00278   uint8_t pos_read_counter = 0;
00279 
00280   size_t index = 0;
00281   std::vector<std::string>::const_iterator joint_name;
00282   for (joint_name = input->name.begin(); joint_name != input->name.end(); ++joint_name,++index)
00283   {
00284     int32_t channel = 0;
00285 
00286     
00287     bool valid_input = false;
00288     for (channel=0;!valid_input && (channel < driver_svh::eSVH_DIMENSION) && (driver_svh::SVHController::m_channel_description[channel] != NULL);++channel)
00289     {
00290         valid_input = (joint_name->compare(name_prefix + "_" + driver_svh::SVHController::m_channel_description[channel]) == 0);
00291     }
00292 
00293     
00294     --channel;
00295 
00296 
00297     if (valid_input)
00298     {
00299       if (input->position.size() > index)
00300       {
00301         target_positions[channel] = input->position[index];
00302         pos_read[channel] = true;
00303         pos_read_counter++;
00304       }
00305       else
00306       {
00307         ROS_WARN("Vector of input joint state is too small! Cannot acces elemnt nr %i", index);
00308       }
00309     }
00310     else
00311     {
00312       
00313     }
00314   }
00315 
00316   
00317   if (pos_read_counter == driver_svh::eSVH_DIMENSION)
00318   {
00319     if (!fm_->setAllTargetPositions(target_positions))
00320     {
00321       ROS_WARN_ONCE("Set target position command rejected!");
00322     }
00323   }
00324   
00325   else
00326   {
00327     for (size_t i = 0; i < driver_svh::eSVH_DIMENSION; ++i)
00328     {
00329       if (pos_read[i])
00330       {
00331         fm_->setTargetPosition(static_cast<driver_svh::SVHChannel>(i), target_positions[i], 0.0);
00332       }
00333     }
00334   }
00335 }
00336 
00337 
00338 sensor_msgs::JointState SVHNode::getChannelFeedback()
00339 {
00340   if (fm_->isConnected())
00341   {
00342     
00343     for (size_t channel = 0; channel < driver_svh::eSVH_DIMENSION; ++channel)
00344     {
00345       double cur_pos = 0.0;
00346       double cur_cur = 0.0;
00347       if (fm_->isHomed(static_cast<driver_svh::SVHChannel>(channel)))
00348       {
00349         fm_->getPosition(static_cast<driver_svh::SVHChannel>(channel), cur_pos);
00350         
00351         fm_->getCurrent(static_cast<driver_svh::SVHChannel>(channel),cur_cur);
00352       }
00353       channel_pos_.position[channel] = cur_pos;
00354       channel_pos_.effort[channel] = cur_cur * driver_svh::SVHController::channel_effort_constants[channel];
00355     }
00356   }
00357 
00358   channel_pos_.header.stamp = ros::Time::now();
00359   return  channel_pos_;
00360 }
00361 
00362 std_msgs::Float64MultiArray SVHNode::getChannelCurrents()
00363 {
00364   if (fm_->isConnected())
00365   {
00366     
00367     for (size_t channel = 0; channel < driver_svh::eSVH_DIMENSION; ++channel)
00368     {
00369       double cur_cur = 0.0;
00370       if (fm_->isHomed(static_cast<driver_svh::SVHChannel>(channel)))
00371       {
00372         fm_->getCurrent(static_cast<driver_svh::SVHChannel>(channel),cur_cur);
00373       }
00374       channel_currents.data[channel] = cur_cur;
00375     }
00376   }
00377 
00378   return  channel_currents;
00379 
00380 }
00381 
00382 
00383 
00384 
00385 
00386 
00387 
00388 int main(int argc, char **argv)
00389 {
00390   
00391   
00392   
00393 
00394   
00395   ros::init(argc, argv, "svh_controller");
00396   
00397   ros::NodeHandle nh("~");
00398 
00399 
00400   
00401   ros::Rate rate(50);
00402 
00403   
00404   
00405   
00406   
00407   SVHNode svh_node(nh);
00408 
00409   
00410   
00411   
00412 
00413   dynamic_reconfigure::Server<svh_controller::svhConfig> server;
00414   dynamic_reconfigure::Server<svh_controller::svhConfig>::CallbackType f;
00415 
00416   f = boost::bind(&SVHNode::dynamic_reconfigure_callback,&svh_node, _1, _2);
00417   server.setCallback(f);
00418 
00419   
00420   
00421   
00422 
00423   
00424   ros::Subscriber connect_sub = nh.subscribe("connect", 1, &SVHNode::connectCallback,&svh_node);
00425   
00426   ros::Subscriber reset_sub = nh.subscribe("reset_channel", 1, &SVHNode::resetChannelCallback,&svh_node);
00427   
00428   ros::Subscriber enable_sub = nh.subscribe("enable_channel", 1, &SVHNode::enableChannelCallback, &svh_node);
00429   
00430   ros::Subscriber channel_target_sub = nh.subscribe<sensor_msgs::JointState>("channel_targets", 1, &SVHNode::jointStateCallback,&svh_node,ros::TransportHints().tcpNoDelay() );
00431   
00432   ros::Publisher channel_pos_pub = nh.advertise<sensor_msgs::JointState>("channel_feedback", 1);
00433   
00434   ros::Publisher channel_current_pub = nh.advertise<std_msgs::Float64MultiArray>("channel_currents", 1);
00435 
00436   
00437   
00438   
00439 
00440   
00441   while (nh.ok())
00442   {
00443     
00444     channel_pos_pub.publish(svh_node.getChannelFeedback());
00445     channel_current_pub.publish(svh_node.getChannelCurrents());
00446 
00447     ros::spinOnce();
00448     rate.sleep();
00449   }
00450 
00451 
00452   return 0;
00453 }