28 #include <nav_msgs/Odometry.h> 29 #include <sensor_msgs/JointState.h> 33 #include <sensor_msgs/NavSatFix.h> 35 #include <boost/bind.hpp> 36 #include <boost/make_shared.hpp> 37 #include <boost/date_time/posix_time/posix_time.hpp> 44 #include <bebop_driver/BebopArdrone3Config.h> 71 BebopDriverNodelet::BebopDriverNodelet()
83 boost::unique_lock<boost::mutex> twist_lock(
twist_mutex_);
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");
104 bebop_ptr_->Connect(nh, private_nh, param_bebop_ip);
106 if (param_reset_settings)
118 std::string iso_time_str = boost::posix_time::to_iso_extended_string(system_time);
124 NODELET_INFO(
"Fetching all settings from the Drone ...");
128 catch (
const std::runtime_error& e)
160 dynr_serv_ptr_.reset(
new dynamic_reconfigure::Server<bebop_driver::BebopArdrone3Config>(private_nh));
161 dynamic_reconfigure::Server<bebop_driver::BebopArdrone3Config>::CallbackType cb =
173 boost::bind(&bebop_driver::BebopDriverNodelet::BebopDriverNodelet::CameraPublisherThread,
this));
176 catch (const::std::runtime_error& e)
183 boost::bind(&bebop_driver::BebopDriverNodelet::BebopDriverNodelet::AuxThread,
this));
197 NODELET_INFO_STREAM(
"Killing Aux Thread ...");
211 const geometry_msgs::Twist& bebop_twist_ = *twist_ptr;
212 bool is_bebop_twist_changed =
false;
214 boost::unique_lock<boost::mutex> twist_lock(
twist_mutex_);
221 if (is_bebop_twist_changed)
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));
229 catch (
const std::runtime_error& e)
241 catch (
const std::runtime_error& e)
253 catch (
const std::runtime_error& e)
266 if (is_camera_twist_changed)
273 catch (
const std::runtime_error& e)
285 catch (
const std::runtime_error& e)
299 catch (
const std::runtime_error& e)
309 ROS_INFO(
"%sing navigate home behavior ...", start_stop_ptr->data ?
"Start" :
"Stopp");
310 bebop_ptr_->NavigateHome(start_stop_ptr->data);
312 catch (
const std::runtime_error& e)
320 std::string filepath;
321 if (filepath_ptr->data.empty())
323 ROS_WARN(
"No flight plan provided. Using default: 'flightplan.mavlink'");
324 filepath =
"flightplan.mavlink";
328 filepath = filepath_ptr->data;
333 ROS_INFO(
"Starting autonomous flight path: %s", filepath.c_str());
336 catch (
const std::runtime_error& e)
346 ROS_INFO(
"Pausing autonomous flight");
349 catch (
const std::runtime_error& e)
359 ROS_INFO(
"Stopping autonomous flight");
362 catch (
const std::runtime_error& e)
373 ROS_INFO(
"Performing flip animation %d ...", animid_ptr->data);
376 catch (
const std::runtime_error& e)
386 ROS_INFO(
"Taking a high-res snapshot on-board");
389 catch (
const std::runtime_error& e)
399 ROS_INFO(
"Setting exposure to %f", exposure_ptr->data);
402 catch (
const std::runtime_error& e)
410 const bool& start_record = toggle_ptr->data;
413 ROS_INFO_STREAM(
"Sending request to " << (start_record ?
"start" :
"stop")
414 <<
" on board video recording");
415 bebop_ptr_->ToggleVideoRecording(start_record);
417 catch (
const std::runtime_error& e)
425 NODELET_INFO(
"Dynamic reconfigure callback with level: %d", level);
432 uint32_t frame_w = 0;
433 uint32_t frame_h = 0;
436 while (!boost::this_thread::interruption_requested())
440 sensor_msgs::ImagePtr image_msg_ptr_(
new sensor_msgs::Image());
445 bebop_ptr_->GetFrontCameraFrame(image_msg_ptr_->data, frame_w, frame_h);
456 image_msg_ptr_->encoding =
"rgb8";
457 image_msg_ptr_->is_bigendian =
false;
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;
467 catch (
const std::runtime_error& e)
481 geometry_msgs::Twist zero_twist;
485 bebop_msgs::Ardrone3CameraStateOrientation::ConstPtr camera_state_ptr;
488 bebop_msgs::Ardrone3PilotingStateSpeedChanged::ConstPtr speed_esd_ptr;
491 bebop_msgs::Ardrone3PilotingStateAttitudeChanged::ConstPtr attitude_ptr;
494 bebop_msgs::Ardrone3PilotingStatePositionChanged::ConstPtr gps_state_ptr;
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;
506 geometry_msgs::TransformStamped odom_to_base_tf;
508 odom_to_base_tf.child_frame_id =
"base_link";
510 tf2::Vector3 odom_to_base_trans_v3(0.0, 0.0, 0.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;
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);
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;
537 while (!boost::this_thread::interruption_requested())
549 boost::unique_lock<boost::mutex> twist_lock(
twist_mutex_);
554 NODELET_WARN(
"[AuxThread] Input cmd_vel timeout, reseting cmd_vel ...");
561 if (
bebop_ptr_->ardrone3_pilotingstate_positionchanged_ptr)
563 gps_state_ptr =
bebop_ptr_->ardrone3_pilotingstate_positionchanged_ptr->GetDataCstPtr();
564 if ((gps_state_ptr->header.stamp - last_gps_time).toSec() >
util::eps)
566 last_gps_time = gps_state_ptr->header.stamp;
567 new_gps_state =
true;
571 if (
bebop_ptr_->ardrone3_camerastate_orientation_ptr)
573 camera_state_ptr =
bebop_ptr_->ardrone3_camerastate_orientation_ptr->GetDataCstPtr();
575 if ((camera_state_ptr->header.stamp - last_camerastate_time).toSec() >
util::eps)
577 last_camerastate_time = camera_state_ptr->header.stamp;
578 new_camera_state =
true;
582 if (
bebop_ptr_->ardrone3_pilotingstate_speedchanged_ptr)
584 speed_esd_ptr =
bebop_ptr_->ardrone3_pilotingstate_speedchanged_ptr->GetDataCstPtr();
587 if ((speed_esd_ptr->header.stamp - last_speed_time).toSec() >
util::eps)
589 last_speed_time = speed_esd_ptr->header.stamp;
590 new_speed_data =
true;
594 if (
bebop_ptr_->ardrone3_pilotingstate_attitudechanged_ptr)
596 attitude_ptr =
bebop_ptr_->ardrone3_pilotingstate_attitudechanged_ptr->GetDataCstPtr();
599 if ((attitude_ptr->header.stamp - last_att_time).toSec() >
util::eps)
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;
606 odom_to_base_rot_q.
setRPY(beb_roll_rad, beb_pitch_rad, beb_yaw_rad);
607 new_attitude_data =
true;
611 const double sync_diff_s = fabs((last_att_time - last_speed_time).toSec());
613 if (new_speed_data && new_attitude_data &&
614 speed_esd_ptr && attitude_ptr &&
617 ros::Time stamp = std::max(speed_esd_ptr->header.stamp, attitude_ptr->header.stamp);
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;
627 odom_to_base_trans_v3 += tf2::Vector3(beb_vx_enu * dt, beb_vy_enu * dt, beb_vz_enu * dt);
629 nav_msgs::OdometryPtr odom_msg_ptr(
new nav_msgs::Odometry());
630 odom_msg_ptr->header.stamp = stamp;
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;
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);
646 odom_to_base_tf.header.stamp = stamp;
652 new_speed_data =
false;
653 new_attitude_data =
false;
656 if (new_gps_state && gps_state_ptr)
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);
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;
670 new_gps_state =
false;
673 if (new_camera_state && camera_state_ptr)
675 js_msg.header.stamp = camera_state_ptr->header.stamp;
677 js_msg.position[1] = -camera_state_ptr->tilt *
util::deg2rad;
679 new_camera_state =
false;
684 catch (
const std::runtime_error& e)
void StartAutonomousFlightCallback(const std_msgs::StringConstPtr &file_path_ptr)
std::string param_camera_frame_id_
ros::Publisher camera_joint_pub_
void FlatTrimCallback(const std_msgs::EmptyConstPtr &empty_ptr)
#define NODELET_INFO_STREAM(...)
void setRPY(const tf2Scalar &roll, const tf2Scalar &pitch, const tf2Scalar &yaw)
ros::Subscriber stop_autoflight_sub_
void publish(const sensor_msgs::Image &image, const sensor_msgs::CameraInfo &info) const
double param_cmd_vel_timeout_
#define NODELET_WARN(...)
void CameraPublisherThread()
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())
geometry_msgs::Twist camera_twist_
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()
ros::Subscriber animation_sub_
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)
ros::Subscriber exposure_sub_
sensor_msgs::CameraInfoPtr camera_info_msg_ptr_
ros::NodeHandle & getPrivateNodeHandle() const
ros::Publisher gps_fix_pub_
#define NODELET_ERROR_STREAM(...)
bool param_publish_odom_tf_
ros::Subscriber land_sub_
ros::Subscriber start_autoflight_sub_
void ToggleRecordingCallback(const std_msgs::BoolConstPtr &toggle_ptr)
bool param(const std::string ¶m_name, T ¶m_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)
geometry_msgs::Twist prev_camera_twist_
void NavigateHomeCallback(const std_msgs::BoolConstPtr &start_stop_ptr)
void TakeoffCallback(const std_msgs::EmptyConstPtr &empty_ptr)
ros::Subscriber navigatehome_sub_
std::string param_odom_frame_id_
void EmergencyCallback(const std_msgs::EmptyConstPtr &empty_ptr)
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
boost::shared_ptr< bebop_driver::Bebop > bebop_ptr_
ros::NodeHandle & getNodeHandle() const
#define NODELET_DEBUG_STREAM(...)
boost::mutex twist_mutex_
#define ROS_LOG(level, name,...)
void FlipAnimationCallback(const std_msgs::UInt8ConstPtr &animid_ptr)
ros::Subscriber flattrim_sub_
ros::Subscriber snapshot_sub_
boost::shared_ptr< camera_info_manager::CameraInfoManager > cinfo_manager_ptr_
virtual ~BebopDriverNodelet()
#define NODELET_INFO(...)
#define ROS_INFO_STREAM(args)
static const double deg2rad
void StopAutonomousFlightCallback(const std_msgs::EmptyConstPtr &empty_ptr)
ros::Subscriber pause_autoflight_sub_
static const ros::console::levels::Level arsal_level_to_ros[ARSAL_PRINT_MAX]
#define NODELET_FATAL_STREAM(...)
void convert(const A &a, B &b)
void ParamCallback(bebop_driver::BebopArdrone3Config &config, uint32_t level)
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
boost::posix_time::ptime toBoost() const
#define ROS_ERROR_STREAM(args)
ros::Subscriber takeoff_sub_
ros::Subscriber toggle_recording_sub_
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)
geometry_msgs::Twist prev_bebop_twist_
ros::Time prev_twist_stamp_
INLINE Rall1d< T, V, S > sin(const Rall1d< T, V, S > &arg)
ros::Subscriber reset_sub_
void CameraMoveCallback(const geometry_msgs::TwistConstPtr &twist_ptr)
ros::Subscriber camera_move_sub_
ros::Subscriber cmd_vel_sub_
void CmdVelCallback(const geometry_msgs::TwistConstPtr &twist_ptr)