pilz_modbus_client.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018 Pilz GmbH & Co. KG
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8 
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU Lesser General Public License for more details.
13 
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef PRBT_HARDWARE_SUPPORT_CLIENT_NODE_H
19 #define PRBT_HARDWARE_SUPPORT_CLIENT_NODE_H
20 
21 #include <atomic>
22 #include <mutex>
23 #include <queue>
24 
25 #include <boost/optional.hpp>
26 
27 #include <ros/ros.h>
28 #include <std_msgs/UInt16MultiArray.h>
29 
32 #include <prbt_hardware_support/WriteModbusRegister.h>
33 
34 namespace prbt_hardware_support
35 {
40 {
41  typedef std::unique_ptr<ModbusClient> ModbusClientUniquePtr;
42 
43 public:
54  PilzModbusClient(ros::NodeHandle& nh, const std::vector<unsigned short>& registers_to_read,
55  ModbusClientUniquePtr modbus_client, unsigned int response_timeout_ms,
56  const std::string& modbus_read_topic_name, const std::string& modbus_write_service_name,
57  double read_frequency_hz = DEFAULT_MODBUS_READ_FREQUENCY_HZ);
58 
59 public:
66  bool init(const char* ip, unsigned int port);
67 
76  bool init(const char* ip, unsigned int port, int retries, const ros::Duration& timeout_ms);
77 
87  void run();
88 
92  void terminate();
93 
98  bool isRunning();
99 
103  std::vector<std::vector<unsigned short>> static splitIntoBlocks(std::vector<unsigned short>& in);
104 
105 private:
106  void sendDisconnectMsg();
107 
112  bool modbus_write_service_cb(WriteModbusRegister::Request& req, WriteModbusRegister::Response& res);
113 
114 private:
118  enum State
119  {
124  };
125 
127  std::vector<unsigned short> registers_to_read_;
128 
130  const unsigned int RESPONSE_TIMEOUT_MS;
132  const double READ_FREQUENCY_HZ;
133 
134 private:
135  static constexpr double DEFAULT_MODBUS_READ_FREQUENCY_HZ{ 500 };
136  static constexpr int DEFAULT_QUEUE_SIZE_MODBUS{ 1 };
137 
138 private:
139  std::atomic<State> state_{ State::not_initialized };
140  std::atomic_bool stop_run_{ false };
141  ModbusClientUniquePtr modbus_client_;
145 
147  std::queue<ModbusRegisterBlock> write_reg_blocks_;
148 };
149 
151 {
152  stop_run_ = true;
153 }
154 
156 {
157  return state_.load() == State::running;
158 }
159 
160 inline bool PilzModbusClient::modbus_write_service_cb(WriteModbusRegister::Request& req,
161  WriteModbusRegister::Response& res)
162 {
163  std::lock_guard<std::mutex> lock(write_reg_blocks_mutex_);
164  write_reg_blocks_.emplace(req.holding_register_block);
165  res.success = true;
166  return true;
167 }
168 
169 } // namespace prbt_hardware_support
170 
171 #endif // PRBT_HARDWARE_SUPPORT_CLIENT_NODE_H
std::vector< unsigned short > registers_to_read_
Registers which have to be read.
void run()
Publishes the register values as messages.
bool init(const char *ip, unsigned int port)
Tries to connect to a modbus server.
static std::vector< std::vector< unsigned short > > splitIntoBlocks(std::vector< unsigned short > &in)
Splits a vector of integers into a vector of vectors with consecutive groups.
const unsigned int RESPONSE_TIMEOUT_MS
Defines how long we wait for a response from the Modbus-server.
bool isRunning()
True if &#39;run()&#39; method is active, false if &#39;run()&#39; method is not active or, currently, finishing.
bool modbus_write_service_cb(WriteModbusRegister::Request &req, WriteModbusRegister::Response &res)
Stores the register which have to be send to the modbus server in a local buffer for further processi...
PilzModbusClient(ros::NodeHandle &nh, const std::vector< unsigned short > &registers_to_read, ModbusClientUniquePtr modbus_client, unsigned int response_timeout_ms, const std::string &modbus_read_topic_name, const std::string &modbus_write_service_name, double read_frequency_hz=DEFAULT_MODBUS_READ_FREQUENCY_HZ)
Sets up publisher. To open the modbus connection call PilzModbusClient::init.
Connects to a modbus server and publishes the received data into ROS.
static constexpr double DEFAULT_MODBUS_READ_FREQUENCY_HZ
std::unique_ptr< ModbusClient > ModbusClientUniquePtr
std::queue< ModbusRegisterBlock > write_reg_blocks_
void terminate()
Ends the infinite loop started in method &#39;run()&#39;.
const double READ_FREQUENCY_HZ
Defines how often the Modbus registers are read in.


prbt_hardware_support
Author(s):
autogenerated on Sun Oct 25 2020 03:13:00