os32c_node.cpp
Go to the documentation of this file.
1 
27 #include <ros/ros.h>
28 #include <boost/shared_ptr.hpp>
29 #include <boost/range/algorithm.hpp>
31 #include <sensor_msgs/LaserScan.h>
32 
35 
40 
41 using std::cout;
42 using std::endl;
43 using boost::shared_ptr;
44 using boost::range::reverse;
45 using sensor_msgs::LaserScan;
48 using namespace omron_os32c_driver;
49 using namespace diagnostic_updater;
50 const double EPS = 1e-3;
51 
52 
53 int main(int argc, char* argv[])
54 {
55  ros::init(argc, argv, "os32c");
56  ros::NodeHandle nh;
57 
58  // get sensor config from params
59  string host, frame_id, local_ip;
60  double start_angle, end_angle, expected_frequency, frequency_tolerance, timestamp_min_acceptable,
61  timestamp_max_acceptable, frequency, reconnect_timeout;
62  bool publish_intensities;
63  bool invert_scan;
64  ros::param::param<std::string>("~host", host, "192.168.1.1");
65  ros::param::param<std::string>("~local_ip", local_ip, "0.0.0.0");
66  ros::param::param<std::string>("~frame_id", frame_id, "laser");
67  ros::param::param<double>("~start_angle", start_angle, OS32C::ANGLE_MAX);
68  ros::param::param<double>("~end_angle", end_angle, OS32C::ANGLE_MIN);
69  ros::param::param<double>("~frequency", frequency, 12.856);
70  ros::param::param<double>("~expected_frequency", expected_frequency, frequency);
71  ros::param::param<double>("~frequency_tolerance", frequency_tolerance, 0.1);
72  ros::param::param<double>("~timestamp_min_acceptable", timestamp_min_acceptable, -1);
73  ros::param::param<double>("~timestamp_max_acceptable", timestamp_max_acceptable, -1);
74  ros::param::param<double>("~reconnect_timeout", reconnect_timeout, 2.0);
75  ros::param::param<bool>("~publish_intensities", publish_intensities, false);
76  ros::param::param<bool>("~invert_scan", invert_scan, false);
77 
78  // publisher for laserscans
79  ros::Publisher laserscan_pub = nh.advertise<LaserScan>("scan", 1);
80 
81  // Validate frequency parameters
82  if (frequency > 25)
83  {
84  ROS_FATAL("Frequency exceeds the limit of 25hz.");
85  return -1;
86  }
87  else if (frequency <= 0)
88  {
89  ROS_FATAL("Frequency should be positive");
90  return -1;
91  }
92 
93  if (fabs(frequency - expected_frequency) > EPS)
94  {
95  ROS_WARN("Frequency parameter is not equal to expected frequency parameter.");
96  }
97 
98  // initialize loop rate
99  ros::Rate loop_rate(frequency);
100 
101  // diagnostics for frequency
103  updater.setHardwareID(host);
104  DiagnosedPublisher<LaserScan> diagnosed_publisher(
105  laserscan_pub, updater, FrequencyStatusParam(&expected_frequency, &expected_frequency, frequency_tolerance),
106  TimeStampStatusParam(timestamp_min_acceptable, timestamp_max_acceptable));
107 
108  while (ros::ok())
109  {
110  boost::asio::io_service io_service;
111  shared_ptr<TCPSocket> socket = shared_ptr<TCPSocket>(new TCPSocket(io_service));
112  shared_ptr<UDPSocket> io_socket = shared_ptr<UDPSocket>(new UDPSocket(io_service, 2222, local_ip));
113  OS32C os32c(socket, io_socket);
114 
115  try
116  {
117  os32c.open(host);
118  }
119  catch (std::runtime_error ex)
120  {
121  ROS_ERROR("Exception caught opening session: %s. Reconnecting in %.2f seconds ...", ex.what(), reconnect_timeout);
122  ros::Duration(reconnect_timeout).sleep();
123  continue;
124  }
125 
126  try
127  {
128  os32c.setRangeFormat(RANGE_MEASURE_50M);
129  os32c.setReflectivityFormat(REFLECTIVITY_MEASURE_TOT_4PS);
130  os32c.selectBeams(start_angle, end_angle);
131  }
132  catch (std::invalid_argument ex)
133  {
134  ROS_ERROR("Invalid arguments in sensor configuration: %s. Reconnecting in %.2f seconds ...", ex.what(),
135  reconnect_timeout);
136  ros::Duration(reconnect_timeout).sleep();
137  continue;
138  }
139 
140  sensor_msgs::LaserScan laserscan_msg;
141  os32c.fillLaserScanStaticConfig(&laserscan_msg);
142  laserscan_msg.header.frame_id = frame_id;
143 
144  while (ros::ok())
145  {
146  try
147  {
148  // Poll ranges and reflectivity
149  RangeAndReflectanceMeasurement report = os32c.getSingleRRScan();
150 
151  // Invert range measurements if z-axis is needed to point upwards.
152  if (invert_scan)
153  {
154  reverse(report.range_data);
155  }
156 
157  OS32C::convertToLaserScan(report, &laserscan_msg);
158 
159  // In earlier versions reflectivity was not received. So to be backwards
160  // compatible clear reflectivity from msg.
161  if (!publish_intensities)
162  {
163  laserscan_msg.intensities.clear();
164  }
165 
166  // Stamp and publish message diagnosed
167  laserscan_msg.header.stamp = ros::Time::now();
168  laserscan_msg.header.seq++;
169  diagnosed_publisher.publish(laserscan_msg);
170 
171  // Update diagnostics
172  updater.update();
173  }
174  catch (std::runtime_error ex)
175  {
176  ROS_ERROR_STREAM_DELAYED_THROTTLE(5.0, "Exception caught requesting scan data: " << ex.what());
177  }
178  catch (std::logic_error ex)
179  {
180  ROS_ERROR_STREAM("Problem parsing return data: " << ex.what());
181  }
182 
183  if (!laserscan_msg.header.stamp.isZero() &&
184  (ros::Time::now() - laserscan_msg.header.stamp).toSec() > reconnect_timeout)
185  {
186  ROS_ERROR("No scan received for %.2f seconds, reconnecting ...", reconnect_timeout);
187  laserscan_msg.header.stamp = ros::Time();
188  break;
189  }
190 
191  ros::spinOnce();
192 
193  // sleep
194  loop_rate.sleep();
195  }
196 
197  if (!ros::ok())
198  {
199  os32c.closeActiveConnection();
200  os32c.close();
201  }
202  }
203 
204  return 0;
205 }
const double EPS
Definition: os32c_node.cpp:50
#define ROS_FATAL(...)
int main(int argc, char *argv[])
Definition: os32c_node.cpp:53
static const double ANGLE_MAX
Definition: os32c.h:92
void setHardwareID(const std::string &hwid)
bool sleep() const
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
virtual void publish(const boost::shared_ptr< T > &message)
updater
#define ROS_WARN(...)
#define ROS_ERROR_STREAM_DELAYED_THROTTLE(rate, args)
ROSCPP_DECL bool ok()
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
REGISTER_ROSCONSOLE_BRIDGE
Definition: os32c_node.cpp:34
bool sleep()
static const double ANGLE_MIN
Definition: os32c.h:91
static void convertToLaserScan(const RangeAndReflectanceMeasurement &rr, sensor_msgs::LaserScan *ls)
Definition: os32c.cpp:161
static Time now()
#define ROS_ERROR_STREAM(args)
ROSCPP_DECL void spinOnce()
#define ROS_ERROR(...)


omron_os32c_driver
Author(s): Kareem Shehata
autogenerated on Fri Nov 27 2020 03:06:12