30 #include <condition_variable> 33 #include <boost/asio.hpp> 35 #include "novatel_oem7_msgs/Oem7AbasciiCmd.h" 36 #include "novatel_oem7_msgs/Oem7RawMsg.h" 113 catch(std::exception
const& ex)
127 << __DATE__ <<
" " << __TIME__);
129 std::lock_guard<std::mutex> guard(nodelet_mtx_);
139 if(publish_delay_sec_ > 0)
141 NODELET_WARN_STREAM(
"Publish Delay: " << publish_delay_sec_ <<
" seconds. Is this is a test?");
146 std::string oem7_if_name;
148 recvr_ = recvr_loader_.createInstance(oem7_if_name);
152 std::string msg_decoder_name;
154 msg_decoder = oem7_msg_decoder_loader.createInstance(msg_decoder_name);
161 std::vector<std::string> oem7_raw_msgs;
163 for(
const auto& msg : oem7_raw_msgs)
173 raw_msg_pub_.insert(raw_msg_id);
180 timer_spinner_->start();
201 bool serviceOem7AbasciiCb(novatel_oem7_msgs::Oem7AbasciiCmd::Request& req, novatel_oem7_msgs::Oem7AbasciiCmd::Response& rsp)
211 std::lock_guard<std::mutex> lk(rsp_ready_mtx_);
215 recvr_->write(boost::asio::buffer(req.cmd));
216 static const std::string NEWLINE(
"\n");
217 recvr_->write(boost::asio::buffer(NEWLINE));
219 std::unique_lock<std::mutex> lk(rsp_ready_mtx_);
220 if(rsp_ready_cond_.wait_until(lk,
221 std::chrono::steady_clock::now() + std::chrono::seconds(3)
222 ) == std::cv_status::no_timeout)
250 <<
"; discarded: " << discarded_msg_num_);
252 for(log_count_map_t::iterator itr = log_counts_.begin();
253 itr != log_counts_.end();
257 long count = itr->second;
270 if(log_counts_.find(raw_msg->getMessageId()) == log_counts_.end())
272 log_counts_[raw_msg->getMessageId()] = 0;
274 log_counts_[raw_msg->getMessageId()]++;
277 if((total_log_count_ % 10000) == 0)
285 novatel_oem7_msgs::Oem7RawMsg::Ptr oem7_raw_msg(
new novatel_oem7_msgs::Oem7RawMsg);
286 oem7_raw_msg->message_data.insert(
287 oem7_raw_msg->message_data.end(),
288 raw_msg->getMessageData(0),
289 raw_msg->getMessageData(raw_msg->getMessageDataLength()));
291 assert(oem7_raw_msg->message_data.size() == raw_msg->getMessageDataLength());
293 oem7rawmsg_pub_.
publish(oem7_raw_msg);
303 <<
" type= " << raw_msg->getMessageType());
306 if(raw_msg->getMessageFormat() == Oem7RawMessageIf::OEM7MSGFMT_UNKNOWN)
310 "Type: " << raw_msg->getMessageType() <<
311 "Fmt: " << raw_msg->getMessageFormat() <<
312 "Len: " << raw_msg->getMessageDataLength() <<
314 if(publish_unknown_oem7raw_)
325 if(raw_msg->getMessageFormat() == Oem7RawMessageIf::OEM7MSGFMT_ASCII ||
326 raw_msg->getMessageFormat() == Oem7RawMessageIf::OEM7MSGFMT_ABASCII)
328 std::string msg(raw_msg->getMessageData(0), raw_msg->getMessageData(raw_msg->getMessageDataLength()));
332 <<
"<---------------------------");
335 if(raw_msg->getMessageType() == Oem7RawMessageIf::OEM7MSGTYPE_RSP)
337 std::string rsp(raw_msg->getMessageData(0), raw_msg->getMessageData(raw_msg->getMessageDataLength()));
338 if(rsp.find_first_not_of(
" /t/r/n") != std::string::npos &&
339 std::all_of(rsp.begin(), rsp.end(), [](
char c){
return std::isprint(c);}))
342 std::lock_guard<std::mutex> lk(rsp_ready_mtx_);
345 rsp_ready_cond_.notify_one();
354 if( raw_msg->getMessageFormat() == Oem7RawMessageIf::OEM7MSGFMT_BINARY ||
355 (raw_msg->getMessageFormat() == Oem7RawMessageIf::OEM7MSGFMT_ASCII &&
isNMEAMessage(raw_msg)))
359 msg_handler_->handleMessage(raw_msg);
362 if(raw_msg_pub_.find(raw_msg->getMessageId()) != raw_msg_pub_.end())
367 if(publish_delay_sec_ > 0)
369 sleep(publish_delay_sec_);
382 msg_decoder->service();
386 NODELET_WARN(
"No more input from Decoder; Oem7MessageNodelet finished.");
392 recvr_loader_(
"novatel_oem7_driver",
"novatel_oem7_driver::Oem7ReceiverIf"),
393 oem7_msg_decoder_loader(
"novatel_oem7_driver",
"novatel_oem7_driver::Oem7MessageDecoderIf"),
396 discarded_msg_num_(0),
397 publish_delay_sec_(0),
398 publish_unknown_oem7raw_(false)
void onNewMessage(Oem7RawMessageIf::ConstPtr raw_msg)
#define NODELET_INFO_STREAM(...)
std::mutex nodelet_mtx_
Protects nodelet internal state.
boost::shared_ptr< void const > VoidConstPtr
pluginlib::ClassLoader< novatel_oem7_driver::Oem7MessageDecoderIf > oem7_msg_decoder_loader
#define NODELET_WARN(...)
boost::shared_ptr< ros::AsyncSpinner > aspinner_
1 thread servicing the command queue.
void outputLogStatistics()
bool isNMEAMessage(const Oem7RawMessageIf::ConstPtr &raw_msg)
std::set< int > raw_msg_pub_
Set of raw messages to publish.
const std::string & getName() const
long total_log_count_
Total number of logs received.
log_count_map_t log_counts_
Indidividual log counts.
bool publish_unknown_oem7raw_
Publish all unknown messages to 'Oem7Raw'.
#define NODELET_WARN_STREAM(...)
void publishOem7RawMsg(Oem7RawMessageIf::ConstPtr raw_msg)
std::condition_variable rsp_ready_cond_
Response ready, signaled from response handler to Oem7 Cmd Handler.
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
void serviceLoopCb(const ros::TimerEvent &event)
ros::CallbackQueue queue_
ros::NodeHandle & getPrivateNodeHandle() const
long discarded_msg_num_
Number of messages received and discarded by the driver.
boost::shared_ptr< novatel_oem7_driver::Oem7MessageDecoderIf > msg_decoder
Message Decoder plugin.
int getOem7MessageId(const std::string &msg_name)
#define NODELET_ERROR_STREAM(...)
boost::shared_ptr< novatel_oem7_driver::Oem7ReceiverIf > recvr_
Oem7 Receiver Interface plugin.
Oem7RosPublisher oem7rawmsg_pub_
Publishes raw Oem7 messages.
void setCallbackQueue(CallbackQueueInterface *queue)
ros::ServiceServer oem7_cmd_srv_
Oem7 command service.
std::mutex rsp_ready_mtx_
Response condition guard.
Timer createTimer(Rate r, Handler h, Obj o, bool oneshot=false, bool autostart=true) const
boost::shared_ptr< MessageHandler > msg_handler_
Dispatches individual messages for handling.
ros::NodeHandle & getNodeHandle() const
void updateLogStatistics(const Oem7RawMessageIf::ConstPtr &raw_msg)
void publish(boost::shared_ptr< M > &msg)
#define NODELET_DEBUG_STREAM(...)
std::map< int, long > log_count_map_t
PLUGINLIB_EXPORT_CLASS(novatel_oem7_driver::Oem7ConfigNodelet, nodelet::Nodelet)
std::string rsp_
The latest response from Oem7 receiver.
#define NODELET_INFO(...)
void setup(const std::string &name, ros::NodeHandle &nh)
void initializeOem7MessageUtil(ros::NodeHandle &nh)
double publish_delay_sec_
Delay after publishing each message; used to throttle output with static data sources.
bool getParam(const std::string &key, std::string &s) const
bool serviceOem7AbasciiCb(novatel_oem7_msgs::Oem7AbasciiCmd::Request &req, novatel_oem7_msgs::Oem7AbasciiCmd::Response &rsp)
#define NODELET_FATAL_STREAM(...)
ros::CallbackQueue timer_queue_
Dedicated queue for command requests.
long unknown_msg_num_
number of messages received that could not be identified.
ROSCPP_DECL void shutdown()
ros::Timer timer_
One time service callback.
const std::string & getOem7MessageName(int msg_id)
pluginlib::ClassLoader< novatel_oem7_driver::Oem7ReceiverIf > recvr_loader_
#define NODELET_DEBUG(...)
boost::shared_ptr< ros::AsyncSpinner > timer_spinner_
1 thread servicing the command queue.