camera_commander.cpp
Go to the documentation of this file.
1 // Copyright 2020 Continental AG
2 // All rights reserved.
3 //
4 // Software License Agreement (BSD 2-Clause Simplified License)
5 //
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions
8 // are met:
9 //
10 // * Redistributions of source code must retain the above copyright
11 // notice, this list of conditions and the following disclaimer.
12 // * Redistributions in binary form must reproduce the above
13 // copyright notice, this list of conditions and the following
14 // disclaimer in the documentation and/or other materials provided
15 // with the distribution.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21 // COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 // POSSIBILITY OF SUCH DAMAGE.
29 
30 
37 
39 
40 #include <string>
41 #include <vector>
42 #include <memory>
43 
45 namespace hfl
46 {
48 {
50 }
51 
53 {
54  // Stop camera if active
56  {
57  ROS_INFO("Shutting down camera...");
58  }
59 }
60 
62 {
63  // Initialize node handler
66 
67  // Initialize flash object (pointer)
68  if (!setFlash())
69  {
70  throw - 1;
71  }
72  // Initialize UPD services, sockets, and subscribers
73  if (!udpInit())
74  {
75  throw - 1;
76  }
77  // Initialize current state and timer_ callback
80  auto set_state_callback =
81  std::bind(&CameraCommander::setCommanderState, this, std::placeholders::_1);
82  timer_ = node_handler_.createTimer(ros::Duration(1), set_state_callback);
83 }
84 
85 bool CameraCommander::createSocket(std::string computer_addr, std::string camera_addr,
86  uint16_t port, bool isMulticast)
87 {
88  // Create a socket Request service message
89  udp_com::UdpSocket socket_request;
90  // Populate request service message
91  socket_request.request.srcAddress = computer_addr;
92  socket_request.request.destAddress = camera_addr;
93  socket_request.request.port = port;
94  socket_request.request.isMulticast = isMulticast;
95  // Return service call response
98  {
99  return true;
100  }
101  // Return false if service call failed
102  return false;
103 }
104 
106 {
107  // Get ethernet interface
108  node_handler_.getParam("ethernet_interface", ethernet_interface_);
109  ROS_INFO("%s/ethernet_interface: %s",
110  node_handler_.getNamespace().c_str(), ethernet_interface_.c_str());
111 
112  // Get camera IP address
113  node_handler_.getParam("camera_ip_address", camera_address_);
114  ROS_INFO("%s/camera_ip_address: %s", namespace_.c_str(), camera_address_.c_str());
115 
116  // Get computer IP address
117  node_handler_.getParam("computer_ip_address", computer_address_);
118  ROS_INFO("%s/computer_ip_address: %s", namespace_.c_str(), computer_address_.c_str());
119 
120  // Get frame data port number
121  node_handler_.getParam("frame_data_port", frame_data_port_);
122  ROS_INFO("%s/frame_data_port: %i", namespace_.c_str(), frame_data_port_);
123 
124  // Get pdm data port number
125  node_handler_.getParam("pdm_data_port", pdm_data_port_);
126  ROS_INFO("%s/pdm_data_port: %i", namespace_.c_str(), pdm_data_port_);
127 
128  // Get object data port number
129  node_handler_.getParam("object_data_port", object_data_port_);
130  ROS_INFO("%s/object_data_port: %i", namespace_.c_str(), object_data_port_);
131 
132  // Get telemetry data port number
133  node_handler_.getParam("tele_data_port", tele_data_port_);
134  ROS_INFO("%s/tele_data_port: %i", namespace_.c_str(), tele_data_port_);
135 
136  // Get slice data port number
137  node_handler_.getParam("slice_data_port", slice_data_port_);
138  ROS_INFO("%s/slice_data_port: %i", namespace_.c_str(), slice_data_port_);
139 
140  // Get ethernet namespace node handler
141  ros::NodeHandle ethernet_interface_handler(ethernet_interface_);
142 
143  // Initialize udp Create Socket service client
145  ethernet_interface_handler.serviceClient<udp_com::UdpSocket>("udp/create_socket");
146  // Initialize udp send service client
148  ethernet_interface_handler.serviceClient<udp_com::UdpSend>("udp/send");
149 
150  ROS_INFO("Checking for UDP Communication...");
152  ros::service::waitForService(udp_send_service_client_.getService(), -1);
153  ROS_INFO("UDP Communication online");
154 
155  // Create a Frame Data Socket
157  {
158  ROS_WARN("Frame Socket not created");
159  return false;
160  }
161 
162  // Subscribe to Frame Data Socket
164  ethernet_interface_handler.subscribe(std::string("udp/p") +
165  std::to_string(frame_data_port_), 1000,
167 
168  // Create a PDM Data Socket
170  {
171  ROS_WARN("PDM Socket not created");
172  return false;
173  }
174 
175  // Subscribe to PDM Data Socket
177  ethernet_interface_handler.subscribe(std::string("udp/p") +
178  std::to_string(pdm_data_port_), 1000,
180 
181  // Create a Object Data Socket
183  {
184  ROS_WARN("Object Socket not created");
185  return false;
186  }
187 
189  ethernet_interface_handler.subscribe(std::string("udp/p") +
190  std::to_string(object_data_port_), 1000,
192 
193  // Create a Telemetry Data Socket
195  {
196  ROS_WARN("Telemetry Socket not created");
197  return false;
198  }
199 
201  ethernet_interface_handler.subscribe(std::string("udp/p") +
202  std::to_string(tele_data_port_), 1000,
204 
205  // Create a Slice Data Socket
207  {
208  ROS_WARN("Slice Socket not created");
209  return false;
210  }
211 
213  ethernet_interface_handler.subscribe(std::string("udp/p") +
214  std::to_string(slice_data_port_), 1000,
216 
217  // Everything Initialized
218  return true;
219 }
220 
222 {
223  // Parameter temporal variables
224  std::string model, version, frame_id;
225 
226  // Get camera model
227  node_handler_.getParam("model", model);
228  ROS_INFO("%s/model: %s", namespace_.c_str(), model.c_str());
229  // Get camera version
230  node_handler_.getParam("version", version);
231  ROS_INFO("%s/version: %s", namespace_.c_str(), version.c_str());
232  // Get camera frame_id
233  node_handler_.getParam("frame_id", frame_id);
234  ROS_INFO("%s/frame_id: %s", namespace_.c_str(), frame_id.c_str());
235 
236  // Initialize flash object
237  try
238  {
239  // Load HFL class instance
240  if (model == "hfl110dcu")
241  {
242  flash_.reset(new HFL110DCU(model, version, frame_id, node_handler_));
243  } else {
244  ROS_ERROR("Camera model not found!");
245  }
246  }
247  catch (int e)
248  {
249  ROS_ERROR("Camera load failed!");
250  return false;
251  }
252  // Return
253  return true;
254 }
255 
257 {
258  std::vector<uint8_t> start_command =
259  {
260  0x1C, 0x00
261  };
262  // Executes states accordingly
263  switch (current_state_)
264  {
265  // Establishes connection
266  case state_probe:
267  ROS_INFO_ONCE("Establishing connection...");
268  break;
269  // Sets camera registers
270  case state_init:
271  // Update Commander state
274  ROS_INFO("Camera active");
275 
277  {
278  // Initialize dynamic reconfigure server
280  std::make_shared<dynamic_reconfigure::Server<hfl_driver::HFLConfig> >(
281  node_handler_);
282  // set dynamic reconfigure callback
283  dynamic_reconfigure::Server<hfl_driver::HFLConfig>::CallbackType
284  dynamic_parameters_callback =
285  boost::bind(&CameraCommander::dynamicPametersCallback, this, _1, _2);
286  dynamic_parameters_server_->setCallback(dynamic_parameters_callback);
287  }
288 
289  break;
290  // Done camera
291  case state_done:
293  if (error_status_ != no_error)
294  {
297  }
298  break;
299 
300  case state_error:
301  if (fixError(error_status_))
302  {
304  }
305  break;
306  // Default state
307  default:
308  // Restart
311  break;
312  }
313 }
314 
316 {
317  // Check for Frame Data Publisher on frame data topic
319  {
320  return frame_socket_error;
321  }
322 
323  // Check for PDM Data Publisher on object data topic
325  {
326  return pdm_socket_error;
327  }
328 
329  // Check for Object Data Publisher on object data topic
331  {
332  return object_socket_error;
333  }
334 
335  // Check for Telemetry Data Publisher on object data topic
337  {
338  return tele_socket_error;
339  }
340 
341  // Check for Slice Data Publisher on slice data topic
343  {
344  return slice_socket_error;
345  }
346  return no_error;
347 }
348 
350 {
351  switch (error)
352  {
353  case frame_socket_error:
354  // Create Frame Socket
356  break;
357  case no_error:
358  // Return true
359  return true;
360  break;
361  default:
362  // Not sure what is wrong.. Go back to state_done to check for error..
363  return true;
364  };
365 }
366 
367 void CameraCommander::frameDataCallback(const udp_com::UdpPacket& udp_packet)
368 {
369  // Checks UPD package source IP address
370  if (udp_packet.address == camera_address_)
371  {
372  switch (current_state_)
373  {
374  case state_probe:
375  ROS_INFO_ONCE("Connection established with Frame Data UDP Port!");
378  break;
379  case state_done:
380  ROS_INFO_ONCE("Frame Data UDP packages arriving...");
381  flash_->processFrameData(udp_packet.data);
382  break;
383  }
384  }
385 }
386 
387 void CameraCommander::pdmDataCallback(const udp_com::UdpPacket& udp_packet)
388 {
389  // Checks UPD package source IP address
390  if (udp_packet.address == camera_address_)
391  {
392  switch (current_state_)
393  {
394  case state_probe:
395  ROS_INFO_ONCE("Connection established with PDM Data UDP Port!");
398  break;
399  case state_done:
400  ROS_INFO_ONCE("PDM Data UDP packages arriving...");
401  //flash_->processPDMData(udp_packet.data);
402  break;
403  }
404  }
405 }
406 
407 void CameraCommander::objectDataCallback(const udp_com::UdpPacket& udp_packet)
408 {
409  // Checks UPD package source IP address
410  if (udp_packet.address == camera_address_)
411  {
412  switch (current_state_)
413  {
414  case state_probe:
415  ROS_INFO_ONCE("Connection established with Object Data UDP Port!");
418  break;
419  case state_done:
420  ROS_INFO_ONCE("Object Data UDP packages arriving...");
421  flash_->processObjectData(udp_packet.data);
422  break;
423  }
424  }
425 }
426 
427 void CameraCommander::teleDataCallback(const udp_com::UdpPacket& udp_packet)
428 {
429  // Checks UPD package source IP address
430  if (udp_packet.address == camera_address_)
431  {
432  switch (current_state_)
433  {
434  case state_probe:
435  ROS_INFO_ONCE("Connection established with Telemetry Data UDP Port!");
438  break;
439  case state_done:
440  ROS_INFO_ONCE("Telemetry Data UDP packages arriving...");
441  flash_->processTelemetryData(udp_packet.data);
442  break;
443  }
444  }
445 }
446 
447 void CameraCommander::sliceDataCallback(const udp_com::UdpPacket& udp_packet)
448 {
449  // Checks UPD package source IP address
450  if (udp_packet.address == camera_address_)
451  {
452  switch (current_state_)
453  {
454  case state_probe:
455  ROS_INFO_ONCE("Connection established with Slice Data UDP Port!");
458  break;
459  case state_done:
460  ROS_INFO_ONCE("Slice Data UDP packages arriving...");
461  flash_->processSliceData(udp_packet.data);
462  break;
463  }
464  }
465 }
466 
467 bool CameraCommander::sendCommand(const std::vector<uint8_t>& data)
468 {
469  // Create a UDP request service message
470  udp_com::UdpSend send_request;
471  // Populate request service message
472  send_request.request.address = computer_address_;
473  send_request.request.srcPort = frame_data_port_;
474  send_request.request.dstPort = frame_data_port_;
475  send_request.request.data = data;
476 
477  // Return service call response
479  udp_send_service_client_.call(send_request))
480  {
481  return send_request.response.sent; // Will always be true
482  } else if (!send_request.response.socketCreated) {
483  // response.socketCreated will be false right at start up
484  // error is immediately set since sockets were not created
487  } else {
488  ROS_ERROR("Could not send data to sensor");
489  ROS_INFO("Please check the connections to the sensor. ");
490  }
491 
492  // Return false if service call failed
493  return false;
494 }
495 
496 void CameraCommander::dynamicPametersCallback(hfl_driver::HFLConfig& config, uint32_t level)
497 {
498  // Checks if camera active
499  if (current_state_ != state_done)
500  {
501  return;
502  } else {
503  // camera is active
504  if (flash_->setGlobalRangeOffset(config.global_range_offset))
505  ROS_INFO("%s/global_range_offset: %f", namespace_.c_str(), config.global_range_offset);
506  }
507 }
508 } // end of namespace hfl
ros::NodeHandle node_handler_
Node Handle.
This file defines the HFL110DCU image processor class.
ros::Subscriber tele_data_subscriber_
UDP Telemetry Data Subscriber.
void teleDataCallback(const udp_com::UdpPacket &udp_packet)
PLUGINLIB_EXPORT_CLASS(udp_com::UdpComNodelet, nodelet::Nodelet)
void objectDataCallback(const udp_com::UdpPacket &udp_packet)
#define ROS_INFO_ONCE(...)
This file defines the CameraCommander class.
error_codes error_status_
Error Status.
bool call(MReq &req, MRes &res)
ros::Subscriber object_data_subscriber_
UDP Object Data Subscriber.
void pdmDataCallback(const udp_com::UdpPacket &udp_packet)
std::string namespace_
Namespace.
#define ROS_WARN(...)
ros::Timer timer_
Status checker timer.
ros::Subscriber frame_data_subscriber_
UDP Frame Data subscriber.
ros::NodeHandle & getPrivateNodeHandle() const
ros::Subscriber slice_data_subscriber_
UDP Slice Data Subscriber.
#define ROS_INFO(...)
int frame_data_port_
Frame Data UDP port.
Implements the HFL110DCU camera image parsing and publishing.
Definition: hfl110dcu.h:229
uint32_t getNumPublishers() const
Timer createTimer(Rate r, Handler h, Obj o, bool oneshot=false, bool autostart=true) const
int slice_data_port_
Slice Data UDP port.
const std::string & getNamespace() const
void sliceDataCallback(const udp_com::UdpPacket &udp_packet)
bool sendCommand(const std::vector< uint8_t > &data)
int tele_data_port_
Telemetry Data UDP port.
commander_states previous_state_
Commander Previous state prior to error.
bool fixError(error_codes error)
void frameDataCallback(const udp_com::UdpPacket &udp_packet)
commander_states current_state_
Commander current state.
std::string camera_address_
IP Address of sensor.
ros::Subscriber pdm_data_subscriber_
UDP PDM Data Subscriber.
std::string ethernet_interface_
Ethernet Interface.
std::shared_ptr< dynamic_reconfigure::Server< hfl_driver::HFLConfig > > dynamic_parameters_server_
Dynamic Reconfigure server.
int pdm_data_port_
PDM Data UDP port.
bool getParam(const std::string &key, std::string &s) const
bool createSocket(std::string computerAddr, std::string cameraAddr, uint16_t port, bool isMulticast)
std::string computer_address_
IP Address of computer.
ros::ServiceClient udp_socket_creation_service_client_
UDP socket service client.
std::string getService()
void setCommanderState(const ros::TimerEvent &timer_event)
ROSCPP_DECL bool exists(const std::string &service_name, bool print_failure_reason)
ros::ServiceClient udp_send_service_client_
UDP send service client.
int object_data_port_
Object Data UDP port.
#define ROS_ERROR(...)
ROSCPP_DECL bool waitForService(const std::string &service_name, int32_t timeout)
void dynamicPametersCallback(hfl_driver::HFLConfig &config, uint32_t level)
std::shared_ptr< hfl::HflInterface > flash_
Pointer to Flash camera.
Implements the camera configuration and setup.
error_codes
Error Codes.


hfl_driver
Author(s): Evan Flynn , Maxton Ginier , Gerardo Bravo , Moises Diaz
autogenerated on Sat Mar 20 2021 02:27:31