CanOpenController.cpp
Go to the documentation of this file.
00001 // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*-
00002 
00003 // -- BEGIN LICENSE BLOCK ----------------------------------------------
00004 // This file is part of the SCHUNK Canopen Driver suite.
00005 //
00006 // This program is free software licensed under the LGPL
00007 // (GNU LESSER GENERAL PUBLIC LICENSE Version 3).
00008 // You can find a copy of this license in LICENSE folder in the top
00009 // directory of the source code.
00010 //
00011 // © Copyright 2016 SCHUNK GmbH, Lauffen/Neckar Germany
00012 // © Copyright 2016 FZI Forschungszentrum Informatik, Karlsruhe, Germany
00013 // -- END LICENSE BLOCK ------------------------------------------------
00014 
00015 //----------------------------------------------------------------------
00023 //----------------------------------------------------------------------
00024 
00025 #include "CanOpenController.h"
00026 #include <icl_hardware_can/tCanDeviceDummy.h>
00027 #include "Logging.h"
00028 #include "ds301.h"
00029 #include "sync.h"
00030 #include "exceptions.h"
00031 
00032 #include <cstdlib> // getenv
00033 #include <boost/filesystem.hpp>
00034 
00035 namespace icl_hardware {
00036 namespace canopen_schunk {
00037 
00038 CanOpenController::CanOpenController(const std::string can_device_identifier,
00039                                      const uint32_t baud_rate,
00040                                      const std::string& resource_folder_location
00041                                     )
00042   : m_can_device_name(can_device_identifier),
00043     m_can_device_flags(O_RDWR|O_NONBLOCK),
00044     m_can_device_acceptance_code(0xff),
00045     m_can_device_acceptance_mask(0xff),
00046     m_can_device_send_fifo_size(300),
00047     m_can_device_receive_fifo_size(2000),
00048     m_can_device_baud_rate(baud_rate),
00049     m_heartbeat_monitor(new HeartBeatMonitor()),
00050     m_polling_period_ms(1),
00051     m_resource_folder_location(resource_folder_location),
00052     m_ws_broadcast_counter(0),
00053     m_ws_broadcast_rate(5)
00054 {
00055     init();
00056 }
00057 
00058 CanOpenController::~CanOpenController ()
00059 {
00060   // Stop receiving thread
00061   if (m_receive_thread)
00062   {
00063     m_receive_thread->stop();
00064   }
00065 }
00066 
00067 void CanOpenController::initNodes (const int16_t node_id)
00068 {
00069   for (std::map<uint8_t, DS301Node::Ptr>::iterator it = m_nodes.begin(); it != m_nodes.end(); ++it)
00070   {
00071     if (it->first == node_id || node_id < 0)
00072     {
00073       it->second->initNode();
00074     }
00075   }
00076 }
00077 
00078 void CanOpenController::processCanMsgCallback ( const can::tCanMessage& msg )
00079 {
00080   if (msg.id == ds301::ID_NMT)
00081   {
00082     LOGGING_DEBUG_C (CanOpen, CanOpenController, "NMT MESSAGE RECEIVED" << endl);
00083     LOGGING_TRACE_C (CanOpen, CanOpenController,
00084                      "Message id: " << msg.id << endl
00085                      << "Message length: " << msg.dlc << endl
00086                      << "Data: " << hexArrayToString(msg.data, msg.dlc) << endl);
00087   }
00088   else if (msg.id == ds301::ID_SYNC)
00089   {
00090     LOGGING_DEBUG_C (CanOpen, CanOpenController, "SYNC MESSAGE RECEIVED" << endl);
00091     LOGGING_TRACE_C (CanOpen, CanOpenController,
00092                      "Message id: " << msg.id << endl
00093                      << "Data: " << hexArrayToString(msg.data, msg.dlc) << endl);
00094   }
00095   else if (msg.id >= ds301::ID_EMCY_MIN && msg.id <= ds301::ID_EMCY_MAX)
00096   {
00097     LOGGING_DEBUG_C (CanOpen, CanOpenController, "EMCY MESSAGE RECEIVED" << endl);
00098     LOGGING_TRACE_C (CanOpen, CanOpenController,
00099                      "Message id: " << msg.id << endl
00100                      << "Data: " << hexArrayToString(msg.data, msg.dlc) << endl);
00101     DS301Node::Ptr node = getNodeById(msg.id - ds301::ID_EMCY_MIN+1);
00102     if (node)
00103     {
00104       try
00105       {
00106         node->m_emcy->update(msg);
00107       }
00108       catch (const std::exception& e)
00109       {
00110         LOGGING_ERROR (CanOpen, "Exception thrown in EMCY update function: " << e.what() << endl);
00111       }
00112     }
00113   }
00114   else if (msg.id == ds301::ID_TIME)
00115   {
00116     LOGGING_DEBUG_C (CanOpen, CanOpenController, "TIME MESSAGE RECEIVED" << endl);
00117     LOGGING_TRACE_C (CanOpen, CanOpenController,
00118                      "Message id: " << msg.id << endl
00119                      << "Data: " << hexArrayToString(msg.data, msg.dlc) << endl);
00120   }
00121   else if (msg.id >= ds301::ID_TPDO1_MIN && msg.id <= ds301::ID_TPDO1_MAX)
00122   {
00123     LOGGING_DEBUG_C (CanOpen, CanOpenController, "TPDO1 MESSAGE for node " << msg.id - ds301::ID_TPDO1_MIN+1 << " RECEIVED" << endl);
00124     LOGGING_TRACE_C (CanOpen, CanOpenController,
00125                      "Message id: " << msg.id << endl
00126                      << "Data: " << hexArrayToString(msg.data, msg.dlc) << endl);
00127     DS301Node::Ptr node = getNodeById(msg.id - ds301::ID_TPDO1_MIN+1);
00128     if (node)
00129     {
00130       try
00131       {
00132         node->m_tpdos.at(0)->update(msg);
00133       }
00134       catch (const std::exception& e)
00135       {
00136         LOGGING_ERROR (CanOpen, "Exception thrown in PDO update function: " << e.what() << endl);
00137       }
00138     }
00139   }
00140   else if (msg.id >= ds301::ID_RPDO1_MIN && msg.id <= ds301::ID_RPDO1_MAX)
00141   {
00142     LOGGING_DEBUG_C (CanOpen, CanOpenController, "RPDO1 MESSAGE RECEIVED" << endl);
00143     LOGGING_TRACE_C (CanOpen, CanOpenController,
00144                      "Message id: " << msg.id << endl
00145                      << "Data: " << hexArrayToString(msg.data, msg.dlc) << endl);
00146   }
00147   else if (msg.id >= ds301::ID_TPDO2_MIN && msg.id <= ds301::ID_TPDO2_MAX)
00148   {
00149     LOGGING_DEBUG_C (CanOpen, CanOpenController, "TPDO2 MESSAGE RECEIVED" << endl);
00150     LOGGING_TRACE_C (CanOpen, CanOpenController,
00151                      "Message id: " << msg.id << endl
00152                      << "Data: " << hexArrayToString(msg.data, msg.dlc) << endl);
00153     DS301Node::Ptr node = getNodeById(msg.id - ds301::ID_TPDO2_MIN+1);
00154     if (node)
00155     {
00156       try
00157       {
00158         node->m_tpdos.at(1)->update(msg);
00159       }
00160       catch (const std::exception& e)
00161       {
00162         LOGGING_ERROR (CanOpen, "Exception thrown in PDO update function: " << e.what() << endl);
00163       }
00164     }
00165   }
00166   else if (msg.id >= ds301::ID_RPDO2_MIN && msg.id <= ds301::ID_RPDO2_MAX)
00167   {
00168     LOGGING_DEBUG_C (CanOpen, CanOpenController, "RPDO2 MESSAGE RECEIVED" << endl);
00169     LOGGING_TRACE_C (CanOpen, CanOpenController,
00170                      "Message id: " << msg.id << endl
00171                      << "Data: " << hexArrayToString(msg.data, msg.dlc) << endl);
00172   }
00173   else if (msg.id >= ds301::ID_TPDO3_MIN && msg.id <= ds301::ID_TPDO3_MAX)
00174   {
00175     LOGGING_DEBUG_C (CanOpen, CanOpenController, "TPDO3 MESSAGE RECEIVED" << endl);
00176     LOGGING_TRACE_C (CanOpen, CanOpenController,
00177                      "Message id: " << msg.id << endl
00178                      << "Data: " << hexArrayToString(msg.data, msg.dlc) << endl);
00179     DS301Node::Ptr node = getNodeById(msg.id - ds301::ID_TPDO3_MIN+1);
00180     if (node)
00181     {
00182       try
00183       {
00184         node->m_tpdos.at(2)->update(msg);
00185       }
00186       catch (const std::exception& e)
00187       {
00188         LOGGING_ERROR (CanOpen, "Exception thrown in PDO update function: " << e.what() << endl);
00189       }
00190     }
00191   }
00192   else if (msg.id >= ds301::ID_RPDO3_MIN && msg.id <= ds301::ID_RPDO3_MAX)
00193   {
00194     LOGGING_DEBUG_C (CanOpen, CanOpenController, "RPDO3 MESSAGE RECEIVED" << endl);
00195     LOGGING_TRACE_C (CanOpen, CanOpenController,
00196                      "Message id: " << msg.id << endl
00197                      << "Data: " << hexArrayToString(msg.data, msg.dlc) << endl);
00198   }
00199   else if (msg.id >= ds301::ID_TPDO4_MIN && msg.id <= ds301::ID_TPDO4_MAX)
00200   {
00201     LOGGING_DEBUG_C (CanOpen, CanOpenController, "TPDO4 MESSAGE RECEIVED" << endl);
00202     LOGGING_TRACE_C (CanOpen, CanOpenController,
00203                      "Message id: " << msg.id << endl
00204                      << "Data: " << hexArrayToString(msg.data, msg.dlc) << endl);
00205     DS301Node::Ptr node = getNodeById(msg.id - ds301::ID_TPDO4_MIN+1);
00206     if (node)
00207     {
00208       try
00209       {
00210         node->m_tpdos.at(3)->update(msg);
00211       }
00212       catch (const std::exception& e)
00213       {
00214         LOGGING_ERROR (CanOpen, "Exception thrown in PDO update function: " << e.what() << endl);
00215       }
00216     }
00217   }
00218   else if (msg.id >= ds301::ID_RPDO4_MIN && msg.id <= ds301::ID_RPDO4_MAX)
00219   {
00220     LOGGING_DEBUG_C (CanOpen, CanOpenController, "RPDO4 MESSAGE RECEIVED" << endl);
00221     LOGGING_TRACE_C (CanOpen, CanOpenController,
00222                      "Message id: " << msg.id << endl
00223                      << "Data: " << hexArrayToString(msg.data, msg.dlc) << endl);
00224   }
00225   else if (msg.id >= ds301::ID_TSDO_MIN && msg.id <= ds301::ID_TSDO_MAX)
00226   {
00227     LOGGING_DEBUG_C (CanOpen, CanOpenController, "TSDO MESSAGE RECEIVED" << endl);
00228     LOGGING_TRACE_C (CanOpen, CanOpenController,
00229                      "Message id: " << msg.id << endl
00230                      << "Data: " << hexArrayToString(msg.data, msg.dlc) << endl);
00231     DS301Node::Ptr node = getNodeById(msg.id - ds301::ID_TSDO_MIN+1);
00232     if (node)
00233     {
00234       try
00235       {
00236         node->m_sdo.update(msg);
00237       }
00238       catch (const ResponseException& e)
00239       {
00240         LOGGING_ERROR (CanOpen, "Exception thrown in SDO update function: " << e.what() << endl);
00241       }
00242     }
00243   }
00244   else if (msg.id >= ds301::ID_RSDO_MIN && msg.id <= ds301::ID_RSDO_MAX)
00245   {
00246     LOGGING_DEBUG_C (CanOpen, CanOpenController, "RSDO MESSAGE RECEIVED" << endl);
00247     LOGGING_TRACE_C (CanOpen, CanOpenController,
00248                      "Message id: " << msg.id << endl
00249                      << "Data: " << hexArrayToString(msg.data, msg.dlc) << endl);
00250     DS301Node::Ptr node = getNodeById(msg.id - ds301::ID_RSDO_MIN+1);
00251     if (node)
00252     {
00253       try
00254       {
00255         node->m_sdo.update(msg);
00256       }
00257       catch (const ResponseException& e)
00258       {
00259         LOGGING_ERROR (CanOpen, "Exception thrown in SDO update function: " << e.what() << endl);
00260       }
00261     }
00262   }
00263   else if (msg.id >= ds301::ID_NMT_ERROR_MIN && msg.id <= ds301::ID_NMT_ERROR_MAX)
00264   {
00265     LOGGING_DEBUG_C (CanOpen, CanOpenController, "NMT_ERROR MESSAGE RECEIVED" << endl);
00266     LOGGING_TRACE_C (CanOpen, CanOpenController,
00267                      "Message id: " << msg.id << endl
00268                      << "Data: " << hexArrayToString(msg.data, msg.dlc) << endl);
00269     uint8_t node_id = msg.id - ds301::ID_NMT_ERROR_MIN+1;
00270     DS301Node::Ptr node = getNodeById(node_id);
00271 
00272     if (node)
00273     {
00274       try
00275       {
00276         node->m_nmt.update(msg);
00277       }
00278       catch (const ResponseException& e)
00279       {
00280         LOGGING_ERROR (CanOpen, "Exception thrown in NMT update function: " << e.what() << endl);
00281       }
00282       if (msg.data[0] != 0x0)
00283       {
00284         m_heartbeat_monitor->addHeartbeat(node_id);
00285       }
00286     }
00287     else if ( msg.dlc == 1 && msg.data[0] == 0x0)
00288     {
00289       // TODO (optional): If byte 0: add new node (autodiscovery)
00290       LOGGING_INFO_C (CanOpen, CanOpenController, "NMT bootup of node " << msg.id - ds301::ID_NMT_ERROR_MIN+1 << endl);
00291     }
00292   }
00293 }
00294 
00295 void CanOpenController::reconnectCanDevice(const std::string& can_identifier, const uint32_t baud_rate)
00296 {
00297   if (baud_rate != 0)
00298   {
00299     m_can_device_baud_rate = baud_rate;
00300   }
00301   m_can_device_name = can_identifier;
00302 
00303   if (m_receive_thread)
00304   {
00305     m_receive_thread->stop();
00306   }
00307 
00308   try
00309   {
00310     init();
00311   }
00312   catch (const DeviceException& e)
00313   {
00314     LOGGING_ERROR_C (CanOpen, CanOpenController, "Initializing device failed. Reason: " << e.what());
00315   }
00316 }
00317 
00318 void CanOpenController::init()
00319 {
00320   #ifdef _IC_BUILDER_ICL_COMM_WEBSOCKET_
00321   m_ws_broadcaster = boost::shared_ptr<icl_comm::websocket::WsBroadcaster>(new icl_comm::websocket::WsBroadcaster(icl_comm::websocket::WsBroadcaster::eRT_LWA4P));
00322   #endif // _IC_BUILDER_ICL_COMM_WEBSOCKET_
00323 
00324 
00325   getResources();
00326 
00327   if (m_can_device_name == "Dummy")
00328   {
00329     m_can_device.reset(new icl_hardware::can::tCanDeviceDummy( m_can_device_name.c_str(),
00330                                                             m_can_device_flags,
00331                                                             m_can_device_acceptance_code,
00332                                                             m_can_device_acceptance_mask,
00333                                                             m_can_device_baud_rate,
00334                                                             m_can_device_send_fifo_size,
00335                                                             m_can_device_receive_fifo_size
00336                                                           ));
00337   }
00338   else if (m_can_device_name == "auto")
00339   {
00340     const boost::array<const std::string, 4> names = {"/dev/pcanusb0","/dev/pcanusb1","/dev/pcanusb2","/dev/pcanusb3"};
00341     bool can_found = false;
00342     LOGGING_INFO (CanOpen, "CAN Device was set to auto. " << endl);
00343 
00344     for (size_t num = 0; num < names.size() ; ++num)
00345     {
00346         m_can_device_name = names[num];
00347         LOGGING_INFO(CanOpen, "Trying CAN device: " << m_can_device_name << "... " << endl);
00348         try
00349         {
00350             m_can_device.reset(icl_hardware::can::tCanDevice::Create( m_can_device_name.c_str(),
00351                                                                       m_can_device_flags,
00352                                                                       m_can_device_acceptance_code,
00353                                                                       m_can_device_acceptance_mask,
00354                                                                       m_can_device_baud_rate,
00355                                                                       m_can_device_send_fifo_size,
00356                                                                       m_can_device_receive_fifo_size
00357                                                                     ));
00358 
00359             if (m_can_device)
00360             {
00361               if (!m_can_device->IsInitialized())
00362               {
00363                 std::stringstream ss;
00364                 continue;
00365               }
00366             }
00367             can_found = true;
00368 
00369             break;
00370 
00371         }
00372         catch (DeviceException const& e)
00373         {
00374             LOGGING_INFO(CanOpen, e.what() << endl);
00375             can_found = false;
00376         }
00377     }
00378     if (!can_found)
00379     {
00380         LOGGING_ERROR(CanOpen, " CAN DEVICE COULD NOT BE OPENED. \n >> Giving up.");
00381         exit(-123);
00382         return;
00383     }
00384   }
00385   else
00386   {
00387     m_can_device.reset(icl_hardware::can::tCanDevice::Create( m_can_device_name.c_str(),
00388                                                             m_can_device_flags,
00389                                                             m_can_device_acceptance_code,
00390                                                             m_can_device_acceptance_mask,
00391                                                             m_can_device_baud_rate,
00392                                                             m_can_device_send_fifo_size,
00393                                                             m_can_device_receive_fifo_size
00394                                                           ));
00395   }
00396 
00397   if (m_can_device)
00398   {
00399     if (!m_can_device->IsInitialized())
00400     {
00401       std::stringstream ss;
00402       ss << "FATAL: COULD NOT INITIALIZE CAN DEVICE in " << m_can_device_name;
00403 
00404       throw DeviceException(ss.str());
00405     }
00406   }
00407   else
00408   {
00409     std::stringstream ss;
00410     ss << "FATAL: COULD NOT GET VALID CAN DEVICE in " << m_can_device_name;
00411 
00412     throw DeviceException(ss.str());
00413   }
00414 
00415   m_receive_thread.reset(new CanOpenReceiveThread(icl_core::TimeSpan::createFromMSec(m_polling_period_ms),
00416                                                   m_can_device,
00417                                                   boost::bind(&CanOpenController::processCanMsgCallback, this, _1)
00418                                                  ));
00419 
00420   if (!m_receive_thread)
00421   {
00422     throw DeviceException("FATAL: Could not start listener thread for CAN bus.");
00423   }
00424 
00425   // add default DS402Group
00426   addGroup<DS402Group>("default");
00427   m_heartbeat_monitor->registerErrorCallback(boost::bind(&CanOpenController::stopAll, this));
00428 }
00429 
00430 void CanOpenController::deleteGroup(const std::string& identifier)
00431 {
00432   std::string sanitized_identifier = sanitizeString(identifier);
00433 
00434   std::map<std::string, DS301Group::Ptr>::iterator group_it;
00435   group_it = m_groups.find(sanitized_identifier);
00436   if (group_it != m_groups.end())
00437   {
00438     std::vector<uint8_t> deleted_node_ids;
00439     group_it->second->deleteNodes(deleted_node_ids); // This will return the IDs of deleted nodes
00440 
00441     // Now also delete shared pointers in controller
00442     for (std::vector<uint8_t>::iterator it = deleted_node_ids.begin();
00443          it != deleted_node_ids.end();
00444          ++it)
00445     {
00446       // Find the node with given Id
00447       std::map<uint8_t, DS301Node::Ptr>::iterator node_it = m_nodes.find(*it);
00448       assert(node_it->second.use_count() == 1);
00449       m_nodes.erase(node_it);
00450     }
00451 
00452     m_groups.erase(group_it);
00453   }
00454   else
00455   {
00456     LOGGING_ERROR_C(CanOpen, CanOpenController, "No group with the given identifer " << sanitized_identifier
00457       << " exists. Not deleting anything." << endl);
00458   }
00459 }
00460 
00461 void CanOpenController::deleteNode(const uint8_t node_id)
00462 {
00463   // Delete node in group
00464   for (std::map<std::string, DS301Group::Ptr>::iterator it = m_groups.begin();
00465        it != m_groups.end();
00466        ++it)
00467   {
00468     if (it->second->deleteNodeFromId(node_id))
00469     {
00470       // group for node_id was found and node was deleted.
00471       break;
00472     }
00473   }
00474 
00475   // Delete node in controller's list
00476   std::map<uint8_t, DS301Node::Ptr>::iterator node_it = m_nodes.find(node_id);
00477   assert(node_it->second.use_count() == 1);
00478   m_nodes.erase(node_it);
00479 }
00480 
00481 DS301Node::Ptr CanOpenController::getNodeById(const uint8_t node_id)
00482 {
00483   std::map<uint8_t, DS301Node::Ptr>::iterator node_it = m_nodes.find(node_id);
00484   if (node_it == m_nodes.end())
00485   {
00486     LOGGING_ERROR_C(CanOpen, CanOpenController, "A node with the given ID " << node_id <<
00487                                                 " does not exist. Therefore this CAN message will be ignored." << endl);
00488     // Return a NULL pointer
00489     return DS301Node::Ptr();
00490   }
00491   return node_it->second;
00492 }
00493 
00494 void CanOpenController::getResources()
00495 {
00496   boost::filesystem::path resources_path(m_resource_folder_location);
00497 
00498   if (m_resource_folder_location == "")
00499   {
00500     char const* tmp = std::getenv("CANOPEN_RESOURCE_PATH");
00501     if (tmp == NULL)
00502     {
00503       LOGGING_WARNING_C(
00504           CanOpen,
00505           CanOpenController,
00506           "The environment variable 'CANOPEN_RESOURCE_PATH' could not be read. Using relative path 'resources/'" << endl);
00507       resources_path = boost::filesystem::path("resources");
00508     }
00509     else
00510     {
00511       resources_path = boost::filesystem::path(tmp);
00512     }
00513   }
00514 
00515   std::string sdo_errors_filename = (resources_path / boost::filesystem::path("SDO.ini")).string();
00516   SDO::addErrorMapFromFile( sdo_errors_filename );
00517 
00518   std::string emcy_emergency_errors_filename = (resources_path / boost::filesystem::path("EMCY.ini")).string();
00519   EMCY::addEmergencyErrorMap( emcy_emergency_errors_filename, "emergency_errors");
00520   EMCY::addErrorRegisterMap( emcy_emergency_errors_filename, "error_registers");
00521 
00522   emcy_emergency_errors_filename = (resources_path / boost::filesystem::path("EMCY_DS402.ini")).string();
00523   EMCY::addEmergencyErrorMap( emcy_emergency_errors_filename, "emergency_errors");
00524 }
00525 
00526 void CanOpenController::syncAll()
00527 {
00528   for (std::map<uint8_t, DS301Node::Ptr>::iterator it = m_nodes.begin();
00529        it != m_nodes.end();
00530   ++it)
00531   {
00532     it->second->downloadPDOs();
00533   }
00534 
00535   sendSync (m_can_device);
00536 
00537   for (std::map<uint8_t, DS301Node::Ptr>::iterator it = m_nodes.begin();
00538        it != m_nodes.end();
00539   ++it)
00540   {
00541     it->second->uploadPDOs();
00542   }
00543 
00544   #ifdef _IC_BUILDER_ICL_COMM_WEBSOCKET_
00545   if(m_ws_broadcast_counter % m_ws_broadcast_rate == 0)
00546   {
00547     if (!m_ws_broadcaster->sendState())
00548     {
00549     //    LOGGING_WARNING_C(
00550     //        CanOpen,
00551     //        CanOpenController, "Can't send ws_broadcaster state - reconnect pending..." << endl);
00552     }
00553     m_ws_broadcast_counter = 0;
00554   }
00555   ++m_ws_broadcast_counter;
00556   #endif // _IC_BUILDER_ICL_COMM_WEBSOCKET_
00557 
00558 }
00559 
00560 void CanOpenController::stopAll()
00561 {
00562   LOGGING_INFO (CanOpen, "Stop of all nodes requested!" << endl);
00563   for (std::map<uint8_t, DS301Node::Ptr>::iterator it = m_nodes.begin();
00564        it != m_nodes.end();
00565   ++it)
00566   {
00567     it->second->stopNode();
00568   }
00569 }
00570 
00571 std::vector< uint8_t > CanOpenController::getNodeList()
00572 {
00573   std::vector <uint8_t> node_list;
00574 
00575   size_t i=0;
00576   for (std::map<uint8_t, DS301Node::Ptr>::iterator it = m_nodes.begin();
00577        it != m_nodes.end();
00578   ++it)
00579   {
00580     it->second->downloadPDOs();
00581     node_list.push_back(it->second->getNodeId());
00582     ++i;
00583   }
00584 
00585   return node_list;
00586 }
00587 
00588 
00589 
00590 void CanOpenController::enablePPMotion(const int16_t node_id)
00591 {
00592   syncAll();
00593   usleep(5000); // sleep 5 ms
00594 
00595   LOGGING_TRACE_C (CanOpen, CanOpenController, "in function " << __FUNCTION__ << endl);
00596 
00597   for (std::map<std::string, DS301Group::Ptr>::iterator it = m_groups.begin();
00598        it != m_groups.end();
00599        ++it)
00600   {
00601     DS402Group::Ptr group_ds402 = boost::dynamic_pointer_cast<DS402Group>(it->second);
00602     if (group_ds402)
00603     {
00604       group_ds402->startPPMovement(node_id);
00605     }
00606   }
00607 
00608   syncAll();
00609   usleep(5000); // sleep 5 ms
00610 
00611   for (std::map<std::string, DS301Group::Ptr>::iterator it = m_groups.begin();
00612        it != m_groups.end();
00613        ++it)
00614   {
00615     DS402Group::Ptr group_ds402 = boost::dynamic_pointer_cast<DS402Group>(it->second);
00616     if (group_ds402)
00617     {
00618       group_ds402->acceptPPTargets(node_id);
00619     }
00620   }
00621   syncAll();
00622   usleep(5000); // sleep 5 ms
00623 
00624 }
00625 
00626 }}//end of NS


schunk_canopen_driver
Author(s): Felix Mauch , Georg Heppner
autogenerated on Sun May 22 2016 03:30:56