00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <unistd.h>
00022 #include <string>
00023 #include <vector>
00024
00025
00026 #include <ros/ros.h>
00027
00028
00029 #include <schunk_sdh/TactileSensor.h>
00030 #include <schunk_sdh/TactileMatrix.h>
00031
00032
00033 #include <diagnostic_msgs/DiagnosticArray.h>
00034 #include <diagnostic_msgs/KeyValue.h>
00035
00036 #include <schunk_sdh/dsa.h>
00037
00038 #include <boost/lexical_cast.hpp>
00039 #include <boost/bind.hpp>
00040
00041 template<typename T>
00042 bool read_vector(ros::NodeHandle &n_, const std::string &key, std::vector<T> & res)
00043 {
00044 XmlRpc::XmlRpcValue namesXmlRpc;
00045 if (!n_.hasParam(key))
00046 {
00047 return false;
00048 }
00049
00050 n_.getParam(key, namesXmlRpc);
00052 res.resize(namesXmlRpc.size());
00053 for (int i = 0; i < namesXmlRpc.size(); i++)
00054 {
00055 res[i] = (T)namesXmlRpc[i];
00056 }
00057 return true;
00058 }
00059
00065 class DsaNode
00066 {
00067 public:
00069 ros::NodeHandle nh_;
00070 private:
00071
00072 ros::Publisher topicPub_TactileSensor_;
00073 ros::Publisher topicPub_Diagnostics_;
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 SDH::cDSA *dsa_;
00086 SDH::UInt32 last_data_publish_;
00087
00088 std::string dsadevicestring_;
00089 int dsadevicenum_;
00090 int maxerror_;
00091
00092 bool isDSAInitialized_;
00093 int error_counter_;
00094 bool polling_;
00095 bool auto_publish_;
00096 bool use_rle_;
00097 bool debug_;
00098 double frequency_;
00099
00100 ros::Timer timer_dsa, timer_publish, timer_diag;
00101
00102 std::vector<int> dsa_reorder_;
00103 public:
00109 DsaNode() :
00110 nh_("~"), dsa_(0), last_data_publish_(0), isDSAInitialized_(false), error_counter_(0)
00111 {
00112 topicPub_Diagnostics_ = nh_.advertise < diagnostic_msgs::DiagnosticArray > ("/diagnostics", 1);
00113 topicPub_TactileSensor_ = nh_.advertise < schunk_sdh::TactileSensor > ("tactile_data", 1);
00114 }
00115
00119 ~DsaNode()
00120 {
00121 if (isDSAInitialized_)
00122 dsa_->Close();
00123 if (dsa_)
00124 delete dsa_;
00125 }
00126
00127 void shutdown()
00128 {
00129 timer_dsa.stop();
00130 timer_publish.stop();
00131 timer_diag.stop();
00132 nh_.shutdown();
00133 }
00134
00138 bool init()
00139 {
00140
00141
00142 nh_.param("dsadevicestring", dsadevicestring_, std::string(""));
00143 if (dsadevicestring_.empty())
00144 return false;
00145
00146 nh_.param("dsadevicenum", dsadevicenum_, 0);
00147 nh_.param("maxerror", maxerror_, 8);
00148
00149 double publish_frequency, diag_frequency;
00150
00151 nh_.param("debug", debug_, false);
00152 nh_.param("polling", polling_, false);
00153 nh_.param("use_rle", use_rle_, true);
00154 nh_.param("diag_frequency", diag_frequency, 5.0);
00155 frequency_ = 30.0;
00156 if (polling_)
00157 nh_.param("poll_frequency", frequency_, 5.0);
00158 nh_.param("publish_frequency", publish_frequency, 0.0);
00159
00160 auto_publish_ = true;
00161
00162 if (polling_)
00163 {
00164 timer_dsa = nh_.createTimer(ros::Rate(frequency_).expectedCycleTime(), boost::bind(&DsaNode::pollDsa, this));
00165 }
00166 else
00167 {
00168 timer_dsa = nh_.createTimer(ros::Rate(frequency_ * 2.0).expectedCycleTime(),
00169 boost::bind(&DsaNode::readDsaFrame, this));
00170 if (publish_frequency > 0.0)
00171 {
00172 auto_publish_ = false;
00173 timer_publish = nh_.createTimer(ros::Rate(publish_frequency).expectedCycleTime(),
00174 boost::bind(&DsaNode::publishTactileData, this));
00175 }
00176 }
00177
00178 timer_diag = nh_.createTimer(ros::Rate(diag_frequency).expectedCycleTime(),
00179 boost::bind(&DsaNode::publishDiagnostics, this));
00180
00181 if (!read_vector(nh_, "dsa_reorder", dsa_reorder_))
00182 {
00183 dsa_reorder_.resize(6);
00184 dsa_reorder_[0] = 2;
00185 dsa_reorder_[1] = 3;
00186 dsa_reorder_[2] = 4;
00187 dsa_reorder_[3] = 5;
00188 dsa_reorder_[4] = 0;
00189 dsa_reorder_[5] = 1;
00190 }
00191
00192 return true;
00193 }
00194 bool stop()
00195 {
00196 if (dsa_)
00197 {
00198 if (isDSAInitialized_)
00199 dsa_->Close();
00200 delete dsa_;
00201 }
00202 dsa_ = 0;
00203 isDSAInitialized_ = false;
00204 return true;
00205 }
00206
00207 bool start()
00208 {
00209 if (isDSAInitialized_ == false)
00210 {
00211
00212 if (!dsadevicestring_.empty())
00213 {
00214 try
00215 {
00216 dsa_ = new SDH::cDSA(0, dsadevicenum_, dsadevicestring_.c_str());
00217 if (!polling_)
00218 dsa_->SetFramerate(frequency_, use_rle_);
00219 else
00220 dsa_->SetFramerate(0, use_rle_);
00221
00222 ROS_INFO("Initialized RS232 for DSA Tactile Sensors on device %s", dsadevicestring_.c_str());
00223
00224
00225
00226 error_counter_ = 0;
00227 isDSAInitialized_ = true;
00228 }
00229 catch (SDH::cSDHLibraryException* e)
00230 {
00231 isDSAInitialized_ = false;
00232 ROS_ERROR("An exception was caught: %s", e->what());
00233 delete e;
00234
00235 shutdown();
00236 return false;
00237 }
00238 }
00239 }
00240
00241 return true;
00242 }
00243
00244 void readDsaFrame()
00245 {
00246 if (debug_)
00247 ROS_DEBUG("readDsaFrame");
00248
00249 if (isDSAInitialized_)
00250 {
00251 try
00252 {
00253 SDH::UInt32 last_time;
00254 last_time = dsa_->GetFrame().timestamp;
00255 dsa_->UpdateFrame();
00256 if (last_time != dsa_->GetFrame().timestamp)
00257 {
00258
00259 if (error_counter_ > 0)
00260 --error_counter_;
00261 if (auto_publish_)
00262 publishTactileData();
00263 }
00264 }
00265 catch (SDH::cSDHLibraryException* e)
00266 {
00267 ROS_ERROR("An exception was caught: %s", e->what());
00268 delete e;
00269 ++error_counter_;
00270 }
00271 if (error_counter_ > maxerror_)
00272 stop();
00273 }
00274 else
00275 {
00276 start();
00277 }
00278 }
00279
00280 void pollDsa()
00281 {
00282 if (debug_)
00283 ROS_DEBUG("pollDsa");
00284
00285 if (isDSAInitialized_)
00286 {
00287 try
00288 {
00289 dsa_->SetFramerate(0, use_rle_);
00290 readDsaFrame();
00291 }
00292 catch (SDH::cSDHLibraryException* e)
00293 {
00294 ROS_ERROR("An exception was caught: %s", e->what());
00295 delete e;
00296 ++error_counter_;
00297 }
00298 if (error_counter_ > maxerror_)
00299 stop();
00300 }
00301 else
00302 {
00303 start();
00304 }
00305 }
00306
00307 void publishTactileData()
00308 {
00309 if (debug_)
00310 ROS_DEBUG("publishTactileData %ul %ul", dsa_->GetFrame().timestamp, last_data_publish_);
00311 if (!isDSAInitialized_ || dsa_->GetFrame().timestamp == last_data_publish_)
00312 return;
00313 last_data_publish_ = dsa_->GetFrame().timestamp;
00314
00315 schunk_sdh::TactileSensor msg;
00316 msg.header.stamp = ros::Time::now();
00317 int m, x, y;
00318 msg.tactile_matrix.resize(dsa_->GetSensorInfo().nb_matrices);
00319 ROS_ASSERT(dsa_->GetSensorInfo().nb_matrices == dsa_reorder_.size());
00320 for (unsigned int i = 0; i < dsa_reorder_.size(); i++)
00321 {
00322 m = dsa_reorder_[i];
00323 schunk_sdh::TactileMatrix &tm = msg.tactile_matrix[i];
00324 tm.matrix_id = i;
00325 tm.cells_x = dsa_->GetMatrixInfo(m).cells_x;
00326 tm.cells_y = dsa_->GetMatrixInfo(m).cells_y;
00327 tm.tactile_array.resize(tm.cells_x * tm.cells_y);
00328 for (y = 0; y < tm.cells_y; y++)
00329 {
00330 for (x = 0; x < tm.cells_x; x++)
00331 tm.tactile_array[tm.cells_x * y + x] = dsa_->GetTexel(m, x, y);
00332 }
00333 }
00334
00335 topicPub_TactileSensor_.publish(msg);
00336 }
00337 void publishDiagnostics()
00338 {
00339
00340 diagnostic_msgs::DiagnosticArray diagnostics;
00341 diagnostics.status.resize(1);
00342 diagnostics.status[0].name = nh_.getNamespace();
00343 diagnostics.status[0].values.resize(1);
00344 diagnostics.status[0].values[0].key = "error_count";
00345 diagnostics.status[0].values[0].value = boost::lexical_cast < std::string > (error_counter_);
00346
00347
00348 if (isDSAInitialized_)
00349 {
00350 diagnostics.status[0].level = 0;
00351 diagnostics.status[0].message = "DSA tactile sensing initialized and running";
00352 }
00353 else if (error_counter_ == 0)
00354 {
00355 diagnostics.status[0].level = 1;
00356 diagnostics.status[0].message = "DSA not initialized";
00357 }
00358 else
00359 {
00360 diagnostics.status[0].level = 2;
00361 diagnostics.status[0].message = "DSA exceeded eror count";
00362 }
00363
00364 topicPub_Diagnostics_.publish(diagnostics);
00365 if (debug_)
00366 ROS_DEBUG_STREAM("publishDiagnostics " << diagnostics);
00367 }
00368 };
00369
00370
00376 int main(int argc, char** argv)
00377 {
00378
00379 ros::init(argc, argv, "schunk_dsa");
00380
00381 DsaNode dsa_node;
00382
00383 if (!dsa_node.init())
00384 return 0;
00385
00386 dsa_node.start();
00387
00388 ROS_INFO("...dsa node running...");
00389
00390 ros::spin();
00391
00392 ROS_INFO("...dsa node shut down...");
00393 return 0;
00394 }
00395