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>()){
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 }