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 
23 
25 {
26 namespace protocol_layer
27 {
31 class ScanRoundError : public std::runtime_error
32 {
33 public:
34  ScanRoundError(const std::string& msg) : std::runtime_error(msg){};
35 };
36 
41 {
42 public:
43  OutdatedMessageError(const std::string& msg = "Detected a MonitoringFrame from an earlier round. "
44  " The scan round will ignore it.")
45  : ScanRoundError(msg){};
46 };
47 
52 {
53 public:
54  ScanRoundEndedEarlyError(const std::string& msg = "Detected a MonitoringFrame from a new scan round before the old "
55  "one was complete."
56  " Dropping the incomplete round."
57  " (Please check the ethernet connection or contact PILZ support if "
58  "the error persists.)")
59  : ScanRoundError(msg){};
60 };
61 
66 {
67 public:
68  ScanRoundOversaturatedError(const std::string& msg = "Received too many MonitoringFrames for one scan round.")
69  : ScanRoundError(msg){};
70 };
71 
80 {
81 public:
82  ScanBuffer(const uint32_t& num_expected_msgs);
96 
101  void reset();
102  std::vector<data_conversion_layer::monitoring_frame::MessageStamped> currentRound();
103 
104  bool isRoundComplete();
105 
106 private:
108 
109 private:
110  std::vector<data_conversion_layer::monitoring_frame::MessageStamped> current_round_{};
111  const uint32_t& num_expected_msgs_;
112  bool first_scan_round_ = true;
113 };
114 
115 inline ScanBuffer::ScanBuffer(const uint32_t& num_expected_msgs) : num_expected_msgs_(num_expected_msgs)
116 {
117 }
118 
119 inline void ScanBuffer::reset()
120 {
121  current_round_.clear();
122 }
123 
124 inline std::vector<data_conversion_layer::monitoring_frame::MessageStamped> ScanBuffer::currentRound()
125 {
126  return current_round_;
127 }
128 
130 {
131  return current_round_.size() == num_expected_msgs_;
132 }
133 
135 {
136  if (current_round_.empty() || stamped_msg.msg_.scanCounter() == current_round_[0].msg_.scanCounter())
137  {
138  current_round_.push_back(stamped_msg);
139  if (current_round_.size() > num_expected_msgs_)
140  {
142  }
143  }
144  else if (stamped_msg.msg_.scanCounter() > current_round_[0].msg_.scanCounter())
145  {
146  startNewRound(stamped_msg);
147  }
148  else
149  {
150  throw OutdatedMessageError();
151  }
152 }
153 
155 {
156  bool old_round_undersaturated = current_round_.size() < num_expected_msgs_;
157  reset();
158  current_round_.push_back(stamped_msg);
159  if (old_round_undersaturated && !first_scan_round_)
160  {
161  throw ScanRoundEndedEarlyError();
162  }
163  first_scan_round_ = false;
164 }
165 } // namespace protocol_layer
166 } // namespace psen_scan_v2_standalone
167 
168 #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:154
psen_scan_v2_standalone::data_conversion_layer::monitoring_frame::MessageStamped::msg_
Message msg_
Definition: monitoring_frame_msg.h:111
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:65
psen_scan_v2_standalone::protocol_layer::ScanRoundError::ScanRoundError
ScanRoundError(const std::string &msg)
Definition: scan_buffer.h:34
psen_scan_v2_standalone::protocol_layer::ScanBuffer::first_scan_round_
bool first_scan_round_
Definition: scan_buffer.h:112
psen_scan_v2_standalone::protocol_layer::ScanBuffer::num_expected_msgs_
const uint32_t & num_expected_msgs_
Definition: scan_buffer.h:111
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:54
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:119
psen_scan_v2_standalone::protocol_layer::OutdatedMessageError
Exception thrown if the incoming frame has an outdated scan_counter.
Definition: scan_buffer.h:40
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:129
psen_scan_v2_standalone::protocol_layer::ScanBuffer::ScanBuffer
ScanBuffer(const uint32_t &num_expected_msgs)
Definition: scan_buffer.h:115
psen_scan_v2_standalone::protocol_layer::ScanBuffer::currentRound
std::vector< data_conversion_layer::monitoring_frame::MessageStamped > currentRound()
Definition: scan_buffer.h:124
psen_scan_v2_standalone::protocol_layer::ScanBuffer::current_round_
std::vector< data_conversion_layer::monitoring_frame::MessageStamped > current_round_
Definition: scan_buffer.h:110
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:43
psen_scan_v2_standalone::protocol_layer::ScanRoundError
Exception indicating problems with the monitoring frames of a scan round.
Definition: scan_buffer.h:31
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:68
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:51
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:134
psen_scan_v2_standalone::protocol_layer::ScanBuffer
Buffers and validates monitoring frames for a scan round.
Definition: scan_buffer.h:79


psen_scan_v2
Author(s): Pilz GmbH + Co. KG
autogenerated on Sat Nov 25 2023 03:46:26