7 const std::string name,
8 const std::shared_ptr<ros::Publisher> error_publisher,
9 const std::string server_ip,
10 const modbus_error_recovery_mode recovery,
11 const unsigned server_port):
13 error_publisher_(error_publisher),
16 ctx_(modbus_new_tcp(server_ip.c_str(), server_port))
19 throw std::runtime_error(
"Unable to allocate libmodbus context:\n" + std::string(modbus_strerror(errno)));
21 if (modbus_connect(
ctx_) == -1)
24 throw std::runtime_error(
"Modbus connection failed:\n" + std::string(modbus_strerror(errno)));
30 if (modbus_set_error_recovery(
ctx_, recovery) != 0)
33 throw std::runtime_error(
"Unable to set error recovery mode:\n" + std::string(modbus_strerror(errno)));
49 for (std::unique_ptr<std::thread> &thread :
threads_)
51 for (std::unique_ptr<std::thread> &thread : threads_)
72 for (std::size_t i(0); i <
threads_.size(); ++i)
73 threads_[i].reset(
new std::thread([
this, i]
84 using std::chrono::system_clock;
85 system_clock::time_point next_start_time(system_clock::now());
89 next_start_time +=
data_.at(index)->poll_rate_;
90 std::this_thread::sleep_until(next_start_time);
92 uint16_t reg_values[
data_.at(index)->number_of_registers_];
98 rc = modbus_read_registers(
100 data_.at(index)->start_register_address_,
101 data_.at(index)->number_of_registers_,
104 if (rc == -1 || (std::size_t)rc !=
data_.at(index)->number_of_registers_)
106 std_msgs::String error;
107 error.data =
data_.at(index)->topic_name_ +
": " + modbus_strerror(errno);
113 std::vector<uint16_t> regs;
114 for (std::size_t i(0); i <
data_.at(index)->number_of_registers_; ++i)
115 regs.emplace_back(reg_values[i]);
117 data_.at(index)->convertAndPublishData(regs);
std::shared_ptr< ros::NodeHandle > nh_
Handler(const std::shared_ptr< ros::NodeHandle > nh, const std::string name, const std::shared_ptr< ros::Publisher > error_pub, const std::string server_ip, const modbus_error_recovery_mode recovery=MODBUS_ERROR_RECOVERY_NONE, const unsigned server_port=MODBUS_TCP_DEFAULT_PORT)
std::shared_ptr< ros::Publisher > error_publisher_
std::vector< std::unique_ptr< std::thread > > threads_
void setData(const std::vector< std::shared_ptr< DataType >> &data)
const std::vector< std::shared_ptr< DataType > > getData()
std::shared_ptr< ros::NodeHandle > nh
void readData(const std::size_t index)
std::vector< std::shared_ptr< DataType > > data_
#define ROS_ERROR_STREAM(args)