bebop_driver_nodelet.cpp
Go to the documentation of this file.
1 
25 #include <ros/ros.h>
27 #include <nodelet/nodelet.h>
28 #include <nav_msgs/Odometry.h>
29 #include <sensor_msgs/JointState.h>
33 #include <sensor_msgs/NavSatFix.h>
34 
35 #include <boost/bind.hpp>
36 #include <boost/make_shared.hpp>
37 #include <boost/date_time/posix_time/posix_time.hpp>
38 #include <cmath>
39 #include <algorithm>
40 #include <string>
41 #include <cstdio>
42 
44 #include <bebop_driver/BebopArdrone3Config.h>
45 
46 // For AuxThread() - without the following, callback wrapper types are incomplete to the compiler
48 
50 
51 namespace bebop_driver
52 {
53 
54 namespace util
55 {
56 
57 int BebopPrintToROSLogCB(eARSAL_PRINT_LEVEL level, const char *tag, const char *format, va_list va)
58 {
59  const int32_t sz = vsnprintf(bebop_err_str, BEBOP_ERR_STR_SZ, format, va);
60  bebop_err_str[std::min(BEBOP_ERR_STR_SZ, sz) - 1] = '\0';
61  // We can't use variable names with ROS_*_NAMED macros
62  static const std::string logger_name = std::string(ROSCONSOLE_NAME_PREFIX) + "." +
63  ros::this_node::getName() + ".bebopsdk";
64  // Use tag inline
65  ROS_LOG(util::arsal_level_to_ros[level], logger_name, "[%s] %s", tag, bebop_err_str);
66  return 1;
67 }
68 
69 } // namespace util
70 
71 BebopDriverNodelet::BebopDriverNodelet()
72  : bebop_ptr_(new bebop_driver::Bebop(util::BebopPrintToROSLogCB))
73 {
74  NODELET_INFO("Nodelet Cstr");
75 }
76 
78 {
80  ros::NodeHandle& private_nh = getPrivateNodeHandle();
82  {
83  boost::unique_lock<boost::mutex> twist_lock(twist_mutex_);
87  }
88 
89  // Params (not dynamically reconfigurable, local)
90  // TODO(mani-monaj): Wrap all calls to .param() in a function call to enable logging
91  const bool param_reset_settings = private_nh.param("reset_settings", false);
92  const bool param_sync_time = private_nh.param("sync_time", false);
93  const std::string& param_camera_info_url = private_nh.param<std::string>("camera_info_url", "");
94  const std::string& param_bebop_ip = private_nh.param<std::string>("bebop_ip", "192.168.42.1");
95 
96  param_camera_frame_id_ = private_nh.param<std::string>("camera_frame_id", "camera_optical");
97  param_odom_frame_id_ = private_nh.param<std::string>("odom_frame_id", "odom");
98  param_publish_odom_tf_ = private_nh.param<bool>("publish_odom_tf", true);
99  param_cmd_vel_timeout_ = private_nh.param<double>("cmd_vel_timeout", 0.2);
100 
101  NODELET_INFO("Connecting to Bebop ...");
102  try
103  {
104  bebop_ptr_->Connect(nh, private_nh, param_bebop_ip);
105 
106  if (param_reset_settings)
107  {
108  NODELET_WARN("Resetting all settings ...");
109  bebop_ptr_->ResetAllSettings();
110  // Wait for 3 seconds
111  ros::Rate(ros::Duration(3.0)).sleep();
112  }
113 
114  if (param_sync_time)
115  {
116  NODELET_WARN("Syncing system and bebop time ...");
117  boost::posix_time::ptime system_time = ros::Time::now().toBoost();
118  std::string iso_time_str = boost::posix_time::to_iso_extended_string(system_time);
119  bebop_ptr_->SetDate(iso_time_str);
120  NODELET_INFO_STREAM("Current time: " << iso_time_str);
121  ros::Rate(ros::Duration(3.0)).sleep();
122  }
123 
124  NODELET_INFO("Fetching all settings from the Drone ...");
125  bebop_ptr_->RequestAllSettings();
126  ros::Rate(ros::Duration(3.0)).sleep();
127  }
128  catch (const std::runtime_error& e)
129  {
130  NODELET_FATAL_STREAM("Init failed: " << e.what());
131  // TODO(mani-monaj): Retry mechanism
132  throw e;
133  }
134 
135  cmd_vel_sub_ = nh.subscribe("cmd_vel", 1, &BebopDriverNodelet::CmdVelCallback, this);
136  camera_move_sub_ = nh.subscribe("camera_control", 1, &BebopDriverNodelet::CameraMoveCallback, this);
138  land_sub_ = nh.subscribe("land", 1, &BebopDriverNodelet::LandCallback, this);
141  navigatehome_sub_ = nh.subscribe("autoflight/navigate_home", 1, &BebopDriverNodelet::NavigateHomeCallback, this);
147  exposure_sub_ = nh.subscribe("set_exposure", 10, &BebopDriverNodelet::SetExposureCallback, this);
149 
150  odom_pub_ = nh.advertise<nav_msgs::Odometry>("odom", 30);
151  camera_joint_pub_ = nh.advertise<sensor_msgs::JointState>("joint_states", 10, true);
152  gps_fix_pub_ = nh.advertise<sensor_msgs::NavSatFix>("fix", 10, true);
153 
154  cinfo_manager_ptr_.reset(new camera_info_manager::CameraInfoManager(nh, "bebop_front", param_camera_info_url));
156  image_transport_pub_ = image_transport_ptr_->advertiseCamera("image_raw", 60);
157 
158  camera_info_msg_ptr_.reset(new sensor_msgs::CameraInfo());
159 
160  dynr_serv_ptr_.reset(new dynamic_reconfigure::Server<bebop_driver::BebopArdrone3Config>(private_nh));
161  dynamic_reconfigure::Server<bebop_driver::BebopArdrone3Config>::CallbackType cb =
162  boost::bind(&bebop_driver::BebopDriverNodelet::ParamCallback, this, _1, _2);
163 
164  dynr_serv_ptr_->setCallback(cb);
165 
166  try
167  {
168  NODELET_INFO("Enabling video stream ...");
169  bebop_ptr_->StartStreaming();
170  if (bebop_ptr_->IsStreamingStarted())
171  {
172  camera_pub_thread_ptr_ = boost::make_shared<boost::thread>(
173  boost::bind(&bebop_driver::BebopDriverNodelet::BebopDriverNodelet::CameraPublisherThread, this));
174  }
175  }
176  catch (const::std::runtime_error& e)
177  {
178  NODELET_ERROR_STREAM("Start() failed: " << e.what());
179  // TODO(mani-monaj): Retry mechanism
180  }
181 
182  aux_thread_ptr_ = boost::make_shared<boost::thread>(
183  boost::bind(&bebop_driver::BebopDriverNodelet::BebopDriverNodelet::AuxThread, this));
184 
185  NODELET_INFO_STREAM("Nodelet lwp_id: " << util::GetLWPId());
186 }
187 
189 {
190  NODELET_INFO_STREAM("Bebop Nodelet Dstr: " << bebop_ptr_->IsConnected());
191  NODELET_INFO_STREAM("Killing Camera Thread ...");
193  {
194  camera_pub_thread_ptr_->interrupt();
195  camera_pub_thread_ptr_->join();
196  }
197  NODELET_INFO_STREAM("Killing Aux Thread ...");
198  if (aux_thread_ptr_)
199  {
200  aux_thread_ptr_->interrupt();
201  aux_thread_ptr_->join();
202  }
203  if (bebop_ptr_->IsStreamingStarted()) bebop_ptr_->StopStreaming();
204  if (bebop_ptr_->IsConnected()) bebop_ptr_->Disconnect();
205 }
206 
207 void BebopDriverNodelet::CmdVelCallback(const geometry_msgs::TwistConstPtr& twist_ptr)
208 {
209  try
210  {
211  const geometry_msgs::Twist& bebop_twist_ = *twist_ptr;
212  bool is_bebop_twist_changed = false;
213  {
214  boost::unique_lock<boost::mutex> twist_lock(twist_mutex_);
215  is_bebop_twist_changed = !util::CompareTwists(bebop_twist_, prev_bebop_twist_);
217  prev_bebop_twist_ = bebop_twist_;
218  }
219 
220  // TODO: Always apply zero after non-zero values
221  if (is_bebop_twist_changed)
222  {
223  bebop_ptr_->Move(CLAMP(-bebop_twist_.linear.y, -1.0, 1.0),
224  CLAMP(bebop_twist_.linear.x, -1.0, 1.0),
225  CLAMP(bebop_twist_.linear.z, -1.0, 1.0),
226  CLAMP(-bebop_twist_.angular.z, -1.0, 1.0));
227  }
228  }
229  catch (const std::runtime_error& e)
230  {
231  ROS_ERROR_STREAM(e.what());
232  }
233 }
234 
235 void BebopDriverNodelet::TakeoffCallback(const std_msgs::EmptyConstPtr& empty_ptr)
236 {
237  try
238  {
239  bebop_ptr_->Takeoff();
240  }
241  catch (const std::runtime_error& e)
242  {
243  ROS_ERROR_STREAM(e.what());
244  }
245 }
246 
247 void BebopDriverNodelet::LandCallback(const std_msgs::EmptyConstPtr& empty_ptr)
248 {
249  try
250  {
251  bebop_ptr_->Land();
252  }
253  catch (const std::runtime_error& e)
254  {
255  ROS_ERROR_STREAM(e.what());
256  }
257 }
258 
259 // We shoudld probably switch to sensor_msgs/JointState instead of Twist
260 void BebopDriverNodelet::CameraMoveCallback(const geometry_msgs::TwistConstPtr& twist_ptr)
261 {
262  try
263  {
264  camera_twist_ = *twist_ptr;
265  const bool is_camera_twist_changed = !util::CompareTwists(camera_twist_, prev_camera_twist_);
266  if (is_camera_twist_changed)
267  {
268  bebop_ptr_->MoveCamera(CLAMP(camera_twist_.angular.y, -83.0, 17.0),
269  CLAMP(camera_twist_.angular.z, -35.0, 35.0));
271  }
272  }
273  catch (const std::runtime_error& e)
274  {
275  ROS_ERROR_STREAM(e.what());
276  }
277 }
278 
279 void BebopDriverNodelet::EmergencyCallback(const std_msgs::EmptyConstPtr& empty_ptr)
280 {
281  try
282  {
283  bebop_ptr_->Emergency();
284  }
285  catch (const std::runtime_error& e)
286  {
287  ROS_ERROR_STREAM(e.what());
288  }
289 }
290 
291 void BebopDriverNodelet::FlatTrimCallback(const std_msgs::EmptyConstPtr &empty_ptr)
292 {
293  try
294  {
295  // TODO(mani-monaj): Check if landed
296  ROS_INFO("Flat Trim");
297  bebop_ptr_->FlatTrim();
298  }
299  catch (const std::runtime_error& e)
300  {
301  ROS_ERROR_STREAM(e.what());
302  }
303 }
304 
305 void BebopDriverNodelet::NavigateHomeCallback(const std_msgs::BoolConstPtr &start_stop_ptr)
306 {
307  try
308  {
309  ROS_INFO("%sing navigate home behavior ...", start_stop_ptr->data ? "Start" : "Stopp");
310  bebop_ptr_->NavigateHome(start_stop_ptr->data);
311  }
312  catch (const std::runtime_error& e)
313  {
314  ROS_ERROR_STREAM(e.what());
315  }
316 }
317 
318 void BebopDriverNodelet::StartAutonomousFlightCallback(const std_msgs::StringConstPtr& filepath_ptr)
319 {
320  std::string filepath;
321  if (filepath_ptr->data.empty())
322  {
323  ROS_WARN("No flight plan provided. Using default: 'flightplan.mavlink'");
324  filepath = "flightplan.mavlink";
325  }
326  else
327  {
328  filepath = filepath_ptr->data;
329  }
330 
331  try
332  {
333  ROS_INFO("Starting autonomous flight path: %s", filepath.c_str());
334  bebop_ptr_->StartAutonomousFlight(filepath);
335  }
336  catch (const std::runtime_error& e)
337  {
338  ROS_ERROR_STREAM(e.what());
339  }
340 }
341 
342 void BebopDriverNodelet::PauseAutonomousFlightCallback(const std_msgs::EmptyConstPtr& empty_ptr)
343 {
344  try
345  {
346  ROS_INFO("Pausing autonomous flight");
347  bebop_ptr_->PauseAutonomousFlight();
348  }
349  catch (const std::runtime_error& e)
350  {
351  ROS_ERROR_STREAM(e.what());
352  }
353 }
354 
355 void BebopDriverNodelet::StopAutonomousFlightCallback(const std_msgs::EmptyConstPtr& empty_ptr)
356 {
357  try
358  {
359  ROS_INFO("Stopping autonomous flight");
360  bebop_ptr_->StopAutonomousFlight();
361  }
362  catch (const std::runtime_error& e)
363  {
364  ROS_ERROR_STREAM(e.what());
365  }
366 }
367 
368 void BebopDriverNodelet::FlipAnimationCallback(const std_msgs::UInt8ConstPtr &animid_ptr)
369 {
370  try
371  {
372  // TODO(mani-monaj): Check if flying
373  ROS_INFO("Performing flip animation %d ...", animid_ptr->data);
374  bebop_ptr_->AnimationFlip(animid_ptr->data);
375  }
376  catch (const std::runtime_error& e)
377  {
378  ROS_ERROR_STREAM(e.what());
379  }
380 }
381 
382 void BebopDriverNodelet::TakeSnapshotCallback(const std_msgs::EmptyConstPtr &empty_ptr)
383 {
384  try
385  {
386  ROS_INFO("Taking a high-res snapshot on-board");
387  bebop_ptr_->TakeSnapshot();
388  }
389  catch (const std::runtime_error& e)
390  {
391  ROS_ERROR_STREAM(e.what());
392  }
393 }
394 
395 void BebopDriverNodelet::SetExposureCallback(const std_msgs::Float32ConstPtr& exposure_ptr)
396 {
397  try
398  {
399  ROS_INFO("Setting exposure to %f", exposure_ptr->data);
400  bebop_ptr_->SetExposure(exposure_ptr->data);
401  }
402  catch (const std::runtime_error& e)
403  {
404  ROS_ERROR_STREAM(e.what());
405  }
406 }
407 
408 void BebopDriverNodelet::ToggleRecordingCallback(const std_msgs::BoolConstPtr &toggle_ptr)
409 {
410  const bool& start_record = toggle_ptr->data;
411  try
412  {
413  ROS_INFO_STREAM("Sending request to " << (start_record ? "start" : "stop")
414  << " on board video recording");
415  bebop_ptr_->ToggleVideoRecording(start_record);
416  }
417  catch (const std::runtime_error& e)
418  {
419  ROS_ERROR_STREAM(e.what());
420  }
421 }
422 
423 void BebopDriverNodelet::ParamCallback(BebopArdrone3Config &config, uint32_t level)
424 {
425  NODELET_INFO("Dynamic reconfigure callback with level: %d", level);
426  bebop_ptr_->UpdateSettings(config);
427 }
428 
429 // Runs its own context
431 {
432  uint32_t frame_w = 0;
433  uint32_t frame_h = 0;
434  NODELET_INFO_STREAM("[CameraThread] thread lwp_id: " << util::GetLWPId());
435 
436  while (!boost::this_thread::interruption_requested())
437  {
438  try
439  {
440  sensor_msgs::ImagePtr image_msg_ptr_(new sensor_msgs::Image());
441  const ros::Time t_now = ros::Time::now();
442 
443  NODELET_DEBUG_STREAM("Grabbing a frame from Bebop");
444  // This is blocking
445  bebop_ptr_->GetFrontCameraFrame(image_msg_ptr_->data, frame_w, frame_h);
446 
447  NODELET_DEBUG_STREAM("Frame grabbed: " << frame_w << " , " << frame_h);
448  camera_info_msg_ptr_.reset(new sensor_msgs::CameraInfo(cinfo_manager_ptr_->getCameraInfo()));
449  camera_info_msg_ptr_->header.stamp = t_now;
450  camera_info_msg_ptr_->header.frame_id = param_camera_frame_id_;
451  camera_info_msg_ptr_->width = frame_w;
452  camera_info_msg_ptr_->height = frame_h;
453 
455  {
456  image_msg_ptr_->encoding = "rgb8";
457  image_msg_ptr_->is_bigendian = false;
458  image_msg_ptr_->header.frame_id = param_camera_frame_id_;
459  image_msg_ptr_->header.stamp = t_now;
460  image_msg_ptr_->width = frame_w;
461  image_msg_ptr_->height = frame_h;
462  image_msg_ptr_->step = image_msg_ptr_->width * 3;
463 
465  }
466  }
467  catch (const std::runtime_error& e)
468  {
469  NODELET_ERROR_STREAM("[CameraThread] " << e.what());
470  }
471  }
472 
473  NODELET_INFO("Camera publisher thread died.");
474 }
475 
477 {
478  NODELET_INFO_STREAM("[AuxThread] thread lwp_id: " << util::GetLWPId());
479  // Since the update rate of bebop states is 5Hz, 15Hz seems fine for this thread
480  ros::Rate loop_rate(15.0);
481  geometry_msgs::Twist zero_twist;
482  util::ResetTwist(zero_twist);
483 
484  // Camera Pan/Tilt State
485  bebop_msgs::Ardrone3CameraStateOrientation::ConstPtr camera_state_ptr;
486 
487  // East-South-Down
488  bebop_msgs::Ardrone3PilotingStateSpeedChanged::ConstPtr speed_esd_ptr;
489 
490  // Inertial frame
491  bebop_msgs::Ardrone3PilotingStateAttitudeChanged::ConstPtr attitude_ptr;
492 
493  // GPS
494  bebop_msgs::Ardrone3PilotingStatePositionChanged::ConstPtr gps_state_ptr;
495 
496  // REP-103
497  double beb_roll_rad = 0.0;
498  double beb_pitch_rad = 0.0;
499  double beb_yaw_rad = 0.0;
500  double beb_vx_m = 0.0;
501  double beb_vy_m = 0.0;
502  double beb_vz_m = 0.0;
503 
504  // TF2, Integerator
505  ros::Time last_odom_time(ros::Time::now());
506  geometry_msgs::TransformStamped odom_to_base_tf;
507  odom_to_base_tf.header.frame_id = param_odom_frame_id_;
508  odom_to_base_tf.child_frame_id = "base_link";
510  tf2::Vector3 odom_to_base_trans_v3(0.0, 0.0, 0.0);
511  tf2::Quaternion odom_to_base_rot_q;
512 
513  // Detect new messages
514  // TODO(mani-monaj): Wrap this functionality into a class to remove duplicate code
515  ros::Time last_speed_time(0);
516  ros::Time last_att_time(0);
517  ros::Time last_camerastate_time(0);
518  ros::Time last_gps_time(0);
519  bool new_speed_data = false;
520  bool new_attitude_data = false;
521  bool new_camera_state = false;
522  bool new_gps_state = false;
523 
524  // We do not publish JointState in a nodelet friendly way
525  // These names should match the joint name defined by bebop_description
526  sensor_msgs::JointState js_msg;
527  js_msg.name.push_back("camera_pan_joint");
528  js_msg.name.push_back("camera_tilt_joint");
529  js_msg.position.resize(2);
530 
531  sensor_msgs::NavSatFix gps_msg;
532  gps_msg.header.frame_id = "/gps";
533  gps_msg.status.status = sensor_msgs::NavSatStatus::STATUS_NO_FIX;
534  gps_msg.status.service = sensor_msgs::NavSatStatus::SERVICE_GPS | sensor_msgs::NavSatStatus::SERVICE_GLONASS;
535  gps_msg.position_covariance_type = sensor_msgs::NavSatFix::COVARIANCE_TYPE_UNKNOWN;
536 
537  while (!boost::this_thread::interruption_requested())
538  {
539  try
540  {
541  if (!bebop_ptr_->IsConnected())
542  {
543  loop_rate.sleep();
544  continue;
545  }
546  {
547  const ros::Time t_now = ros::Time::now();
548  // cmd_vel safety
549  boost::unique_lock<boost::mutex> twist_lock(twist_mutex_);
550  if ( !util::CompareTwists(prev_bebop_twist_, zero_twist) &&
551  ((t_now - prev_twist_stamp_).toSec() > param_cmd_vel_timeout_)
552  )
553  {
554  NODELET_WARN("[AuxThread] Input cmd_vel timeout, reseting cmd_vel ...");
556  bebop_ptr_->Move(0.0, 0.0, 0.0, 0.0);
557  }
558  }
559 
560  // Experimental
561  if (bebop_ptr_->ardrone3_pilotingstate_positionchanged_ptr)
562  {
563  gps_state_ptr = bebop_ptr_->ardrone3_pilotingstate_positionchanged_ptr->GetDataCstPtr();
564  if ((gps_state_ptr->header.stamp - last_gps_time).toSec() > util::eps)
565  {
566  last_gps_time = gps_state_ptr->header.stamp;
567  new_gps_state = true;
568  }
569  }
570 
571  if (bebop_ptr_->ardrone3_camerastate_orientation_ptr)
572  {
573  camera_state_ptr = bebop_ptr_->ardrone3_camerastate_orientation_ptr->GetDataCstPtr();
574 
575  if ((camera_state_ptr->header.stamp - last_camerastate_time).toSec() > util::eps)
576  {
577  last_camerastate_time = camera_state_ptr->header.stamp;
578  new_camera_state = true;
579  }
580  }
581 
582  if (bebop_ptr_->ardrone3_pilotingstate_speedchanged_ptr)
583  {
584  speed_esd_ptr = bebop_ptr_->ardrone3_pilotingstate_speedchanged_ptr->GetDataCstPtr();
585 
586  // conside new data only
587  if ((speed_esd_ptr->header.stamp - last_speed_time).toSec() > util::eps)
588  {
589  last_speed_time = speed_esd_ptr->header.stamp;
590  new_speed_data = true;
591  }
592  }
593 
594  if (bebop_ptr_->ardrone3_pilotingstate_attitudechanged_ptr)
595  {
596  attitude_ptr = bebop_ptr_->ardrone3_pilotingstate_attitudechanged_ptr->GetDataCstPtr();
597 
598  // conside new data only
599  if ((attitude_ptr->header.stamp - last_att_time).toSec() > util::eps)
600  {
601  last_att_time = attitude_ptr->header.stamp;
602  beb_roll_rad = attitude_ptr->roll;
603  beb_pitch_rad = -attitude_ptr->pitch;
604  beb_yaw_rad = -attitude_ptr->yaw;
605 
606  odom_to_base_rot_q.setRPY(beb_roll_rad, beb_pitch_rad, beb_yaw_rad);
607  new_attitude_data = true;
608  }
609  }
610 
611  const double sync_diff_s = fabs((last_att_time - last_speed_time).toSec());
612  // When new data (speed and rpy) is available and they are approx. synced
613  if (new_speed_data && new_attitude_data &&
614  speed_esd_ptr && attitude_ptr &&
615  (sync_diff_s < 0.2))
616  {
617  ros::Time stamp = std::max(speed_esd_ptr->header.stamp, attitude_ptr->header.stamp);
618 
619  const double beb_vx_enu = speed_esd_ptr->speedX;
620  const double beb_vy_enu = -speed_esd_ptr->speedY;
621  const double beb_vz_enu = -speed_esd_ptr->speedZ;
622  beb_vx_m = cos(beb_yaw_rad) * beb_vx_enu + sin(beb_yaw_rad) * beb_vy_enu;
623  beb_vy_m = -sin(beb_yaw_rad) * beb_vx_enu + cos(beb_yaw_rad) * beb_vy_enu;
624  beb_vz_m = beb_vz_enu;
625 
626  const double dt = (ros::Time::now() - last_odom_time).toSec();
627  odom_to_base_trans_v3 += tf2::Vector3(beb_vx_enu * dt, beb_vy_enu * dt, beb_vz_enu * dt);
628 
629  nav_msgs::OdometryPtr odom_msg_ptr(new nav_msgs::Odometry());
630  odom_msg_ptr->header.stamp = stamp;
631  odom_msg_ptr->header.frame_id = param_odom_frame_id_;
632  odom_msg_ptr->child_frame_id = "base_link";
633  odom_msg_ptr->twist.twist.linear.x = beb_vx_m;
634  odom_msg_ptr->twist.twist.linear.y = beb_vy_m;
635  odom_msg_ptr->twist.twist.linear.z = beb_vz_m;
636 
637  // TODO(mani-monaj): Optimize this
638  odom_msg_ptr->pose.pose.position.x = odom_to_base_trans_v3.x();
639  odom_msg_ptr->pose.pose.position.y = odom_to_base_trans_v3.y();
640  odom_msg_ptr->pose.pose.position.z = odom_to_base_trans_v3.z();
641  tf2::convert(odom_to_base_rot_q, odom_msg_ptr->pose.pose.orientation);
642  odom_pub_.publish(odom_msg_ptr);
643 
645  {
646  odom_to_base_tf.header.stamp = stamp;
647  tf2::convert(tf2::Transform(odom_to_base_rot_q, odom_to_base_trans_v3), odom_to_base_tf.transform);
648  tf_broad.sendTransform(odom_to_base_tf);
649  }
650 
651  last_odom_time = ros::Time::now();
652  new_speed_data = false;
653  new_attitude_data = false;
654  }
655 
656  if (new_gps_state && gps_state_ptr)
657  {
658  // The SDK reports 500, 500, 500 when there is no GPS fix
659  const bool is_valid_gps = (fabs(gps_state_ptr->latitude - 500.0) > util::eps) &&
660  (fabs(gps_state_ptr->longitude - 500.0) > util::eps) &&
661  (fabs(gps_state_ptr->altitude - 500.0) > util::eps);
662 
663  gps_msg.header.stamp = gps_state_ptr->header.stamp;
664  gps_msg.status.status = is_valid_gps ? static_cast<int8_t>(sensor_msgs::NavSatStatus::STATUS_FIX):
665  static_cast<int8_t>(sensor_msgs::NavSatStatus::STATUS_NO_FIX);
666  gps_msg.latitude = gps_state_ptr->latitude;
667  gps_msg.longitude = gps_state_ptr->longitude;
668  gps_msg.altitude = gps_state_ptr->altitude;
669  gps_fix_pub_.publish(gps_msg);
670  new_gps_state = false;
671  }
672 
673  if (new_camera_state && camera_state_ptr)
674  {
675  js_msg.header.stamp = camera_state_ptr->header.stamp;
676  js_msg.position[0] = -camera_state_ptr->pan * util::deg2rad;
677  js_msg.position[1] = -camera_state_ptr->tilt * util::deg2rad;
678  camera_joint_pub_.publish(js_msg);
679  new_camera_state = false;
680  }
681 
682  loop_rate.sleep();
683  }
684  catch (const std::runtime_error& e)
685  {
686  NODELET_ERROR_STREAM("[AuxThread] " << e.what());
687  }
688  }
689 }
690 
691 } // namespace bebop_driver
void StartAutonomousFlightCallback(const std_msgs::StringConstPtr &file_path_ptr)
void FlatTrimCallback(const std_msgs::EmptyConstPtr &empty_ptr)
#define NODELET_INFO_STREAM(...)
void setRPY(const tf2Scalar &roll, const tf2Scalar &pitch, const tf2Scalar &yaw)
void publish(const sensor_msgs::Image &image, const sensor_msgs::CameraInfo &info) const
#define NODELET_WARN(...)
void SetExposureCallback(const std_msgs::Float32ConstPtr &exposure_ptr)
void publish(const boost::shared_ptr< M > &message) const
boost::shared_ptr< boost::thread > aux_thread_ptr_
boost::shared_ptr< image_transport::ImageTransport > image_transport_ptr_
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
void PauseAutonomousFlightCallback(const std_msgs::EmptyConstPtr &empty_ptr)
image_transport::CameraPublisher image_transport_pub_
boost::shared_ptr< boost::thread > camera_pub_thread_ptr_
boost::shared_ptr< dynamic_reconfigure::Server< bebop_driver::BebopArdrone3Config > > dynr_serv_ptr_
uint32_t getNumSubscribers() const
static char bebop_err_str[BEBOP_ERR_STR_SZ]
ROSCPP_DECL const std::string & getName()
bool CompareTwists(const geometry_msgs::Twist &lhs, const geometry_msgs::Twist &rhs)
#define ROSCONSOLE_NAME_PREFIX
void TakeSnapshotCallback(const std_msgs::EmptyConstPtr &empty_ptr)
void LandCallback(const std_msgs::EmptyConstPtr &empty_ptr)
#define ROS_WARN(...)
sensor_msgs::CameraInfoPtr camera_info_msg_ptr_
ros::NodeHandle & getPrivateNodeHandle() const
#define NODELET_ERROR_STREAM(...)
void ToggleRecordingCallback(const std_msgs::BoolConstPtr &toggle_ptr)
#define ROS_INFO(...)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
int BebopPrintToROSLogCB(eARSAL_PRINT_LEVEL level, const char *tag, const char *format, va_list va)
void ResetTwist(geometry_msgs::Twist &t)
void NavigateHomeCallback(const std_msgs::BoolConstPtr &start_stop_ptr)
void TakeoffCallback(const std_msgs::EmptyConstPtr &empty_ptr)
void EmergencyCallback(const std_msgs::EmptyConstPtr &empty_ptr)
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
#define CLAMP(x, l, h)
boost::shared_ptr< bebop_driver::Bebop > bebop_ptr_
ros::NodeHandle & getNodeHandle() const
void sendTransform(const geometry_msgs::TransformStamped &transform)
#define NODELET_DEBUG_STREAM(...)
long int GetLWPId()
Definition: bebop.h:64
bool sleep()
#define ROS_LOG(level, name,...)
void FlipAnimationCallback(const std_msgs::UInt8ConstPtr &animid_ptr)
boost::shared_ptr< camera_info_manager::CameraInfoManager > cinfo_manager_ptr_
#define NODELET_INFO(...)
#define ROS_INFO_STREAM(args)
static const double deg2rad
void StopAutonomousFlightCallback(const std_msgs::EmptyConstPtr &empty_ptr)
static const ros::console::levels::Level arsal_level_to_ros[ARSAL_PRINT_MAX]
#define NODELET_FATAL_STREAM(...)
#define BEBOP_ERR_STR_SZ
Definition: bebop.h:28
static Time now()
void convert(const A &a, B &b)
void ParamCallback(bebop_driver::BebopArdrone3Config &config, uint32_t level)
static const double eps
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
boost::posix_time::ptime toBoost() const
#define ROS_ERROR_STREAM(args)
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)
INLINE Rall1d< T, V, S > sin(const Rall1d< T, V, S > &arg)
void CameraMoveCallback(const geometry_msgs::TwistConstPtr &twist_ptr)
void CmdVelCallback(const geometry_msgs::TwistConstPtr &twist_ptr)


bebop_driver
Author(s): Mani Monajjemi
autogenerated on Mon Jun 10 2019 12:58:56