fifo.h
Go to the documentation of this file.
1 #include "sick_scan/sick_scan_base.h" /* Base definitions included in all header files, added by add_sick_scan_base_header.py. Do not edit this line. */
2 /*
3  * @brief fifo implements a thread-safe fifo.
4  *
5  * Copyright (C) 2020 Ing.-Buero Dr. Michael Lehning, Hildesheim
6  * Copyright (C) 2020 SICK AG, Waldkirch
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  * All rights reserved.
21  *
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions are met:
24  *
25  * * Redistributions of source code must retain the above copyright
26  * notice, this list of conditions and the following disclaimer.
27  * * Redistributions in binary form must reproduce the above copyright
28  * notice, this list of conditions and the following disclaimer in the
29  * documentation and/or other materials provided with the distribution.
30  * * Neither the name of SICK AG nor the names of its
31  * contributors may be used to endorse or promote products derived from
32  * this software without specific prior written permission
33  * * Neither the name of Ing.-Buero Dr. Michael Lehning nor the names of its
34  * contributors may be used to endorse or promote products derived from
35  * this software without specific prior written permission
36  *
37  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
38  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
39  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
40  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
41  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
43  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
44  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
45  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
47  * POSSIBILITY OF SUCH DAMAGE.
48  *
49  * Authors:
50  * Michael Lehning <michael.lehning@lehning.de>
51  *
52  * Copyright 2020 SICK AG
53  * Copyright 2020 Ing.-Buero Dr. Michael Lehning
54  *
55  */
56 #ifndef __SICK_SCANSEGMENT_XD_FIFO_H
57 #define __SICK_SCANSEGMENT_XD_FIFO_H
58 
59 #include <chrono>
60 #include <condition_variable>
61 #include <mutex>
62 #include <queue>
63 #include <thread>
64 
65 /*
66  * Shortcuts to use either std::chrono::high_resolution_clock or std::chrono::system_clock
67  */
68 typedef std::chrono::time_point<std::chrono::system_clock> fifo_timestamp;
69 typedef std::chrono::system_clock fifo_clock;
70 // typedef std::chrono::time_point<std::chrono::high_resolution_clock> fifo_timestamp;
71 // typedef std::chrono::high_resolution_clock fifo_clock;
72 
73 namespace sick_scansegment_xd
74 {
75  template <typename T> class Fifo
76  {
77  public:
78 
79  /*
80  * @brief Fifo default constructor
81  * @param[in] fifo_length max. fifo length (-1: unlimited, default: 20 for buffering 1 second at 20 Hz), elements will be removed from front if number of elements exceeds the fifo_length
82  */
83  Fifo(int fifo_length = 20) : m_fifo_length(fifo_length), m_shutdown(false), m_num_messages_received(0), m_timestamp_last_msg_received() {}
84 
85  /*
86  * @brief Fifo destructor
87  */
88  virtual ~Fifo() {}
89 
90  /*
91  * @brief Pushes an element to the end of the fifo and returns the new number of elements in the fifo.
92  */
93  virtual size_t Push(const T& element, const fifo_timestamp timestamp = fifo_clock::now(), size_t counter = 0)
94  {
95  std::unique_lock<std::mutex> lock(m_mutex);
96  m_queue.push(std::make_tuple(element, timestamp, counter));
99  while(m_fifo_length > 0 && m_queue.size() > m_fifo_length)
100  m_queue.pop();
101  m_cond.notify_all();
102  return m_queue.size();
103  }
104 
105  /*
106  * @brief Pops an element from the front of the fifo.
107  */
108  virtual bool Pop(T& element, fifo_timestamp& timestamp, size_t& counter)
109  {
110  std::unique_lock<std::mutex> lock(m_mutex);
111  while (!m_shutdown && m_queue.empty())
112  {
113  m_cond.wait(lock);
114  }
115  if (m_shutdown || m_queue.empty())
116  return false;
117  const fifo_element& queue_front = m_queue.front();
118  element = std::get<0>(queue_front);
119  timestamp = std::get<1>(queue_front);
120  counter = std::get<2>(queue_front);
121  m_queue.pop();
122  return true;
123  }
124 
125  /*
126  * @brief Returns the number of elements in the fifo.
127  */
128  virtual size_t Size(void)
129  {
130  std::unique_lock<std::mutex> lock(m_mutex);
131  return m_queue.size();
132  }
133 
134  /*
135  * @brief Sets the fifo in shutdown mode and interrupts a waiting Pop() call.
136  * After Shutdown(), any Pop() will return immediately with false.
137  */
138  virtual void Shutdown(void)
139  {
140  std::unique_lock<std::mutex> lock(m_mutex);
141  m_shutdown = true;
142  m_cond.notify_all();
143  }
144 
145  /*
146  * @brief Returns the total number of messages pushed to fifo since constructed
147  */
148  virtual size_t TotalMessagesPushed()
149  {
150  std::unique_lock<std::mutex> lock(m_mutex);
152  }
153 
154  /*
155  * @brief Returns the time in seconds since the last message has been pushed (i.e. since last message received from lidar)
156  */
157  virtual double SecondsSinceLastPush()
158  {
159  std::unique_lock<std::mutex> lock(m_mutex);
161  }
162 
163  /*
164  * @brief Returns the duration in seconds between a push (start) and pop (end) timestamps
165  */
167  {
168  return (1.0e-9) * (std::chrono::duration_cast<std::chrono::nanoseconds>(timestamp_end - timestamp_start)).count(); // std::chrono::duration::count() in nanoseconds
169  }
170 
171 
172  protected:
173 
174  typedef std::tuple<T, fifo_timestamp, size_t> fifo_element;
175  std::queue<fifo_element> m_queue; // queue to buffer the elements in a fifo
176  std::mutex m_mutex; // mutex to protect multithreaded queue access
177  std::condition_variable m_cond; // condition to wait and notify on push and pop
178  int m_fifo_length; // max. fifo length (-1: unlimited, default: 20 for buffering 1 second at 20 Hz), elements will be removed from front if number of elements exceeds the fifo_length
179  bool m_shutdown; // if true, fifo is in shutdown mode and Pop returns immediately, default: false
180  size_t m_num_messages_received; // total number of messages pushed to fifo
181  fifo_timestamp m_timestamp_last_msg_received; // timestamp of last message pushed to fifo
182  };
183 
184  /*
185  * Fifo for any payload, i.e. a chunk of bytes
186  */
187  class PayloadFifo : public Fifo<std::vector<uint8_t>>
188  {
189  public:
190  /*
191  * @brief PayloadFifo default constructor
192  * @param[in] fifo_length max. fifo length (-1: unlimited, default: 20 for buffering 1 second at 20 Hz), elements will be removed from front if number of elements exceeds the fifo_length
193  */
194  PayloadFifo(int fifo_length = 20) : Fifo<std::vector<uint8_t>>(fifo_length) {}
195  };
196 
197 } // namespace sick_scansegment_xd
198 #endif // __SICK_SCANSEGMENT_XD_FIFO_H
sick_scansegment_xd::PayloadFifo
Definition: fifo.h:187
sick_scansegment_xd::Fifo::m_cond
std::condition_variable m_cond
Definition: fifo.h:177
sick_scansegment_xd::Fifo::Size
virtual size_t Size(void)
Definition: fifo.h:128
sick_scansegment_xd::Fifo::m_mutex
std::mutex m_mutex
Definition: fifo.h:176
sick_scansegment_xd::Fifo< std::vector< uint8_t > >::fifo_element
std::tuple< std::vector< uint8_t >, fifo_timestamp, size_t > fifo_element
Definition: fifo.h:174
sick_scansegment_xd::Fifo::m_queue
std::queue< fifo_element > m_queue
Definition: fifo.h:175
sick_scansegment_xd
Definition: include/sick_scansegment_xd/common.h:138
sick_scansegment_xd::Fifo::Pop
virtual bool Pop(T &element, fifo_timestamp &timestamp, size_t &counter)
Definition: fifo.h:108
ROS::now
ROS::Time now(void)
Definition: ros_wrapper.cpp:116
sick_scansegment_xd::Fifo::Push
virtual size_t Push(const T &element, const fifo_timestamp timestamp=fifo_clock::now(), size_t counter=0)
Definition: fifo.h:93
imu_delay_tester.timestamp
timestamp
Definition: imu_delay_tester.py:142
sick_scansegment_xd::Fifo::m_shutdown
bool m_shutdown
Definition: fifo.h:179
sick_scansegment_xd::Fifo
Definition: fifo.h:75
multiscan_pcap_player.timestamp_end
float timestamp_end
Definition: multiscan_pcap_player.py:196
sick_scansegment_xd::Fifo::Seconds
static double Seconds(const fifo_timestamp &timestamp_start, const fifo_timestamp &timestamp_end=fifo_clock::now())
Definition: fifo.h:166
sick_scansegment_xd::Fifo::~Fifo
virtual ~Fifo()
Definition: fifo.h:88
fifo_timestamp
std::chrono::time_point< std::chrono::system_clock > fifo_timestamp
Definition: fifo.h:68
sick_scansegment_xd::Fifo::SecondsSinceLastPush
virtual double SecondsSinceLastPush()
Definition: fifo.h:157
imu_delay_tester.timestamp_start
float timestamp_start
Definition: imu_delay_tester.py:133
sick_scansegment_xd::Fifo::TotalMessagesPushed
virtual size_t TotalMessagesPushed()
Definition: fifo.h:148
fifo_clock
std::chrono::system_clock fifo_clock
Definition: fifo.h:69
sick_scansegment_xd::PayloadFifo::PayloadFifo
PayloadFifo(int fifo_length=20)
Definition: fifo.h:194
sick_scansegment_xd::Fifo::Fifo
Fifo(int fifo_length=20)
Definition: fifo.h:83
std
sick_scan_base.h
sick_scansegment_xd::Fifo::m_timestamp_last_msg_received
fifo_timestamp m_timestamp_last_msg_received
Definition: fifo.h:181
sick_scansegment_xd::Fifo::m_fifo_length
int m_fifo_length
Definition: fifo.h:178
sick_scansegment_xd::Fifo::m_num_messages_received
size_t m_num_messages_received
Definition: fifo.h:180
sick_scansegment_xd::Fifo::Shutdown
virtual void Shutdown(void)
Definition: fifo.h:138


sick_scan_xd
Author(s): Michael Lehning , Jochen Sprickerhof , Martin Günther
autogenerated on Fri Oct 25 2024 02:47:08