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 }