gazebo_optical_flow_plugin.cpp
Go to the documentation of this file.
00001 
00002 /*
00003  * Copyright (C) 2012-2015 Open Source Robotics Foundation
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License");
00006  * you may not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  *     http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  *
00017 */
00018 #ifdef _WIN32
00019   // Ensure that Winsock2.h is included before Windows.h, which can get
00020   // pulled in by anybody (e.g., Boost).
00021 #include <Winsock2.h>
00022 #endif
00023 
00024 #include "gazebo/sensors/DepthCameraSensor.hh"
00025 
00026 #include "rotors_gazebo_plugins/common.h"
00027 #include "rotors_gazebo_plugins/external/gazebo_optical_flow_plugin.h"
00028 
00029 #include <highgui.h>
00030 #include <math.h>
00031 #include <string>
00032 #include <iostream>
00033 #include <boost/algorithm/string.hpp>
00034 
00035 using namespace cv;
00036 using namespace std;
00037 
00038 using namespace gazebo;
00039 GZ_REGISTER_SENSOR_PLUGIN(OpticalFlowPlugin)
00040 
00041 
00042 OpticalFlowPlugin::OpticalFlowPlugin()
00043 : SensorPlugin(), width(0), height(0), depth(0), timer_()
00044 {
00045 
00046 }
00047 
00049 OpticalFlowPlugin::~OpticalFlowPlugin()
00050 {
00051   this->parentSensor.reset();
00052   this->camera.reset();
00053 }
00054 
00056 void OpticalFlowPlugin::Load(sensors::SensorPtr _sensor, sdf::ElementPtr _sdf)
00057 {
00058   if(kPrintOnPluginLoad) {
00059     gzdbg << __FUNCTION__ << "() called." << std::endl;
00060   }
00061 
00062   if (!_sensor)
00063     gzerr << "Invalid sensor pointer.\n";
00064 
00065   this->parentSensor =
00066     std::dynamic_pointer_cast<sensors::CameraSensor>(_sensor);
00067 
00068   if (!this->parentSensor)
00069   {
00070     gzerr << "OpticalFlowPlugin requires a CameraSensor.\n";
00071     if (std::dynamic_pointer_cast<sensors::DepthCameraSensor>(_sensor))
00072       gzmsg << "It is a depth camera sensor\n";
00073   }
00074 
00075   this->camera = this->parentSensor->Camera();
00076 
00077   if (!this->parentSensor)
00078   {
00079     gzerr << "OpticalFlowPlugin not attached to a camera sensor\n";
00080     return;
00081   }
00082 
00083   this->width = this->camera->ImageWidth();
00084   this->height = this->camera->ImageHeight();
00085   this->depth = this->camera->ImageDepth();
00086   this->format = this->camera->ImageFormat();
00087 
00088   if (this->width != 64 || this->height != 64) {
00089     gzerr << "[gazebo_optical_flow_plugin] Incorrect image size, must by 64 x 64.\n";
00090   }
00091 
00092   if (_sdf->HasElement("robotNamespace"))
00093     namespace_ = _sdf->GetElement("robotNamespace")->Get<std::string>();
00094   else
00095     gzwarn << "[gazebo_optical_flow_plugin] Please specify a robotNamespace.\n";
00096 
00097   node_handle_ = transport::NodePtr(new transport::Node());
00098   node_handle_->Init(namespace_);
00099 
00100   const string scopedName = _sensor->ParentName();
00101 
00102   string topicName = "~/" + scopedName + "/opticalFlow";
00103   boost::replace_all(topicName, "::", "/");
00104 
00105   opticalFlow_pub_ = node_handle_->Advertise<opticalFlow_msgs::msgs::opticalFlow>(topicName, 10);
00106 
00107   hfov = float(this->camera->HFOV().Radian());
00108   first_frame_time = this->camera->LastRenderWallTime().Double();
00109 
00110   old_frame_time = first_frame_time;
00111   focal_length = (this->width/2)/tan(hfov/2);
00112 
00113   this->newFrameConnection = this->camera->ConnectNewImageFrame(
00114       boost::bind(&OpticalFlowPlugin::OnNewFrame, this, _1, this->width, this->height, this->depth, this->format));
00115 
00116   this->parentSensor->SetActive(true);
00117 
00118   //init flow
00119   const int ouput_rate = 20; // -1 means use rate of camera
00120   _optical_flow = new OpticalFlowOpenCV(focal_length, focal_length, ouput_rate);
00121   // _optical_flow = new OpticalFlowPX4(focal_length, focal_length, ouput_rate, this->width);
00122 
00123 }
00124 
00126 void OpticalFlowPlugin::OnNewFrame(const unsigned char * _image,
00127                               unsigned int _width,
00128                               unsigned int _height,
00129                               unsigned int _depth,
00130                               const std::string &_format)
00131 {
00132 
00133   rate = this->camera->AvgFPS();
00134   _image = this->camera->ImageData(0);
00135   frame_time = this->camera->LastRenderWallTime().Double();
00136 
00137   frame_time_us = (frame_time - first_frame_time) * 1e6; //since start
00138 
00139   timer_.stop();
00140 
00141   float flow_x_ang = 0;
00142   float flow_y_ang = 0;
00143   //calculate angular flow
00144   int quality = _optical_flow->calcFlow((uint8_t *)_image, frame_time_us, dt_us, flow_x_ang, flow_y_ang);
00145 
00146 
00147 
00148   if (quality >= 0) { // calcFlow(...) returns -1 if data should not be published yet -> output_rate
00149     //prepare optical flow message
00150     opticalFlow_message.set_time_usec(0);//will be filled in simulator_mavlink.cpp
00151     opticalFlow_message.set_sensor_id(2.0);
00152     opticalFlow_message.set_integration_time_us(dt_us);
00153     opticalFlow_message.set_integrated_x(flow_x_ang);
00154     opticalFlow_message.set_integrated_y(flow_y_ang);
00155     opticalFlow_message.set_integrated_xgyro(0.0); //get real values in gazebo_mavlink_interface.cpp
00156     opticalFlow_message.set_integrated_ygyro(0.0); //get real values in gazebo_mavlink_interface.cpp
00157     opticalFlow_message.set_integrated_zgyro(0.0); //get real values in gazebo_mavlink_interface.cpp
00158     opticalFlow_message.set_temperature(20.0);
00159     opticalFlow_message.set_quality(quality);
00160     opticalFlow_message.set_time_delta_distance_us(0.0);
00161     opticalFlow_message.set_distance(0.0); //get real values in gazebo_mavlink_interface.cpp
00162     //send message
00163     opticalFlow_pub_->Publish(opticalFlow_message);
00164     timer_.start();
00165   }
00166 }
00167 
00168 /* vim: set et fenc=utf-8 ff=unix sts=0 sw=2 ts=2 : */


rotors_gazebo_plugins
Author(s): Fadri Furrer, Michael Burri, Mina Kamel, Janosch Nikolic, Markus Achtelik
autogenerated on Thu Apr 18 2019 02:43:43