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