sync_node.cpp
Go to the documentation of this file.
00001 #include <canopen_master/bcm_sync.h>
00002 #include <socketcan_interface/string.h>
00003 #include <canopen_master/can_layer.h>
00004 #include <ros/ros.h>
00005 #include <diagnostic_updater/diagnostic_updater.h>
00006 
00007 template<typename T > std::string join(const T &container, const std::string &delim){
00008     if(container.empty()) return std::string();
00009     std::stringstream sstr;
00010     typename T::const_iterator it = container.begin();
00011     sstr << *it;
00012     for(++it; it != container.end(); ++it){
00013         sstr << delim << *it;
00014     }
00015     return sstr.str();
00016 }
00017 void report_diagnostics(canopen::LayerStack &sync, diagnostic_updater::DiagnosticStatusWrapper &stat){
00018     canopen::LayerReport r;
00019     sync.read(r);
00020     sync.diag(r);
00021     if(sync.getLayerState() !=canopen::Layer::Off  &&  r.bounded<canopen::LayerStatus::Unbounded>()){ // valid
00022         stat.summary(r.get(), r.reason());
00023         for(std::vector<std::pair<std::string, std::string> >::const_iterator it = r.values().begin(); it != r.values().end(); ++it){
00024             stat.add(it->first, it->second);
00025         }
00026         if(!r.bounded<canopen::LayerStatus::Warn>()){
00027             canopen::LayerStatus s;
00028             sync.recover(s);
00029         }
00030     }else{
00031         stat.summary(stat.WARN, "sync not initilized");
00032         canopen::LayerStatus s;
00033         sync.init(s);
00034     }
00035 }
00036 
00037 int main(int argc, char** argv){
00038     ros::init(argc, argv, "canopen_sync_node");
00039 
00040     ros::NodeHandle nh;
00041     ros::NodeHandle nh_priv("~");
00042 
00043     ros::NodeHandle sync_nh(nh_priv, "sync");
00044     int sync_ms;
00045     if(!sync_nh.getParam("interval_ms", sync_ms) || sync_ms <=0){
00046         ROS_ERROR_STREAM("Sync interval  "<< sync_ms << " is invalid");
00047         return false;
00048     }
00049 
00050     int sync_overflow = 0;
00051     if(!sync_nh.getParam("overflow", sync_overflow)){
00052         ROS_WARN("Sync overflow was not specified, so overflow is disabled per default");
00053     }
00054     if(sync_overflow == 1 || sync_overflow > 240){
00055         ROS_ERROR_STREAM("Sync overflow  "<< sync_overflow << " is invalid");
00056         return false;
00057     }
00058 
00059 
00060     std::string can_device;
00061     if(!nh_priv.getParam("bus/device",can_device)){
00062         ROS_ERROR("Device not set");
00063         return 1;
00064     }
00065 
00066     boost::shared_ptr<can::SocketCANDriver> driver = boost::make_shared<can::SocketCANDriver>();
00067     canopen::SyncProperties sync_properties(can::MsgHeader(sync_nh.param("sync_id", 0x080)), sync_ms, sync_overflow);
00068 
00069     boost::shared_ptr<canopen::BCMsync> sync = boost::make_shared<canopen::BCMsync>(can_device, driver, sync_properties);
00070 
00071     std::vector<int> nodes;
00072 
00073     if(sync_nh.getParam("monitored_nodes",nodes)){
00074         sync->setMonitored(nodes);
00075     }else{
00076         std::string msg;
00077         if(nh_priv.getParam("heartbeat/msg", msg)){
00078             can::Frame f = can::toframe(msg);
00079             if(f.isValid() && (f.id & ~canopen::BCMsync::ALL_NODES_MASK) == canopen::BCMsync::HEARTBEAT_ID){
00080                 nodes.push_back(f.id & canopen::BCMsync::ALL_NODES_MASK);
00081             }
00082         }
00083         sync_nh.getParam("ignored_nodes",nodes);
00084         sync->setIgnored(nodes);
00085     }
00086 
00087     canopen::LayerStack stack("SyncNodeLayer");
00088 
00089     stack.add(boost::make_shared<canopen::CANLayer>(driver, can_device, false));
00090     stack.add(sync);
00091 
00092     diagnostic_updater::Updater diag_updater(nh, nh_priv);
00093     diag_updater.setHardwareID(nh_priv.param("hardware_id", std::string("none")));
00094     diag_updater.add("sync", boost::bind(report_diagnostics,boost::ref(stack), _1));
00095 
00096     ros::Timer diag_timer = nh.createTimer(ros::Duration(diag_updater.getPeriod()/2.0),boost::bind(&diagnostic_updater::Updater::update, &diag_updater));
00097 
00098     ros::spin();
00099     return 0;
00100 }


canopen_chain_node
Author(s): Mathias Lüdtke
autogenerated on Thu Jun 6 2019 20:44:05