]> rtime.felk.cvut.cz Git - hubacji1/bcar.git/blob - incl/bcar.hh
Add set pose method
[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 Point {
15 private:
16         double x_ = 0.0;
17         double y_ = 0.0;
18 public:
19         Point(double x, double y);
20         Point();
21
22         /*! Get horizontal coordinate. */
23         double x() const;
24
25         /*! Set horizontal coordinate. */
26         void x(double x);
27
28         /*! Get vertical coordinate. */
29         double y() const;
30
31         /*! Set vertical coordinate. */
32         void y(double y);
33
34         /*! \brief Return the smallest angle between three points.
35
36         \see https://math.stackexchange.com/questions/361412/finding-the-angle-between-three-points
37         */
38         double min_angle_between(Point const& p1, Point const& p2) const;
39
40         /*! \brief Return `true` if `this` point is inside of polygon `poly`.
41          *
42          * The polygon is given by the vector of `Point`s.
43          *
44          * \see https://en.wikipedia.org/wiki/Even%E2%80%93odd_rule
45          *
46          * \param poly Polygon to consider.
47          */
48         bool inside_of(std::vector<Point> const& poly) const;
49 };
50
51 class Line {
52 private:
53         Point first;
54         Point last;
55         Point intersection1;
56         Point intersection2;
57 public:
58         Line(Point const& fp, Point const& lp);
59
60         /*! Get first point. */
61         Point fp() const&;
62
63         /*! Get last point. */
64         Point lp() const&;
65
66         /*! Get intersection point. */
67         Point in1() const&;
68
69         /*! Get intersection point. */
70         Point in2() const&;
71
72         /*! \brief Return if `this` line intersects with line `li`.
73          *
74          * If the method returns `true`, the intersection `Point` is available
75          * in `this->in1()`.
76          *
77          * \see https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection
78          *
79          * \param li The line to check the intersection with.
80          */
81         bool intersects_with(Line const& li);
82
83         /*! \brief Return intersections of `this` (infinite) line and circle.
84          *
85          * If the method returns `true`, the intersection `Point`s are available
86          * in `this->in1()` and `this->in2()`.
87          *
88          * \see https://mathworld.wolfram.com/Circle-LineIntersection.html
89          *
90          * \param c Circle center.
91          * \param r Circle radius.
92          */
93         bool intersects_with(Point const& c, double const r);
94
95         /*! \brief Return if point `p` is on the right side of the plane.
96          *
97          * The plane is given by the line `this`, where `this->fp()` is the base
98          * point and the direction is given by `this->lp() - this->fp()`.
99          *
100          * \param p The point to consider.
101          */
102         bool is_on_right_side(Point const& p) const;
103 };
104
105 /*! Store coordinates `x`, `y`, and heading `h`. */
106 class Pose {
107 private:
108         double x_ = 0.0;
109         double y_ = 0.0;
110         double h_ = 0.0;
111 public:
112         /*! Get horizontal coordinate. */
113         double x() const;
114
115         /*! Set horizontal coordinate. */
116         void x(double x);
117
118         /*! Get vertical coordinate. */
119         double y() const;
120
121         /*! Set vertical coordinate. */
122         void y(double y);
123
124         /*! Get heading in the interval [-pi, +pi] radians. */
125         double h() const;
126
127         /*! Set heading in radians. It's recomputed to [-pi, +pi]. */
128         void h(double h);
129
130         /*! Set pose (`x`, `y`, and `h`.) */
131         void set_pose(Pose const& p);
132
133         /*! \brief Rotate self around the point.
134
135         \param c Rotation center `Point`.
136         \param angl Angle of rotation.
137         */
138         void rotate(Point const& c, double const angl);
139
140         friend std::ostream& operator<<(std::ostream& out, Pose const& p);
141 };
142
143 class PoseRange : public Pose {
144 private:
145         double e_ = 0.0;
146         using Pose::h;
147 public:
148         /*! Get heading's begin in the interval [-pi, +pi] radians. */
149         double b() const;
150
151         /*! Set heading's begin in radians. It's recomputed to [-pi, +pi]. */
152         void b(double b);
153
154         /*! Get heading's end in the interval [-pi, +pi] radians. */
155         double e() const;
156
157         /*! Set heading's end in radians. It's recomputed to [-pi, +pi]. */
158         void e(double e);
159
160         void rotate(Point const& c, double const angl);
161
162         friend std::ostream& operator<<(std::ostream& out, PoseRange const& p);
163 };
164
165 /*! \brief Store car size.
166  *
167  * - Default is https://en.wikipedia.org/wiki/Fiat_Punto
168  */
169 class CarSize {
170 private:
171         double curb_to_curb = 10.820;
172         double width = 1.625;
173         double wheelbase = 2.450;
174         double distance_to_front = 3.105;
175         double length = 3.760;
176 public:
177         /*! Get curb-to-curb distance. */
178         double ctc() const;
179
180         /*! Set curb-to-curb distance. */
181         void ctc(double ctc);
182
183         /*! Get wheelbase. */
184         double wb() const;
185
186         /*! Set wheelbase. */
187         void wb(double wb);
188
189         /*! Get width. */
190         double w() const;
191
192         /*! Set width. */
193         void w(double w);
194
195         /*! Get length. */
196         double len() const;
197
198         /*! Set length. */
199         void len(double len);
200
201         /*! Get distance from rear axle to front. */
202         double df() const;
203
204         /*! Set distance from rear axle to front. */
205         void df(double df);
206
207         /*! Get distance from rear axle to rear. */
208         double dr() const;
209
210         /*! \brief Get minimum turning radius.
211          *
212          * Please, note that the method returns really _minimum turning radius_,
213          * which is the distance from the reare axle center to the center of
214          * left or right rotation given by the kinematics constrants, i.e.
215          * _wheelbase_ and _curb-to-curb_ distance.
216          *
217          * Sometimes _minimum turning radius_ is not radius, not minimum, or not
218          * turning. In this method, _minimum turning radius_ is minimum turning
219          * radius.
220          */
221         double mtr() const;
222
223         /*! \brief Return inner radius.
224          *
225          * The inner radius is the distance from minimum turning radius circle
226          * center to the nearest point on the car. In this case, the nearest
227          * points on the car are rear axle endpoints.
228          */
229         double iradi() const;
230
231         /*! \brief Return outer front radius.
232          *
233          * The outer front radius is the distance from minimum turning radius
234          * circle center to the farthest point on the front (from the rear axle
235          * view) part of the car.
236          */
237         double ofradi() const;
238
239         /*! \brief Return outer rear radius.
240          *
241          * The outer rear radius is the distance from minimum turning radius
242          * circle center to the farthest point on the rear (from the rear axle
243          * view) part of the car.
244          */
245         double orradi() const;
246
247         /*! \brief Return length of perfect parking slot.
248          *
249          * The width of the slot is the same as the width of the car.
250          *
251          * \see Simon R. Blackburn *The Geometry of Perfect Parking*
252          * \see https://www.ma.rhul.ac.uk/SRBparking
253          */
254         double perfect_parking_slot_len() const;
255 };
256
257 /*! Store car motion. */
258 class CarMove {
259 private:
260         double speed = 0.0;
261         double steer = 0.0;
262 public:
263         /*! Get speed. */
264         double sp() const;
265
266         /*! Set speed. */
267         void sp(double sp);
268
269         /*! Get steer. */
270         double st() const;
271
272         /*! Set steer. */
273         void st(double st);
274 };
275
276 /*! \brief Geometrical computations of a bicycle car.
277  *
278  * - `x()` and `y()` methods returns coordinates of rear axle center.
279  */
280 class BicycleCar : public Pose, public CarSize, public 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 */