48 OscillationCritic::CommandTrend::CommandTrend()
    53 void OscillationCritic::CommandTrend::reset()
    56   positive_only_ = 
false;
    57   negative_only_ = 
false;
    60 bool OscillationCritic::CommandTrend::update(
double velocity)
    62   bool flag_set = 
false;
    65     if (sign_ == Sign::POSITIVE)
    67       negative_only_ = 
true;
    70     sign_ = Sign::NEGATIVE;
    72   else if (velocity > 0.0)
    74     if (sign_ == Sign::NEGATIVE)
    76       positive_only_ = 
true;
    79     sign_ = Sign::POSITIVE;
    84 bool OscillationCritic::CommandTrend::isOscillating(
double velocity)
    86   return (positive_only_ && velocity < 0.0) || (negative_only_ && velocity > 0.0);
    89 bool OscillationCritic::CommandTrend::hasSignFlipped()
    91   return positive_only_ || negative_only_;
    94 void OscillationCritic::onInit()
    97   oscillation_reset_dist_sq_ = oscillation_reset_dist_ * oscillation_reset_dist_;
   108   std::string resolved_name;
   109   if (critic_nh_.hasParam(
"x_only_threshold"))
   111     critic_nh_.getParam(
"x_only_threshold", x_only_threshold_);
   113   else if (critic_nh_.searchParam(
"min_speed_xy", resolved_name))
   115     critic_nh_.getParam(resolved_name, x_only_threshold_);
   117   else if (critic_nh_.searchParam(
"min_trans_vel", resolved_name))
   119     ROS_WARN_NAMED(
"OscillationCritic", 
"Parameter min_trans_vel is deprecated. "   120                                         "Please use the name min_speed_xy or x_only_threshold instead.");
   121     critic_nh_.getParam(resolved_name, x_only_threshold_);
   125     x_only_threshold_ = 0.05;
   131 bool OscillationCritic::prepare(
const geometry_msgs::Pose2D& pose,
   132                                 const nav_2d_msgs::Twist2D& vel,
   133                                 const geometry_msgs::Pose2D& goal,
   134                                 const nav_2d_msgs::Path2D& global_plan)
   140 void OscillationCritic::debrief(
const nav_2d_msgs::Twist2D& cmd_vel)
   142   if (setOscillationFlags(cmd_vel))
   144     prev_stationary_pose_ = pose_;
   149   if (x_trend_.hasSignFlipped() || y_trend_.hasSignFlipped() || theta_trend_.hasSignFlipped())
   152     if (resetAvailable())
   159 bool OscillationCritic::resetAvailable()
   161   if (oscillation_reset_dist_ >= 0.0)
   163     double x_diff = pose_.x - prev_stationary_pose_.x;
   164     double y_diff = pose_.y - prev_stationary_pose_.y;
   165     double sq_dist = x_diff * x_diff + y_diff * y_diff;
   166     if (sq_dist > oscillation_reset_dist_sq_)
   171   if (oscillation_reset_angle_ >= 0.0)
   173     double th_diff = pose_.theta - prev_stationary_pose_.theta;
   174     if (fabs(th_diff) > oscillation_reset_angle_)
   179   if (oscillation_reset_time_ >= 0.0)
   182     if (t_diff > oscillation_reset_time_)
   190 void OscillationCritic::reset()
   194   theta_trend_.reset();
   197 bool OscillationCritic::setOscillationFlags(
const nav_2d_msgs::Twist2D& cmd_vel)
   199   bool flag_set = 
false;
   201   flag_set |= x_trend_.update(cmd_vel.x);
   204   if (x_only_threshold_ < 0.0 || fabs(cmd_vel.x) <= x_only_threshold_)
   206     flag_set |= y_trend_.update(cmd_vel.y);
   207     flag_set |= theta_trend_.update(cmd_vel.theta);
   212 double OscillationCritic::scoreTrajectory(
const dwb_msgs::Trajectory2D& traj)
   214   if (x_trend_.isOscillating(traj.velocity.x) ||
   215       y_trend_.isOscillating(traj.velocity.y) ||
   216       theta_trend_.isOscillating(traj.velocity.theta))
 #define ROS_WARN_NAMED(name,...)
Checks to see whether the sign of the commanded velocity flips frequently. 
param_t searchAndGetParam(const ros::NodeHandle &nh, const std::string ¶m_name, const param_t &default_value)
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)