holonomic_cart_planner.cpp
Go to the documentation of this file.
00001 /*
00002  * holonomic_cart_planner.cpp
00003  *
00004  *  Created on: Aug 17, 2010
00005  *      Author: jscholz
00006  */
00007 
00008 #include <cart_local_planner/holonomic_cart_planner.h>
00009 #include <cart_local_planner/utils.h>
00010 #include <pluginlib/class_list_macros.h>
00011 
00012 PLUGINLIB_DECLARE_CLASS(cart_local_planner, HolonomicCartPlanner, cart_local_planner::HolonomicCartPlanner, nav_core::BaseLocalPlanner)
00013 
00014 namespace cart_local_planner {
00015 HolonomicCartPlanner::HolonomicCartPlanner()
00016 {
00017 }
00018 
00019 void HolonomicCartPlanner::initialization_extras()
00020 {
00021 }
00022 
00023 HolonomicCartPlanner::~HolonomicCartPlanner() {
00024 }
00025 
00026 void HolonomicCartPlanner::setControlMode()
00027 {
00028   // double yaw_err = tf::getYaw(robot_pose_error_.getRotation());
00029   boost::mutex::scoped_lock lock(invalid_pose_mutex_);    
00030   if (ros::Time::now() - last_invalid_pose_time_ < ros::Duration(3.0)) 
00031     control_mode_ = PULLING_ARMS_IN;
00032   //  else if (fabs(yaw_err) > M_PI_4 && control_mode_ != RECOVERY)
00033   //    control_mode_ = ROTATING_IN_PLACE;
00034   else
00035     control_mode_ = REGULAR;
00036 
00037   ROS_DEBUG_COND_NAMED(debug_print_, "mode", "mode = %d", control_mode_);
00038 }
00039 
00040 void HolonomicCartPlanner::controlModeAction()
00041 {
00042   switch (control_mode_) {
00043 
00044 
00045   case PULLING_ARMS_IN:
00046     {
00047       /* 2010/9/3: Disabling to test the articulate cart server recovery
00048       ROS_DEBUG_STREAM_NAMED ("recovery", "In pulling-arms-in recovery; current cart pose goal is " <<
00049                               toString(cart_pose_goal_) << "; robot pose goal is " << toString(robot_pose_goal_));
00050       // Reset the cart goal pose to be close to the robot
00051       tf::Stamped<tf::Pose> goal;
00052       goal.setIdentity();
00053       goal.getOrigin().setX(0.5*(cart_range.x_min+cart_range.x_max));
00054       setRobotPoseGoal(robot_pose_actual_);;
00055       setCartPoseGoal(goal);
00056       ROS_DEBUG_STREAM_NAMED ("recovery", "  Modified cart pose goal to " << toString(cart_pose_goal_) <<
00057                               " and robot goal to " << toString(robot_pose_goal_));
00058       */
00059 
00060     }
00061     // We don't break, but continue with the regular behavior with the modified goals
00062     
00063   case REGULAR:
00064     {
00065       // Compute base twist
00066       baseTwistFromError();
00067 
00068       // Compute cart twist
00069       cartTwistFromError();
00070 
00071       // Coordinate base and cart velocities for smooth and safe action
00072       filterTwistsCombined(GLOBAL_SCALING);
00073 
00074       if (robot_pose_error_.getOrigin().length() < tolerance_trans_ && current_waypoint_ < global_plan_.size()-1 && mag(cart_pose_error_) < 0.1)
00075         current_waypoint_++;
00076     }
00077     break;
00078 
00079   case ROTATING_IN_PLACE:
00080     {
00081       cartTwistFromError();
00082       baseTwistFromError();
00083 
00084       // Coordinate base and cart velocities for smooth and safe action
00085       filterTwistsCombined(GLOBAL_SCALING);
00086     }
00087     break;
00088 
00089   case RECOVERY:
00090     ROS_WARN("NOT IMPLEMENTED");
00091     break;
00092 
00093   default:
00094     ROS_WARN("Unrecognized control mode requested");
00095     break;
00096   }
00097 }
00098 
00099 void HolonomicCartPlanner::filterTwistsCombined(int filter_options)
00100 {
00102   if (filter_options & GLOBAL_SCALING) {
00103     double xv_scale = fabs(twist_base_->linear.x) / twist_base_max_.linear.x;
00104     double yv_scale = fabs(twist_base_->linear.y) / twist_base_max_.linear.y;
00105     double tv_scale = fabs(twist_base_->angular.z) / twist_base_max_.angular.z;
00106 
00107     double base_scaling_factor = std::max(xv_scale, std::max(yv_scale, tv_scale));
00108 
00109     double xv_cart_scale = fabs(twist_cart_.twist.linear.x) / twist_cart_max_.linear.x;
00110     double yv_cart_scale = fabs(twist_cart_.twist.linear.y) / twist_cart_max_.linear.y;
00111     double tv_cart_scale = fabs(twist_cart_.twist.angular.z)/ twist_cart_max_.angular.z;
00112 
00113     double cart_scaling_factor = std::max(xv_cart_scale, std::max(yv_cart_scale, tv_cart_scale));
00114     double scaling_factor = std::max(base_scaling_factor, cart_scaling_factor);
00115 
00116     // Scales both twists together such that none are above their limits
00117     if (scaling_factor > 1.0) {
00118       double scale_mult = 1.0 / scaling_factor;
00119       scaleTwist2D(*twist_base_, scale_mult); //TODO verify that this works
00120       scaleTwist2D(twist_cart_.twist, scale_mult);
00121       ROS_DEBUG_STREAM_COND_NAMED (debug_print_, "twist_filter",
00122                                    "Scaling, to keep things in range, cart and base twists by " << scale_mult);
00123     }
00124 
00125   }
00126 
00128   if (filter_options & CART_ERR_SCALING) {
00129     const double scaling_factor = pow(M_E, -50.0 * pow(mag(twist_cart_.twist), 2)); // tuned to fall off around 0.1
00130     scaleTwist2D(*twist_base_, scaling_factor);
00131     ROS_DEBUG_STREAM_COND_NAMED (debug_print_, "twist_filter",
00132                                  "Scaling, based on cart error, base velocity by " << scaling_factor);
00133   }
00134 
00136   if (filter_options & COMPENSATE_BASE_TWIST) {
00137     geometry_msgs::Twist base_twist_at_cart = mapBaseTwistToCart(*twist_base_);
00138     ROS_DEBUG_STREAM_COND_NAMED (debug_print_, "twist_filter", "Cart twist " << twist_cart_ <<
00139                                  " and base twist " << base_twist_at_cart);
00140     twist_cart_.twist.linear.y -= base_twist_at_cart.linear.y;
00141     twist_cart_.twist.angular.z -= base_twist_at_cart.angular.z;
00142     ROS_DEBUG_STREAM_COND_NAMED (debug_print_, "twist_filter", "After compensating for base twist, cart twist is "
00143                                  << twist_cart_);
00144   }
00145 
00147   if (filter_options & GLOBAL_SCALING) {
00148     double xv_scale = fabs(twist_base_->linear.x) / twist_base_max_.linear.x;
00149     double yv_scale = fabs(twist_base_->linear.y) / twist_base_max_.linear.y;
00150     double tv_scale = fabs(twist_base_->angular.z) / twist_base_max_.angular.z;
00151 
00152     double base_scaling_factor = std::max(xv_scale, std::max(yv_scale, tv_scale));
00153 
00154     double xv_cart_scale = fabs(twist_cart_.twist.linear.x) / twist_cart_max_.linear.x;
00155     double yv_cart_scale = fabs(twist_cart_.twist.linear.y) / twist_cart_max_.linear.y;
00156     double tv_cart_scale = fabs(twist_cart_.twist.angular.z)/ twist_cart_max_.angular.z;
00157 
00158     double cart_scaling_factor = std::max(xv_cart_scale, std::max(yv_cart_scale, tv_cart_scale));
00159     double scaling_factor = std::max(base_scaling_factor, cart_scaling_factor);
00160 
00161     // Scales both twists together such that none are above their limits
00162     if (scaling_factor > 1.0) {
00163       double scale_mult = 1.0 / scaling_factor;
00164       scaleTwist2D(*twist_base_, scale_mult); //TODO verify that this works
00165       scaleTwist2D(twist_cart_.twist, scale_mult);
00166       ROS_DEBUG_STREAM_COND_NAMED (debug_print_, "twist_filter",
00167                                    "Scaling, to keep things in range, cart and base twists by " << scale_mult);
00168     }
00169 
00170   }
00171 
00172 }
00173 
00174 }; // namespace cart_local_planner


cart_local_planner
Author(s): Jonathan Scholz
autogenerated on Tue Jan 7 2014 11:11:33