]> rtime.felk.cvut.cz Git - hubacji1/bcar.git/blob - incl/bcar.hh
Add operator<< for line
[hubacji1/bcar.git] / incl / bcar.hh
1 /*! \file */
2 #ifndef BCAR_BCAR_H
3 #define BCAR_BCAR_H
4
5 #include <ostream>
6 #include <vector>
7
8 namespace bcar {
9
10 template <typename T> int sgn(T val) {
11         return (T(0) < val) - (val < T(0));
12 }
13
14 class Line;
15
16 class Point {
17 private:
18         double x_ = 0.0;
19         double y_ = 0.0;
20 public:
21         Point(double x, double y);
22         Point();
23
24         /*! Get horizontal coordinate. */
25         double x() const;
26
27         /*! Set horizontal coordinate. */
28         void x(double x);
29
30         /*! Get vertical coordinate. */
31         double y() const;
32
33         /*! Set vertical coordinate. */
34         void y(double y);
35
36         /*! \brief Return the smallest angle between three points.
37
38         \see https://math.stackexchange.com/questions/361412/finding-the-angle-between-three-points
39         */
40         double min_angle_between(Point const& p1, Point const& p2) const;
41
42         /*! \brief Return `true` if `this` point is inside of polygon `poly`.
43          *
44          * The polygon is given by the vector of `Point`s.
45          *
46          * \see https://en.wikipedia.org/wiki/Even%E2%80%93odd_rule
47          *
48          * \param poly Polygon to consider.
49          */
50         bool inside_of(std::vector<Point> const& poly) const;
51
52         /*! \brief Return `true` if on the right side of the plane.
53          *
54          * The plane is given by the line `li`, where `li->fp()` is the base
55          * point and the direction is given by `li->lp() - li->fp()`.
56          *
57          * \param li The plane to consider is given by `li`.
58          */
59         bool on_right_side_of(Line const& li) const;
60
61         /*! \brief Rotate self around the point.
62
63         \param c Rotation center `Point`.
64         \param angl Angle of rotation.
65         */
66         void rotate(Point const& c, double const angl);
67
68         friend std::ostream& operator<<(std::ostream& out, Point const& p);
69 };
70
71 class Line {
72 private:
73         Point first;
74         Point last;
75         Point intersection1;
76         Point intersection2;
77 public:
78         Line(Point const& fp, Point const& lp);
79
80         /*! Get first point. */
81         Point fp() const&;
82
83         /*! Get last point. */
84         Point lp() const&;
85
86         /*! Get intersection point. */
87         Point in1() const&;
88
89         /*! Get intersection point. */
90         Point in2() const&;
91
92         /*! \brief Return if `this` line intersects with line `li`.
93          *
94          * If the method returns `true`, the intersection `Point` is available
95          * in `this->in1()`.
96          *
97          * \see https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection
98          *
99          * \param li The line to check the intersection with.
100          */
101         bool intersects_with(Line const& li);
102
103         /*! \brief Return intersections of `this` (infinite) line and circle.
104          *
105          * If the method returns `true`, the intersection `Point`s are available
106          * in `this->in1()` and `this->in2()`.
107          *
108          * \see https://mathworld.wolfram.com/Circle-LineIntersection.html
109          *
110          * \param c Circle center.
111          * \param r Circle radius.
112          */
113         bool intersects_with(Point const& c, double const r);
114
115         double len() const;
116
117         friend std::ostream& operator<<(std::ostream& out, Line const& li);
118 };
119
120 /*! Store coordinates `x`, `y`, and heading `h`. */
121 class Pose : public virtual Point {
122 private:
123         double h_ = 0.0;
124 public:
125         Pose(double x, double y, double h);
126         Pose();
127
128         /*! Get heading in the interval [-pi, +pi] radians. */
129         double h() const;
130
131         /*! Set heading in radians. It's recomputed to [-pi, +pi]. */
132         void h(double h);
133
134         /*! Set pose (`x`, `y`, and `h`.) */
135         void set_pose(Pose const& p);
136
137         void rotate(Point const& c, double const angl);
138
139         friend std::ostream& operator<<(std::ostream& out, Pose const& p);
140 };
141
142 class PoseRange : public virtual Pose {
143 private:
144         double e_ = 0.0;
145         using Pose::h;
146 public:
147         /*! Get heading's begin in the interval [-pi, +pi] radians. */
148         double b() const;
149
150         /*! Set heading's begin in radians. It's recomputed to [-pi, +pi]. */
151         void b(double b);
152
153         /*! Get heading's end in the interval [-pi, +pi] radians. */
154         double e() const;
155
156         /*! Set heading's end in radians. It's recomputed to [-pi, +pi]. */
157         void e(double e);
158
159         void rotate(Point const& c, double const angl);
160
161         friend std::ostream& operator<<(std::ostream& out, PoseRange const& p);
162 };
163
164 /*! \brief Store car size.
165  *
166  * - Default is https://en.wikipedia.org/wiki/Fiat_Punto
167  */
168 class CarSize {
169 private:
170         double curb_to_curb = 10.820;
171         double width = 1.625;
172         double wheelbase = 2.450;
173         double distance_to_front = 3.105;
174         double length = 3.760;
175 public:
176         /*! Get curb-to-curb distance. */
177         double ctc() const;
178
179         /*! Set curb-to-curb distance. */
180         void ctc(double ctc);
181
182         /*! Get wheelbase. */
183         double wb() const;
184
185         /*! Set wheelbase. */
186         void wb(double wb);
187
188         /*! Get width. */
189         double w() const;
190
191         /*! Set width. */
192         void w(double w);
193
194         /*! Get length. */
195         double len() const;
196
197         /*! Set length. */
198         void len(double len);
199
200         /*! Get distance from rear axle to front. */
201         double df() const;
202
203         /*! Set distance from rear axle to front. */
204         void df(double df);
205
206         /*! Get distance from rear axle to rear. */
207         double dr() const;
208
209         /*! \brief Get minimum turning radius.
210          *
211          * Please, note that the method returns really _minimum turning radius_,
212          * which is the distance from the reare axle center to the center of
213          * left or right rotation given by the kinematics constrants, i.e.
214          * _wheelbase_ and _curb-to-curb_ distance.
215          *
216          * Sometimes _minimum turning radius_ is not radius, not minimum, or not
217          * turning. In this method, _minimum turning radius_ is minimum turning
218          * radius.
219          */
220         double mtr() const;
221
222         /*! \brief Return inner radius.
223          *
224          * The inner radius is the distance from minimum turning radius circle
225          * center to the nearest point on the car. In this case, the nearest
226          * points on the car are rear axle endpoints.
227          */
228         double iradi() const;
229
230         /*! \brief Return outer front radius.
231          *
232          * The outer front radius is the distance from minimum turning radius
233          * circle center to the farthest point on the front (from the rear axle
234          * view) part of the car.
235          */
236         double ofradi() const;
237
238         /*! \brief Return outer rear radius.
239          *
240          * The outer rear radius is the distance from minimum turning radius
241          * circle center to the farthest point on the rear (from the rear axle
242          * view) part of the car.
243          */
244         double orradi() const;
245
246         /*! \brief Return length of perfect parking slot.
247          *
248          * The width of the slot is the same as the width of the car.
249          *
250          * \see Simon R. Blackburn *The Geometry of Perfect Parking*
251          * \see https://www.ma.rhul.ac.uk/SRBparking
252          */
253         double perfect_parking_slot_len() const;
254 };
255
256 /*! Store car motion. */
257 class CarMove {
258 private:
259         double speed = 0.0;
260         double steer = 0.0;
261 public:
262         /*! Get speed. */
263         double sp() const;
264
265         /*! Set speed. */
266         void sp(double sp);
267
268         /*! Get steer. */
269         double st() const;
270
271         /*! Set steer. */
272         void st(double st);
273 };
274
275 /*! \brief Geometrical computations of a bicycle car.
276  *
277  * - `x()` and `y()` methods returns coordinates of rear axle center.
278  */
279 class BicycleCar : public virtual Pose, public virtual CarSize,
280                 public virtual CarMove {
281 private:
282 public:
283         /*! \brief Return `false` if `bc` is not achievable.
284          *
285          * When `false` is returned the `bc` may still be drivable, but not
286          * trivially, i.e. by "line segment - circle arc - line segment".
287          *
288          * \param p `PoseRange` (resp. `Pose`) to achieve.
289          */
290         bool drivable(PoseRange const& p) const;
291         bool drivable(Pose const& p) const;
292
293         /*! Set maximum steering angle. */
294         void set_max_steer();
295
296         /*! Get frame's left front x coordinate. */
297         double lfx() const;
298
299         /*! Get frame's left front y coordinate. */
300         double lfy() const;
301
302         /*! Get frame's left rear x coordinate. */
303         double lrx() const;
304
305         /*! Get frame's left rear y coordinate. */
306         double lry() const;
307
308         /*! Get frame's right rear x coordinate. */
309         double rrx() const;
310
311         /*! Get frame's right rear y coordinate. */
312         double rry() const;
313
314         /*! Get frame's right front x coordinate. */
315         double rfx() const;
316
317         /*! Get frame's right front y coordinate. */
318         double rfy() const;
319
320         /*! Get rear axle's left x coordinate. */
321         double ralx() const;
322
323         /*! Get rear axle's left y coordinate. */
324         double raly() const;
325
326         /*! Get rear axle's right x coordinate. */
327         double rarx() const;
328
329         /*! Get rear axle's right y coordinate. */
330         double rary() const;
331
332         /*! Min. turning radius circle center on left. */
333         Point ccl() const;
334
335         /*! Min. turning radius circle center on rigth. */
336         Point ccr() const;
337
338         /*! Next car position based on speed `sp` and steer `st`. */
339         void next();
340 };
341
342 } // namespace bcar
343 #endif /* BCAR_BCAR_H */