auto_docking_ros.cpp
Go to the documentation of this file.
00001 
00009 /*****************************************************************************
00010 ** Includes
00011 *****************************************************************************/
00012 
00013 #include "kobuki_auto_docking/auto_docking_ros.hpp"
00014 
00015 namespace kobuki
00016 {
00017 
00018 //AutoDockingROS::AutoDockingROS()
00019 AutoDockingROS::AutoDockingROS(std::string name)
00020 //AutoDockingROS::AutoDockingROS(ros::NodeHandle& nh)
00021 //AutoDockingROS::AutoDockingROS(ros::NodeHandle& nh, std::string name)
00022   : name_(name)
00023   , shutdown_requested_(false)
00024   , as_(nh_, name_+"_action", false)
00025 {
00026   self = this;
00027 
00028   as_.registerGoalCallback(boost::bind(&AutoDockingROS::goalCb, this));
00029   as_.registerPreemptCallback(boost::bind(&AutoDockingROS::preemptCb, this));
00030   as_.start();
00031 }
00032 
00033 AutoDockingROS::~AutoDockingROS()
00034 {
00035   shutdown_requested_ = true;
00036   if (as_.isActive()) {
00037     result_.text = "Aborted: Shutdown requested.";
00038     as_.setAborted( result_, result_.text );
00039   }
00040   dock_.disable();
00041   toggleMotor(false);
00042 }
00043 
00044 bool AutoDockingROS::init(ros::NodeHandle& nh)
00045 {
00046   motor_power_enabler_ = nh.advertise<kobuki_msgs::MotorPower>("motor_power", 10);
00047   velocity_commander_ = nh.advertise<geometry_msgs::Twist>("velocity", 10);
00048   debug_jabber_ = nh.advertise<std_msgs::String>("debug/feedback", 10);
00049 
00050   debug_ = nh.subscribe("debug/mode_shift", 10, &AutoDockingROS::debugCb, this);
00051 
00052   odom_sub_.reset(new message_filters::Subscriber<nav_msgs::Odometry>(nh, "odom", 10));
00053   core_sub_.reset(new message_filters::Subscriber<kobuki_msgs::SensorState>(nh, "core", 10));
00054   ir_sub_.reset(new message_filters::Subscriber<kobuki_msgs::DockInfraRed>(nh, "dock_ir", 10));
00055   sync_.reset(new message_filters::Synchronizer<SyncPolicy>(SyncPolicy(10), *odom_sub_, *core_sub_, *ir_sub_));
00056   sync_->registerCallback(boost::bind(&AutoDockingROS::syncCb, this, _1, _2, _3));
00057 
00058   return dock_.init();
00059 }
00060 
00061 void AutoDockingROS::spin()
00062 {
00063   return;
00064 
00065   while(!shutdown_requested_){;}
00066 }
00067 
00068 void AutoDockingROS::goalCb()
00069 {
00070   if (dock_.isEnabled()) {
00071     goal_ = *(as_.acceptNewGoal());
00072     result_.text = "Rejected: dock_drive is already enabled.";
00073     as_.setAborted( result_, result_.text );
00074     ROS_INFO_STREAM("[" << name_ << "] New goal received but rejected.");
00075   } else {
00076     goal_ = *(as_.acceptNewGoal());
00077     toggleMotor(true);
00078     dock_.enable();
00079     ROS_INFO_STREAM("[" << name_ << "] New goal received and accepted.");
00080   }
00081 }
00082 
00083 void AutoDockingROS::preemptCb()
00084 {
00085   //ROS_DEBUG_STREAM("[" << name_ << "] Preempt requested.");
00086   dock_.disable();
00087   if (as_.isNewGoalAvailable()) {
00088     result_.text = "Preempted: New goal received.";
00089     as_.setPreempted( result_, result_.text );
00090     ROS_INFO_STREAM("[" << name_ << "] " << result_.text );
00091   } else {
00092     result_.text = "Cancelled: Cancel requested.";
00093     as_.setPreempted( result_, result_.text );
00094     ROS_INFO_STREAM("[" << name_ << "] " << result_.text );
00095     dock_.disable();
00096     toggleMotor(false);
00097   }
00098 }
00099 
00100 void AutoDockingROS::syncCb(const nav_msgs::OdometryConstPtr& odom,
00101                             const kobuki_msgs::SensorStateConstPtr& core,
00102                             const kobuki_msgs::DockInfraRedConstPtr& ir)
00103 {
00104   //process and run
00105   if (self->dock_.isEnabled()) {
00106     //conversions
00107     KDL::Rotation rot;
00108     tf::quaternionMsgToKDL( odom->pose.pose.orientation, rot );
00109 
00110     double r, p, y;
00111     rot.GetRPY(r, p, y);
00112 
00113     ecl::Pose2D<double> pose;
00114     pose.x(odom->pose.pose.position.x);
00115     pose.y(odom->pose.pose.position.y);
00116     pose.heading(y);
00117 
00118     //update
00119     self->dock_.update(ir->data, core->bumper, core->charger, pose);
00120 
00121     //publish debug stream
00122     std_msgs::StringPtr debug_log(new std_msgs::String);
00123     debug_log->data = self->dock_.getDebugStream();
00124     debug_jabber_.publish(debug_log);
00125 
00126     //publish command velocity
00127     if (self->dock_.canRun()) {
00128       geometry_msgs::TwistPtr cmd_vel(new geometry_msgs::Twist);
00129       cmd_vel->linear.x = self->dock_.getVX();
00130       cmd_vel->angular.z = self->dock_.getWZ();
00131       velocity_commander_.publish(cmd_vel);
00132     }
00133   }
00134 
00135   //action server execution
00136   if( as_.isActive() ) {
00137     if ( dock_.getState() == dock_.DONE ) {
00138       result_.text = "Arrived on docking station successfully.";
00139       as_.setSucceeded(result_);
00140       ROS_INFO_STREAM( "[" << name_ << "]: Arrived on docking station successfully.");
00141       ROS_DEBUG_STREAM( "[" << name_ << "]: Result sent.");
00142       dock_.disable();
00143       toggleMotor(false);
00144     } else if ( !dock_.isEnabled() ) { //Action Server is activated, but DockDrive is not enabled, or disabled unexpectedly
00145       ROS_ERROR_STREAM("[" << name_ << "] Unintended Case: ActionService is active, but DockDrive is not enabled..");
00146       result_.text = "Aborted: dock_drive is disabled unexpectedly.";
00147       as_.setAborted( result_, "Aborted: dock_drive is disabled unexpectedly." );
00148       ROS_INFO_STREAM("[" << name_ << "] Goal aborted.");
00149       dock_.disable();
00150       toggleMotor(false);
00151     } else {
00152       feedback_.state = dock_.getStateStr();
00153       feedback_.text = dock_.getDebugStr();
00154       as_.publishFeedback(feedback_);
00155       ROS_DEBUG_STREAM( "[" << name_ << "]: Feedback sent.");
00156     }
00157   }
00158   return;
00159 }
00160 
00161 void AutoDockingROS::debugCb(const std_msgs::StringConstPtr& msg)
00162 {
00163   dock_.modeShift(msg->data);
00164 }
00165 
00166 void AutoDockingROS::toggleMotor(const bool& on_off)
00167 {
00168   kobuki_msgs::MotorPowerPtr power_cmd(new kobuki_msgs::MotorPower);
00169   if (on_off) power_cmd->state = kobuki_msgs::MotorPower::ON;
00170   else        power_cmd->state = kobuki_msgs::MotorPower::OFF;
00171   motor_power_enabler_.publish(power_cmd);
00172 }
00173 
00174 } //namespace kobuki


kobuki_auto_docking
Author(s): Younghun Ju
autogenerated on Mon Oct 6 2014 01:30:37