注:室外版对GPS和气压计的初始化漂移进行了补偿,可以用于室内,室内版的代码不能用于室外,切忌切忌切忌 #include < ros/ ros. h> 
#include < std_msgs/ Bool. h> 
#include < geometry_msgs/ PoseStamped. h> 
#include < geometry_msgs/ TwistStamped. h> 
#include < mavros_msgs/ CommandBool. h> 
#include < mavros_msgs/ SetMode. h> 
#include < mavros_msgs/ State. h> 
#include < mavros_msgs/ PositionTarget. h> 
#include < cmath> 
#include < tf/ transform_listener. h> 
#include < nav_msgs/ Odometry. h> 
#include < mavros_msgs/ CommandLong. h>    
#include < string> #define MAX_ERROR  0.20 
#define VEL_SET    0.10 
#define ALTITUDE   0.40 using namespace std; float target_x_angle =  0 ; 
float target_distance =  1500 ; 
float target_hgt =  0 ; 
float linear_x_p =  0.6 ; 
float linear_x_d =  0.22 ; 
float yaw_rate_p =  0.8 ; 
float yaw_rate_d =  0.5 ; 
float x_angle_threshold =  0.1 ; 
float distance_threshold =  300 ; 
float linear_z_p =  0.5 ; 
float linear_z_d =  0.33 ; 
float hgt_threshold =  100 ; 
float max_velocity_z =  0.3 ; 
float max_raw_velocity_x =  2.0 ; 
float max_raw_yaw_rate =  1.0 ; geometry_msgs : : PointStamped object_pos; tf : : Quaternion quat;  
double roll,  pitch,  yaw; 
float init_position_x_take_off = 0 ; 
float init_position_y_take_off = 0 ; 
float init_position_z_take_off = 0 ; 
bool  flag_init_position =  false ;  
nav_msgs : : Odometry local_pos; mavros_msgs : : State current_state;   
mavros_msgs : : PositionTarget setpoint_raw; 
string current_frame_id   =  "no_object" ; 
double current_position_x =  0 ; 
double current_position_y =  0 ; 
double current_distance   =  0 ; 
double current_position_z =  0 ; int tmp_flag_frame =  0 ; 
ros : : Subscriber state_sub; 
ros : : Subscriber local_pos_sub; 
ros : : Subscriber object_pos_sub; 
ros : : Publisher  mavros_setpoint_pos_pub; 
ros : : ServiceClient arming_client; 
ros : : ServiceClient set_mode_client; bool  flag_no_object =  false ; 
bool  temp_flag_no_object =  true ; 
bool  temp_flag =  true ; 
float current_x_record =  0 ;  
float current_y_record =  0 ;  
float current_z_record =  0 ;  bool temp_flag_hgt =  true ; 
bool temp_flag_distance =  true ; 
bool temp_flag_hgt_distance =  true ; float temp_distance_threshold =  0 ; 
float temp_hgt_threshold      =  0 ; 
void  pid_control ( ) 
{ static  float last_error_x_angle =  0 ; static  float last_error_distance =  0 ; static  float last_error_hgt =  0 ; float x_angle; float distance; float hgt; if ( current_position_x ==  0  &&  current_position_y ==  0  &&  current_distance ==  0 ) { flag_no_object =  true ; x_angle  =  target_x_angle; distance =  target_distance; hgt =  target_hgt; } else { flag_no_object =  false ; x_angle  =  current_position_x /  current_distance; distance =  current_distance; hgt      =  current_position_y; } float error_x_angle =  x_angle -  target_x_angle; float error_distance =  distance -  target_distance; float error_hgt =  hgt -  target_hgt; if ( error_x_angle >  - x_angle_threshold &&  error_x_angle <  x_angle_threshold)   { error_x_angle =  0 ; } if ( error_distance >  - distance_threshold &&  error_distance <  distance_threshold)  { error_distance =  0 ; } if  ( error_hgt >  - hgt_threshold &&  error_hgt <  hgt_threshold) { error_hgt =  0 ; } printf ( "hgt = %f\r\n" , hgt) ; printf ( "error_hgt = %f\r\n" , error_hgt) ; printf ( "error_x_angle = %f\r\n" , error_x_angle) ; setpoint_raw. velocity. x =  error_distance* linear_x_p/ 1000  +  ( error_distance -  last_error_distance) * linear_x_d/ 1000 ; if ( setpoint_raw. velocity. x <  - max_raw_velocity_x)   { setpoint_raw. velocity. x =  - max_raw_velocity_x; } else  if ( setpoint_raw. velocity. x >  max_raw_velocity_x)  { setpoint_raw. velocity. x =  max_raw_velocity_x; 	} setpoint_raw. velocity. z =  error_hgt *  linear_z_p/ 1000  +  ( error_hgt -  last_error_hgt)  *  linear_z_d/ 1000 ; if  ( setpoint_raw. velocity. z <  - max_velocity_z) { setpoint_raw. velocity. z =  - max_velocity_z; } else  if  ( setpoint_raw. velocity. z >  max_velocity_z) { setpoint_raw. velocity. z =  max_velocity_z; } setpoint_raw. yaw_rate =  error_x_angle* yaw_rate_p +  ( error_x_angle -  last_error_x_angle) * yaw_rate_d; if ( setpoint_raw. yaw_rate <  - max_raw_yaw_rate)   { setpoint_raw. yaw_rate =  - max_raw_yaw_rate; } else  if ( setpoint_raw. yaw_rate >  max_raw_yaw_rate)  { setpoint_raw. yaw_rate =  max_raw_yaw_rate; } if ( fabs ( setpoint_raw. yaw_rate)  <  0.1 )   { setpoint_raw. yaw_rate =  0 ; } if ( flag_no_object) { setpoint_raw. type_mask =   +  64  +  128  +  256  +  512  +  1024  ; 			if ( temp_flag_no_object) { temp_flag_no_object =  false ; current_x_record =  local_pos. pose. pose. position. x; current_y_record =  local_pos. pose. pose. position. y; current_z_record =  local_pos. pose. pose. position. z; } setpoint_raw. position. x =  current_x_record; setpoint_raw. position. y =  current_y_record; setpoint_raw. position. z =  current_z_record; setpoint_raw. coordinate_frame =  1 ; } else { temp_flag_no_object =  true ; if ( fabs ( error_hgt) <= hgt_threshold) { if ( temp_flag_hgt) { temp_flag_hgt =  false ; 					current_z_record =  local_pos. pose. pose. position. z; } if ( error_hgt>= 0 ) { setpoint_raw. position. z =  current_z_record +  0.4 * hgt_threshold* 0.001 ; } else { setpoint_raw. position. z =  current_z_record -  0.4 * hgt_threshold* 0.001 ; } setpoint_raw. type_mask =  1  +  2   +  64  +  128  +  256  +  512  +  1024  ; setpoint_raw. coordinate_frame =  8 ; } else { temp_flag_hgt =  true ; setpoint_raw. type_mask =  1  +  2  +  4   +  64  +  128  +  256  +  512  +  1024  ; setpoint_raw. coordinate_frame =  8 ; } } 		mavros_setpoint_pos_pub. publish ( setpoint_raw) ; last_error_x_angle  =  error_x_angle; last_error_distance =  error_distance; last_error_hgt      =  error_hgt; } void  state_cb ( const  mavros_msgs : : State: : ConstPtr&  msg) 
{ current_state =  * msg; 
} void  local_pos_cb ( const  nav_msgs : : Odometry: : ConstPtr&  msg) 
{ local_pos =  * msg; if  ( flag_init_position== false  &&  ( local_pos. pose. pose. position. z!= 0 ) ) { init_position_x_take_off =  local_pos. pose. pose. position. x; init_position_y_take_off =  local_pos. pose. pose. position. y; init_position_z_take_off =  local_pos. pose. pose. position. z; flag_init_position =  true ; 		    } 	
} double positon_x_table[ 5 ] = { } ; 
double positon_y_table[ 5 ] = { } ; 
double distance_table[ 5 ]  = { } ; 
int count_positon_x =  0 ; 
int count_positon_y =  0 ; 
int count_distance  =  0 ; void  object_pos_cb ( const  geometry_msgs : : PointStamped: : ConstPtr&  msg) 
{ double temp_current_position_x; double temp_current_position_y; double temp_current_distance; int count_target_lost =  0 ; object_pos =  * msg; current_frame_id   =  object_pos. header. frame_id;  tf : : quaternionMsgToTF ( local_pos. pose. pose. orientation,  quat) ; 	tf : : Matrix3x3 ( quat) . getRPY ( roll,  pitch,  yaw) ; printf ( "pitch = %f\r\n" , pitch) ; temp_current_position_x =  object_pos. point. x* ( - 1000 ) ; temp_current_position_y =  object_pos. point. y* ( - 1000 ) ; temp_current_distance   =  object_pos. point. z* ( 1000 ) / cos ( pitch) ; printf ( "temp_current_distance = %f\r\n" , temp_current_distance) ; positon_x_table[ count_positon_x]  =  temp_current_position_x; count_positon_x++ ; if ( count_positon_x>= 5 ) { count_positon_x =  0 ; }  positon_y_table[ count_positon_y]  =  temp_current_position_y; count_positon_y++ ; if ( count_positon_y>= 5 ) { count_positon_y =  0 ; } distance_table[ count_distance]  =  temp_current_distance; count_distance++ ; if ( count_distance>= 5 ) { count_distance =  0 ; }  double temp_positon_x_table[ 5 ] = { } ; double temp_positon_y_table[ 5 ] = { } ; double temp_distance_table[ 5 ]  = { } ; int temp_i =  0 ; for ( int i= 0 ; i<= 4 ; i++ ) { if ( positon_x_table[ i] == 0  &&  positon_y_table[ i] == 0  &&  distance_table[ i] == 0 ) { count_target_lost++ ; ROS_INFO ( "count_target_lost = %d" , count_target_lost) ;  } else { temp_positon_x_table[ temp_i]  =   positon_x_table[ i] ; temp_positon_y_table[ temp_i]  =   positon_y_table[ i] ; temp_distance_table[ temp_i]   =   distance_table[ i] ; temp_i++ ; } } if ( count_target_lost> 3 ) { current_position_x =  0 ; current_position_y =  0 ; current_distance   =  0 ; } else { current_position_x =  ( temp_positon_x_table[ 0 ] + temp_positon_x_table[ 1 ] + temp_positon_x_table[ 2 ] ) / 3 ; current_position_y =  ( temp_positon_y_table[ 0 ] + temp_positon_y_table[ 1 ] + temp_positon_y_table[ 2 ] ) / 3 ; current_distance   =  ( temp_distance_table[ 0 ]  + temp_distance_table[ 1 ]  + temp_distance_table[ 2 ] ) / 3 ; } if ( tmp_flag_frame ==  1 ) { pid_control ( ) ; 	 } 
} int main ( int argc,  char * argv[ ]  ) 
{ ros : : init ( argc,  argv,  "follow_pid" ) ; ros : : NodeHandle nh; state_sub     =  nh. subscribe< mavros_msgs: : State> ( "mavros/state" ,  100 ,  state_cb) ; local_pos_sub =  nh. subscribe< nav_msgs: : Odometry> ( "/mavros/local_position/odom" ,  100 ,  local_pos_cb) ; object_pos_sub =  nh. subscribe< geometry_msgs: : PointStamped> ( "object_position" ,  100 ,  object_pos_cb) ; mavros_setpoint_pos_pub =  nh. advertise< mavros_msgs: : PositionTarget> ( "/mavros/setpoint_raw/local" ,  100 ) ;    arming_client =  nh. serviceClient< mavros_msgs: : CommandBool> ( "mavros/cmd/arming" ) ; set_mode_client =  nh. serviceClient< mavros_msgs: : SetMode> ( "mavros/set_mode" ) ; ros : : Rate rate ( 20.0 ) ;  ros : : param: : get ( "linear_x_p" , linear_x_p) ; ros : : param: : get ( "linear_x_d" , linear_x_d) ; ros : : param: : get ( "yaw_rate_p" , yaw_rate_p) ; ros : : param: : get ( "yaw_rate_d" , yaw_rate_d) ; ros : : param: : get ( "target_x_angle" ,  target_x_angle) ; ros : : param: : get ( "target_distance" , target_distance) ; ros : : param: : get ( "x_angle_threshold" ,  x_angle_threshold) ; ros : : param: : get ( "distance_threshold" ,  distance_threshold) ; ros : : param: : get ( "linear_z_p" ,  linear_z_d) ; ros : : param: : get ( "target_hgt" ,  target_hgt) ; ros : : param: : get ( "hgt_threshold" ,  hgt_threshold) ; ros : : param: : get ( "max_velocity_z" , max_velocity_z) ; ros : : param: : get ( "max_raw_velocity_x" , max_raw_velocity_x) ; ros : : param: : get ( "max_raw_yaw_rate" , max_raw_yaw_rate) ; temp_distance_threshold =  distance_threshold; temp_hgt_threshold      =  hgt_threshold; printf ( "temp_distance_threshold = %f\r\n" , temp_distance_threshold) ; printf ( "temp_hgt_threshold = %f\r\n" ,      temp_hgt_threshold) ; while ( ros: : ok ( )  &&  current_state. connected) { ros : : spinOnce ( ) ; rate. sleep ( ) ; } setpoint_raw. type_mask =   +  64  +  128  +  256  +  512  ; setpoint_raw. coordinate_frame =  1 ; setpoint_raw. position. x =  0 ; setpoint_raw. position. y =  0 ; setpoint_raw. position. z =  0  +  ALTITUDE ; mavros_setpoint_pos_pub. publish ( setpoint_raw) ; for ( int i =  100 ;  ros: : ok ( )  &&  i >  0 ;  -- i) { mavros_setpoint_pos_pub. publish ( setpoint_raw) ; ros : : spinOnce ( ) ; rate. sleep ( ) ; } mavros_msgs : : SetMode offb_set_mode; offb_set_mode. request. custom_mode =  "OFFBOARD" ; mavros_msgs : : CommandBool arm_cmd; arm_cmd. request. value =  true ; ros : : Time last_request =  ros: : Time: : now ( ) ; while ( ros: : ok ( ) ) { if (  current_state. mode !=  "OFFBOARD"  &&  ( ros: : Time: : now ( )  -  last_request >  ros: : Duration ( 5.0 ) ) ) { if (  set_mode_client . call ( offb_set_mode)  &&  offb_set_mode. response. mode_sent) { ROS_INFO ( "Offboard enabled" ) ; } last_request =  ros: : Time: : now ( ) ; } else  { if (  ! current_state. armed &&  ( ros: : Time: : now ( )  -  last_request >  ros: : Duration ( 5.0 ) ) ) { if (  arming_client . call ( arm_cmd)  &&  arm_cmd. response. success) { ROS_INFO ( "Vehicle armed" ) ; } last_request =  ros: : Time: : now ( ) ; } } if ( fabs ( local_pos. pose. pose. position. z- ALTITUDE ) < 0.1 ) { if ( ros: : Time: : now ( )  -  last_request >  ros: : Duration ( 1.0 ) ) { tmp_flag_frame=  1 ; break ; } } mavros_setpoint_pos_pub. publish ( setpoint_raw) ; ros : : spinOnce ( ) ; rate. sleep ( ) ; }   while ( ros: : ok ( ) ) { mavros_setpoint_pos_pub. publish ( setpoint_raw) ; ros : : spinOnce ( ) ; rate. sleep ( ) ; } } 
#include < ros/ ros. h> 
#include < std_msgs/ Bool. h> 
#include < geometry_msgs/ PoseStamped. h> 
#include < geometry_msgs/ TwistStamped. h> 
#include < mavros_msgs/ CommandBool. h> 
#include < mavros_msgs/ SetMode. h> 
#include < mavros_msgs/ State. h> 
#include < mavros_msgs/ PositionTarget. h> 
#include < cmath> 
#include < tf/ transform_listener. h> 
#include < nav_msgs/ Odometry. h> 
#include < mavros_msgs/ CommandLong. h>    
#include < string> #define MAX_ERROR  0.20 
#define VEL_SET    0.10 
#define ALTITUDE   1.0 using namespace std; float target_x_angle =  0 ; 
float target_distance =  1500 ; 
float target_hgt =  0 ; 
float linear_x_p =  0.6 ; 
float linear_x_d =  0.22 ; 
float yaw_rate_p =  0.8 ; 
float yaw_rate_d =  0.5 ; 
float x_angle_threshold =  0.1 ; 
float distance_threshold =  300 ; 
float linear_z_p =  0.5 ; 
float linear_z_d =  0.33 ; 
float hgt_threshold =  100 ; 
float max_velocity_z =  0.3 ; 
float max_raw_velocity_x =  2.0 ; 
float max_raw_yaw_rate =  1.0 ; geometry_msgs : : PointStamped object_pos; tf : : Quaternion quat;  
double roll,  pitch,  yaw; 
float init_position_x_take_off = 0 ; 
float init_position_y_take_off = 0 ; 
float init_position_z_take_off = 0 ; 
bool  flag_init_position =  false ;  
nav_msgs : : Odometry local_pos; mavros_msgs : : State current_state;   
mavros_msgs : : PositionTarget setpoint_raw; 
string current_frame_id   =  "no_object" ; 
double current_position_x =  0 ; 
double current_position_y =  0 ; 
double current_distance   =  0 ; 
double current_position_z =  0 ; int tmp_flag_frame =  0 ; 
ros : : Subscriber state_sub; 
ros : : Subscriber local_pos_sub; 
ros : : Subscriber object_pos_sub; 
ros : : Publisher  mavros_setpoint_pos_pub; 
ros : : ServiceClient arming_client; 
ros : : ServiceClient set_mode_client; bool  flag_no_object =  false ; 
bool  temp_flag_no_object =  true ; 
bool  temp_flag =  true ; 
float current_x_record =  0 ;  
float current_y_record =  0 ;  
float current_z_record =  0 ;  bool temp_flag_hgt =  true ; 
float temp_distance_threshold =  0 ; 
float temp_hgt_threshold      =  0 ; 
void  pid_control ( ) 
{ static  float last_error_x_angle =  0 ; static  float last_error_distance =  0 ; static  float last_error_hgt =  0 ; float x_angle; float distance; float hgt; if ( current_position_x ==  0  &&  current_position_y ==  0  &&  current_distance ==  0 ) { flag_no_object =  true ; x_angle  =  target_x_angle; distance =  target_distance; hgt =  target_hgt; } else { flag_no_object =  false ; x_angle  =  current_position_x /  current_distance; distance =  current_distance; hgt      =  current_position_y; } float error_x_angle =  x_angle -  target_x_angle; float error_distance =  distance -  target_distance; float error_hgt =  hgt -  target_hgt; if ( error_x_angle >  - x_angle_threshold &&  error_x_angle <  x_angle_threshold)   { error_x_angle =  0 ; } if ( error_distance >  - distance_threshold &&  error_distance <  distance_threshold)  { error_distance =  0 ; } if  ( error_hgt >  - hgt_threshold &&  error_hgt <  hgt_threshold) { error_hgt =  0 ; } printf ( "hgt = %f\r\n" , hgt) ; printf ( "error_hgt = %f\r\n" , error_hgt) ; printf ( "error_x_angle = %f\r\n" , error_x_angle) ; setpoint_raw. velocity. x =  error_distance* linear_x_p/ 1000  +  ( error_distance -  last_error_distance) * linear_x_d/ 1000 ; if ( setpoint_raw. velocity. x <  - max_raw_velocity_x)   { setpoint_raw. velocity. x =  - max_raw_velocity_x; } else  if ( setpoint_raw. velocity. x >  max_raw_velocity_x)  { setpoint_raw. velocity. x =  max_raw_velocity_x; 	} setpoint_raw. velocity. z =  error_hgt *  linear_z_p/ 1000  +  ( error_hgt -  last_error_hgt)  *  linear_z_d/ 1000 ; if  ( setpoint_raw. velocity. z <  - max_velocity_z) { setpoint_raw. velocity. z =  - max_velocity_z; } else  if  ( setpoint_raw. velocity. z >  max_velocity_z) { setpoint_raw. velocity. z =  max_velocity_z; } setpoint_raw. yaw_rate =  error_x_angle* yaw_rate_p +  ( error_x_angle -  last_error_x_angle) * yaw_rate_d; if ( setpoint_raw. yaw_rate <  - max_raw_yaw_rate)   { setpoint_raw. yaw_rate =  - max_raw_yaw_rate; } else  if ( setpoint_raw. yaw_rate >  max_raw_yaw_rate)  { setpoint_raw. yaw_rate =  max_raw_yaw_rate; } if ( fabs ( setpoint_raw. yaw_rate)  <  0.1 )   { setpoint_raw. yaw_rate =  0 ; } if ( flag_no_object) { printf ( "no_object\r\n" ) ; setpoint_raw. type_mask =   +  64  +  128  +  256  +  512  +  1024  ; 			if ( temp_flag_no_object) { temp_flag_no_object =  false ; current_x_record =  local_pos. pose. pose. position. x; current_y_record =  local_pos. pose. pose. position. y; current_z_record =  local_pos. pose. pose. position. z; } setpoint_raw. position. x =  current_x_record; setpoint_raw. position. y =  current_y_record; setpoint_raw. position. z =  current_z_record; setpoint_raw. coordinate_frame =  1 ; } else { printf ( "yes_object\r\n" ) ; temp_flag_no_object =  true ; if ( fabs ( error_hgt) <= hgt_threshold) { if ( temp_flag_hgt) { temp_flag_hgt =  false ; 					current_z_record =  local_pos. pose. pose. position. z; } if ( error_hgt> 0 ) { setpoint_raw. position. z =  current_z_record +  0.4 * hgt_threshold* 0.001 ; } else { setpoint_raw. position. z =  current_z_record -  0.4 * hgt_threshold* 0.001 ; } setpoint_raw. type_mask =  1  +  2   +  64  +  128  +  256  +  512  +  1024  ; setpoint_raw. coordinate_frame =  8 ; } else { temp_flag_hgt =  true ; setpoint_raw. type_mask =  1  +  2  +  4   +  64  +  128  +  256  +  512  +  1024  ; setpoint_raw. coordinate_frame =  8 ; } } 	printf ( "error_hgt = %f\r\n" , error_hgt) ; 	printf ( "current_x_record = %f\r\n" , current_x_record) ; printf ( "current_y_record = %f\r\n" , current_y_record) ; printf ( "current_z_record = %f\r\n" , current_z_record) ; printf ( "setpoint_raw.position.x = %f\r\n" , setpoint_raw. position. x) ; 		printf ( "setpoint_raw.position.y = %f\r\n" , setpoint_raw. position. y) ; 		printf ( "setpoint_raw.position.z = %f\r\n" , setpoint_raw. position. z) ; 		mavros_setpoint_pos_pub. publish ( setpoint_raw) ; last_error_x_angle  =  error_x_angle; last_error_distance =  error_distance; last_error_hgt      =  error_hgt; } void  state_cb ( const  mavros_msgs : : State: : ConstPtr&  msg) 
{ current_state =  * msg; 
} void  local_pos_cb ( const  nav_msgs : : Odometry: : ConstPtr&  msg) 
{ local_pos =  * msg; if ( flag_init_position== false  &&  ( local_pos. pose. pose. position. z!= 0 ) ) { init_position_x_take_off =  local_pos. pose. pose. position. x; init_position_y_take_off =  local_pos. pose. pose. position. y; init_position_z_take_off =  local_pos. pose. pose. position. z; flag_init_position =  true ; 		    } 	
} double positon_x_table[ 5 ] = { } ; 
double positon_y_table[ 5 ] = { } ; 
double distance_table[ 5 ]  = { } ; 
int count_positon_x =  0 ; 
int count_positon_y =  0 ; 
int count_distance  =  0 ; void  object_pos_cb ( const  geometry_msgs : : PointStamped: : ConstPtr&  msg) 
{ double temp_current_position_x; double temp_current_position_y; double temp_current_distance; int count_target_lost =  0 ; object_pos =  * msg; current_frame_id   =  object_pos. header. frame_id;  tf : : quaternionMsgToTF ( local_pos. pose. pose. orientation,  quat) ; 	tf : : Matrix3x3 ( quat) . getRPY ( roll,  pitch,  yaw) ; temp_current_position_x =  object_pos. point. x* ( - 1000 ) ; temp_current_position_y =  object_pos. point. y* ( - 1000 ) ; temp_current_distance   =  object_pos. point. z* ( 1000 ) / cos ( pitch) ; positon_x_table[ count_positon_x]  =  temp_current_position_x; count_positon_x++ ; if ( count_positon_x>= 5 ) { count_positon_x =  0 ; }  positon_y_table[ count_positon_y]  =  temp_current_position_y; count_positon_y++ ; if ( count_positon_y>= 5 ) { count_positon_y =  0 ; } distance_table[ count_distance]  =  temp_current_distance; count_distance++ ; if ( count_distance>= 5 ) { count_distance =  0 ; }  double temp_positon_x_table[ 5 ] = { } ; double temp_positon_y_table[ 5 ] = { } ; double temp_distance_table[ 5 ]  = { } ; int temp_i =  0 ; for ( int i= 0 ; i<= 4 ; i++ ) { if ( positon_x_table[ i] == 0  &&  positon_y_table[ i] == 0  &&  distance_table[ i] == 0 ) { count_target_lost++ ; ROS_INFO ( "count_target_lost = %d" , count_target_lost) ;  } else { temp_positon_x_table[ temp_i]  =   positon_x_table[ i] ; temp_positon_y_table[ temp_i]  =   positon_y_table[ i] ; temp_distance_table[ temp_i]   =   distance_table[ i] ; temp_i++ ; } } if ( count_target_lost> 3 ) { current_position_x =  0 ; current_position_y =  0 ; current_distance   =  0 ; } else { current_position_x =  ( temp_positon_x_table[ 0 ] + temp_positon_x_table[ 1 ] + temp_positon_x_table[ 2 ] ) / 3 ; current_position_y =  ( temp_positon_y_table[ 0 ] + temp_positon_y_table[ 1 ] + temp_positon_y_table[ 2 ] ) / 3 ; current_distance   =  ( temp_distance_table[ 0 ]  + temp_distance_table[ 1 ]  + temp_distance_table[ 2 ] ) / 3 ; } if ( tmp_flag_frame ==  1 ) { pid_control ( ) ; 	 } 
} int main ( int argc,  char * argv[ ]  ) 
{ ros : : init ( argc,  argv,  "follow_pid" ) ; ros : : NodeHandle nh; state_sub     =  nh. subscribe< mavros_msgs: : State> ( "mavros/state" ,  100 ,  state_cb) ; local_pos_sub =  nh. subscribe< nav_msgs: : Odometry> ( "/mavros/local_position/odom" ,  100 ,  local_pos_cb) ; object_pos_sub =  nh. subscribe< geometry_msgs: : PointStamped> ( "object_position" ,  100 ,  object_pos_cb) ; mavros_setpoint_pos_pub =  nh. advertise< mavros_msgs: : PositionTarget> ( "/mavros/setpoint_raw/local" ,  100 ) ;    arming_client =  nh. serviceClient< mavros_msgs: : CommandBool> ( "mavros/cmd/arming" ) ; set_mode_client =  nh. serviceClient< mavros_msgs: : SetMode> ( "mavros/set_mode" ) ; ros : : Rate rate ( 20.0 ) ;  ros : : param: : get ( "linear_x_p" , linear_x_p) ; ros : : param: : get ( "linear_x_d" , linear_x_d) ; ros : : param: : get ( "yaw_rate_p" , yaw_rate_p) ; ros : : param: : get ( "yaw_rate_d" , yaw_rate_d) ; ros : : param: : get ( "target_x_angle" ,  target_x_angle) ; ros : : param: : get ( "target_distance" , target_distance) ; ros : : param: : get ( "x_angle_threshold" ,  x_angle_threshold) ; ros : : param: : get ( "distance_threshold" ,  distance_threshold) ; ros : : param: : get ( "linear_z_p" ,  linear_z_d) ; ros : : param: : get ( "target_hgt" ,  target_hgt) ; ros : : param: : get ( "hgt_threshold" ,  hgt_threshold) ; ros : : param: : get ( "max_velocity_z" , max_velocity_z) ; ros : : param: : get ( "max_raw_velocity_x" , max_raw_velocity_x) ; ros : : param: : get ( "max_raw_yaw_rate" , max_raw_yaw_rate) ; temp_distance_threshold =  distance_threshold; temp_hgt_threshold      =  hgt_threshold; printf ( "temp_distance_threshold = %f\r\n" , temp_distance_threshold) ; printf ( "temp_hgt_threshold = %f\r\n" ,      temp_hgt_threshold) ; while ( ros: : ok ( )  &&  current_state. connected) { ros : : spinOnce ( ) ; rate. sleep ( ) ; } setpoint_raw. type_mask =   +  64  +  128  +  256  +  512  ; setpoint_raw. coordinate_frame =  1 ; setpoint_raw. position. x =  init_position_x_take_off +  0 ; setpoint_raw. position. y =  init_position_y_take_off +  0 ; setpoint_raw. position. z =  init_position_z_take_off +  ALTITUDE ; mavros_setpoint_pos_pub. publish ( setpoint_raw) ; for ( int i =  100 ;  ros: : ok ( )  &&  i >  0 ;  -- i) { mavros_setpoint_pos_pub. publish ( setpoint_raw) ; ros : : spinOnce ( ) ; rate. sleep ( ) ; } mavros_msgs : : SetMode offb_set_mode; offb_set_mode. request. custom_mode =  "OFFBOARD" ; mavros_msgs : : CommandBool arm_cmd; arm_cmd. request. value =  true ; ros : : Time last_request =  ros: : Time: : now ( ) ; while ( ros: : ok ( ) ) { if (  current_state. mode !=  "OFFBOARD"  &&  ( ros: : Time: : now ( )  -  last_request >  ros: : Duration ( 5.0 ) ) ) { if (  set_mode_client . call ( offb_set_mode)  &&  offb_set_mode. response. mode_sent) { ROS_INFO ( "Offboard enabled" ) ; } last_request =  ros: : Time: : now ( ) ; } else  { if (  ! current_state. armed &&  ( ros: : Time: : now ( )  -  last_request >  ros: : Duration ( 5.0 ) ) ) { if (  arming_client . call ( arm_cmd)  &&  arm_cmd. response. success) { ROS_INFO ( "Vehicle armed" ) ; } last_request =  ros: : Time: : now ( ) ; } } if ( fabs ( local_pos. pose. pose. position. z- ALTITUDE ) < 0.1 ) { if ( ros: : Time: : now ( )  -  last_request >  ros: : Duration ( 1.0 ) ) { tmp_flag_frame=  1 ; break ; } } 		setpoint_raw. position. x =  init_position_x_take_off +  0 ; setpoint_raw. position. y =  init_position_y_take_off +  0 ; setpoint_raw. position. z =  init_position_z_take_off +  ALTITUDE ; mavros_setpoint_pos_pub. publish ( setpoint_raw) ; ros : : spinOnce ( ) ; rate. sleep ( ) ; }   while ( ros: : ok ( ) ) { mavros_setpoint_pos_pub. publish ( setpoint_raw) ; ros : : spinOnce ( ) ; rate. sleep ( ) ; } }