53 #define FAR_AWAY 1000.0 64 for (MSLane::VehCont::const_iterator j = vehs.begin(); j != vehs.end(); ++j) {
66 myIDs.insert((*j)->getID());
75 for (
auto p : persons) {
77 myIDs.insert(p->getID());
105 std::vector<Subscription> Helper::mySubscriptions;
106 std::map<int, std::shared_ptr<VariableWrapper> > Helper::myWrapper;
107 Helper::VehicleStateListener Helper::myVehicleStateListener;
108 std::map<int, NamedRTree*> Helper::myObjects;
110 std::map<std::string, MSVehicle*> Helper::myRemoteControlledVehicles;
111 std::map<std::string, MSPerson*> Helper::myRemoteControlledPersons;
118 Helper::subscribe(
const int commandId,
const std::string&
id,
const std::vector<int>& variables,
119 const double beginTime,
const double endTime,
const int contextDomain,
const double range) {
120 std::vector<std::vector<unsigned char> > parameters;
124 mySubscriptions.push_back(s);
125 handleSingleSubscription(s);
132 if (s.beginTime > t) {
135 handleSingleSubscription(s);
143 std::set<std::string> objIDs;
152 if (myWrapper.empty()) {
168 auto wrapper = myWrapper.find(getCommandId);
169 if (wrapper == myWrapper.end()) {
172 std::shared_ptr<VariableWrapper> handler = wrapper->second;
173 for (
const std::string& objID : objIDs) {
176 handler->handle(objID, variable, handler.get());
180 handler->handle(objID,
ID_LIST, handler.get());
190 for (
int i = 0; i < (int)positionVector.size(); ++i) {
191 tp.push_back(makeTraCIPosition(positionVector[i]));
200 for (
int i = 0; i < (int)vector.size(); i++) {
201 pv.push_back(
Position(vector[i].x, vector[i].y));
220 return RGBColor((
unsigned char)c.
r, (
unsigned char)c.
g, (
unsigned char)c.
b, (
unsigned char)c.
a);
225 Helper::makeTraCIPosition(
const Position& position,
const bool includeZ) {
241 Helper::getEdge(
const std::string& edgeID) {
244 throw TraCIException(
"Referenced edge '" + edgeID +
"' is not known.");
251 Helper::getLaneChecking(
const std::string& edgeID,
int laneIndex,
double pos) {
256 if (laneIndex < 0 || laneIndex >= (
int)edge->
getLanes().size()) {
260 if (pos < 0 || pos > lane->
getLength()) {
267 std::pair<MSLane*, double>
270 std::pair<MSLane*, double> result;
271 std::vector<std::string> allEdgeIds;
272 double minDistance = std::numeric_limits<double>::max();
275 for (std::vector<std::string>::iterator itId = allEdgeIds.begin(); itId != allEdgeIds.end(); itId++) {
277 for (std::vector<MSLane*>::const_iterator itLane = allLanes.begin(); itLane != allLanes.end(); itLane++) {
278 const double newDistance = (*itLane)->getShape().distance2D(pos);
279 if (newDistance < minDistance) {
280 minDistance = newDistance;
281 result.first = (*itLane);
286 result.second = result.first->getShape().nearest_offset_to_point2D(pos,
false);
293 for (
const auto i : myObjects) {
303 Helper::registerVehicleStateListener() {
308 const std::vector<std::string>&
310 return myVehicleStateListener.myVehicleStateChanges[state];
315 Helper::clearVehicleStates() {
316 for (
auto& i : myVehicleStateListener.myVehicleStateChanges) {
323 Helper::findObjectShape(
int domain,
const std::string&
id,
PositionVector& shape) {
326 InductionLoop::storeShape(
id, shape);
329 Lane::storeShape(
id, shape);
332 Vehicle::storeShape(
id, shape);
335 Person::storeShape(
id, shape);
338 POI::storeShape(
id, shape);
341 Polygon::storeShape(
id, shape);
344 Junction::storeShape(
id, shape);
347 Edge::storeShape(
id, shape);
356 Helper::collectObjectsInRange(
int domain,
const PositionVector& shape,
double range, std::set<std::string>& into) {
358 if (myObjects.find(domain) == myObjects.end()) {
388 const float cmin[2] = {(float) b.
xmin(), (float) b.
ymin()};
389 const float cmax[2] = {(float) b.
xmax(), (float) b.
ymax()};
396 myObjects[domain]->Search(cmin, cmax, sv);
404 myLaneTree->Search(cmin, cmax, sv);
415 myRemoteControlledVehicles[v->
getID()] = v;
422 myRemoteControlledPersons[p->
getID()] = p;
428 Helper::postProcessRemoteControl() {
429 for (
auto& controlled : myRemoteControlledVehicles) {
431 controlled.second->getInfluencer().postProcessRemoteControl(controlled.second);
433 WRITE_WARNING(
"Vehicle '" + controlled.first +
"' was removed though being controlled by TraCI");
436 myRemoteControlledVehicles.clear();
437 for (
auto& controlled : myRemoteControlledPersons) {
439 controlled.second->getInfluencer().postProcessRemoteControl(controlled.second);
441 WRITE_WARNING(
"Person '" + controlled.first +
"' was removed though being controlled by TraCI");
444 myRemoteControlledPersons.clear();
449 Helper::moveToXYMap(
const Position& pos,
double maxRouteDistance,
bool mayLeaveNetwork,
const std::string& origID,
const double angle,
450 double speed,
const ConstMSEdgeVector& currentRoute,
const int routePosition,
MSLane* currentLane,
double currentLanePos,
bool onRoad,
453 const MSEdge*
const currentRouteEdge = currentRoute[routePosition];
454 std::set<std::string> into;
456 shape.push_back(pos);
459 std::map<MSLane*, LaneUtility> lane2utility;
461 for (std::set<std::string>::const_iterator j = into.begin(); j != into.end(); ++j) {
463 const MSEdge* prevEdge = 0;
464 const MSEdge* nextEdge = 0;
465 bool onRoute =
false;
469 #ifdef DEBUG_MOVEXY_ANGLE 470 std::cout <<
"Ego on normal" << std::endl;
476 ConstMSEdgeVector::const_iterator searchStart = currentRoute.begin() + routePosition;
480 ConstMSEdgeVector::const_iterator edgePos = std::find(searchStart, currentRoute.end(), e);
481 onRoute = edgePos != currentRoute.end();
482 if (edgePos == currentRoute.end() - 1 && currentRouteEdge == e) {
488 nextEdge = !onRoute || edgePos == currentRoute.end() - 1 ? 0 : *(edgePos + 1);
489 #ifdef DEBUG_MOVEXY_ANGLE 490 std::cout <<
"normal:" << e->
getID() <<
" prev:" << prevEdge->
getID() <<
" next:";
492 std::cout << nextEdge->
getID();
494 std::cout << std::endl;
497 #ifdef DEBUG_MOVEXY_ANGLE 498 std::cout <<
"Ego on internal" << std::endl;
503 while (prevEdge != 0 && prevEdge->
isInternal()) {
506 prevEdge = l == 0 ? 0 : &l->
getEdge();
509 ConstMSEdgeVector::const_iterator prevEdgePos = std::find(currentRoute.begin() + routePosition, currentRoute.end(), prevEdge);
511 while (nextEdge != 0 && nextEdge->isInternal()) {
514 if (prevEdgePos != currentRoute.end() && (prevEdgePos + 1) != currentRoute.end()) {
515 onRoute = *(prevEdgePos + 1) == nextEdge;
517 #ifdef DEBUG_MOVEXY_ANGLE 518 std::cout <<
"internal:" << e->
getID() <<
" prev:" << prevEdge->
getID() <<
" next:" << nextEdge->getID() << std::endl;
524 const std::vector<MSLane*>& lanes = e->
getLanes();
525 const bool perpendicular =
false;
526 for (std::vector<MSLane*>::const_iterator k = lanes.begin(); k != lanes.end(); ++k) {
528 double langle = 180.;
530 double perpendicularDist =
FAR_AWAY;
549 if (mayLeaveNetwork && dist != perpendicularDist) {
554 #ifdef DEBUG_MOVEXY_ANGLE 555 std::cout << lane->
getID() <<
" lAngle:" << langle <<
" lLength=" << lane->
getLength()
556 <<
" angleDiff:" << angleDiff
558 <<
" pDist=" << perpendicularDist
560 <<
" dist2=" << dist2
565 dist2, perpendicularDist, off, angleDiff,
567 onRoute, sameEdge, prevEdge, nextEdge);
575 double bestValue = 0;
577 for (std::map<MSLane*, LaneUtility>::iterator i = lane2utility.begin(); i != lane2utility.end(); ++i) {
580 double distN = u.
dist > 999 ? -10 : 1. - (u.
dist / maxDist);
581 double angleDiffN = 1. - (u.
angleDiff / 180.);
582 double idN = u.
ID ? 1 : 0;
583 double onRouteN = u.
onRoute ? 1 : 0;
585 double value = (distN * .5
591 std::cout <<
" x; l:" << l->
getID() <<
" d:" << u.
dist <<
" dN:" << distN <<
" aD:" << angleDiffN <<
592 " ID:" << idN <<
" oRN:" << onRouteN <<
" sEN:" << sameEdgeN <<
" value:" << value << std::endl;
594 if (value > bestValue || bestLane == 0) {
607 const LaneUtility& u = lane2utility.find(bestLane)->second;
608 bestDistance = u.
dist;
613 ConstMSEdgeVector::const_iterator prevEdgePos = std::find(currentRoute.begin(), currentRoute.end(), prevEdge);
614 routeOffset = (int)std::distance(currentRoute.begin(), prevEdgePos);
627 #ifdef DEBUG_MOVEXY_ANGLE 640 const std::vector<MSLane*>& lanes = edge->
getLanes();
641 bool newBest =
false;
642 for (std::vector<MSLane*>::const_iterator k = lanes.begin(); k != lanes.end() && bestDistance >
POSITION_EPS; ++k) {
643 MSLane* candidateLane = *k;
646 std::cout <<
" b at lane " << candidateLane->
getID() <<
" dist:" << dist <<
" best:" << bestDistance << std::endl;
648 if (dist < bestDistance) {
651 *lane = candidateLane;
660 Helper::moveToXYMap_matchingRoutePosition(
const Position& pos,
const std::string& origID,
662 double& bestDistance,
MSLane** lane,
double& lanePos,
int& routeOffset) {
670 for (
int i = routeIndex; i < (int)currentRoute.size(); ++i) {
671 const MSEdge* cand = currentRoute[i];
675 findCloserLane(internalCand, pos, bestDistance, lane);
678 if (findCloserLane(cand, pos, bestDistance, lane)) {
684 const MSEdge* next = currentRoute[routeIndex];
685 for (
int i = routeIndex; i >= 0; --i) {
686 const MSEdge* cand = currentRoute[i];
692 if (findCloserLane(internalCand, pos, bestDistance, lane)) {
697 if (findCloserLane(cand, pos, bestDistance, lane)) {
707 std::cout <<
" b failed - no best route lane" << std::endl;
715 if (!(*lane)->getEdge().isInternal()) {
716 const std::vector<MSLane*>& lanes = (*lane)->getEdge().getLanes();
717 for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
726 (*lane)->interpolateGeometryPosToLanePos(
727 (*lane)->getShape().nearest_offset_to_point2D(pos,
false))));
730 std::cout <<
" b ok lane " << (*lane)->getID() <<
" lanePos:" << lanePos << std::endl;
737 :
VariableWrapper(handler), myResults(into), myContextResults(context), myActiveResults(into) {
750 myActiveResults[objID][variable] = std::make_shared<TraCIDouble>(value);
764 myActiveResults[objID][variable] = std::make_shared<TraCIString>(value);
771 auto sl = std::make_shared<TraCIStringList>();
780 myActiveResults[objID][variable] = std::make_shared<TraCIPosition>(value);
787 myActiveResults[objID][variable] = std::make_shared<TraCIColor>(value);
794 myVehicleStateChanges[to].push_back(vehicle->
getID());
static double getMinAngleDiff(double angle1, double angle2)
Returns the minimum distance (clockwise/counter-clockwise) between both angles.
std::map< std::string, TraCIResults > SubscriptionResults
{object->{variable->value}}
MSLane * getLogicalPredecessorLane() const
get the most likely precedecessor lane (sorted using by_connections_to_sorter). The result is cached ...
double ymin() const
Returns minimum y-coordinate.
#define CMD_SUBSCRIBE_VEHICLE_CONTEXT
double xmax() const
Returns maximum x-coordinate.
MSEdge & getEdge() const
Returns the lane's edge.
Representation of a vehicle in the micro simulation.
Representation of a subscription.
double range
The range of the context.
#define CMD_GET_TL_VARIABLE
#define CMD_SUBSCRIBE_JUNCTION_CONTEXT
double z() const
Returns the z-position.
#define CMD_GET_VEHICLE_VARIABLE
double distance2D(const Position &p, bool perpendicular=false) const
closest 2D-distance to point p (or -1 if perpendicular is true and the point is beyond this vector) ...
#define CMD_GET_INDUCTIONLOOP_VARIABLE
bool wrapDouble(const std::string &objID, const int variable, const double value)
bool wrapString(const std::string &objID, const int variable, const std::string &value)
static void fill(RTREE &into)
Fills the given RTree with lane instances.
unsigned char alpha() const
Returns the alpha-amount of the color.
const double SUMO_const_laneWidth
double y() const
Returns the y-position.
#define CMD_GET_LANEAREA_VARIABLE
#define CMD_GET_PERSON_VARIABLE
double x() const
Returns the x-position.
void setRemoteControlled(Position xyPos, MSLane *l, double pos, double posLat, double angle, int edgeOffset, const ConstMSEdgeVector &route, SUMOTime t)
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
void visit(const LaneStoringVisitor &cont) const
Callback for visiting the lane when traversing an RTree.
double getLength() const
Returns the lane's length.
virtual const VehCont & getVehiclesSecure() const
Returns the vehicles container; locks it for microsimulation.
const PositionVector & getShape() const
Returns this lane's shape.
static std::string getIDSecure(const T *obj, const std::string &fallBack="NULL")
get an identifier for Named-like object which may be Null
#define CMD_SUBSCRIBE_POLYGON_CONTEXT
static bool dictionary(const std::string &id, MSEdge *edge)
Inserts edge into the static dictionary Returns true if the key id isn't already in the dictionary...
double rotationAtOffset(double pos) const
Returns the rotation at the given length.
unsigned char blue() const
Returns the blue-amount of the color.
std::map< std::string, SubscriptionResults > ContextSubscriptionResults
#define CMD_GET_POLYGON_VARIABLE
ContextSubscriptionResults myContextResults
std::vector< const MSEdge * > ConstMSEdgeVector
SubscriptionResults & myActiveResults
const std::string & getID() const
Returns the id.
bool wrapPosition(const std::string &objID, const int variable, const TraCIPosition &value)
double getLength() const
return the length of the edge
std::vector< MSTransportable * > getSortedPersons(SUMOTime timestep, bool includeRiding=false) const
Returns this edge's persons sorted by pos.
void addVehicleStateListener(VehicleStateListener *listener)
Adds a vehicle states listener.
#define CMD_GET_ROUTE_VARIABLE
A class that stores a 2D geometrical boundary.
#define CMD_SUBSCRIBE_INDUCTIONLOOP_CONTEXT
#define WRITE_WARNING(msg)
std::vector< std::string > getEdgeNames() const
Returns the list of names of all known edges.
std::string id
The id of the object that is subscribed.
bool wrapColor(const std::string &objID, const int variable, const TraCIColor &value)
int commandId
commandIdArg The command id of the subscription
#define CMD_SUBSCRIBE_LANE_CONTEXT
#define CMD_GET_VEHICLETYPE_VARIABLE
A road/street connecting two junctions.
static double naviDegree(const double angle)
Influencer & getInfluencer()
Returns the velocity/lane influencer.
Representation of a vehicle.
int contextDomain
The domain ID of the context.
A point in 2D or 3D with translation and scaling methods.
#define CMD_GET_POI_VARIABLE
bool wrapStringList(const std::string &objID, const int variable, const std::vector< std::string > &value)
#define CMD_GET_LANE_VARIABLE
void add(const MSLane *const l) const
Adds the given object to the container.
double xmin() const
Returns minimum x-coordinate.
const std::string & getID() const
returns the id of the transportable
#define CMD_GET_SIM_VARIABLE
#define CMD_GET_EDGE_VARIABLE
SubscriptionResults myResults
Boundary & grow(double by)
extends the boundary by the given amount
#define CMD_SUBSCRIBE_EDGE_CONTEXT
#define CMD_GET_JUNCTION_VARIABLE
static const double INVALID_OFFSET
a value to signify offsets outside the range of [0, Line.length()]
void setRemoteControlled(Position xyPos, MSLane *l, double pos, double posLat, double angle, int edgeOffset, const ConstMSEdgeVector &route, SUMOTime t)
bool isInternal() const
return whether this edge is an internal edge
std::vector< MSVehicle * > VehCont
Container for vehicles.
const MSEdge * getInternalFollowingEdge(const MSEdge *followerAfterInternal) const
#define INVALID_DOUBLE_VALUE
VehicleState
Definition of a vehicle state.
#define LAST_STEP_VEHICLE_NUMBER
const MSEdgeVector & getSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges, restricted by vClass.
Allows to store the object; used as context while traveling the rtree in TraCI.
std::set< std::string > & myIDs
The container.
Influencer & getInfluencer()
Returns the velocity/lane influencer.
void vehicleStateChanged(const SUMOVehicle *const vehicle, MSNet::VehicleState to, const std::string &info="")
Called if a vehicle changes its state.
const PositionVector & myShape
#define CMD_SUBSCRIBE_PERSON_CONTEXT
unsigned char green() const
Returns the green-amount of the color.
std::vector< int > variables
The subscribed variables.
#define CMD_GET_MULTIENTRYEXIT_VARIABLE
bool wrapInt(const std::string &objID, const int variable, const int value)
const std::string getParameter(const std::string &key, const std::string &defaultValue="") const
Returns the value for a given key.
const std::string SUMO_PARAM_ORIGID
unsigned char red() const
Returns the red-amount of the color.
MSEdgeControl & getEdgeControl()
Returns the edge control.
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
double ymax() const
Returns maximum y-coordinate.
virtual void releaseVehicles() const
Allows to use the container for microsimulation again.
double nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D
const std::string & getID() const
Returns the name of the vehicle.
#define CMD_SUBSCRIBE_POI_CONTEXT
Representation of a lane in the micro simulation.
virtual const std::string & getID() const =0
Get the vehicle's ID.
static const Position INVALID
used to indicate that a position is valid
void setContext(const std::string &refID)