5 #include <std_msgs/Int8.h> 6 #include <std_msgs/Int16.h> 7 #include <std_msgs/Int32.h> 8 #include <std_msgs/Int64.h> 9 #include <std_msgs/UInt8.h> 10 #include <std_msgs/UInt16.h> 11 #include <std_msgs/UInt32.h> 12 #include <std_msgs/UInt64.h> 13 #include <std_msgs/Float32.h> 14 #include <std_msgs/Float64.h> 15 #include <std_msgs/String.h> 48 if(interface && !interface->translateError(s.
internal_error, msg)) msg =
"Undefined"; ;
54 time_point abs_time = boost::chrono::high_resolution_clock::now();
67 abs_time += update_duration_;
68 boost::this_thread::sleep_until(abs_time);
75 boost::mutex::scoped_lock lock(mutex_);
76 if(getLayerState() > Off){
78 res.message =
"already initialized";
86 res.message = status.
reason();
89 res.message = status.
reason();
91 heartbeat_timer_.restart();
95 catch(
const std::exception &e){
96 std::string info = boost::diagnostic_information(e);
99 status.
error(res.message);
102 res.message =
"Unknown exception";
103 status.
error(res.message);
113 boost::mutex::scoped_lock lock(mutex_);
116 if(getLayerState() > Init){
126 res.message = status.
reason();
128 catch(
const std::exception &e){
129 std::string info = boost::diagnostic_information(e);
134 res.message =
"Unknown exception";
137 res.message =
"not running";
144 if(current_state > Shutdown){
145 for(std::vector<PublishFunc::FuncType>::iterator it = publishers_.begin(); it != publishers_.end(); ++it) (*it)();
150 boost::mutex::scoped_lock lock(diag_mutex_);
151 heartbeat_timer_.stop();
155 thread_->interrupt();
163 boost::mutex::scoped_lock lock(mutex_);
165 if(getLayerState() > Init){
170 res.message =
"not running";
177 boost::mutex::scoped_lock lock(mutex_);
179 if(getLayerState() > Init){
183 res.message =
"not running";
189 std::map<std::string, canopen::NodeSharedPtr >::iterator it = nodes_lookup_.find(req.node);
190 if(it == nodes_lookup_.end()){
191 res.message =
"node not found";
196 }
catch(std::exception& e) {
197 res.message = boost::diagnostic_information(e);
204 std::map<std::string, canopen::NodeSharedPtr >::iterator it = nodes_lookup_.find(req.node);
205 if(it == nodes_lookup_.end()){
206 res.message =
"node not found";
211 }
catch(std::exception& e) {
212 res.message = boost::diagnostic_information(e);
220 std::string can_device;
221 std::string driver_plugin;
222 std::string master_alloc;
225 if(!bus_nh.
getParam(
"device",can_device)){
230 bus_nh.
param(
"loopback",loopback,
false);
232 bus_nh.
param(
"driver_plugin",driver_plugin, std::string(
"can::SocketCANInterface"));
235 interface_ = driver_loader_.createInstance(driver_plugin);
245 if(bus_nh.
getParam(
"master_type",master_alloc)){
246 ROS_ERROR(
"please migrate to master allocators");
250 bus_nh.
param(
"master_allocator",master_alloc, std::string(
"canopen::SimpleMaster::Allocator"));
253 master_= master_allocator_.allocateInstance(master_alloc, can_device, interface_);
255 catch(
const std::exception &e){
256 std::string info = boost::diagnostic_information(e);
266 add(boost::make_shared<CANLayer>(interface_, can_device, loopback));
275 int sync_overflow = 0;
277 if(!sync_nh.
getParam(
"interval_ms", sync_ms)){
278 ROS_WARN(
"Sync interval was not specified, so sync is disabled per default");
286 int update_ms = sync_ms;
287 if(sync_ms == 0) nh_priv_.getParam(
"update_ms", update_ms);
292 update_duration_ = boost::chrono::milliseconds(update_ms);
296 if(!sync_nh.
getParam(
"overflow", sync_overflow)){
297 ROS_WARN(
"Sync overflow was not specified, so overflow is disabled per default");
299 if(sync_overflow == 1 || sync_overflow > 240){
303 if(sync_nh.
param(
"silence_us", 0) != 0){
304 ROS_WARN(
"silence_us is not supported anymore");
310 if(!sync_ && sync_ms){
324 bool got_any = hb_nh.
getParam(
"msg", msg);
325 got_any = hb_nh.
getParam(
"rate", rate) || got_any;
327 if( !got_any)
return true;
337 if(!hb_sender_.frame.isValid()){
342 hb_sender_.interface = interface_;
344 heartbeat_timer_.start(
Timer::TimerDelegate(&hb_sender_, &HeartbeatSender::send) , boost::chrono::duration<double>(1.0/rate),
false);
351 size_t pos = obj_name.find(
'!');
352 bool force = pos != std::string::npos;
353 if(force) obj_name.erase(pos);
354 return std::make_pair(obj_name, force);
361 for(
int i = 0; i < objs.
size(); ++i){
364 if(!logger.
add(level, obj_name.first, obj_name.second)){
385 if(!nh_priv_.getParam(
"nodes", nodes)){
386 ROS_WARN(
"falling back to 'modules', please switch to 'nodes'");
387 nh_priv_.getParam(
"modules", nodes);
390 nh_priv_.getParam(
"defaults", defaults);
394 for(
size_t i = 0; i < nodes.
size(); ++i){
395 if(nodes[i].hasMember(
"name")){
396 std::string &name = nodes[i][
"name"];
397 new_stuct[name] = nodes[i];
409 node_id = it->second[
"id"];
417 if(!it->second.hasMember(
"name")){
418 merged[
"name"]=it->first;
433 overlay.push_back(ObjectDict::Overlay::value_type(ito->first, ito->second));
441 eds = (std::string) merged[
"eds_file"];
450 std::string pkg = merged[
"eds_pkg"];
455 eds = (boost::filesystem::path(p)/eds).make_preferred().native();;
471 if(!nodeAdded(merged, node, logger))
return false;
473 if(!
addLoggerEntries(merged,
"log", diagnostic_updater::DiagnosticStatusWrapper::OK, *logger))
return false;
474 if(!
addLoggerEntries(merged,
"log_warn", diagnostic_updater::DiagnosticStatusWrapper::WARN, *logger))
return false;
475 if(!
addLoggerEntries(merged,
"log_error", diagnostic_updater::DiagnosticStatusWrapper::ERROR, *logger))
return false;
477 loggers_.push_back(logger);
478 diag_updater_.add(it->first, boost::bind(&
Logger::log, logger, _1));
480 std::string node_name = std::string(merged[
"name"]);
485 for(
int i = 0; i < objs.
size(); ++i){
490 ROS_ERROR_STREAM(
"Could not create publisher for '" << obj_name.first <<
"'");
493 publishers_.push_back(pub);
497 ROS_ERROR(
"Could not parse publish parameter");
502 nodes_lookup_.insert(std::make_pair(node_name, node));
505 emcy_handlers_->add(emcy);
516 boost::mutex::scoped_lock lock(diag_mutex_);
518 if(getLayerState() == Off){
519 stat.
summary(stat.WARN,
"Not initailized");
521 stat.
summary(stat.ERROR,
"Thread is not running");
526 for(std::vector<std::pair<std::string, std::string> >::const_iterator it = r.
values().begin(); it != r.
values().end(); ++it){
527 stat.
add(it->first, it->second);
534 :
LayerStack(
"ROS stack"),driver_loader_(
"socketcan_interface",
"can::DriverInterface"),
535 master_allocator_(
"canopen_master",
"canopen::Master::Allocator"),
536 nh_(nh), nh_priv_(nh_priv),
537 diag_updater_(nh_,nh_priv_),
539 reset_errors_before_recover_(false){}
542 boost::mutex::scoped_lock lock(
mutex_);
576 }
catch(...){
LOG(
"CATCH"); }
bool addLoggerEntries(XmlRpc::XmlRpcValue merged, const std::string param, uint8_t level, Logger &logger)
virtual void add(const VectorMemberSharedPtr &l)
ros::ServiceServer srv_shutdown_
#define ROS_ERROR_STREAM_THROTTLE(period, args)
std::list< std::pair< std::string, std::string > > Overlay
virtual void handleWrite(LayerStatus &status, const LayerState ¤t_state)
#define ROS_WARN_STREAM_THROTTLE(period, args)
ValueStruct::iterator iterator
ros::ServiceServer srv_set_object_
void shutdown(LayerStatus &status)
virtual bool handle_halt(std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &res)
void summary(unsigned char lvl, const std::string s)
void init(const M_string &remappings)
void setHardwareID(const std::string &hwid)
static FuncType create(ros::NodeHandle &nh, const std::string &name, canopen::NodeSharedPtr node, const std::string &key, bool force)
void add(const std::string &name, TaskFunction f)
virtual bool handle_init(std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &res)
const std::string reason() const
bool reset_errors_before_recover_
static ObjectDictSharedPtr fromFile(const std::string &path, const Overlay &overlay=Overlay())
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
Type const & getType() const
virtual bool handle_recover(std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &res)
bool handle_get_object(canopen_chain_node::GetObject::Request &req, canopen_chain_node::GetObject::Response &res)
ros::ServiceServer srv_init_
boost::function< void()> FuncType
Frame toframe(const std::string &s)
ros::ServiceServer srv_get_object_
ros::ServiceServer srv_halt_
void halt(LayerStatus &status)
virtual bool handle_shutdown(std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &res)
boost::chrono::high_resolution_clock::time_point time_point
virtual void handleShutdown(LayerStatus &status)
void report_diagnostics(diagnostic_updater::DiagnosticStatusWrapper &stat)
void logState(const can::State &s)
std::pair< std::string, bool > parseObjectName(std::string obj_name)
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
virtual void log(diagnostic_updater::DiagnosticStatusWrapper &stat)
Timer createTimer(Rate r, Handler h, Obj o, bool oneshot=false, bool autostart=true) const
void resetErrors(LayerStatus &status)
const std::vector< std::pair< std::string, std::string > > & values() const
#define ROS_WARN_STREAM(args)
enum can::State::DriverState driver_state
ROSLIB_DECL std::string getPath(const std::string &package_name)
virtual bool nodeAdded(XmlRpc::XmlRpcValue ¶ms, const canopen::NodeSharedPtr &node, const LoggerSharedPtr &logger)
bool hasMember(const std::string &name) const
RosChain(const ros::NodeHandle &nh, const ros::NodeHandle &nh_priv)
#define ROS_INFO_STREAM(args)
ROSCONSOLE_DECL void shutdown()
bool getParam(const std::string &key, std::string &s) const
virtual bool setup_chain()
const void error(const std::string &r)
virtual void handleWrite(LayerStatus &status, const LayerState ¤t_state)
diagnostic_updater::Updater diag_updater_
unsigned int internal_error
void add(const std::string &key, const T &val)
#define ROS_ERROR_STREAM(args)
bool add(uint8_t level, const std::string &key, bool forced)
ros::ServiceServer srv_recover_
virtual void handleShutdown(LayerStatus &status)
bool handle_set_object(canopen_chain_node::SetObject::Request &req, canopen_chain_node::SetObject::Response &res)
boost::system::error_code error_code
boost::shared_ptr< canopen::LayerGroupNoDiag< canopen::EMCYHandler > > emcy_handlers_