@@ -133,38 +133,48 @@ YesenseDriver::~YesenseDriver()
133133 {
134134 serial_.close ();
135135 }
136- data_buffer_ptr_.reset ();
137136
138137 configured_ = false ;
138+ cv_data_.notify_all ();
139139 deseralize_thread_.join ();
140+
141+ data_buffer_ptr_.reset ();
140142}
141143
142144void YesenseDriver::run ()
143145{
144146 try
145147 {
146- rclcpp::Rate rate (100000 );
147-
148148 while (rclcpp::ok ())
149149 {
150- // read data from serial
151- if (serial_. available () )
150+ size_t avail = serial_. available ();
151+ if (avail > 0 )
152152 {
153- data_ = serial_.read (serial_. available () );
153+ data_ = serial_.read (avail );
154154
155+ if (!data_.empty ())
155156 {
156- std::lock_guard<std::mutex> lock (m_mutex_);
157-
158- for (size_t i=0 ;i<data_.length ();i++)
159157 {
160- data_buffer_ptr_->push_back (data_[i]);
158+ std::lock_guard<std::mutex> lock (m_mutex_);
159+ if (data_buffer_ptr_->size () + data_.size () > kMaxPendingBytes )
160+ {
161+ RCLCPP_WARN_THROTTLE (node_->get_logger (), *node_->get_clock (), 1000 ,
162+ " IMU parser falling behind, dropping %zu buffered bytes" ,
163+ data_buffer_ptr_->size ());
164+ data_buffer_ptr_->clear ();
165+ }
166+ for (char c : data_)
167+ data_buffer_ptr_->push_back (c);
161168 }
169+ cv_data_.notify_one ();
162170 }
163-
171+ }
172+ else
173+ {
174+ std::this_thread::sleep_for (std::chrono::milliseconds (1 ));
164175 }
165176
166177 rclcpp::spin_some (node_);
167- rate.sleep ();
168178 }
169179
170180 RCLCPP_WARN (node_->get_logger (), " ROS Exited !" );
@@ -1244,7 +1254,7 @@ void YesenseDriver::_spin()
12441254
12451255void YesenseDriver::spin ()
12461256{
1247- rclcpp::Rate rate ( 100000 ) ;
1257+ std::deque< char > local_buf ;
12481258
12491259 uint8_t data = 0x00 ;
12501260 uint8_t prev_data = 0x00 ;
@@ -1256,13 +1266,18 @@ void YesenseDriver::spin()
12561266
12571267 while (configured_)
12581268 {
1259- while (!data_buffer_ptr_->empty ())
1269+ // Block until data is available, then swap the entire shared buffer at once.
1270+ // This eliminates both the 100kHz busy-wait and per-byte mutex acquisitions.
12601271 {
1261- {
1262- std::lock_guard<std::mutex> lock (m_mutex_);
1263- data = uint8_t (data_buffer_ptr_->front ());
1264- data_buffer_ptr_->pop_front ();
1265- }
1272+ std::unique_lock<std::mutex> lock (m_mutex_);
1273+ cv_data_.wait (lock, [this ]{ return !data_buffer_ptr_->empty () || !configured_; });
1274+ std::swap (local_buf, *data_buffer_ptr_);
1275+ }
1276+
1277+ while (!local_buf.empty ())
1278+ {
1279+ data = uint8_t (local_buf.front ());
1280+ local_buf.pop_front ();
12661281
12671282 if (mode_ == MODE_MESSAGE) /* message data being recieved */
12681283 {
@@ -1553,8 +1568,6 @@ void YesenseDriver::spin()
15531568 bytes_ = 0 ;
15541569 }
15551570 }
1556-
1557- rate.sleep ();
15581571 }
15591572}
15601573
0 commit comments