oscillation.cpp
Go to the documentation of this file.
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2017, Locus Robotics
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above
14  * copyright notice, this list of conditions and the following
15  * disclaimer in the documentation and/or other materials provided
16  * with the distribution.
17  * * Neither the name of the copyright holder nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  */
34 
37 #include <nav_core2/exceptions.h>
39 #include <cmath>
40 #include <string>
41 #include <vector>
42 
44 
45 namespace dwb_critics
46 {
47 
49 {
50  reset();
51 }
52 
54 {
55  sign_ = Sign::ZERO;
56  positive_only_ = false;
57  negative_only_ = false;
58 }
59 
61 {
62  bool flag_set = false;
63  if (velocity < 0.0)
64  {
65  if (sign_ == Sign::POSITIVE)
66  {
67  negative_only_ = true;
68  flag_set = true;
69  }
70  sign_ = Sign::NEGATIVE;
71  }
72  else if (velocity > 0.0)
73  {
74  if (sign_ == Sign::NEGATIVE)
75  {
76  positive_only_ = true;
77  flag_set = true;
78  }
79  sign_ = Sign::POSITIVE;
80  }
81  return flag_set;
82 }
83 
85 {
86  return (positive_only_ && velocity < 0.0) || (negative_only_ && velocity > 0.0);
87 }
88 
90 {
91  return positive_only_ || negative_only_;
92 }
93 
95 {
96  oscillation_reset_dist_ = nav_2d_utils::searchAndGetParam(critic_nh_, "oscillation_reset_dist", 0.05);
98  oscillation_reset_angle_ = nav_2d_utils::searchAndGetParam(critic_nh_, "oscillation_reset_angle", 0.2);
99  oscillation_reset_time_ = nav_2d_utils::searchAndGetParam(critic_nh_, "oscillation_reset_time", -1.0);
100 
108  std::string resolved_name;
109  if (critic_nh_.hasParam("x_only_threshold"))
110  {
111  critic_nh_.getParam("x_only_threshold", x_only_threshold_);
112  }
113  else if (critic_nh_.searchParam("min_speed_xy", resolved_name))
114  {
115  critic_nh_.getParam(resolved_name, x_only_threshold_);
116  }
117  else if (critic_nh_.searchParam("min_trans_vel", resolved_name))
118  {
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_);
122  }
123  else
124  {
125  x_only_threshold_ = 0.05;
126  }
127 
128  reset();
129 }
130 
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)
135 {
136  pose_ = pose;
137  return true;
138 }
139 
140 void OscillationCritic::debrief(const nav_2d_msgs::Twist2D& cmd_vel)
141 {
142  if (setOscillationFlags(cmd_vel))
143  {
146  }
147 
148  // if we've got restrictions... check if we can reset any oscillation flags
150  {
151  // Reset flags if enough time or distance has passed
152  if (resetAvailable())
153  {
154  reset();
155  }
156  }
157 }
158 
160 {
161  if (oscillation_reset_dist_ >= 0.0)
162  {
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_)
167  {
168  return true;
169  }
170  }
171  if (oscillation_reset_angle_ >= 0.0)
172  {
173  double th_diff = pose_.theta - prev_stationary_pose_.theta;
174  if (fabs(th_diff) > oscillation_reset_angle_)
175  {
176  return true;
177  }
178  }
179  if (oscillation_reset_time_ >= 0.0)
180  {
181  double t_diff = (ros::Time::now() - prev_reset_time_).toSec();
182  if (t_diff > oscillation_reset_time_)
183  {
184  return true;
185  }
186  }
187  return false;
188 }
189 
191 {
192  x_trend_.reset();
193  y_trend_.reset();
195 }
196 
197 bool OscillationCritic::setOscillationFlags(const nav_2d_msgs::Twist2D& cmd_vel)
198 {
199  bool flag_set = false;
200  // set oscillation flags for moving forward and backward
201  flag_set |= x_trend_.update(cmd_vel.x);
202 
203  // we'll only set flags for strafing and rotating when we're not moving forward at all
204  if (x_only_threshold_ < 0.0 || fabs(cmd_vel.x) <= x_only_threshold_)
205  {
206  flag_set |= y_trend_.update(cmd_vel.y);
207  flag_set |= theta_trend_.update(cmd_vel.theta);
208  }
209  return flag_set;
210 }
211 
212 double OscillationCritic::scoreTrajectory(const dwb_msgs::Trajectory2D& traj)
213 {
214  if (x_trend_.isOscillating(traj.velocity.x) ||
215  y_trend_.isOscillating(traj.velocity.y) ||
216  theta_trend_.isOscillating(traj.velocity.theta))
217  {
218  throw nav_core2::IllegalTrajectoryException(name_, "Trajectory is oscillating.");
219  }
220  return 0.0;
221 }
222 
223 } // namespace dwb_critics
nav_2d_utils::searchAndGetParam
param_t searchAndGetParam(const ros::NodeHandle &nh, const std::string &param_name, const param_t &default_value)
dwb_critics::OscillationCritic::scoreTrajectory
double scoreTrajectory(const dwb_msgs::Trajectory2D &traj) override
Definition: oscillation.cpp:212
nav_core2::IllegalTrajectoryException
dwb_critics::OscillationCritic::oscillation_reset_dist_
double oscillation_reset_dist_
Definition: oscillation.h:141
dwb_critics::OscillationCritic::CommandTrend::reset
void reset()
Definition: oscillation.cpp:53
ros::NodeHandle::getParam
bool getParam(const std::string &key, bool &b) const
dwb_local_planner::TrajectoryCritic::name_
std::string name_
dwb_critics::OscillationCritic::reset
void reset() override
Definition: oscillation.cpp:190
dwb_critics::OscillationCritic::prev_reset_time_
ros::Time prev_reset_time_
Definition: oscillation.h:150
dwb_critics::OscillationCritic::CommandTrend::update
bool update(double velocity)
update internal flags based on the commanded velocity
Definition: oscillation.cpp:60
class_list_macros.h
dwb_critics::OscillationCritic
Checks to see whether the sign of the commanded velocity flips frequently.
Definition: oscillation.h:79
PLUGINLIB_EXPORT_CLASS
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)
dwb_critics::OscillationCritic::y_trend_
CommandTrend y_trend_
Definition: oscillation.h:140
oscillation.h
dwb_critics::OscillationCritic::x_trend_
CommandTrend x_trend_
Definition: oscillation.h:140
dwb_critics::OscillationCritic::pose_
geometry_msgs::Pose2D pose_
Definition: oscillation.h:148
dwb_critics::OscillationCritic::x_only_threshold_
double x_only_threshold_
Definition: oscillation.h:141
ros::NodeHandle::searchParam
bool searchParam(const std::string &key, std::string &result) const
parameters.h
ros::NodeHandle::hasParam
bool hasParam(const std::string &key) const
dwb_critics::OscillationCritic::CommandTrend::hasSignFlipped
bool hasSignFlipped()
Check whether we are currently tracking a flipped sign.
Definition: oscillation.cpp:89
dwb_critics::OscillationCritic::setOscillationFlags
bool setOscillationFlags(const nav_2d_msgs::Twist2D &cmd_vel)
Given a command that has been selected, track each component's sign for oscillations.
Definition: oscillation.cpp:197
exceptions.h
dwb_critics::OscillationCritic::prev_stationary_pose_
geometry_msgs::Pose2D prev_stationary_pose_
Definition: oscillation.h:148
dwb_critics::OscillationCritic::CommandTrend::CommandTrend
CommandTrend()
Definition: oscillation.cpp:48
dwb_critics::OscillationCritic::oscillation_reset_dist_sq_
double oscillation_reset_dist_sq_
Definition: oscillation.h:145
dwb_local_planner::TrajectoryCritic::critic_nh_
ros::NodeHandle critic_nh_
dwb_critics::OscillationCritic::onInit
void onInit() override
Definition: oscillation.cpp:94
dwb_critics::OscillationCritic::CommandTrend::isOscillating
bool isOscillating(double velocity)
Check to see whether the proposed velocity would be considered oscillating.
Definition: oscillation.cpp:84
ROS_WARN_NAMED
#define ROS_WARN_NAMED(name,...)
dwb_critics::OscillationCritic::oscillation_reset_time_
double oscillation_reset_time_
Definition: oscillation.h:142
dwb_critics::OscillationCritic::theta_trend_
CommandTrend theta_trend_
Definition: oscillation.h:140
dwb_critics
Definition: alignment_util.h:40
dwb_critics::OscillationCritic::oscillation_reset_angle_
double oscillation_reset_angle_
Definition: oscillation.h:141
dwb_local_planner::TrajectoryCritic
dwb_critics::OscillationCritic::resetAvailable
bool resetAvailable()
Return true if the robot has travelled far enough or waited long enough.
Definition: oscillation.cpp:159
dwb_critics::OscillationCritic::debrief
void debrief(const nav_2d_msgs::Twist2D &cmd_vel) override
Definition: oscillation.cpp:140
dwb_critics::OscillationCritic::prepare
bool prepare(const geometry_msgs::Pose2D &pose, const nav_2d_msgs::Twist2D &vel, const geometry_msgs::Pose2D &goal, const nav_2d_msgs::Path2D &global_plan) override
Definition: oscillation.cpp:131
ros::Time::now
static Time now()


dwb_critics
Author(s): David V. Lu!!
autogenerated on Sun May 18 2025 02:47:34