NimbRo ROS Soccer Package
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
wak_utils.h
1 // Walk and kick: Behaviour utilities
2 // Author: Philipp Allgeuer <pallgeuer@ais.uni-bonn.de>
3 
4  // Ensure header is only included once
5 #ifndef WAK_UTILS_H
6 #define WAK_UTILS_H
7 
8 // Includes
9 #include <walk_and_kick/wak_common.h>
10 #include <config_server/parameter.h>
11 #include <field_model/field_model.h>
12 #include <rc_utils/math_spline.h>
13 
14 // Walk and kick namespace
15 namespace walk_and_kick
16 {
17  // Using declarations
19 
25  class WAKUtils
26  {
27  public:
28  // Tangent information struct
29  struct TangentInfo
30  {
31  TangentInfo() : posAngle(0.0f), negAngle(0.0f), maxAdjust(0.0f), length(0.0f) {}
32  float posAngle;
33  float negAngle;
34  float maxAdjust;
35  float length;
36  };
37 
38  // Calculate the tangents from a point to a circle of given centre and radius
39  static void calcCircleTangent(TangentInfo& TI, const Vec2f& point, const Vec2f& centre, float radius);
40 
41  // Calculate a path from one position to another, subject to a halo (circle) of given centre and radius
42  static float calculateHaloPath(Vec2f& fromNormal, const Vec2f& fromPos, const Vec2f& toPos, const Vec2f& centre, float radius, bool smoothFromNormal = true) { Vec2fArray path; return calculateHaloPath(fromNormal, path, fromPos, toPos, centre, radius, smoothFromNormal); }
43  static float calculateHaloPath(Vec2f& fromNormal, Vec2fArray& path, const Vec2f& fromPos, const Vec2f& toPos, const Vec2f& centre, float radius, bool smoothFromNormal = true);
44 
45  // Calculate the wedge from a particular angle, to another particular angle, possibly forcing the sign of the output in the process
46  static float calcWedge(float fromAngle, float toAngle, int forceSign = 0);
47 
48  private:
49  // Constructor
50  WAKUtils() {}
51  };
52 
63  class Counter
64  {
65  public:
66  Counter() { reset(); }
67  void reset() { m_count = 0; }
68  int count() const { return m_count; }
69  void add(bool expr = true) { if(expr) m_count++; else m_count = (m_count > 0 ? m_count - 1 : 0); }
70  void increment() { m_count++; }
71  bool reached(int limit) const { return (m_count >= limit); }
72  private:
73  int m_count;
74  };
75 
83  class TheWorm
84  {
85  public:
86  explicit TheWorm(int limit = 100) { reset(limit); }
87  void reset() { m_worm = 0; }
88  void reset(bool decision) { if(decision) m_worm = m_limit; else m_worm = -m_limit; }
89  void reset(int limit) { reset(); setLimit(limit); }
90  void resetR(int range) { reset(); setRange(range); }
91  void setLimit(int limit) { m_limit = (limit >= 1 ? limit : 1); } // The count from zero to a positive or negative decision
92  void setRange(int range) { m_limit = (range >= 2 ? range >> 1 : 1); } // The count from a decision to the opposite decision
93  void setWorm(int value) { m_worm = (value >= m_limit ? m_limit : (value <= -m_limit ? -m_limit : value)); }
94  void vote(bool decision) { if(decision) m_worm = (m_worm < m_limit ? m_worm + 1 : m_limit); else m_worm = (m_worm > -m_limit ? m_worm - 1 : -m_limit); }
95  void vote(bool decision, int numVotes) { if(numVotes <= 0) return; if(decision) m_worm = std::min(m_worm + numVotes, m_limit); else m_worm = std::max(m_worm - numVotes, -m_limit); }
96  void neutralise() { if(m_worm > 0) m_worm = std::min(m_worm - 1, m_limit); else if(m_worm < 0) m_worm = std::max(m_worm + 1, -m_limit); }
97  int limit() const { return m_limit; }
98  int range() const { return m_limit << 1; }
99  int count() const { return m_worm; }
100  bool decision() const { return (m_worm >= 0); } // Balanced votes is a decision of true!
101  bool unanimousTrue() const { return (m_worm >= m_limit); }
102  bool unanimousFalse() const { return (m_worm <= -m_limit); }
103  bool unanimous() const { return (unanimousTrue() || unanimousFalse()); }
104  void updateWormTime(const config_server::Parameter<float>* param) { setRange(TO_COUNT(param->get())); }
105  private:
106  int m_limit;
107  int m_worm;
108  };
109 
116  {
117  public:
118  LiveTrapVelSpline() { reset(); }
119  void reset() { m_valid = false; m_x = m_v = m_t = 0.0; }
120  void setState(double x, double v = 0.0) { m_x = x; m_v = v; m_t = 0.0; m_valid = false; }
121  bool valid() const { return m_valid; }
122  bool finished() const { return (!m_valid || m_t >= m_spline.T()); }
123  double curX() const { return m_x; }
124  double curV() const { return m_v; }
125  void newTarget(double x, double v, double maxVel, double maxAcc, bool ctsVel = true)
126  {
127  m_spline.setParams(m_x, (ctsVel ? m_v : 0.0), x, v, maxVel, maxAcc);
128  m_valid = true;
129  m_t = 0.0;
130  }
131  double forward(double dT)
132  {
133  if(!m_valid) return m_x;
134  m_t += dT;
135  m_x = m_spline.x(m_t);
136  m_v = m_spline.v(m_t);
137  return m_x;
138  }
139  private:
140  rc_utils::TrapVelSpline m_spline;
141  bool m_valid; // Flag whether the spline is currently valid
142  double m_x; // Current position
143  double m_v; // Current velocity
144  double m_t; // Current time relative to the start of the spline (only if valid)
145  };
146 
157  {
158  public:
159  TrapVelSpline2D() { reset(); }
160  void reset() { m_valid = false; m_x = m_xi = m_xf = 0.0; m_y = m_yi = m_yf = 0.0; m_t = 0.0; }
161  void setState(double x, double y) { m_valid = false; m_x = m_xi = m_xf = x; m_y = m_yi = m_yf = y; m_t = 0.0; }
162  bool valid() const { return m_valid; }
163  bool finished() const { return (!m_valid || m_t >= m_spline.T()); }
164  double curX() const { return m_x; }
165  double curY() const { return m_y; }
166  double targetX() const { return m_xf; }
167  double targetY() const { return m_yf; }
168  void newTarget(double x, double y, double maxVel, double maxAcc)
169  {
170  m_xi = m_x;
171  m_yi = m_y;
172  m_xf = x;
173  m_yf = y;
174  double dx = m_xf - m_xi;
175  double dy = m_yf - m_yi;
176  double D = sqrt(dx*dx + dy*dy);
177  m_spline.setParams(0.0, 0.0, D, 0.0, maxVel, maxAcc);
178  m_valid = true;
179  m_t = 0.0;
180  }
181  void forward(double dT)
182  {
183  if(!m_valid) return;
184  m_t += dT;
185  double D = m_spline.xf();
186  if(D == 0.0)
187  {
188  m_x = m_xf;
189  m_y = m_yf;
190  }
191  else
192  {
193  double d = m_spline.x(m_t);
194  double r = d/D;
195  m_x = m_xi + r*(m_xf - m_xi);
196  m_y = m_yi + r*(m_yf - m_yi);
197  }
198  }
199  private:
200  rc_utils::TrapVelSpline m_spline;
201  bool m_valid; // Flag whether the spline is currently valid
202  double m_xi; // Initial x position of the current spline (only if valid)
203  double m_yi; // Initial y position of the current spline (only if valid)
204  double m_xf; // Final x position of the current spline (only if valid)
205  double m_yf; // Final y position of the current spline (only if valid)
206  double m_x; // Current x position
207  double m_y; // Current y position
208  double m_t; // Current time relative to the start of the spline (only if valid)
209  };
210 
217  {
218  public:
219  // Constructor
220  FieldDimensions() : m_field(FieldModel::getInstance()) {}
221 
222  // Field parameters
223  FieldModel::FieldType fieldType() const { return m_field->type(); }
224  const std::string& fieldTypeName() const { return m_field->typeName(); }
225  float fieldLength() const { return m_field->length(); }
226  float fieldWidth() const { return m_field->width(); }
227  float circleDiameter() const { return m_field->centerCircleDiameter(); }
228  float boundary() const { return m_field->boundary(); }
229  float goalWidth() const { return m_field->goalWidth(); }
230  float goalAreaLength() const { return m_field->goalAreaDepth(); }
231  float goalAreaWidth() const { return m_field->goalAreaWidth(); }
232  float penaltyMarkDist() const { return m_field->penaltyMarkerDist(); }
233  float ballDiameter() const { return m_field->ballDiameter(); }
234  float fieldLengthH() const { return 0.5*m_field->length(); }
235  float fieldWidthH() const { return 0.5*m_field->width(); }
236  float circleRadius() const { return 0.5*m_field->centerCircleDiameter(); }
237  float goalWidthH() const { return 0.5*m_field->goalWidth(); }
238  float ballRadius() const { return 0.5*m_field->ballDiameter(); }
239 
240  private:
241  // Field model
242  const FieldModel* const m_field;
243  };
244 }
245 
246 #endif
247 // EOF
float goalWidth() const
The width of the goals from one goal post to the other.
Definition: wak_utils.h:229
float fieldWidthH() const
Half of the width of the field, i.e. the distance from centre point to the side lines.
Definition: wak_utils.h:235
float penaltyMarkDist() const
The distance from the goal line to the penalty marker in that half of the field.
Definition: wak_utils.h:232
float boundary() const
The width of the green boundary (on all four sides) outside the outer white lines of the field...
Definition: wak_utils.h:228
double goalWidth() const
Goal width.
Definition: field_model.h:110
FieldModel::FieldType fieldType() const
The type of the field that is being played on.
Definition: wak_utils.h:223
float ballRadius() const
The radius of the ball.
Definition: wak_utils.h:238
double goalAreaWidth() const
Width of the penalty area before each goal.
Definition: field_model.h:114
A trapezoidal velocity spline that operates in 2D, based on the rc_utils::TrapVelSpline class...
Definition: wak_utils.h:156
Model of the soccer field.
Definition: field_model.h:73
FieldType type() const
Field type.
Definition: field_model.h:90
A collection of independent helper functions that should be available to all.
Definition: wak_utils.h:25
float fieldWidth() const
The width of the field from one sideline to the other.
Definition: wak_utils.h:226
double ballDiameter() const
Diameter of the ball.
Definition: field_model.h:129
const std::string & typeName() const
Field type name.
Definition: field_model.h:94
float circleDiameter() const
The diameter of the centre circle.
Definition: wak_utils.h:227
double goalAreaDepth() const
Depth of the penalty area before each goal.
Definition: field_model.h:118
float fieldLengthH() const
Half of the length of the field, i.e. the distance from the centre line to the goal lines...
Definition: wak_utils.h:234
float circleRadius() const
The radius of the centre circle.
Definition: wak_utils.h:236
A simple class for abstracting away the source of the field dimensions.
Definition: wak_utils.h:216
float goalWidthH() const
Half of the width of the goals, i.e. half of the distance separation between the two goal posts...
Definition: wak_utils.h:237
double boundary() const
Field boundary (amount of green outside the field boundary)
Definition: field_model.h:106
float ballDiameter() const
The diameter of the ball.
Definition: wak_utils.h:233
A simple counter class for counting events.
Definition: wak_utils.h:63
float goalAreaWidth() const
The larger dimension of the goal area box, from outside of the left goal post to outside of...
Definition: wak_utils.h:231
double width() const
Field width (inside the lines)
Definition: field_model.h:98
float goalAreaLength() const
The smaller dimension of the goal area box, from the goal line to the manual robot starting line...
Definition: wak_utils.h:230
double penaltyMarkerDist() const
Distance from the goal line to the penalty marker.
Definition: field_model.h:125
A wrapper class for the trapezoidal velocity spline class rc_utils::TrapVelSpline with a focus on smo...
Definition: wak_utils.h:115
double length() const
Field length (inside the lines)
Definition: field_model.h:102
A class that implements the worm, for making a live decision between two opposites.
Definition: wak_utils.h:83
float fieldLength() const
The length of the field from one goal side to the other.
Definition: wak_utils.h:225
const std::string & fieldTypeName() const
A string representation of the type of the field that is being played on.
Definition: wak_utils.h:224