Go to the documentation of this file.00001 #include "ros/ros.h"
00002 #include "geometry_msgs/Vector3Stamped.h"
00003 #include <math.h>
00004 #include "mav_msgs/Height.h"
00005 #include <sensor_msgs/Imu.h>
00006 #include <tf/transform_datatypes.h>
00007 #include <math.h>
00008 
00009 ros::Publisher OF_message;
00010 double alpha, focal_length, current_height, delta_pitch, delta_roll;
00011 
00012 double sum_of_x =0,sum_of_y =0;
00013 
00014 double raw_dx=0,raw_dy=0;
00015 
00016 double last_roll, last_pitch;
00017 
00018 double last_time, current_time;
00019 ros::Duration t;
00020 btScalar yaw, pitch, roll;
00021 
00022 geometry_msgs::Vector3Stamped OF;
00023 
00024 
00026 
00027 
00029 
00030 void calc_field_of_view(void){
00031   double d=30*60*pow(10,-6);
00032   alpha=2*atan2(d,2*focal_length*pow(10,-3));
00033 }
00034 
00035 void OF_RawCallback(geometry_msgs::Vector3 const &msg){
00036     sum_of_x=sum_of_x+msg.x*0.01;
00037     sum_of_y=sum_of_y+msg.y*0.01;
00038     raw_dx=msg.x;
00039     raw_dy=msg.y;
00040     
00041     
00042 
00043     
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 
00058     
00059     
00060     
00061     
00062     
00063     
00064     
00065 }
00066 
00067 void imuCallback(sensor_msgs::Imu const &imu){
00068 
00069     
00070     current_time=ros::Time::now().toSec();
00071     if(last_time>0){
00072         last_roll=roll;
00073         last_pitch=pitch;
00074         tf::Quaternion orientation;
00075         tf::quaternionMsgToTF(imu.orientation, orientation);
00076         tf::Matrix3x3(orientation).getEulerYPR(yaw, pitch, roll);
00077 
00078         delta_pitch=pitch-last_pitch;
00079         delta_roll=roll-last_roll;
00080 
00081         
00082         OF.header.stamp=ros::Time::now();
00083         
00084         
00085         
00086         
00087         
00088         
00089         if(raw_dx==0){
00090             OF.vector.x=-sum_of_x;
00091         }else{
00092             OF.vector.x=-(sum_of_x+(30/alpha)*delta_pitch);
00093         }
00094         if(raw_dy==0){
00095             OF.vector.y=-sum_of_y;
00096         }else{
00097             OF.vector.y=-(sum_of_y+(30/alpha)*delta_roll);
00098         }
00099         OF_message.publish(OF);
00100         ROS_INFO("Comp Factor: %lf   %lf   %lf",OF.vector.y, sum_of_y, (30/alpha)*delta_roll);
00101     }
00102     else{
00103         tf::Quaternion orientation;
00104         tf::quaternionMsgToTF(imu.orientation, orientation);
00105         tf::Matrix3x3(orientation).getEulerYPR(yaw, pitch, roll);
00106     }
00107     last_time=current_time;
00108     sum_of_x=0;
00109     sum_of_y=0;
00110 
00111     
00112 
00113 
00114 
00115 
00116 
00117 }
00118 
00119 void heightCallback(const mav_msgs::Height& msg){
00120     
00121     current_height=msg.height+0.1;
00122 }
00123 
00124 int main(int argc, char **argv){
00125 
00126     ros::init(argc, argv, "quad_OF");
00127     ros::NodeHandle nh("~");
00128 
00129     nh.param("focal_length", focal_length, 12.0);
00130     calc_field_of_view();
00131 
00132     roll=0;
00133     last_roll=0;
00134     pitch=0;
00135     last_pitch=0;
00136     last_time = -1;
00137     current_time = -1;
00138 
00139     
00140     ros::Subscriber sub1 = nh.subscribe("/quad_height/height_to_base", 10, heightCallback);
00141     ros::Subscriber sub2 = nh.subscribe("/OF_Raw", 10, OF_RawCallback);
00142     ros::Subscriber sub3 = nh.subscribe("/imu/att", 10, &imuCallback);
00143 
00144     OF_message = nh.advertise<geometry_msgs::Vector3Stamped>("O_Flow", 10);
00145 
00146     ros::spin();
00147     return 0;
00148 }