1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
/** 
 * @file BallPercept.h
 * @author <a href="mailto:mohr@informatik.hu-berlin.de">Christian Mohr</a>
 * Declaration of class LinePerceptOld
 */

#ifndef _LinePerceptOld_h_
#define _LinePerceptOld_h_

#include <vector>

#include "Tools/Math/Vector2.h"
#include "Tools/Math/Line.h"
#include "Tools/LinesTable.h"

#include <Tools/DataStructures/Printable.h>
#include <Tools/DataStructures/Serializer.h>

#include "Representations/Infrastructure/FrameInfo.h"


class LinePerceptOld : public naoth::Printable
{ 
public:

  enum LineType
  {
    unknown, //equals ColorClasses::none
    O, //line along field bounds, equals ColorClasses::orange
    I, //line inside of field, equals ColorClasses::yellow
    C, //circle line, equals ColorClasses::skyblue
    none //invalid line, equals ColorClasses::white
  };

  enum LineID
  {
    center_line,
    goal_line_own,
    goal_line_opponent,
    unknown_id
  };

  /**
   The class LineSegmentImage describes a segment of a line in the image coordinates.
  */
  class LineSegmentImage
  {
  public:
    LineSegmentImage()
      :
      thickness(0.0),
      angle(0.0),
      //type(LinePerceptOld::unknown),
      valid(false)
    {}

    /** the line detected in the image (pixel coordinates) */
    Math::LineSegment segment;

    // information in image
    double thickness;
    double angle;

    /** the type of the line estimated in image */
    //LineType type;

    // what do we need it for?
    bool valid;
  };



  class FieldLineSegment
  {
    public:
      FieldLineSegment()
        :
        //valid(false),
        type(LinePerceptOld::unknown),
        seen_id(unknown_id)
      {}

      // TODO: when exactly is a line segment valid?
      //bool valid; 

      // TODO: is the type filled properly?
      /** the type of the detected line */
      LineType type;

      /** estimated id of the line, e.g., center line, goal line etc. */
      LineID seen_id;

      /** the line detected in the image (pixel coordinates) */
      LineSegmentImage lineInImage;

      /** the projection of the line segment on the ground (robot coordinates) */
      Math::LineSegment lineOnField;
  };//end class FieldLineSegment


  /** 
    currently used only in 3DSim to represent the seen corners.
  */
  class Flag
  {
  public:
    Flag(const Vector2d& seenPosOnField, const Vector2d& absolutePosOnField)
      : 
      seenPosOnField(seenPosOnField),
      absolutePosOnField(absolutePosOnField)
    {}
    Vector2d seenPosOnField;
    Vector2d absolutePosOnField; // model of the flag (i.e. its known absolute osition on the field)
  };



  class Intersection
  {
  public:

    Intersection()
      : type(LineIntersection::unknown)
    {
    }

    Intersection(const Vector2d& pos)
      :
      type(LineIntersection::unknown),
      pos(pos)
    {
    }

    void setSegments(int segOne, int segTwo)
    {
      segmentIndices[0] = segOne;
      segmentIndices[1] = segTwo;
    }

    void setSegments(int segOne, int segTwo, double distOne, double distTwo)
    {
      segmentIndices[0] = segOne;
      segmentsDistanceToIntersection[0] = distOne;
      segmentIndices[1] = segTwo;
      segmentsDistanceToIntersection[1] = distTwo;
    }

    void setType(LineIntersection::Type typeToSet){ type = typeToSet; }
    void setPosOnField(const Vector2d& p) { posOnField = p; }
    void setPosInImage(const Vector2<unsigned int>& p) { pos = p; }
    
    // getters
    LineIntersection::Type getType() const { return type; }
    const Vector2<unsigned int>& getSegmentIndices() const { return segmentIndices; }
    const Vector2d& getSegmentsDistancesToIntersection() const { return segmentsDistanceToIntersection; }
    const Vector2d& getPos() const { return pos; }
    const Vector2d& getPosOnField() const { return posOnField; }

  private:
    LineIntersection::Type type;
    Vector2<unsigned int> segmentIndices;
    Vector2d segmentsDistanceToIntersection;
    Vector2d pos;
    Vector2d posOnField;
  };

  // seen lines
  std::vector<FieldLineSegment> lines;
  std::vector<FieldLineSegment> short_lines;
  std::vector<FieldLineSegment> extended_lines;
  std::vector<int> edgelLineIDs;

  // seen corners
  std::vector<Intersection> intersections;
  // seen flags (only S3D)
  std::vector<Flag> flags;

  // middle circle was seen
  bool middleCircleWasSeen;
  Vector2d middleCircleCenter;

  bool middleCircleOrientationWasSeen;
  Vector2d middleCircleOrientation;


  // representation for the closest line
  // TODO: this calculations can be made sowhere else
  double closestLineSeenLength;
  Vector2d closestPoint;
  Vector2d estOrthPointOfClosestLine;
  Vector2d closestPointOfClosestLine;

  // a line was seen
  // TODO: do we need it? (lines.empty() also does the job)
  bool lineWasSeen;

  // TODO: do we need it?
  naoth::FrameInfo frameInfoWhenLineWasSeen;


  LinePerceptOld()
  :
    middleCircleWasSeen(false),
    middleCircleOrientationWasSeen(false),
    closestLineSeenLength(0.0),
    lineWasSeen(false)
  {
    reset();
  }

  ~LinePerceptOld() {}
  
  /* reset percept */
  void reset()
  {
    lines.clear();
    short_lines.clear();
    extended_lines.clear();
    //lines.reserve(INITIAL_NUMBER_OF_LINES);

    intersections.clear();
    //intersections.reserve(INITIAL_NUMBER_OF_LINES);

    flags.clear();

    middleCircleWasSeen = false;
    middleCircleCenter.x = 0.0;
    middleCircleCenter.y = 0.0;
    
  }//end reset

  virtual void print(std::ostream& stream) const;

};

class LinePerceptOldTop : public LinePerceptOld
{
public:
  virtual ~LinePerceptOldTop() {}
};

/*
// FIXME: deprecated
class RansacCirclePercept
{
public:
  bool middleCircleWasSeen;
  Vector2d middleCircleCenter;

  // reset percept
  void reset()
  {
    middleCircleWasSeen = false;
    middleCircleCenter.x = 0.0;
    middleCircleCenter.y = 0.0;
  }//end reset

  RansacCirclePercept()
  {
    reset();
  }

  ~RansacCirclePercept() {}
};
*/

namespace naoth
{
  template<>
  class Serializer<LinePerceptOld>
  {
  public:
    static void serialize(const LinePerceptOld& representation, std::ostream& stream);
    static void deserialize(std::istream& stream, LinePerceptOld& representation);
  };

  template<>
  class Serializer<LinePerceptOldTop> : public Serializer<LinePerceptOld>
  {};

}

#endif // _LinePerceptOld_h_