os32c.cpp
Go to the documentation of this file.
1 
27 #include <ros/ros.h>
28 #include <boost/shared_ptr.hpp>
29 #include <boost/make_shared.hpp>
30 #include <boost/asio.hpp>
31 
38 
39 using std::cout;
40 using std::endl;
41 using boost::shared_ptr;
42 using boost::make_shared;
43 using boost::asio::buffer;
44 using eip::Session;
47 using eip::CPFItem;
48 using eip::CPFPacket;
52 
53 namespace omron_os32c_driver {
54 
55 const double OS32C::ANGLE_MIN = DEG2RAD(-135.2);
56 const double OS32C::ANGLE_MAX = DEG2RAD(135.2);
57 const double OS32C::ANGLE_INC = DEG2RAD(0.4);
58 const double OS32C::DISTANCE_MIN = 0.002;
59 const double OS32C::DISTANCE_MAX = 50;
60 
62 {
65 }
66 
68 {
69  setSingleAttribute(0x73, 1, 4, format);
70  mrc_.range_report_format = format;
71 }
72 
74 {
77 }
78 
80 {
81  setSingleAttribute(0x73, 1, 5, format);
83 }
84 
85 void OS32C::calcBeamMask(double start_angle, double end_angle, EIP_BYTE mask[])
86 {
87  if (start_angle > (ANGLE_MAX + ANGLE_INC / 2))
88  {
89  throw std::invalid_argument("Start angle is greater than max");
90  }
91  if (end_angle < (ANGLE_MIN - ANGLE_INC / 2))
92  {
93  throw std::invalid_argument("End angle is greater than max");
94  }
95  if (start_angle - end_angle <= ANGLE_INC)
96  {
97  throw std::invalid_argument("Starting angle is less than ending angle");
98  }
99 
100  int start_beam = calcBeamNumber(start_angle);
101  int end_beam = calcBeamNumber(end_angle);
102  start_angle_ = calcBeamCentre(start_beam);
103  end_angle_ = calcBeamCentre(end_beam);
104 
105  // figure out where we're starting and ending in the array
106  int start_byte = start_beam / 8;
107  int start_bit = start_beam - start_byte * 8;
108  int end_byte = end_beam / 8;
109  int end_bit = end_beam - end_byte * 8;
110 
111  // clear out all of the whole bytes that need to be set in one shot
112  if (start_byte > 0)
113  {
114  memset(mask, 0, start_byte);
115  }
116 
117  // if we're starting in the middle of the byte, then we need to do some bit math
118  if (start_bit)
119  {
120  // clear out the bits at the start of the byte, while making the higher bits 1
121  mask[start_byte] = ~((1 << start_bit) - 1);
122  }
123  else
124  {
125  --start_byte;
126  }
127 
128  // mark all of the whole bytes
129  memset(mask + start_byte + 1, 0xFF, end_byte - start_byte - 1);
130 
131  // clear out the bits above the end beam
132  mask[end_byte] = (1 << (end_bit + 1)) - 1;
133 
134  // zero out everything after the end
135  memset(mask + end_byte + 1, 0, 87 - end_byte);
136 }
137 
138 void OS32C::selectBeams(double start_angle, double end_angle)
139 {
140  calcBeamMask(start_angle, end_angle, mrc_.beam_selection_mask);
141  shared_ptr<SerializableBuffer> sb = make_shared<SerializableBuffer>(buffer(mrc_.beam_selection_mask));
142  setSingleAttributeSerializable(0x73, 1, 12, sb);
143 }
144 
146 {
148  getSingleAttributeSerializable(0x75, 1, 3, rr);
149  return rr;
150 }
151 
152 void OS32C::fillLaserScanStaticConfig(sensor_msgs::LaserScan* ls)
153 {
154  ls->angle_max = start_angle_;
155  ls->angle_min = end_angle_;
156  ls->angle_increment = ANGLE_INC;
157  ls->range_min = DISTANCE_MIN;
158  ls->range_max = DISTANCE_MAX;
159 }
160 
161 void OS32C::convertToLaserScan(const RangeAndReflectanceMeasurement& rr, sensor_msgs::LaserScan* ls)
162 {
163  if (rr.range_data.size() != rr.header.num_beams || rr.reflectance_data.size() != rr.header.num_beams)
164  {
165  throw std::invalid_argument("Number of beams does not match vector size");
166  }
167 
168  // Beam period is in ns
169  ls->time_increment = rr.header.scan_beam_period / 1000000000.0;
170  // Scan period is in microseconds.
171  ls->scan_time = rr.header.scan_rate / 1000000.0;
172 
173  // TODO: this currently makes assumptions of the report format. Should likely
174  // accomodate all of them, or at least anything reasonable.
175  ls->ranges.resize(rr.header.num_beams);
176  ls->intensities.resize(rr.header.num_beams);
177  for (int i = 0; i < rr.header.num_beams; ++i)
178  {
179  if (rr.range_data[i] == 0x0001)
180  {
181  // noisy beam detected
182  ls->ranges[i] = 0;
183  }
184  else if (rr.range_data[i] == 0xFFFF)
185  {
186  // no return
187  ls->ranges[i] = DISTANCE_MAX;
188  }
189  else
190  {
191  ls->ranges[i] = rr.range_data[i] / 1000.0;
192  }
193  ls->intensities[i] = rr.reflectance_data[i];
194  }
195 }
196 
197 void OS32C::convertToLaserScan(const MeasurementReport& mr, sensor_msgs::LaserScan* ls)
198 {
199  if (mr.measurement_data.size() != mr.header.num_beams)
200  {
201  throw std::invalid_argument("Number of beams does not match vector size");
202  }
203 
204  // Beam period is in ns.
205  ls->time_increment = mr.header.scan_beam_period / 1000000000.0;
206  // Scan period is in microseconds.
207  ls->scan_time = mr.header.scan_rate / 1000000.0;
208 
209  // TODO: this currently makes assumptions of the report format. Should likely
210  // accomodate all of them, or at least anything reasonable.
211  ls->ranges.resize(mr.header.num_beams);
212  for (int i = 0; i < mr.header.num_beams; ++i)
213  {
214  if (mr.measurement_data[i] == 0x0001)
215  {
216  // noisy beam detected
217  ls->ranges[i] = 0;
218  }
219  else if (mr.measurement_data[i] == 0xFFFF)
220  {
221  // no return
222  ls->ranges[i] = DISTANCE_MAX;
223  }
224  else
225  {
226  ls->ranges[i] = mr.measurement_data[i] / 1000.0;
227  }
228  }
229 }
230 
232 {
233  // TODO: check that connection is valid
234  CPFPacket pkt;
236  make_shared<SequencedAddressItem>(getConnection(connection_num_).o_to_t_connection_id, mrc_sequence_num_++);
237  shared_ptr<MeasurementReportConfig> data = make_shared<MeasurementReportConfig>();
238  *data = mrc_;
239  pkt.getItems().push_back(CPFItem(0x8002, address));
240  pkt.getItems().push_back(CPFItem(0x00B1, data));
241  sendIOPacket(pkt);
242 }
243 
245 {
246  CPFPacket pkt = receiveIOPacket();
247  if (pkt.getItemCount() != 2)
248  {
249  throw std::logic_error("IO Packet received with wrong number of items");
250  }
251  if (pkt.getItems()[1].getItemType() != 0x00B1)
252  {
253  throw std::logic_error("IO Packet received with wrong data type");
254  }
255 
257  pkt.getItems()[1].getDataAs(data);
258  return data;
259 }
260 
262 {
263  EIP_CONNECTION_INFO_T o_to_t, t_to_o;
264  o_to_t.assembly_id = 0x71;
265  o_to_t.buffer_size = 0x006E;
266  o_to_t.rpi = 0x00177FA0;
267  t_to_o.assembly_id = 0x66;
268  t_to_o.buffer_size = 0x0584;
269  t_to_o.rpi = 0x00013070;
270 
271  connection_num_ = createConnection(o_to_t, t_to_o);
272  ROS_INFO("Opened connection with id %d", connection_num_);
273 }
274 
276 {
277  if (connection_num_ >= 0)
278  {
279  ROS_INFO("Closing connection with id %d", connection_num_);
281  }
282 }
283 
284 } // namespace omron_os32c_driver
omron_os32c_driver::RangeAndReflectanceMeasurement
Definition: range_and_reflectance_measurement.h:50
cpf_item.h
omron_os32c_driver::OS32C::ANGLE_INC
static const double ANGLE_INC
Definition: os32c.h:93
DEG2RAD
#define DEG2RAD(a)
Definition: os32c.h:47
eip::CPFPacket
omron_os32c_driver::MeasurementReportHeader::num_beams
EIP_UINT num_beams
Definition: measurement_report_header.h:66
EIP_CONNECTION_INFO_T
omron_os32c_driver::OS32C::connection_num_
int connection_num_
Definition: os32c.h:216
omron_os32c_driver::MeasurementReport::measurement_data
vector< EIP_UINT > measurement_data
Definition: measurement_report.h:54
eip::Session
boost::shared_ptr
eip::Session::getConnection
const Connection & getConnection(size_t n)
EIP_BYTE
uint8_t EIP_BYTE
omron_os32c_driver::OS32C::getReflectivityFormat
EIP_UINT getReflectivityFormat()
Definition: os32c.cpp:73
eip::CPFPacket::getItems
vector< CPFItem > & getItems()
omron_os32c_driver::MeasurementReportConfig::range_report_format
EIP_UINT range_report_format
Definition: measurement_report_config.h:52
omron_os32c_driver::MeasurementReportHeader::scan_rate
EIP_UDINT scan_rate
Definition: measurement_report_header.h:51
ros.h
EIP_UINT
uint16_t EIP_UINT
omron_os32c_driver::OS32C::mrc_
MeasurementReportConfig mrc_
Definition: os32c.h:217
omron_os32c_driver::OS32C::getRangeFormat
EIP_UINT getRangeFormat()
Definition: os32c.cpp:61
omron_os32c_driver::MeasurementReportHeader::scan_beam_period
EIP_UDINT scan_beam_period
Definition: measurement_report_header.h:53
eip::SequencedAddressItem
eip::Session::setSingleAttribute
void setSingleAttribute(EIP_USINT class_id, EIP_USINT instance_id, EIP_USINT attribute_id, T v)
omron_os32c_driver::OS32C::receiveMeasurementReportUDP
MeasurementReport receiveMeasurementReportUDP()
Definition: os32c.cpp:244
omron_os32c_driver::OS32C::closeActiveConnection
void closeActiveConnection()
Definition: os32c.cpp:275
eip::SequencedDataItem
omron_os32c_driver::OS32C::startUDPIO
void startUDPIO()
Definition: os32c.cpp:261
data
data
omron_os32c_driver::OS32C::DISTANCE_MAX
static const double DISTANCE_MAX
Definition: os32c.h:95
omron_os32c_driver::OS32C::mrc_sequence_num_
EIP_UDINT mrc_sequence_num_
Definition: os32c.h:218
eip::Session::getSingleAttribute
T getSingleAttribute(EIP_USINT class_id, EIP_USINT instance_id, EIP_USINT attribute_id, T v)
omron_os32c_driver::OS32C::convertToLaserScan
static void convertToLaserScan(const RangeAndReflectanceMeasurement &rr, sensor_msgs::LaserScan *ls)
Definition: os32c.cpp:161
omron_os32c_driver::RangeAndReflectanceMeasurement::reflectance_data
vector< EIP_UINT > reflectance_data
Definition: range_and_reflectance_measurement.h:55
omron_os32c_driver::OS32C::getSingleRRScan
RangeAndReflectanceMeasurement getSingleRRScan()
Definition: os32c.cpp:145
omron_os32c_driver::MeasurementReportConfig::reflectivity_report_format
EIP_UINT reflectivity_report_format
Definition: measurement_report_config.h:53
omron_os32c_driver::OS32C::end_angle_
double end_angle_
Definition: os32c.h:213
omron_os32c_driver
Definition: measurement_report.h:43
os32c.h
sequenced_address_item.h
EIP_CONNECTION_INFO_T::assembly_id
EIP_USINT assembly_id
omron_os32c_driver::OS32C::calcBeamCentre
static double calcBeamCentre(int beam_num)
Definition: os32c.h:168
omron_os32c_driver::MeasurementReportConfig::beam_selection_mask
EIP_BYTE beam_selection_mask[88]
Definition: measurement_report_config.h:54
omron_os32c_driver::MeasurementReport
Definition: measurement_report.h:50
omron_os32c_driver::MeasurementReport::header
MeasurementReportHeader header
Definition: measurement_report.h:53
omron_os32c_driver::OS32C::setReflectivityFormat
void setReflectivityFormat(EIP_UINT format)
Definition: os32c.cpp:79
omron_os32c_driver::OS32C::sendMeasurmentReportConfigUDP
void sendMeasurmentReportConfigUDP()
Definition: os32c.cpp:231
omron_os32c_driver::OS32C::ANGLE_MIN
static const double ANGLE_MIN
Definition: os32c.h:91
cpf_packet.h
omron_os32c_driver::RangeAndReflectanceMeasurement::range_data
vector< EIP_UINT > range_data
Definition: range_and_reflectance_measurement.h:54
EIP_CONNECTION_INFO_T::rpi
EIP_UDINT rpi
omron_os32c_driver::OS32C::calcBeamNumber
static int calcBeamNumber(double angle)
Definition: os32c.h:157
eip::Session::createConnection
int createConnection(const EIP_CONNECTION_INFO_T &o_to_t, const EIP_CONNECTION_INFO_T &t_to_o)
omron_os32c_driver::OS32C::DISTANCE_MIN
static const double DISTANCE_MIN
Definition: os32c.h:94
eip::RRDataResponse
eip::Session::sendIOPacket
void sendIOPacket(CPFPacket &pkt)
omron_os32c_driver::OS32C::start_angle_
double start_angle_
Definition: os32c.h:212
omron_os32c_driver::OS32C::selectBeams
void selectBeams(double start_angle, double end_angle)
Definition: os32c.cpp:138
eip::CPFPacket::getItemCount
EIP_UINT getItemCount() const
sequenced_data_item.h
omron_os32c_driver::OS32C::setRangeFormat
void setRangeFormat(EIP_UINT format)
Definition: os32c.cpp:67
eip::Session::setSingleAttributeSerializable
void setSingleAttributeSerializable(EIP_USINT class_id, EIP_USINT instance_id, EIP_USINT attribute_id, shared_ptr< Serializable > data)
eip::Session::closeConnection
void closeConnection(size_t n)
omron_os32c_driver::OS32C::calcBeamMask
void calcBeamMask(double start_angle, double end_angle, EIP_BYTE mask[])
Definition: os32c.cpp:85
eip::serialization::SerializableBuffer
eip::Session::receiveIOPacket
CPFPacket receiveIOPacket()
eip::CPFItem
omron_os32c_driver::OS32C::ANGLE_MAX
static const double ANGLE_MAX
Definition: os32c.h:92
ROS_INFO
#define ROS_INFO(...)
serializable_buffer.h
omron_os32c_driver::RangeAndReflectanceMeasurement::header
MeasurementReportHeader header
Definition: range_and_reflectance_measurement.h:53
eip::Session::getSingleAttributeSerializable
void getSingleAttributeSerializable(EIP_USINT class_id, EIP_USINT instance_id, EIP_USINT attribute_id, Serializable &result)
EIP_CONNECTION_INFO_T::buffer_size
EIP_UINT buffer_size
omron_os32c_driver::OS32C::fillLaserScanStaticConfig
void fillLaserScanStaticConfig(sensor_msgs::LaserScan *ls)
Definition: os32c.cpp:152


omron_os32c_driver
Author(s): Kareem Shehata
autogenerated on Wed Mar 2 2022 00:39:14