1 package org.opentrafficsim.road.gtu.lane.tactical.util;
2
3 import java.util.ArrayList;
4 import java.util.List;
5 import java.util.Set;
6
7 import org.djunits.value.vdouble.scalar.Angle;
8 import org.djunits.value.vdouble.scalar.Duration;
9 import org.djunits.value.vdouble.scalar.Length;
10 import org.djunits.value.vdouble.scalar.Speed;
11 import org.djutils.exceptions.Throw;
12 import org.opentrafficsim.base.parameters.ParameterException;
13 import org.opentrafficsim.base.parameters.ParameterTypeDouble;
14 import org.opentrafficsim.base.parameters.ParameterTypeDuration;
15 import org.opentrafficsim.base.parameters.Parameters;
16 import org.opentrafficsim.base.parameters.constraint.NumericConstraint;
17 import org.opentrafficsim.core.geometry.OTSGeometryException;
18 import org.opentrafficsim.core.geometry.OTSLine3D;
19 import org.opentrafficsim.core.geometry.OTSPoint3D;
20 import org.opentrafficsim.core.gtu.GTU;
21 import org.opentrafficsim.core.gtu.RelativePosition;
22 import org.opentrafficsim.core.gtu.plan.operational.OperationalPlan;
23 import org.opentrafficsim.core.gtu.plan.operational.OperationalPlan.Segment;
24 import org.opentrafficsim.core.gtu.plan.operational.OperationalPlanException;
25 import org.opentrafficsim.road.gtu.lane.LaneBasedGTU;
26
27 import nl.tudelft.simulation.language.d3.DirectedPoint;
28
29
30
31
32
33
34
35
36
37
38
39
40 public final class Steering
41 {
42
43
44 static final ParameterTypeDuration DT =
45 new ParameterTypeDuration("DTS", "Steering update time step", Duration.createSI(0.01), NumericConstraint.POSITIVE);
46
47
48 static final ParameterTypeDouble C_FRONT = new ParameterTypeDouble("C_FRONT", "Front tire cornering stiffness", 80000);
49
50
51 static final ParameterTypeDouble C_REAR = new ParameterTypeDouble("C_REAR", "Rear tire cornering stiffness", 80000);
52
53
54
55
56 private Steering()
57 {
58
59 }
60
61
62
63
64
65
66
67
68
69
70
71 public static OperationalPlan fromReferencePlan(final LaneBasedGTU gtu, final Parameters params,
72 final SteeringState steeringState, final OperationalPlan referencePlan, final FeedbackTable feedbackTable)
73 throws ParameterException
74 {
75 Duration step = Duration.ZERO;
76 DirectedPoint pos;
77 try
78 {
79 pos = referencePlan.getLocation(step);
80 }
81 catch (OperationalPlanException exception)
82 {
83 throw new RuntimeException(exception);
84 }
85 List<OTSPoint3D> points = new ArrayList<>();
86 points.add(new OTSPoint3D(pos));
87 Angle steeringAngle = steeringState.getSteeringAngle();
88 Angle angularError = steeringState.getAngularError();
89 double angularErrorDerivative = steeringState.getAngularErrorDerivative();
90 Length positionError = steeringState.getPositionError();
91 Speed positionErrorDerivative = steeringState.getPositionErrorDerivative();
92 while (step.lt(referencePlan.getTotalDuration()))
93 {
94 Speed speed;
95 gtu.getLength();
96 gtu.getWidth();
97 gtu.getVehicleModel().getMomentOfInertiaAboutZ();
98 gtu.getRelativePositions().get(RelativePosition.CENTER_GRAVITY).getDx();
99 gtu.getFront();
100 gtu.getRear();
101 try
102 {
103 speed = referencePlan.getSpeed(step);
104 }
105 catch (OperationalPlanException exception)
106 {
107 throw new RuntimeException(exception);
108 }
109
110
111 points.add(new OTSPoint3D(pos));
112 step = step.plus(params.getParameter(DT));
113 }
114 steeringState.setSteeringAngle(steeringAngle);
115 steeringState.setAngularError(angularError);
116 steeringState.setAngularErrorDerivative(angularErrorDerivative);
117 steeringState.setPositionError(positionError);
118 steeringState.setPositionErrorDerivative(positionErrorDerivative);
119 OTSLine3D path;
120 try
121 {
122 path = new OTSLine3D(points.toArray(new OTSPoint3D[points.size()]));
123 }
124 catch (OTSGeometryException exception)
125 {
126 throw new RuntimeException("The path has too few or too close points.", exception);
127 }
128 OperationalPlan realPlan;
129 try
130 {
131 realPlan = new OperationalPlan(gtu, path, referencePlan.getStartTime(), referencePlan.getStartSpeed(),
132 referencePlan.getOperationalPlanSegmentList());
133 }
134 catch (OperationalPlanException exception)
135 {
136
137
138 throw new RuntimeException(exception);
139 }
140
141 return referencePlan;
142 }
143
144
145
146
147
148
149
150
151
152
153
154 public static OperationalPlan fromReferencePoints(final GTU gtu, final Parameters params, final SteeringState steeringState,
155 final Set<DirectedPoint> points, final List<Segment> segments) throws ParameterException
156 {
157
158 throw new UnsupportedOperationException();
159 }
160
161
162
163
164
165
166
167
168
169
170
171
172
173 public static class SteeringState
174 {
175
176
177 private Angle steeringAngle = Angle.ZERO;
178
179
180 private Angle angularError = Angle.ZERO;
181
182
183 private double angularErrorDerivative = 0.0;
184
185
186 private Length positionError = Length.ZERO;
187
188
189 private Speed positionErrorDerivative = Speed.ZERO;
190
191
192
193
194 protected Angle getSteeringAngle()
195 {
196 return this.steeringAngle;
197 }
198
199
200
201
202 protected void setSteeringAngle(final Angle steeringAngle)
203 {
204 this.steeringAngle = steeringAngle;
205 }
206
207
208
209
210 protected Angle getAngularError()
211 {
212 return this.angularError;
213 }
214
215
216
217
218 protected void setAngularError(final Angle angularError)
219 {
220 this.angularError = angularError;
221 }
222
223
224
225
226 protected double getAngularErrorDerivative()
227 {
228 return this.angularErrorDerivative;
229 }
230
231
232
233
234 protected void setAngularErrorDerivative(final double angularErrorDerivative)
235 {
236 this.angularErrorDerivative = angularErrorDerivative;
237 }
238
239
240
241
242 protected Length getPositionError()
243 {
244 return this.positionError;
245 }
246
247
248
249
250 protected void setPositionError(final Length positionError)
251 {
252 this.positionError = positionError;
253 }
254
255
256
257
258 protected Speed getPositionErrorDerivative()
259 {
260 return this.positionErrorDerivative;
261 }
262
263
264
265
266 protected void setPositionErrorDerivative(final Speed positionErrorDerivative)
267 {
268 this.positionErrorDerivative = positionErrorDerivative;
269 }
270
271 }
272
273
274
275
276
277
278
279
280
281
282
283
284
285 public static class FeedbackTable
286 {
287
288
289 private final List<FeedbackVector> feedbackVectors;
290
291
292
293
294 public FeedbackTable(final List<FeedbackVector> feedbackVectors)
295 {
296 Throw.when(feedbackVectors == null || feedbackVectors.size() == 0, IllegalArgumentException.class,
297 "At least one feedback vector should be defined.");
298 this.feedbackVectors = feedbackVectors;
299 }
300
301
302
303
304
305
306 protected FeedbackVector getAngularErrorFeedback(final Speed speed)
307 {
308 FeedbackVector feedbackVector = null;
309 Speed deviation = Speed.POSITIVE_INFINITY;
310 for (int i = 0; i < this.feedbackVectors.size(); i++)
311 {
312 Speed dev = speed.minus(this.feedbackVectors.get(i).getSpeed()).abs();
313 if (dev.lt(deviation))
314 {
315 feedbackVector = this.feedbackVectors.get(i);
316 deviation = dev;
317 }
318 }
319 return feedbackVector;
320 }
321
322
323
324
325
326
327
328
329
330
331
332
333
334 public static class FeedbackVector
335 {
336
337
338 private final Speed speed;
339
340
341 private final double angularErrorFeedback;
342
343
344 private final double angularErrorDerivateFeedback;
345
346
347 private final double positionErrorFeedback;
348
349
350 private final double positionErrorDerivativeFeedback;
351
352
353
354
355
356
357
358
359 public FeedbackVector(final Speed speed, final double angularErrorFeedback,
360 final double angularErrorDerivateFeedback, final double positionErrorFeedback,
361 final double positionErrorDerivativeFeedback)
362 {
363 this.speed = speed;
364 this.angularErrorFeedback = angularErrorFeedback;
365 this.angularErrorDerivateFeedback = angularErrorDerivateFeedback;
366 this.positionErrorFeedback = positionErrorFeedback;
367 this.positionErrorDerivativeFeedback = positionErrorDerivativeFeedback;
368 }
369
370
371
372
373 protected Speed getSpeed()
374 {
375 return this.speed;
376 }
377
378
379
380
381 protected double getAngularErrorFeedback()
382 {
383 return this.angularErrorFeedback;
384 }
385
386
387
388
389 protected double getAngularErrorDerivateFeedback()
390 {
391 return this.angularErrorDerivateFeedback;
392 }
393
394
395
396
397 protected double getPositionErrorFeedback()
398 {
399 return this.positionErrorFeedback;
400 }
401
402
403
404
405 protected double getPositionErrorDerivativeFeedback()
406 {
407 return this.positionErrorDerivativeFeedback;
408 }
409 }
410
411 }
412
413 }