scan_buffer.h
Go to the documentation of this file.
1 // Copyright (c) 2020-2021 Pilz GmbH & Co. KG
2 //
3 // This program is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU Lesser General Public License as published by
5 // the Free Software Foundation, either version 3 of the License, or
6 // (at your option) any later version.
7 //
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public License
14 // along with this program. If not, see <https://www.gnu.org/licenses/>.
15 
16 #ifndef PSEN_SCAN_V2_STANDALONE_SCAN_ROUND_H
17 #define PSEN_SCAN_V2_STANDALONE_SCAN_ROUND_H
18 
19 #include <exception>
20 
24 
26 {
27 namespace protocol_layer
28 {
32 class ScanRoundError : public std::runtime_error
33 {
34 public:
35  ScanRoundError(const std::string& msg) : std::runtime_error(msg){};
36 };
37 
42 {
43 public:
44  OutdatedMessageError(const std::string& msg = "Detected a MonitoringFrame from an earlier round. "
45  "The scan round will ignore it.")
46  : ScanRoundError(msg){};
47 };
48 
53 {
54 public:
55  ScanRoundEndedEarlyError(const std::string& msg = "Detected a MonitoringFrame from a new scan round before the old "
56  "one was complete."
57  " Dropping the incomplete round."
58  " (Please check the ethernet connection or contact PILZ support if "
59  "the error persists.)")
60  : ScanRoundError(msg){};
61 };
62 
67 {
68 public:
69  ScanRoundOversaturatedError(const std::string& msg = "Received too many MonitoringFrames for one scan round.")
70  : ScanRoundError(msg){};
71 };
72 
81 {
82 public:
83  ScanBuffer(const uint32_t& num_expected_msgs);
97 
102  void reset();
103  std::vector<data_conversion_layer::monitoring_frame::MessageStamped> currentRound();
104 
105  bool isRoundComplete();
106 
107 private:
109 
110 private:
111  std::vector<data_conversion_layer::monitoring_frame::MessageStamped> current_round_{};
112  const uint32_t num_expected_msgs_;
113  bool first_scan_round_ = true;
114 };
115 
116 inline ScanBuffer::ScanBuffer(const uint32_t& num_expected_msgs) : num_expected_msgs_(num_expected_msgs)
117 {
118 }
119 
120 inline void ScanBuffer::reset()
121 {
122  current_round_.clear();
123 }
124 
125 inline std::vector<data_conversion_layer::monitoring_frame::MessageStamped> ScanBuffer::currentRound()
126 {
127  return current_round_;
128 }
129 
131 {
132  return current_round_.size() == num_expected_msgs_;
133 }
134 
136 {
137  // Condition to fix the bug of the first scanCounter data of the Subscriber0
138  if (first_scan_round_ &&
140  {
141  first_scan_round_ = false;
142  }
143  else
144  {
145  if (current_round_.empty() || stamped_msg.msg_.scanCounter() == current_round_[0].msg_.scanCounter())
146  {
147  current_round_.push_back(stamped_msg);
148  if (current_round_.size() > num_expected_msgs_)
149  {
151  }
152  }
153  else if (stamped_msg.msg_.scanCounter() > current_round_[0].msg_.scanCounter())
154  {
155  startNewRound(stamped_msg);
156  }
157  else
158  {
159  throw OutdatedMessageError();
160  }
161  }
162 }
163 
165 {
166  bool old_round_undersaturated = current_round_.size() < num_expected_msgs_;
167  reset();
168  current_round_.push_back(stamped_msg);
169  if (old_round_undersaturated && !first_scan_round_)
170  {
171  throw ScanRoundEndedEarlyError();
172  }
173  first_scan_round_ = false;
174 }
175 } // namespace protocol_layer
176 } // namespace psen_scan_v2_standalone
177 
178 #endif // PSEN_SCAN_V2_STANDALONE_SCAN_ROUND_H
psen_scan_v2_standalone::protocol_layer::ScanBuffer::startNewRound
void startNewRound(const data_conversion_layer::monitoring_frame::MessageStamped &stamped_msg)
Definition: scan_buffer.h:164
psen_scan_v2_standalone::data_conversion_layer::monitoring_frame::MessageStamped::msg_
Message msg_
Definition: monitoring_frame_msg.h:111
psen_scan_v2_standalone::data_conversion_layer::monitoring_frame::Message::scannerId
configuration::ScannerId scannerId() const
Definition: monitoring_frame_msg.cpp:31
monitoring_frame_msg.h
psen_scan_v2_standalone::protocol_layer::ScanRoundOversaturatedError
Exception thrown if a scan round has to many messages.
Definition: scan_buffer.h:66
psen_scan_v2_standalone::protocol_layer::ScanRoundError::ScanRoundError
ScanRoundError(const std::string &msg)
Definition: scan_buffer.h:35
psen_scan_v2_standalone::protocol_layer::ScanBuffer::first_scan_round_
bool first_scan_round_
Definition: scan_buffer.h:113
psen_scan_v2_standalone::protocol_layer::ScanRoundEndedEarlyError::ScanRoundEndedEarlyError
ScanRoundEndedEarlyError(const std::string &msg="Detected a MonitoringFrame from a new scan round before the old " "one was complete." " Dropping the incomplete round." " (Please check the ethernet connection or contact PILZ support if " "the error persists.)")
Definition: scan_buffer.h:55
psen_scan_v2_standalone::protocol_layer::ScanBuffer::reset
void reset()
Readies the validator for a new validation round. This function has to be called whenever there is an...
Definition: scan_buffer.h:120
psen_scan_v2_standalone::protocol_layer::OutdatedMessageError
Exception thrown if the incoming frame has an outdated scan_counter.
Definition: scan_buffer.h:41
psen_scan_v2_standalone::protocol_layer::ScanBuffer::num_expected_msgs_
const uint32_t num_expected_msgs_
Definition: scan_buffer.h:112
psen_scan_v2_standalone::configuration::ScannerId::subscriber0
@ subscriber0
psen_scan_v2_standalone::data_conversion_layer::monitoring_frame::Message::scanCounter
uint32_t scanCounter() const
Definition: monitoring_frame_msg.cpp:46
psen_scan_v2_standalone::data_conversion_layer::monitoring_frame::MessageStamped
Wrapping class for a Message and its corresponding timestamp.
Definition: monitoring_frame_msg.h:109
psen_scan_v2_standalone::protocol_layer::ScanBuffer::isRoundComplete
bool isRoundComplete()
Definition: scan_buffer.h:130
psen_scan_v2_standalone::protocol_layer::ScanBuffer::ScanBuffer
ScanBuffer(const uint32_t &num_expected_msgs)
Definition: scan_buffer.h:116
psen_scan_v2_standalone::protocol_layer::ScanBuffer::currentRound
std::vector< data_conversion_layer::monitoring_frame::MessageStamped > currentRound()
Definition: scan_buffer.h:125
psen_scan_v2_standalone::protocol_layer::ScanBuffer::current_round_
std::vector< data_conversion_layer::monitoring_frame::MessageStamped > current_round_
Definition: scan_buffer.h:111
scanner_ids.h
psen_scan_v2_standalone::protocol_layer::OutdatedMessageError::OutdatedMessageError
OutdatedMessageError(const std::string &msg="Detected a MonitoringFrame from an earlier round. " "The scan round will ignore it.")
Definition: scan_buffer.h:44
psen_scan_v2_standalone::protocol_layer::ScanRoundError
Exception indicating problems with the monitoring frames of a scan round.
Definition: scan_buffer.h:32
psen_scan_v2_standalone::protocol_layer::ScanRoundOversaturatedError::ScanRoundOversaturatedError
ScanRoundOversaturatedError(const std::string &msg="Received too many MonitoringFrames for one scan round.")
Definition: scan_buffer.h:69
std
logging.h
psen_scan_v2_standalone
Root namespace in which the software components to communicate with the scanner (firmware-version: 2)...
Definition: udp_client.h:41
psen_scan_v2_standalone::protocol_layer::ScanRoundEndedEarlyError
Exception thrown if a new scan round started without the last one finishing.
Definition: scan_buffer.h:52
psen_scan_v2_standalone::protocol_layer::ScanBuffer::add
void add(const data_conversion_layer::monitoring_frame::MessageStamped &stamped_msg)
Adds the message to the current scan round.
Definition: scan_buffer.h:135
psen_scan_v2_standalone::protocol_layer::ScanBuffer
Buffers and validates monitoring frames for a scan round.
Definition: scan_buffer.h:80


psen_scan_v2
Author(s): Pilz GmbH + Co. KG
autogenerated on Sat Jun 22 2024 02:46:12