#pragma once
#include <vector>
#include <memory>
#include <libsumo/Subscription.h>
#include <microsim/MSLane.h>
#include <microsim/MSNet.h>
#include <microsim/traffic_lights/MSTLLogicControl.h>
#include <microsim/trigger/MSCalibrator.h>
#include <utils/vehicle/SUMOVehicleParameter.h>
class Position;
class PositionVector;
class RGBColor;
class MSEdge;
class SUMOTrafficObject;
class MSPerson;
class MSVehicle;
class MSBaseVehicle;
class MSVehicleType;
class MSStoppingPlace;
namespace libsumo {
class Helper {
public:
static void subscribe(const int commandId, const std::string& id, const std::vector<int>& variables,
const double beginTime, const double endTime, const libsumo::TraCIResults& params,
const int contextDomain = 0, const double range = 0.);
static void handleSubscriptions(const SUMOTime t);
static bool needNewSubscription(libsumo::Subscription& s, std::vector<Subscription>& subscriptions, libsumo::Subscription*& modifiedSubscription);
static void clearSubscriptions();
static Subscription* addSubscriptionFilter(SubscriptionFilterType filter);
static TraCIPositionVector makeTraCIPositionVector(const PositionVector& positionVector);
static TraCIPosition makeTraCIPosition(const Position& position, const bool includeZ = false);
static Position makePosition(const TraCIPosition& position);
static PositionVector makePositionVector(const TraCIPositionVector& vector);
static TraCIColor makeTraCIColor(const RGBColor& color);
static RGBColor makeRGBColor(const TraCIColor& color);
static MSEdge* getEdge(const std::string& edgeID);
static const MSLane* getLaneChecking(const std::string& edgeID, int laneIndex, double pos);
static std::pair<MSLane*, double> convertCartesianToRoadMap(const Position& pos, const SUMOVehicleClass vClass);
static double getDrivingDistance(std::pair<const MSLane*, double>& roadPos1, std::pair<const MSLane*, double>& roadPos2);
static MSBaseVehicle* getVehicle(const std::string& id);
static MSPerson* getPerson(const std::string& id);
static SUMOTrafficObject* getTrafficObject(int domain, const std::string& id);
static const MSVehicleType& getVehicleType(const std::string& vehicleID);
static MSTLLogicControl::TLSLogicVariants& getTLS(const std::string& id);
static MSStoppingPlace* getStoppingPlace(const std::string& id, const SumoXMLTag type);
static SUMOVehicleParameter::Stop buildStopParameters(const std::string& edgeOrStoppingPlaceID,
double pos, int laneIndex, double startPos, int flags, double duration, double until);
static TraCINextStopData buildStopData(const SUMOVehicleParameter::Stop& stopPar);
static void findObjectShape(int domain, const std::string& id, PositionVector& shape);
static void collectObjectsInRange(int domain, const PositionVector& shape, double range, std::set<const Named*>& into);
static void collectObjectIDsInRange(int domain, const PositionVector& shape, double range, std::set<std::string>& into);
static void applySubscriptionFilters(const Subscription& s, std::set<std::string>& objIDs);
static void applySubscriptionFilterLanes(const Subscription& s, std::set<const SUMOTrafficObject*>& vehs, std::vector<int>& filterLanes,
double downstreamDist, double upstreamDist, bool disregardOppositeDirection);
static void applySubscriptionFilterTurn(const Subscription& s, std::set<const SUMOTrafficObject*>& vehs);
static void applySubscriptionFilterFieldOfVision(const Subscription& s, std::set<std::string>& objIDs);
static void applySubscriptionFilterLateralDistance(const Subscription& s, std::set<const SUMOTrafficObject*>& vehs, double downstreamDist,
double upstreamDist, double lateralDist);
static void applySubscriptionFilterLateralDistanceSinglePass(const Subscription& s,
std::set<std::string>& objIDs,
std::set<const SUMOTrafficObject*>& vehs,
const std::vector<const MSLane*>& lanes,
double posOnLane, double posLat, bool isDownstream);
static void setRemoteControlled(MSVehicle* v, Position xyPos, MSLane* l, double pos, double posLat, double angle,
int edgeOffset, ConstMSEdgeVector route, SUMOTime t);
static void setRemoteControlled(MSPerson* p, Position xyPos, MSLane* l, double pos, double posLat, double angle,
int edgeOffset, ConstMSEdgeVector route, SUMOTime t);
static int postProcessRemoteControl();
static void cleanup();
static void registerStateListener();
static const std::vector<std::string>& getVehicleStateChanges(const MSNet::VehicleState state);
static const std::vector<std::string>& getTransportableStateChanges(const MSNet::TransportableState state);
static void clearStateChanges();
static MSCalibrator::AspiredState getCalibratorState(const MSCalibrator* c);
static bool moveToXYMap(const Position& pos, double maxRouteDistance, bool mayLeaveNetwork, const std::string& origID,
const double angle, double speed, const ConstMSEdgeVector& currentRoute, const int routePosition,
const MSLane* currentLane, double currentLanePos, bool onRoad, SUMOVehicleClass vClass, double currentAngle, bool setLateralPos,
double& bestDistance, MSLane** lane, double& lanePos, int& routeOffset, ConstMSEdgeVector& edges);
static bool moveToXYMap_matchingRoutePosition(const Position& pos, const std::string& origID,
const ConstMSEdgeVector& currentRoute, int routeIndex,
SUMOVehicleClass vClass, bool setLateralPos,
double& bestDistance, MSLane** lane, double& lanePos, int& routeOffset);
static bool findCloserLane(const MSEdge* edge, const Position& pos, SUMOVehicleClass vClass, double& bestDistance, MSLane** lane);
static double patchShapeDistance(const MSLane* lane, const Position& pos, double dist, bool wasPerpendicular);
static int readDistanceRequest(tcpip::Storage& data, TraCIRoadPosition& roadPos, Position& pos);
class LaneUtility {
public:
LaneUtility(double dist_, double perpendicularDist_, double lanePos_, double angleDiff_, bool ID_,
bool onRoute_, bool sameEdge_, const MSEdge* prevEdge_, const MSEdge* nextEdge_) :
dist(dist_), perpendicularDist(perpendicularDist_), lanePos(lanePos_), angleDiff(angleDiff_), ID(ID_),
onRoute(onRoute_), sameEdge(sameEdge_), prevEdge(prevEdge_), nextEdge(nextEdge_) {}
~LaneUtility() {}
double dist;
double perpendicularDist;
double lanePos;
double angleDiff;
bool ID;
bool onRoute;
bool sameEdge;
const MSEdge* prevEdge;
const MSEdge* nextEdge;
};
class SubscriptionWrapper final : public VariableWrapper {
public:
SubscriptionWrapper(VariableWrapper::SubscriptionHandler handler, SubscriptionResults& into, ContextSubscriptionResults& context);
void setContext(const std::string* const refID);
void clear();
bool wrapConnectionVector(const std::string& objID, const int variable, const std::vector<TraCIConnection>& value);
bool wrapDouble(const std::string& objID, const int variable, const double value);
bool wrapInt(const std::string& objID, const int variable, const int value);
bool wrapString(const std::string& objID, const int variable, const std::string& value);
bool wrapStringList(const std::string& objID, const int variable, const std::vector<std::string>& value);
bool wrapDoubleList(const std::string& objID, const int variable, const std::vector<double>& value);
bool wrapPosition(const std::string& objID, const int variable, const TraCIPosition& value);
bool wrapPositionVector(const std::string& objID, const int variable, const TraCIPositionVector& value);
bool wrapColor(const std::string& objID, const int variable, const TraCIColor& value);
bool wrapStringDoublePair(const std::string& objID, const int variable, const std::pair<std::string, double>& value);
bool wrapStringDoublePairList(const std::string& objID, const int variable, const std::vector<std::pair<std::string, double> >& value);
bool wrapStringPair(const std::string& objID, const int variable, const std::pair<std::string, std::string>& value);
bool wrapIntPair(const std::string& objID, const int variable, const std::pair<int, int>& value);
bool wrapStage(const std::string& objID, const int variable, const TraCIStage& value);
bool wrapReservationVector(const std::string& objID, const int variable, const std::vector<TraCIReservation>& value);
bool wrapLogicVector(const std::string& objID, const int variable, const std::vector<TraCILogic>& value);
bool wrapLinkVectorVector(const std::string& objID, const int variable, const std::vector<std::vector<TraCILink> >& value);
bool wrapSignalConstraintVector(const std::string& objID, const int variable, const std::vector<TraCISignalConstraint>& value);
bool wrapJunctionFoeVector(const std::string& objID, const int variable, const std::vector<TraCIJunctionFoe>& value);
bool wrapNextStopDataVector(const std::string& objID, const int variable, const std::vector<TraCINextStopData>& value);
bool wrapVehicleDataVector(const std::string& objID, const int variable, const std::vector<TraCIVehicleData>& value);
bool wrapBestLanesDataVector(const std::string& objID, const int variable, const std::vector<TraCIBestLanesData>& value);
bool wrapNextTLSDataVector(const std::string& objID, const int variable, const std::vector<TraCINextTLSData>& value);
void empty(const std::string& objID);
private:
SubscriptionResults& myResults;
ContextSubscriptionResults& myContextResults;
SubscriptionResults* myActiveResults;
private:
SubscriptionWrapper& operator=(const SubscriptionWrapper& s) = delete;
};
private:
static void handleSingleSubscription(const Subscription& s);
static void fuseLaneCoverage(std::shared_ptr<LaneCoverageInfo> aggregatedLaneCoverage, const std::shared_ptr<LaneCoverageInfo> newLaneCoverage);
static void debugPrint(const SUMOTrafficObject* veh);
private:
class VehicleStateListener : public MSNet::VehicleStateListener {
public:
void vehicleStateChanged(const SUMOVehicle* const vehicle, MSNet::VehicleState to, const std::string& info = "");
std::map<MSNet::VehicleState, std::vector<std::string> > myVehicleStateChanges;
};
class TransportableStateListener : public MSNet::TransportableStateListener {
public:
void transportableStateChanged(const MSTransportable* const transportable, MSNet::TransportableState to, const std::string& info = "");
std::map<MSNet::TransportableState, std::vector<std::string> > myTransportableStateChanges;
};
static std::vector<Subscription> mySubscriptions;
static Subscription* myLastContextSubscription;
static std::map<int, std::shared_ptr<VariableWrapper> > myWrapper;
static VehicleStateListener myVehicleStateListener;
static TransportableStateListener myTransportableStateListener;
static LANE_RTREE_QUAL* myLaneTree;
static std::map<std::string, MSVehicle*> myRemoteControlledVehicles;
static std::map<std::string, MSPerson*> myRemoteControlledPersons;
Helper() = delete;
};
}