Go to the documentation of this file.
21 namespace protocol_layer
36 , control_client_(control_msg_callback,
37 control_error_callback,
38 config_.hostUDPPortControl(),
40 config_.scannerControlPort())
41 , data_client_(data_msg_callback,
43 config_.hostUDPPortData(),
45 config_.scannerDataPort())
46 , scanner_started_callback_(scanner_started_callback)
47 , scanner_stopped_callback_(scanner_stopped_callback)
48 , start_error_callback_(start_error_callback)
49 , stop_error_callback_(stop_error_callback)
50 , inform_user_about_laser_scan_callback_(laser_scan_callback)
51 , start_timeout_callback_(start_timeout_callback)
52 , monitoring_frame_timeout_callback_(monitoring_frame_timeout_callback)
55 for (
int i = 0; i <
config.nrSubscribers(); i++)
65 #define DEFAULT_ON_ENTRY_IMPL(state_name)\
66 template <class Event, class FSM>\
67 void ScannerProtocolDef::state_name::on_entry(Event const&, FSM& fsm)\
69 PSENSCAN_DEBUG("StateMachine", "Entering state: " #state_name);\
72 #define DEFAULT_ON_EXIT_IMPL(state_name)\
73 template <class Event, class FSM>\
74 void ScannerProtocolDef::state_name::on_exit(Event const&, FSM& fsm)\
76 PSENSCAN_DEBUG("StateMachine", "Exiting state: " #state_name);\
79 #define DEFAULT_STATE_IMPL(state_name)\
80 DEFAULT_ON_ENTRY_IMPL(state_name)\
81 DEFAULT_ON_EXIT_IMPL(state_name)
89 template <
class Event,
class FSM>
90 void ScannerProtocolDef::Idle::on_exit(Event
const& , FSM& fsm)
93 fsm.control_client_.startAsyncReceiving();
94 fsm.data_client_.startAsyncReceiving();
97 template <
class Event,
class FSM>
98 void ScannerProtocolDef::WaitForStartReply::on_entry(Event
const& , FSM& fsm)
100 PSENSCAN_DEBUG(
"StateMachine",
"Entering state: WaitForStartReply");
102 fsm.start_reply_watchdog_ = fsm.watchdog_factory_.create(
WATCHDOG_TIMEOUT, fsm.start_timeout_callback_);
105 template <
class Event,
class FSM>
106 void ScannerProtocolDef::WaitForStartReply::on_exit(Event
const& , FSM& fsm)
108 PSENSCAN_DEBUG(
"StateMachine",
"Exiting state: WaitForStartReply");
110 fsm.start_reply_watchdog_.reset();
113 template <
class Event,
class FSM>
114 void ScannerProtocolDef::WaitForMonitoringFrame::on_entry(Event
const& , FSM& fsm)
116 PSENSCAN_DEBUG(
"StateMachine",
"Entering state: WaitForMonitoringFrame");
117 for (
auto& sb : fsm.scan_buffers_)
121 fsm.monitoring_frame_watchdog_ =
122 fsm.watchdog_factory_.create(
WATCHDOG_TIMEOUT, fsm.monitoring_frame_timeout_callback_);
125 template <
class Event,
class FSM>
126 void ScannerProtocolDef::WaitForMonitoringFrame::on_exit(Event
const& , FSM& fsm)
128 PSENSCAN_DEBUG(
"StateMachine",
"Exiting state: WaitForMonitoringFrame");
130 fsm.monitoring_frame_watchdog_.reset();
133 template <
class Event,
class FSM>
134 void ScannerProtocolDef::Stopped::on_entry(Event
const& , FSM& )
156 PSENSCAN_INFO(
"StateMachine",
"No host ip set! Using local ip: {}", host_ip.to_string());
164 PSENSCAN_DEBUG(
"StateMachine",
"Action: handleStartRequestTimeout");
166 "Timeout while waiting for the scanner to start! Retrying... "
167 "(Please check the ethernet connection or contact PILZ support if the error persists.)");
214 *(reply_event.
data_)) };
216 fmt::format(
"Unknown result code {:#04x} in start reply.",
static_cast<uint32_t
>(msg.result())));
227 *(reply_event.
data_)) };
228 stop_error_callback_(fmt::format(
"Unknown result code {:#04x} in stop reply.",
static_cast<uint32_t
>(msg.result())));
278 const std::vector<data_conversion_layer::monitoring_frame::MessageStamped>& stamped_msgs)
296 const std::vector<data_conversion_layer::monitoring_frame::MessageStamped>& stamped_msgs)
298 if (std::all_of(stamped_msgs.begin(), stamped_msgs.end(), [](
const auto& stamped_msg) {
299 return stamped_msg.msg_.measurements().empty();
302 PSENSCAN_DEBUG(
"StateMachine",
"No measurement data in current monitoring frame(s), skipping laser scan callback.");
310 PSENSCAN_DEBUG(
"StateMachine",
"Action: handleMonitoringFrameTimeout");
313 "Timeout while waiting for MonitoringFrame message."
314 " (Please check the ethernet connection or contact PILZ support if the error persists.)");
321 :
std::runtime_error(error_msg)
350 *(reply_event.
data_)) };
357 *(reply_event.
data_)) };
364 *(reply_event.
data_)) };
371 *(reply_event.
data_)) };
378 *(reply_event.
data_)) };
385 *(reply_event.
data_)) };
419 using recursive_transition_table =
typename boost::msm::back::recursive_get_transition_table<FSM>::type;
420 using states =
typename boost::msm::back::generate_state_set<recursive_transition_table>::type;
422 std::string mangle_state_name;
423 boost::mpl::for_each<states, boost::msm::wrap<boost::mpl::placeholders::_1> >(
424 boost::msm::back::get_state_name<recursive_transition_table>(mangle_state_name, state_id));
425 const auto full_name{ boost::core::demangle(mangle_state_name.c_str()) };
426 return full_name.substr(full_name.rfind(
"::") + 2);
432 const auto full_name{ boost::core::demangle(
typeid(
t).name()) };
433 return full_name.substr(full_name.rfind(
"::") + 2);
437 template <
class FSM,
class Event>
440 PSENSCAN_ERROR(
"StateMachine",
"Received error \"{}\". Shutting down now.", exception.what());
446 template <
class FSM,
class Event>
450 "No transition in state \"{}\" for event \"{}\".",
451 getStateName<FSM>(state),
460 PSENSCAN_WARN(
"StateMachine",
"Received monitoring frame despite not waiting for it");
bool isAcceptedStopReply(scanner_events::RawReplyReceived const &reply_event)
ScannerConfiguration config_
const std::size_t num_bytes_
#define PSENSCAN_WARN(name,...)
void notifyUserAboutRefusedStartReply(scanner_events::RawReplyReceived const &reply_event)
configuration::ScannerId scannerId() const
void checkForInternalErrors(const data_conversion_layer::scanner_reply::Message &msg)
Exception thrown when something goes wrong with the scanner reply.
bool isUnknownStartReply(scanner_events::RawReplyReceived const &reply_event)
constexpr OperationResult result() const
#define DEFAULT_STATE_IMPL(state_name)
const ScannerStartedCallback scanner_started_callback_
void notifyUserAboutUnknownStopReply(scanner_events::RawReplyReceived const &reply_event)
void write(const data_conversion_layer::RawData &data)
Asynchronously sends the specified data to the other endpoint.
Exception thrown if an additional field was missing during deserialization of a Message.
bool isStartReply(data_conversion_layer::scanner_reply::Message const &msg)
void exception_caught(Event const &event, FSM &fsm, std::exception &exception)
bool framesContainMeasurements(const std::vector< data_conversion_layer::monitoring_frame::MessageStamped > &stamped_msg)
communication_layer::UdpClientImpl data_client_
void handleMonitoringFrame(const scanner_events::RawMonitoringFrameReceived &event)
std::function< void()> ScannerStoppedCallback
void stop()
Stops the underlying io_service so that no messages are received anymore.
InternalScannerReplyError(const std::string &error_msg)
void informUserAboutTheScanData(const data_conversion_layer::monitoring_frame::MessageStamped &stamped_msg)
RawData serialize(const data_conversion_layer::start_request::Message &start_request, const uint32_t &seq_number=DEFAULT_SEQ_NUMBER)
Received Start- or Stop-Reply message from scanner device.
std::function< void(const LaserScan &)> InformUserAboutLaserScanCallback
#define PSENSCAN_DEBUG(name,...)
bool isRefusedReply(data_conversion_layer::scanner_reply::Message const &msg)
void sendMessageWithMeasurements(const std::vector< data_conversion_layer::monitoring_frame::MessageStamped > &stamped_msg)
static constexpr uint32_t DEFAULT_NUM_MSG_PER_ROUND
Timeout while waiting for scanner device to start.
: Exception thrown if data received from the scanner hardware could not be processed according to pro...
bool isRefusedStopReply(scanner_events::RawReplyReceived const &reply_event)
constexpr Type type() const
bool isUnknownStopReply(scanner_events::RawReplyReceived const &reply_event)
void notifyUserAboutRefusedStopReply(scanner_events::RawReplyReceived const &reply_event)
static LaserScan toLaserScan(const std::vector< data_conversion_layer::monitoring_frame::MessageStamped > &stamped_msgs)
Converts monitoring_frames of a scan_round to the user friendly LaserScan type sent by the IScanner::...
#define DEFAULT_ON_ENTRY_IMPL(state_name)
std::function< void()> ScannerStartedCallback
bool hasDiagnosticMessagesField() const
static ScannerId subscriber_number_to_scanner_id(uint8_t nr)
void handleMonitoringFrameTimeout(const scanner_events::MonitoringFrameTimeout &event)
std::unique_ptr< util::Watchdog > monitoring_frame_watchdog_
Higher level data type representing a reply message from the scanner.
const data_conversion_layer::RawDataConstPtr data_
void checkForChangedActiveZoneset(const data_conversion_layer::monitoring_frame::Message &msg)
void no_transition(Event const &event, FSM &, int state)
void notifyUserAboutStart(scanner_events::RawReplyReceived const &reply_event)
uint32_t scanCounter() const
bool isUnknownReply(data_conversion_layer::scanner_reply::Message const &msg)
Wrapping class for a Message and its corresponding timestamp.
bool isRefusedStartReply(scanner_events::RawReplyReceived const &reply_event)
const InformUserAboutLaserScanCallback inform_user_about_laser_scan_callback_
#define PSENSCAN_INFO(name,...)
ScannerProtocolDef(const ScannerConfiguration &config, const communication_layer::NewMessageCallback &control_msg_callback, const communication_layer::ErrorCallback &control_error_callback, const communication_layer::ErrorCallback &start_error_callback, const communication_layer::ErrorCallback &stop_error_callback, const communication_layer::NewMessageCallback &data_msg_callback, const communication_layer::ErrorCallback &data_error_callback, const ScannerStartedCallback &scanner_started_callback, const ScannerStoppedCallback &scanner_stopped_callback, const InformUserAboutLaserScanCallback &laser_scan_callback, const TimeoutCallback &start_timeout_callback, const TimeoutCallback &monitoring_frame_timeout_callback)
Message deserialize(const data_conversion_layer::RawData &data)
std::vector< diagnostic::Message > diagnosticMessages() const
static std::string classNameShort(const T &t)
std::string formatRange(const T &range)
#define DEFAULT_ON_EXIT_IMPL(state_name)
#define PSENSCAN_WARN_THROTTLE(period, name,...)
Timeout while waiting for MonitoringFrame.
const ScannerStoppedCallback scanner_stopped_callback_
const StartErrorCallback start_error_callback_
uint8_t activeZoneset() const
static std::string getStateName(const int &state_id)
Received monitoring frame from scanner device.
Exception indicating problems with the monitoring frames of a scan round.
boost::optional< uint32_t > hostIp() const
static constexpr std::chrono::milliseconds WATCHDOG_TIMEOUT
monitoring_frame::Message deserialize(const data_conversion_layer::RawData &data, const std::size_t &num_bytes)
void handleStartRequestTimeout(const scanner_events::StartTimeout &event)
bool fragmentedScansEnabled() const
Root namespace in which the software components to communicate with the scanner (firmware-version: 2)...
void notifyUserAboutUnknownStartReply(scanner_events::RawReplyReceived const &reply_event)
boost::asio::ip::address_v4 hostIp()
Returns local ip address of current socket connection.
std::unordered_map< ScannerId, ScanBuffer > scan_buffers_
#define PSENSCAN_ERROR(name,...)
bool isStopReply(data_conversion_layer::scanner_reply::Message const &msg)
const StopErrorCallback stop_error_callback_
Higher level data type representing a single monitoring frame.
boost::optional< data_conversion_layer::monitoring_frame::Message > zoneset_reference_msg_
std::function< void(const std::string &)> ErrorCallback
std::function< void(const data_conversion_layer::RawDataConstPtr &, const std::size_t &, const int64_t ×tamp)> NewMessageCallback
void checkForDiagnosticErrors(const data_conversion_layer::monitoring_frame::Message &msg)
void sendStopRequest(const T &event)
bool isAcceptedReply(data_conversion_layer::scanner_reply::Message const &msg)
std::function< void()> TimeoutCallback
Higher level data type representing a scanner start request.
void sendStartRequest(const T &event)
const data_conversion_layer::RawDataConstPtr data_
Contains the events needed to define and implement the scanner protocol.
Buffers and validates monitoring frames for a scan round.
geometry_msgs::TransformStamped t
communication_layer::UdpClientImpl control_client_
void notifyUserAboutStop(scanner_events::RawReplyReceived const &reply_event)
bool isAcceptedStartReply(scanner_events::RawReplyReceived const &reply_event)
Higher level data type storing the configuration details of the scanner like scanner IP,...
psen_scan_v2
Author(s): Pilz GmbH + Co. KG
autogenerated on Sat Jun 22 2024 02:46:12