dsa_only.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright 2017 Fraunhofer Institute for Manufacturing Engineering and Automation (IPA)
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *   http://www.apache.org/licenses/LICENSE-2.0
00009 
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 
00018 // ##################
00019 // #### includes ####
00020 // standard includes
00021 #include <unistd.h>
00022 #include <string>
00023 #include <vector>
00024 
00025 // ROS includes
00026 #include <ros/ros.h>
00027 
00028 // ROS message includes
00029 #include <schunk_sdh/TactileSensor.h>
00030 #include <schunk_sdh/TactileMatrix.h>
00031 
00032 // ROS diagnostic msgs
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   // declaration of topics to publish
00072   ros::Publisher topicPub_TactileSensor_;
00073   ros::Publisher topicPub_Diagnostics_;
00074 
00075   // topic subscribers
00076 
00077   // service servers
00078 
00079   // actionlib server
00080 
00081   // service clients
00082   // --
00083 
00084   // other variables
00085   SDH::cDSA *dsa_;
00086   SDH::UInt32 last_data_publish_;  // time stamp of last data publishing
00087 
00088   std::string dsadevicestring_;
00089   int dsadevicenum_;
00090   int maxerror_;  // maximum error count allowed
00091 
00092   bool isDSAInitialized_;
00093   int error_counter_;
00094   bool polling_;  // try to publish on each response
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     // implementation of topics to publish
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;  // t1
00185       dsa_reorder_[1] = 3;  // t2
00186       dsa_reorder_[2] = 4;  // f11
00187       dsa_reorder_[3] = 5;  // f12
00188       dsa_reorder_[4] = 0;  // f21
00189       dsa_reorder_[5] = 1;  // f22
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       // Init tactile data
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           // ROS_INFO("Set sensitivity to 1.0");
00224           // for(int i=0; i<6; i++)
00225           //  dsa_->SetMatrixSensitivity(i, 1.0);
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           // new data
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;  // no new frame available
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     // publish matrix
00335     topicPub_TactileSensor_.publish(msg);
00336   }
00337   void publishDiagnostics()
00338   {
00339     // publishing diagnotic messages
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     // set data to diagnostics
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     // publish diagnostic message
00364     topicPub_Diagnostics_.publish(diagnostics);
00365     if (debug_)
00366       ROS_DEBUG_STREAM("publishDiagnostics " << diagnostics);
00367   }
00368 };
00369 // DsaNode
00370 
00376 int main(int argc, char** argv)
00377 {
00378   // initialize ROS, spezify name of node
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 


schunk_sdh
Author(s): Mathias Luedtke , Florian Weisshardt
autogenerated on Sat Jun 8 2019 20:25:21