Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
PolygonDynamics.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2004-2024 German Aerospace Center (DLR) and others.
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// https://www.eclipse.org/legal/epl-2.0/
7// This Source Code may also be made available under the following Secondary
8// Licenses when the conditions for such availability set forth in the Eclipse
9// Public License 2.0 are satisfied: GNU General Public License, version 2
10// or later which is available at
11// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13/****************************************************************************/
18// A polygon, which holds a timeSpan for displaying dynamic properties
19/****************************************************************************/
20
21
22#include "PolygonDynamics.h"
23
24#include <assert.h>
28
29
30//#define DEBUG_DYNAMIC_SHAPES
31
33 SUMOPolygon* p,
34 SUMOTrafficObject* trackedObject,
35 const std::vector<double>& timeSpan,
36 const std::vector<double>& alphaSpan,
37 bool looped,
38 bool rotate) :
39 myPolygon(p),
40 myCurrentTime(0),
41 myLastUpdateTime(creationTime),
42 animated(!timeSpan.empty()),
43 looped(looped),
44 tracking(trackedObject != nullptr),
45 rotate(rotate),
46 myTrackedObject(trackedObject),
47 myTrackedObjectID(""),
48 myTrackedObjectsInitialPositon(nullptr),
49 myTrackedObjectsInitialAngle(-1),
50 myOriginalShape(nullptr),
51 myTimeSpan(nullptr),
52 myAlphaSpan(nullptr),
53 myVis(nullptr) {
54 // Check for consistency
55 if (animated) {
56 myTimeSpan = std::unique_ptr<std::vector<double> >(new std::vector<double>(timeSpan));
57 assert(myTimeSpan->size() >= 2);
58 assert((*myTimeSpan)[0] == 0.0);
59 assert(myAlphaSpan == nullptr || myAlphaSpan->size() >= 2);
60#ifdef DEBUG_DYNAMIC_SHAPES
61 if (myTimeSpan->size() >= 2) {
62 for (unsigned int i = 1; i < myTimeSpan->size(); ++i) {
63 assert((*myTimeSpan)[i - 1] <= (*myTimeSpan)[i]);
64 }
65 }
66#endif
67 myPrevTime = myTimeSpan->begin();
68 myNextTime = ++myTimeSpan->begin();
69 }
70#ifdef DEBUG_DYNAMIC_SHAPES
71 else {
72 assert(myAlphaSpan == nullptr);
73 }
74#endif
75
76 myOriginalShape = std::unique_ptr<PositionVector>(new PositionVector(p->getShape()));
77
78 if (tracking) {
79 // Try initializing the tracked position (depends on whether object is already on the road)
82 }
83
84 if (!alphaSpan.empty()) {
85 myAlphaSpan = std::unique_ptr<std::vector<double> >(new std::vector<double>(alphaSpan));
86 assert(myAlphaSpan->size() >= 2);
87 assert(myAlphaSpan->size() == myTimeSpan->size());
88 myPrevAlpha = myAlphaSpan->begin();
89 myNextAlpha = ++myAlphaSpan->begin();
90 }
91}
92
95
96
99#ifdef DEBUG_DYNAMIC_SHAPES
100 std::cout << t << " PolygonDynamics::update() for polygon '" << myPolygon->getID() << "'" << std::endl;
101#endif
102 const double simtime = STEPS2TIME(t);
103 const double dt = simtime - myLastUpdateTime;
104 myLastUpdateTime = simtime;
105
106 SUMOTime ret = DELTA_T;
107
108 if (tracking) {
109 if (myTrackedObjectsInitialPositon == nullptr) {
110 // Tracked object hasn't entered the network, until now.
111 // Continuously try to obtain its initial position
113 }
114 if (myTrackedObjectsInitialPositon != nullptr) {
115 // Initial position was initialized, relative tracking is possible
116 const Position& objPos = myTrackedObject->getPosition();
117 const bool onRoad = objPos != Position::INVALID;
118 if (onRoad) {
119#ifdef DEBUG_DYNAMIC_SHAPES
120 std::cout << " Tracked object '" << myTrackedObject->getID() << "' is on the road. Tracked position=" << objPos << std::endl;
121#endif
122 // Update polygon's shape
124 if (rotate) {
125 const double relRotation = myTrackedObject->getAngle() - myTrackedObjectsInitialAngle;
126 newShape.rotate2D(relRotation);
127#ifdef DEBUG_DYNAMIC_SHAPES
128 std::cout << " Relative rotation wrt original rotation: " << relRotation << std::endl;
129#endif
130 }
131 newShape.add(objPos);
132 myPolygon->setShape(newShape);
133 }
134#ifdef DEBUG_DYNAMIC_SHAPES
135 else {
136 // tracked object is off road
137 std::cout << " Tracked object '" << myTrackedObject->getID() << "' is off road." << std::endl;
138 }
139#endif
140 }
141#ifdef DEBUG_DYNAMIC_SHAPES
142 else {
143 // Initial position was not initialized, yet
144 std::cout << " Tracked object '" << myTrackedObject->getID() << "' hasn't entered the network since tracking was started." << std::endl;
145 }
146#endif
147 }
148
149 if (animated) {
150 // Continue animation
151 myCurrentTime += dt;
152 while (myCurrentTime >= *myNextTime) {
153 // step forward along time lines to appropriate anchor points
154 ++myPrevTime;
155 ++myNextTime;
156 if (myNextTime == myTimeSpan->end()) {
157 // Set iterators back to point to valid positions
158 --myPrevTime;
159 --myNextTime;
160 break;
161 } else {
162 // Forward corresponding iterators for property time lines
163 if (myAlphaSpan != nullptr) {
164 ++myPrevAlpha;
165 ++myNextAlpha;
166 }
167 }
168 }
169
170 // Linear interpolation factor between previous and next time
171 double theta = 1.0;
172#ifdef DEBUG_DYNAMIC_SHAPES
173 std::cout << " animation: dt=" << dt
174 << ", current animation time: " << myCurrentTime
175 << ", previous anchor time: " << *myPrevTime
176 << ", next anchor time: " << *myNextTime;
177#endif
178 if (looped) {
179 const bool resetAnimation = myCurrentTime >= *myNextTime;
180#ifdef DEBUG_DYNAMIC_SHAPES
181 if (resetAnimation) {
182 std::cout << " (resetting animation!)";
183 }
184#endif
185 if (resetAnimation) {
186 // Reset animation time line to start, if appropriate
187 while (myCurrentTime >= *myNextTime) {
189 }
191 myPrevTime = myTimeSpan->begin();
192 myNextTime = ++myTimeSpan->begin();
193 if (myAlphaSpan != nullptr) {
194 myPrevAlpha = myAlphaSpan->begin();
195 myNextAlpha = ++myAlphaSpan->begin();
196 }
197 }
198 }
199 if (myCurrentTime >= *myNextTime) {
200 assert(!looped);
201 // Reached the end of the dynamics, indicate expiration by returning zero
202 // and set all properties to the final state (theta remains one)
203 ret = 0;
204#ifdef DEBUG_DYNAMIC_SHAPES
205 std::cout << " (animation elapsed!)";
206#endif
207 } else {
208 // Animation is still going on, schedule next update
209 if (*myNextTime - *myPrevTime != 0) {
210 theta = (myCurrentTime - *myPrevTime) / (*myNextTime - *myPrevTime);
211 }
212 }
213 if (myAlphaSpan != nullptr) {
214 // Interpolate values of properties
216#ifdef DEBUG_DYNAMIC_SHAPES
217 std::cout << ", previous anchor alpha: " << *myPrevAlpha
218 << ", next anchor alpha: " << *myNextAlpha;
219#endif
220 }
221#ifdef DEBUG_DYNAMIC_SHAPES
222 std::cout << ", theta=" << theta << std::endl;
223#endif
224 }
225 return ret;
226}
227
228void
230 const Position& objPos = myTrackedObject->getPosition();
231 if (objPos != Position::INVALID) {
232 // Initialize Position of tracked object
233 myTrackedObjectsInitialPositon = std::unique_ptr<Position>(new Position(objPos));
235 // Store original polygon shape relative to the tracked object's original position
237#ifdef DEBUG_DYNAMIC_SHAPES
238 std::cout << " Tracking object '" << myTrackedObject->getID() << "' at initial positon: " << *myTrackedObjectsInitialPositon << std::endl;
239#endif
240 }
241}
242
243void
245 int a = (int) alpha;
246 myPolygon->setShapeAlpha((unsigned char) a);
247#ifdef DEBUG_DYNAMIC_SHAPES
248 std::cout << "\n DynamicPolygon::setAlpha() Converted alpha=" << alpha << " into myAlpha=" << a << std::endl;
249#endif
250}
long long int SUMOTime
Definition GUI.h:36
SUMOTime DELTA_T
Definition SUMOTime.cpp:38
#define STEPS2TIME(x)
Definition SUMOTime.h:55
T MAX2(T a, T b)
Definition StdDefs.h:82
const std::string & getID() const
Returns the id.
Definition Named.h:74
std::vector< double >::const_iterator myNextAlpha
PolygonDynamics(double creationTime, SUMOPolygon *p, SUMOTrafficObject *trackedObject, const std::vector< double > &timeSpan, const std::vector< double > &alphaSpan, bool looped, bool rotate)
Constructor that takes a SUMOPolygon and adds timelines for the properties to be modified dynamically...
std::unique_ptr< Position > myTrackedObjectsInitialPositon
Initial position of the tracked object.
bool looped
Whether animation should be looped.
virtual ~PolygonDynamics()
void initTrackedPosition()
Initialize the object's position.
bool tracking
Whether this polygon tracks an object.
std::string myTrackedObjectID
double myTrackedObjectsInitialAngle
Initial angle of the tracked object.
std::unique_ptr< std::vector< double > > myTimeSpan
Time points corresponding to the anchor values of the dynamic properties.
std::vector< double >::const_iterator myNextTime
void setAlpha(double alpha)
Sets the alpha value for the shape's color.
bool animated
Whether this polygon is animated, i.e., whether timelines should be used to control properties.
double myCurrentTime
Current time.
SUMOTime update(SUMOTime t)
Updates the polygon according to its timeSpan and follows the tracked object.
SUMOTrafficObject * myTrackedObject
An object tracked by the shape, deletion by caller.
std::vector< double >::const_iterator myPrevTime
Pointer to the next time points in timeSpan.
SUMOPolygon * myPolygon
The polygon this dynamics acts upon.
bool rotate
Whether this polygon should be rotated with the tracked object.
std::unique_ptr< PositionVector > myOriginalShape
the original shape of the polygon (in case of tracking another object, this is converted to relative ...
std::unique_ptr< std::vector< double > > myAlphaSpan
Alpha values corresponding to.
double myLastUpdateTime
The last time the animation has been updated.
std::vector< double >::const_iterator myPrevAlpha
Pointer to the next alpha points in alphaSpan.
A point in 2D or 3D with translation and scaling methods.
Definition Position.h:37
static const Position INVALID
used to indicate that a position is valid
Definition Position.h:322
A list of positions.
void rotate2D(double angle)
void add(double xoff, double yoff, double zoff)
const PositionVector & getShape() const
Returns the shape of the polygon.
virtual void setShape(const PositionVector &shape)
Sets the shape of the polygon.
Representation of a vehicle, person, or container.
virtual double getAngle() const =0
Returns the object's angle in degrees.
virtual Position getPosition(const double offset=0) const =0
Return current position (x/y, cartesian)
void setShapeAlpha(unsigned char alpha)
Sets a new alpha value.
Definition Shape.h:143