gazebo_optical_flow_plugin.cpp
Go to the documentation of this file.
1 
2 /*
3  * Copyright (C) 2012-2015 Open Source Robotics Foundation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17 */
18 #ifdef _WIN32
19  // Ensure that Winsock2.h is included before Windows.h, which can get
20  // pulled in by anybody (e.g., Boost).
21 #include <Winsock2.h>
22 #endif
23 
24 #include "gazebo/sensors/DepthCameraSensor.hh"
25 
28 
29 #include <highgui.h>
30 #include <math.h>
31 #include <string>
32 #include <iostream>
33 #include <boost/algorithm/string.hpp>
34 
35 using namespace cv;
36 using namespace std;
37 
38 using namespace gazebo;
40 
41 OpticalFlowPlugin::OpticalFlowPlugin()
43 : SensorPlugin(), width(0), height(0), depth(0), timer_()
44 {
45 
46 }
47 
50 {
51  this->parentSensor.reset();
52  this->camera.reset();
53 }
54 
56 void OpticalFlowPlugin::Load(sensors::SensorPtr _sensor, sdf::ElementPtr _sdf)
57 {
58  if(kPrintOnPluginLoad) {
59  gzdbg << __FUNCTION__ << "() called." << std::endl;
60  }
61 
62  if (!_sensor)
63  gzerr << "Invalid sensor pointer.\n";
64 
65  this->parentSensor =
66  std::dynamic_pointer_cast<sensors::CameraSensor>(_sensor);
67 
68  if (!this->parentSensor)
69  {
70  gzerr << "OpticalFlowPlugin requires a CameraSensor.\n";
71  if (std::dynamic_pointer_cast<sensors::DepthCameraSensor>(_sensor))
72  gzmsg << "It is a depth camera sensor\n";
73  }
74 
75  this->camera = this->parentSensor->Camera();
76 
77  if (!this->parentSensor)
78  {
79  gzerr << "OpticalFlowPlugin not attached to a camera sensor\n";
80  return;
81  }
82 
83  this->width = this->camera->ImageWidth();
84  this->height = this->camera->ImageHeight();
85  this->depth = this->camera->ImageDepth();
86  this->format = this->camera->ImageFormat();
87 
88  if (this->width != 64 || this->height != 64) {
89  gzerr << "[gazebo_optical_flow_plugin] Incorrect image size, must by 64 x 64.\n";
90  }
91 
92  if (_sdf->HasElement("robotNamespace"))
93  namespace_ = _sdf->GetElement("robotNamespace")->Get<std::string>();
94  else
95  gzwarn << "[gazebo_optical_flow_plugin] Please specify a robotNamespace.\n";
96 
97  node_handle_ = transport::NodePtr(new transport::Node());
98  node_handle_->Init(namespace_);
99 
100  const string scopedName = _sensor->ParentName();
101 
102  string topicName = "~/" + scopedName + "/opticalFlow";
103  boost::replace_all(topicName, "::", "/");
104 
105  opticalFlow_pub_ = node_handle_->Advertise<opticalFlow_msgs::msgs::opticalFlow>(topicName, 10);
106 
107  hfov = float(this->camera->HFOV().Radian());
108  first_frame_time = this->camera->LastRenderWallTime().Double();
109 
110  old_frame_time = first_frame_time;
111  focal_length = (this->width/2)/tan(hfov/2);
112 
113  this->newFrameConnection = this->camera->ConnectNewImageFrame(
114  boost::bind(&OpticalFlowPlugin::OnNewFrame, this, _1, this->width, this->height, this->depth, this->format));
115 
116  this->parentSensor->SetActive(true);
117 
118  //init flow
119  const int ouput_rate = 20; // -1 means use rate of camera
120  _optical_flow = new OpticalFlowOpenCV(focal_length, focal_length, ouput_rate);
121  // _optical_flow = new OpticalFlowPX4(focal_length, focal_length, ouput_rate, this->width);
122 
123 }
124 
126 void OpticalFlowPlugin::OnNewFrame(const unsigned char * _image,
127  unsigned int _width,
128  unsigned int _height,
129  unsigned int _depth,
130  const std::string &_format)
131 {
132 
133  rate = this->camera->AvgFPS();
134  _image = this->camera->ImageData(0);
135  frame_time = this->camera->LastRenderWallTime().Double();
136 
137  frame_time_us = (frame_time - first_frame_time) * 1e6; //since start
138 
139  timer_.stop();
140 
141  float flow_x_ang = 0;
142  float flow_y_ang = 0;
143  //calculate angular flow
144  int quality = _optical_flow->calcFlow((uint8_t *)_image, frame_time_us, dt_us, flow_x_ang, flow_y_ang);
145 
146 
147 
148  if (quality >= 0) { // calcFlow(...) returns -1 if data should not be published yet -> output_rate
149  //prepare optical flow message
150  opticalFlow_message.set_time_usec(0);//will be filled in simulator_mavlink.cpp
151  opticalFlow_message.set_sensor_id(2.0);
152  opticalFlow_message.set_integration_time_us(dt_us);
153  opticalFlow_message.set_integrated_x(flow_x_ang);
154  opticalFlow_message.set_integrated_y(flow_y_ang);
155  opticalFlow_message.set_integrated_xgyro(0.0); //get real values in gazebo_mavlink_interface.cpp
156  opticalFlow_message.set_integrated_ygyro(0.0); //get real values in gazebo_mavlink_interface.cpp
157  opticalFlow_message.set_integrated_zgyro(0.0); //get real values in gazebo_mavlink_interface.cpp
158  opticalFlow_message.set_temperature(20.0);
159  opticalFlow_message.set_quality(quality);
160  opticalFlow_message.set_time_delta_distance_us(0.0);
161  opticalFlow_message.set_distance(0.0); //get real values in gazebo_mavlink_interface.cpp
162  //send message
163  opticalFlow_pub_->Publish(opticalFlow_message);
164  timer_.start();
165  }
166 }
167 
168 /* vim: set et fenc=utf-8 ff=unix sts=0 sw=2 ts=2 : */
std::string format(const std::string &fmt, Args ... args)
GZ_REGISTER_SENSOR_PLUGIN(GazeboGpsPlugin)
virtual void OnNewFrame(const unsigned char *_image, unsigned int _width, unsigned int _height, unsigned int _depth, const std::string &_format)
static const bool kPrintOnPluginLoad
Definition: common.h:41
virtual void Load(sensors::SensorPtr _sensor, sdf::ElementPtr _sdf)
INLINE Rall1d< T, V, S > tan(const Rall1d< T, V, S > &arg)
gazebo::transport::NodePtr node_handle_


rotors_gazebo_plugins
Author(s): Fadri Furrer, Michael Burri, Mina Kamel, Janosch Nikolic, Markus Achtelik
autogenerated on Mon Feb 28 2022 23:39:04