r2000_node.cpp
Go to the documentation of this file.
1 // Copyright (c) 2014, Pepperl+Fuchs GmbH, Mannheim
2 // Copyright (c) 2014, Denis Dillenberger
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification,
6 // are permitted provided that the following conditions are met:
7 //
8 // * Redistributions of source code must retain the above copyright notice, this
9 // list of conditions and the following disclaimer.
10 //
11 // * Redistributions in binary form must reproduce the above copyright notice, this
12 // list of conditions and the following disclaimer in the documentation and/or
13 // other materials provided with the distribution.
14 //
15 // * Neither the name of Pepperl+Fuchs nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23 // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26 // ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 
30 #include "r2000_node.h"
31 #include <sensor_msgs/LaserScan.h>
33 
34 namespace pepperl_fuchs {
35 
36 //-----------------------------------------------------------------------------
38 {
39  driver_ = 0;
40  // Reading and checking parameters
41  //-------------------------------------------------------------------------
42  nh_.param("frame_id", frame_id_, std::string("/scan"));
43  nh_.param("scanner_ip",scanner_ip_,std::string(""));
44  nh_.param("scan_frequency",scan_frequency_,35);
45  nh_.param("samples_per_scan",samples_per_scan_,3600);
46 
47  if( scanner_ip_ == "" )
48  {
49  std::cerr << "IP of laser range finder not set!" << std::endl;
50  return;
51  }
52 
53  if( !connect() )
54  return;
55 
56  // Declare publisher and create timer
57  //-------------------------------------------------------------------------
58  scan_publisher_ = nh_.advertise<sensor_msgs::LaserScan>("scan",100);
59  cmd_subscriber_ = nh_.subscribe("control_command",100,&R2000Node::cmdMsgCallback,this);
60  get_scan_data_timer_ = nh_.createTimer(ros::Duration(1/(2*std::atof(driver_->getParametersCached().at("scan_frequency").c_str()))), &R2000Node::getScanData, this);
61 }
62 
63 //-----------------------------------------------------------------------------
65 {
66  delete driver_;
67 
68  // Connecting to laser range finder
69  //-------------------------------------------------------------------------
70  driver_ = new R2000Driver();
71  std::cout << "Connecting to scanner at " << scanner_ip_ << " ... ";
72  if( driver_->connect(scanner_ip_,80) )
73  std::cout << "OK" << std::endl;
74  else
75  {
76  std::cout << "FAILED!" << std::endl;
77  std::cerr << "Connection to scanner at " << scanner_ip_ << " failed!" << std::endl;
78  return false;
79  }
80 
81  // Setting, reading and displaying parameters
82  //-------------------------------------------------------------------------
85  auto params = driver_->getParameters();
86  std::cout << "Current scanner settings:" << std::endl;
87  std::cout << "============================================================" << std::endl;
88  for( const auto& p : params )
89  std::cout << p.first << " : " << p.second << std::endl;
90  std::cout << "============================================================" << std::endl;
91 
92  // Start capturing scanner data
93  //-------------------------------------------------------------------------
94  std::cout << "Starting capturing: ";
95  if( driver_->startCapturingTCP() )
96  std::cout << "OK" << std::endl;
97  else
98  {
99  std::cout << "FAILED!" << std::endl;
100  return false;
101  }
102  return true;
103 }
104 
105 //-----------------------------------------------------------------------------
107 {
108  if( !driver_->isCapturing() )
109  {
110  std::cout << "ERROR: Laser range finder disconnected. Trying to reconnect..." << std::endl;
111  while( !connect() )
112  {
113  std::cout << "ERROR: Reconnect failed. Trying again in 2 seconds..." << std::endl;
114  usleep((2*1000000));
115  }
116  }
117  auto scandata = driver_->getFullScan();
118  if( scandata.amplitude_data.empty() || scandata.distance_data.empty() )
119  return;
120 
121  sensor_msgs::LaserScan scanmsg;
122  scanmsg.header.frame_id = frame_id_;
123  scanmsg.header.stamp = ros::Time::now();
124 
125  scanmsg.angle_min = -M_PI;
126  scanmsg.angle_max = +M_PI;
127  scanmsg.angle_increment = 2*M_PI/float(scandata.distance_data.size());
128  scanmsg.time_increment = 1/35.0f/float(scandata.distance_data.size());
129 
130  scanmsg.scan_time = 1/std::atof(driver_->getParametersCached().at("scan_frequency").c_str());
131  scanmsg.range_min = std::atof(driver_->getParametersCached().at("radial_range_min").c_str());
132  scanmsg.range_max = std::atof(driver_->getParametersCached().at("radial_range_max").c_str());
133 
134  scanmsg.ranges.resize(scandata.distance_data.size());
135  scanmsg.intensities.resize(scandata.amplitude_data.size());
136  for( std::size_t i=0; i<scandata.distance_data.size(); i++ )
137  {
138  scanmsg.ranges[i] = float(scandata.distance_data[i])/1000.0f;
139  scanmsg.intensities[i] = scandata.amplitude_data[i];
140  }
141  scan_publisher_.publish(scanmsg);
142 }
143 
144 //-----------------------------------------------------------------------------
145 void R2000Node::cmdMsgCallback(const std_msgs::StringConstPtr &msg)
146 {
147  const std::string& cmd = msg->data;
148  static const std::string set_scan_frequency_cmd("set scan_frequency=");
149  static const std::string set_samples_per_scan_cmd("set samples_per_scan=");
150 
151  // Setting of scan_frequency
152  //-------------------------------------------------------------------------
153  if( cmd.substr(0,set_scan_frequency_cmd.size()) == set_scan_frequency_cmd )
154  {
155  std::string value = cmd.substr(set_scan_frequency_cmd.size());
156  int frequency = std::atoi(value.c_str());
157  if(frequency>=10 && frequency<=50)
158  {
159  scan_frequency_ = frequency;
160  driver_->setScanFrequency(frequency);
161  }
162  }
163 
164  // Setting of samples_per_scan
165  //-------------------------------------------------------------------------
166  if( cmd.substr(0,set_samples_per_scan_cmd.size()) == set_samples_per_scan_cmd )
167  {
168  std::string value = cmd.substr(set_samples_per_scan_cmd.size());
169  int samples = std::atoi(value.c_str());
170  if(samples>=72 && samples<=25200)
171  {
172  samples_per_scan_ = samples;
173  driver_->setSamplesPerScan(samples);
174  }
175  }
176 }
177 
178 //-----------------------------------------------------------------------------
179 } // NS
180 
181 int main(int argc, char **argv)
182 {
183  ros::init(argc, argv, "r2000_node", ros::init_options::AnonymousName);
185  ros::spin();
186  return 0;
187 }
int scan_frequency_
scan_frequency parameter
Definition: r2000_node.h:77
Driver for the laserscanner R2000 of Pepperl+Fuchs.
Definition: r2000_driver.h:47
const std::map< std::string, std::string > & getParametersCached() const
Definition: r2000_driver.h:97
R2000Node()
Initialize and connect to laser range finder.
Definition: r2000_node.cpp:37
int samples_per_scan_
samples_per_scan parameter
Definition: r2000_node.h:80
void publish(const boost::shared_ptr< M > &message) const
ros::NodeHandle nh_
Internal ROS node handle.
Definition: r2000_node.h:59
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
void cmdMsgCallback(const std_msgs::StringConstPtr &msg)
Callback function for control commands.
Definition: r2000_node.cpp:145
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
bool setSamplesPerScan(unsigned int samples)
bool setScanFrequency(unsigned int frequency)
ROS driver node for the Pepperl+Fuchs R2000 laser range finder.
Definition: r2000_node.h:41
void getScanData(const ros::TimerEvent &e)
Time callback function for getting data from the driver and sending them out.
Definition: r2000_node.cpp:106
std::string scanner_ip_
IP or hostname of laser range finder.
Definition: r2000_node.h:74
bool param(const std::string &param_name, T &param_val, const T &default_val) const
ros::Subscriber cmd_subscriber_
ROS subscriber for receiving control commands.
Definition: r2000_node.h:68
Timer createTimer(Rate r, Handler h, Obj o, bool oneshot=false, bool autostart=true) const
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
ROSCPP_DECL void spin()
ros::Timer get_scan_data_timer_
Callback timer for getScanData(...)
Definition: r2000_node.h:62
ros::Publisher scan_publisher_
ROS publisher for publishing scan data.
Definition: r2000_node.h:65
bool connect(const std::string hostname, int port=80)
int main(int argc, char **argv)
Definition: r2000_node.cpp:181
R2000Driver * driver_
Pointer to driver.
Definition: r2000_node.h:83
std::string frame_id_
frame_id of sensor_msgs/Laserscan messages
Definition: r2000_node.h:71
static Time now()
const std::map< std::string, std::string > & getParameters()


pepperl_fuchs_r2000
Author(s): Denis Dillenberger
autogenerated on Mon Jun 10 2019 14:12:48