-
Notifications
You must be signed in to change notification settings - Fork 125
/
osi_referenceline.proto
318 lines (307 loc) · 14.5 KB
/
osi_referenceline.proto
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
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
syntax = "proto2";
option optimize_for = SPEED;
import "osi_common.proto";
package osi3;
//
// \brief A reference line for defining a non-Euclidean ST coordinate system
//
// A reference line is a 3D polyline, used for generating a non-Euclidean
// ST coordinate system.
//
// \note This ST coordinate system is specific to OSI and not to be confused with
// similar definitions in other standards like OpenDRIVE or OpenSCENARIO 1.x.
// Nevertheless the goal of this definition is to approximate the source
// coordinates (e.g. OpenDRIVE).
//
// Notes on design decisions:
// - This is a polyline, and not some more complex curve. The advantage of a
// polyline is that it is very simple to generate from various map formats,
// and it is also easy to handle. The downside is that a polyline has no
// direct curvature, and even the angle is not continuous (only C0 smooth).
// In the author's experience, the benefits of a polyline outweigh the costs.
//
message ReferenceLine
{
// The ID of the reference line.
//
// \note Note ID is global unique.
//
// \rules
// is_globally_unique
// is_set
// \endrules
//
optional Identifier id = 1;
// The type of the reference line.
//
optional Type type = 3;
// ReferenceLine types
//
// ReferenceLinePoints might be interpreted differently depending on the type
// of the ReferenceLine.
//
// See also: "Adding T coordinates"
//
enum Type
{
// ReferenceLine is a polyline, where the coordinates of points are
// calculated by projection onto the nearest point on the line.
//
// \attention DEPRECATED: Due to the shortcomings documented below, this
// type will be removed in 4.0.0.
//
TYPE_POLYLINE = 0;
// ReferenceLine is a polyline, where the coordinates of points are
// calculated using the T axis definition.
//
// \note If this type is used, ReferenceLinePoint::t_axis_yaw must be set.
//
TYPE_POLYLINE_WITH_T_AXIS = 1;
}
// Points comprising the polyline.
//
// At least two points must be given.
// The polyline is defined as the lines between consecutive points.
// Each point has an S coordinate. Other attributes might be set, depending
// on the type of the polyline (see Type).
//
// ## Rules on the S position
//
// There are a few requirements on the S position:
// - Later points in the list must have strictly larger S coordinates than
// earlier points.
// - For consecutive points, the S difference between them must be at
// least as large as the 2D Euclidean distance between the points (2D
// distance == Euclidean distance between the points taking only X and Y
// into account).
// - The S distance between two points may be larger than the 2D Euclidean
// distance, but should be not much larger. It is allowed to be larger if
// the underlying reference line (e.g. in an OpenDRIVE map) is a curve,
// and thus the sampled reference line has a smaller length than the original
// curve.
//
// Together, these rules allow directly putting OpenDRIVE S coordinates
// into an OSI ReferenceLine.
//
// If the reference line approximates a curve (e.g. a clothoid in
// OpenDRIVE), the points must be chosen in a way that the lateral distance
// to the ideal line does not exceed 5cm. As shown in the following image:
//
// \image html line_approximation_error.svg "Approximation error"
// Approximation error green line.
//
// Between two ReferenceLinePoints, both the world coordinate and the S
// coordinate is interpolated linearly. So each S value uniquely describes
// a point on the polyline.
//
// ## Extending the coordinate system infinitely
//
// For the purpose of this discussion, let's call the S position of the
// first point \c sStart, and the S position of the last point \c sEnd.
//
// For some purposes, S positions outside the normally defined range (i.e.
// outside [\c sStart,\c sEnd]) need to be defined. For this purpose, the
// first line of the polyline is infinitely extended in negative S
// direction. Similarly, the last line of the polyline is infinitely
// extended beyond the last point. The S value of points outside [\c
// sStart,\c sEnd] is defined by the Euclidean 2D distance from the start
// or end point, respectively. So if <code>sStart = 15</code>, and a point
// is on the line extended from the start position, with a 2D Euclidean
// distance of 10 from the first point, then it has an S position of 5.
//
// A point is "before" the reference line, if its s coordinate is < \c sStart.
// A point is "after" the reference line, if its s coordinate is > \c sEnd.
//
// ## Adding T coordinates
//
// To describe points that are not directly on the polyline, a T coordinate
// is added. T is the signed 2D distance between the point to describe (P)
// and a projected point (P_proj) on the polyline. There are two ways of
// defining this point, depending on the ReferenceLine::Type (see below).
//
// The T coordinate of the point in question is then defined as
// <code>hypot(P.X-P_proj.X,P.Y-P_proj.Y)</code>. The projected point P_proj
// might either be on a line segment or at an edge between two line segments.
// The distance is positive if the point is left of the polyline (in
// definition direction), negative if it is right of it. The S position of
// such a point outside the reference line is the same as the S value of the
// projected point on the polyline.
//
// ## Nearest point (TYPE_POLYLINE)
//
// The projection point is the nearest point on the polyline (this point might
// either be on a line segment or at an edge between two line segments).
//
// Notes:
// - The "nearest point on the polyline" is determined in 3D (even if the
// resulting T value is only the 2D distance), in order to choose the
// correct point for 3D curves (think reference lines for roads in parking
// decks).
// - If there are several "nearest points", the one with the smallest S
// coordinate on the polyline is chosen.
//
// Example:
// \image html OSI_ReferenceLine1.svg "S, T calculation using nearest point"
//
// This shows a reference line (consisting of three points), and five points
// not on the reference line.
//
// - For \c P1, the situation is clear, since there is exactly one nearest
// point on the polyline. The resulting ST coordinate uniquely maps back
// to \c P1.
// - \c P2 has multiple points "nearest points" on the polyline.
// As can be seen here, two ST coordinates map to \c P2 (red and gray
// dotted line). Following the rules above, the one with the smallest S
// value is chosen (the red dotted line).
// - \c P3 has a unique "nearest point" on the polyline. However, multiple
// points map to the same ST coordinate as that of \c P3, e.g. \c P4
// (drawn in gray).
// - Finally, \c P5 shows how the reference line is extended infinitely for
// points that are "outside" the reference line.
//
// ## T axis definition (TYPE_POLYLINE_WITH_T_AXIS)
//
// The T axes of the two ReferenceLinePoints of each ReferenceLine segment
// define a sector (or strip if parallel) of the plane. A point is associated
// with the segment if it lies within this sector. For points being
// associated with multiple segments, the actual segment to consider is
// determined by the shortest 3D Euclidean distance between the point and the
// segments in question.
//
// The T axis (projecting axis) is the line going through P and the
// intersection point (I). I is defined as the intersection of both
// T axes of two consecutive ReferenceLinePoints (see example and
// image below for illustration).
//
// Special cases:
// 1. If both T axes of the consecutive ReferenceLinePoint are parallel (so
// no intersection point exists), the resulting T axis orientation is equal
// to the T axis of these ReferenceLinePoints.
// 2. For the extended lines outside the defined range the projection axis is
// parallel to the T axis of the respective end point.
//
// ## Rules on the T axis
//
// For the T axis at a specific ReferenceLinePoint the following rules apply:
// - The T axis shall be close to the angle bisector (to the left in S
// direction) of the neighboring ReferenceLine segments.
// - Small deviations from the angle bisector are allowed (e.g. to represent
// the T axis of OpenDRIVE, which is perpendicular to the OpenDRIVE
// reference line).
// - The T axis must be located inside the sectors spanned by rotating the
// normal of one neighboring ReferenceLine segment into the normal of the
// other ReferenceLine segment on the shortest way.
// - The T axis in the first and the last point of a ReferenceLine has to be
// perpendicular to the first and last segment of the ReferenceLine,
// respectively.
//
// Example:
// \image html OSI_ReferenceLine2.svg "S, T calculation using T axis"
//
// This shows a reference line (consisting of three points \c R0, \c R1 and
// \c R2) and two points (\c P1 and \c P2) not part of the reference line.
//
// Calculation of ST for \c P1:
// - Calculate the intersection point \c I of the T axes of \c R0 and \c R1.
// - As \c P1 lies in the sector defined by these T axes it is considered part
// of the reference line section between \c R0 and \c R1.
// - The point \c P1 is projected onto the line segment [\c R0, \c R1] via the
// straight line through \c I (by calculating the intersection of the line
// segment and the projection axis), resulting in point \c P1_proj.
// If the T axes are parallel, projection is applied in the direction of
// these axes.
// - The S coordinate of \c P1 is the S coordinate of \c P1_proj
// - The T coordinate of \c P1 is the signed Euclidean distance to \c P1_proj.
//
// Calculation of \c P2 follows the same pattern.
//
// ## Defining angles
//
// Sometimes an angle to a reference line is needed. This shall be defined
// as follows:
// First the projected point on the polyline is determined, as described
// below. If this point is on a line segment, then the angle is calculated
// relative to the line segment on which the reference point lays.
// If the projected point is at the edge between line segments, then the
// angle of the following line shall be chosen.
//
// ## Converting between world coordinates and ST coordinates
//
// The above rules define an ST coordinate system across the whole XY plane.
// Every XY position has an ST coordinate, but not necessarily a unique ST
// coordinate.
//
// The sampling of the polyline must be chosen such that the error
// when converting coordinates is "small enough". The exact needed
// precision is defined for each user, where the reference line is
// referenced.
//
// ## Creating reference lines
//
// When OSI is generated from OpenDRIVE, typically the reference lines will
// be taken directly from the road reference lines in OpenDRIVE, and
// sampled according to the accuracy requirements outlined above.
//
// Other map formats may not have reference lines, so they will have to be
// synthesized by the tool generating OSI data. A few guidelines on this
// process:
//
// - The reference line should follow the road
// - It is preferable to have the reference line in the center of the road
// (e.g. on a highway, it should be in the middle between the two driving
// directions). Rationale: this makes S differences better approximate
// Euclidean distances, compared to having the reference line at one side
// of a curvy road.
//
// ## Various notes
//
// Notes on OpenDRIVE compatibility:
// Ideally, one would want the polyline to be fully compatible with
// OpenDRIVE, so that calculations done for OpenDRIVE directly match those
// in OSI. There are a few difficulties with this:
// - The T coordinate is nearly the same as for OpenDRIVE, but
// unfortunately not perfectly. In OpenDRIVE, if the road is tilted using
// superelevation, then the t coordinate system is tilted along, so the T
// coordinate is no longer calculated in the XY plane (as proposed for
// OSI). It doesn't seem feasible to implement the same tilting for OSI,
// so simulation tools will have to consider superelevation and convert
// the T coordinate accordingly: <code>t_OSI = t_OpenDRIVE *
// cos(alpha)</code>, where alpha is the superelevation angle.
// - The angle will not be perfectly the same, due to the use of line
// segments in OSI, and curves in OpenDRIVE. In the authors opinion, the
// difference will be negligible if the #poly_line is suitably sampled.
//
// Notes on design decisions:
// - The S coordinate is included directly, both for OpenDRIVE
// compatibility, and to speed up calculations.
// - The rules on S coordinates (e.g. the calculation in 2D space) are
// there to ensure OpenDRIVE compatibility.
// - The rules on T coordinates are there to ensure OpenDRIVE compatibility
// for lanes without superelevation, and to make it easier to convert
// between OSI and OpenDRIVE in case superelevation is present.
//
repeated ReferenceLinePoint poly_line = 2;
//
// \brief A point on the reference line
//
message ReferenceLinePoint
{
// A world position
//
optional Vector3d world_position = 1;
// S position on the reference line
//
optional double s_position = 2;
// Yaw angle of the T axis in the world coordinate system
//
// When converting from formats like OpenDRIVE, the yaw angle is equal to
// the angle of the normal to the reference line in the sampled point.
//
// Also see image "S, T coordinates" at #poly_line for reference.
//
// \note This field is only set if the type of the reference line is
// TYPE_POLYLINE_WITH_T_AXIS.
//
optional double t_axis_yaw = 3;
}
}