cod_decod_manager.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2013, Shadow Robot Company, All rights reserved.
00003  * 
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 3.0 of the License, or (at your option) any later version.
00008  * 
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00012  * Lesser General Public License for more details.
00013  * 
00014  * You should have received a copy of the GNU Lesser General Public
00015  * License along with this library.
00016  */
00017 
00028 #include "sr_ronex_drivers/cod_decod/cod_decod_manager.hpp"
00029 #include "sr_ronex_drivers/cod_decod/cod_decod_std_io.hpp"
00030 #include <boost/foreach.hpp>
00031 #include <boost/regex.hpp>
00032 
00033 namespace sr_cod_decod
00034 {
00035 
00036   CodDecodManager::CodDecodManager(hardware_interface::HardwareInterface *hw, EtherCAT_SlaveHandler *sh, int n_digital_outputs, int n_analog_outputs, int n_digital_inputs, int n_analog_inputs, int n_PWM_outputs)
00037     :cod_decod_loader_("sr_ronex_drivers", "sr_cod_decod::CodDecod")
00038   {
00039     uint32_t product_code = sh->get_product_code();
00040     uint32_t serial = sh->get_serial();
00041     uint32_t revision = sh->get_revision();
00042     uint32_t slave = sh->get_station_address()-1;
00043 
00044     // The point of this code to find a cod_decod class whose name matches the EtherCAT product ID and Serial Number
00045     // for a given device.
00046     // Thus cod_decod plugins would register themselves with PLUGINLIB_EXPORT_CLASS
00047     //
00048     //   PLUGINLIB_EXPORT_CLASS(class_namespace::class_type, base_class_namespace::base_class_type)
00049     //
00050     // For the CodDecodExample cod_decod example module to be use with e.g productID = 87032868 and serialNumber = 21, this statement would look something like:
00051     //
00052     //  PLUGINLIB_EXPORT_CLASS(sr_cod_decod::CodDecodExample, sr_cod_decod::CodDecod);
00053     //
00054     //
00055     // Unfortunately, we don't know which ROS package a particular cod_decod class is defined in.
00056     // To account for this, we search through the list of class names, one-by-one and find string where
00057     // last part of string matches product ID and serial number of a device.
00058     stringstream class_name_regex_str;
00059     class_name_regex_str << "(.*/)?" << product_code << "_" << serial;
00060     boost::regex class_name_regex(class_name_regex_str.str(), boost::regex::extended);
00061 
00062     std::vector<std::string> classes = cod_decod_loader_.getDeclaredClasses();
00063     std::string matching_class_name;
00064 
00065     BOOST_FOREACH(const std::string &class_name, classes)
00066     {
00067       if (regex_match(class_name, class_name_regex))
00068       {
00069         if (matching_class_name.size() != 0)
00070         {
00071           ROS_ERROR("Found more than 1 CodDecod class for device with product code : %u (0x%X) and serial number : %u (0x%X)", product_code, product_code, serial, serial);
00072           ROS_ERROR("First class name = '%s'.  Second class name = '%s'",
00073                     class_name.c_str(), matching_class_name.c_str());
00074         }
00075         matching_class_name = class_name;
00076       }
00077     }
00078 
00079     if (matching_class_name.size() != 0)
00080     {
00081       //ROS_WARN("Using driver class '%s' for device with product code %d",
00082       //         matching_class_name.c_str(), product_code);
00083       try {
00084         cod_decod_ = cod_decod_loader_.createInstance( matching_class_name );
00085       }
00086       catch (pluginlib::LibraryLoadException &e)
00087       {
00088         cod_decod_.reset();
00089         ROS_FATAL("Unable to load CodDecod plugin for slave #%d, product code: %u (0x%X), serial: %u (0x%X), revision: %d (0x%X)",
00090                   slave, product_code, product_code, serial, serial, revision, revision);
00091         ROS_FATAL("%s", e.what());
00092       }
00093     }
00094     else
00095     {
00096       ROS_INFO("Unable to find a dedicated CodDecod plugin for slave #%d, product code: %u (0x%X), serial: %u (0x%X), revision: %d (0x%X)",
00097                 slave, product_code, product_code, serial, serial, revision, revision);
00098       ROS_INFO("Possible classes:");
00099       BOOST_FOREACH(const std::string &class_name, classes)
00100       {
00101         ROS_INFO("  %s", class_name.c_str());
00102       }
00103       ROS_INFO("Loading the default CodDecod plugin: CodDecodStdIo");
00104       try {
00105         cod_decod_ = cod_decod_loader_.createInstance( "sr_ronex_drivers/87032868_0" );
00106       }
00107       catch (pluginlib::LibraryLoadException &e)
00108       {
00109         cod_decod_.reset();
00110         ROS_FATAL("Unable to load CodDecod plugin for slave #%d, product code: %u (0x%X), serial: %u (0x%X), revision: %d (0x%X)",
00111                   slave, product_code, product_code, serial, serial, revision, revision);
00112         ROS_FATAL("%s", e.what());
00113       }
00114     }
00115 
00116     if (cod_decod_ != NULL)
00117     {
00118       cod_decod_->construct(hw, sh, n_digital_outputs, n_analog_outputs, n_digital_inputs, n_analog_inputs, n_PWM_outputs);
00119     }
00120 
00121   }
00122 
00123   void CodDecodManager::update(unsigned char *status_buffer)
00124   {
00125     if(cod_decod_)
00126     {
00127       cod_decod_->update(status_buffer);
00128     }
00129   }
00130 
00131   void CodDecodManager::build_command(unsigned char *command_buffer)
00132   {
00133     if(cod_decod_)
00134     {
00135       cod_decod_->build_command(command_buffer);
00136     }
00137   }
00138 
00139 }


sr_ronex_drivers
Author(s): Ugo Cupcic, Toni Oliver, Mark Pitchless
autogenerated on Fri Aug 28 2015 13:12:23