Skip to content

Commit

Permalink
first version of fcd replay #1922
Browse files Browse the repository at this point in the history
  • Loading branch information
behrisch committed Mar 14, 2024
1 parent b5283f1 commit 71c8d76
Show file tree
Hide file tree
Showing 6 changed files with 326 additions and 2 deletions.
2 changes: 1 addition & 1 deletion src/microsim/MSFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@
#include <microsim/devices/MSDevice_Vehroutes.h>
#include <microsim/output/MSStopOut.h>
#include <utils/common/RandHelper.h>
#include "MSFrame.h"
#include <utils/common/SystemFrame.h>
#include "MSFrame.h"


// ===========================================================================
Expand Down
2 changes: 2 additions & 0 deletions src/microsim/devices/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ set(microsim_devices_STAT_SRCS
MSDevice_Bluelight.h
MSDevice_FCD.cpp
MSDevice_FCD.h
MSDevice_FCDReplay.cpp
MSDevice_FCDReplay.h
MSDevice_ElecHybrid.cpp
MSDevice_ElecHybrid.h
MSDevice_Taxi.cpp
Expand Down
5 changes: 4 additions & 1 deletion src/microsim/devices/MSDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
#include <microsim/MSVehicleControl.h>
#include <microsim/MSEdge.h>

#include "MSDevice.h"
#include "MSDevice_Vehroutes.h"
#include "MSDevice_Tripinfo.h"
#include "MSDevice_Routing.h"
Expand All @@ -49,6 +48,8 @@
#include "MSTransportableDevice_FCD.h"
#include "MSRoutingEngine.h"
#include "MSDevice_Friction.h"
#include "MSDevice_FCDReplay.h"
#include "MSDevice.h"


// ===========================================================================
Expand Down Expand Up @@ -89,6 +90,7 @@ MSDevice::insertOptions(OptionsCont& oc) {
MSDevice_Tripinfo::insertOptions(oc);
MSDevice_Vehroutes::insertOptions(oc);
MSDevice_Friction::insertOptions(oc);
MSDevice_FCDReplay::insertOptions(oc);

MSTransportableDevice_Routing::insertOptions(oc);
MSTransportableDevice_FCD::insertOptions(oc);
Expand Down Expand Up @@ -126,6 +128,7 @@ MSDevice::buildVehicleDevices(SUMOVehicle& v, std::vector<MSVehicleDevice*>& int
MSDevice_Taxi::buildVehicleDevices(v, into);
MSDevice_GLOSA::buildVehicleDevices(v, into);
MSDevice_Friction::buildVehicleDevices(v, into);
MSDevice_FCDReplay::buildVehicleDevices(v, into);
}


Expand Down
192 changes: 192 additions & 0 deletions src/microsim/devices/MSDevice_FCDReplay.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
/****************************************************************************/
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
// Copyright (C) 2013-2024 German Aerospace Center (DLR) and others.
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0/
// This Source Code may also be made available under the following Secondary
// Licenses when the conditions for such availability set forth in the Eclipse
// Public License 2.0 are satisfied: GNU General Public License, version 2
// or later which is available at
// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
/****************************************************************************/
/// @file MSDevice_FCDReplay.cpp
/// @author Daniel Krajzewicz
/// @author Michael Behrisch
/// @author Jakob Erdmann
/// @date 11.06.2013
///
// A device which stands as an implementation FCD and which outputs movereminder calls
/****************************************************************************/
#include <config.h>

#include <utils/geom/Position.h>
#include <utils/options/OptionsCont.h>
#include <utils/xml/XMLSubSys.h>
#include <libsumo/Helper.h>
#include <microsim/MSNet.h>
#include <microsim/MSEdge.h>
#include <microsim/MSLane.h>
#include <microsim/MSRoute.h>
#include <microsim/MSEventControl.h>
#include <microsim/MSInsertionControl.h>
#include "MSDevice_FCDReplay.h"


// ===========================================================================
// static member initializations
// ===========================================================================
MSDevice_FCDReplay::FCDHandler MSDevice_FCDReplay::myHandler;


// ===========================================================================
// method definitions
// ===========================================================================
// ---------------------------------------------------------------------------
// static initialisation methods
// ---------------------------------------------------------------------------
void
MSDevice_FCDReplay::insertOptions(OptionsCont& oc) {
oc.addOptionSubTopic("FCD Replay Device");
insertDefaultAssignmentOptions("fcd-replay", "FCD Replay Device", oc);

oc.doRegister("device.fcd-replay.file", new Option_FileName());
oc.addDescription("device.fcd.begin", "FCD Replay Device", TL("FCD file to read"));
}


void
MSDevice_FCDReplay::buildVehicleDevices(SUMOVehicle& v, std::vector<MSVehicleDevice*>& into) {
OptionsCont& oc = OptionsCont::getOptions();
if (equippedByDefaultAssignmentOptions(oc, "fcd-replay", v, oc.isSet("device.fcd-replay.file"))) {
MSDevice_FCDReplay* device = new MSDevice_FCDReplay(v, "fcdReplay_" + v.getID());
into.push_back(device);
}
}


void
MSDevice_FCDReplay::init() {
const OptionsCont& oc = OptionsCont::getOptions();
if (oc.isSet("device.fcd-replay.file")) {
if (!XMLSubSys::runParser(myHandler, oc.getString("device.fcd-replay.file"))) {
throw ProcessError();
}
myHandler.addVehicles();
}
}


// ---------------------------------------------------------------------------
// MSDevice_FCDReplay-methods
// ---------------------------------------------------------------------------
MSDevice_FCDReplay::MSDevice_FCDReplay(SUMOVehicle& holder, const std::string& id) :
MSVehicleDevice(holder, id) {
}


MSDevice_FCDReplay::~MSDevice_FCDReplay() {
}


bool
MSDevice_FCDReplay::notifyMove(SUMOTrafficObject& veh,
double /*oldPos*/,
double /*newPos*/,
double /*newSpeed*/) {
if (myTrajectory == nullptr || myTrajectory->empty()) {
// TODO remove vehicle
return false;
}
MSVehicle* v = dynamic_cast<MSVehicle*>(&veh);
if (v == nullptr) {
return false;
}
const auto& p = myTrajectory->front();
MSLane* lane = nullptr;
double lanePos;
double lanePosLat = 0;
double bestDistance = std::numeric_limits<double>::max();
int routeOffset = 0;
ConstMSEdgeVector edges;
libsumo::Helper::moveToXYMap_matchingRoutePosition(std::get<0>(p), std::get<1>(p),
v->getRoute().getEdges(), v->getRoutePosition(),
v->getVehicleType().getVehicleClass(), true,
bestDistance, &lane, lanePos, routeOffset);
libsumo::Helper::setRemoteControlled(v, std::get<0>(p), lane, std::get<2>(p), lanePosLat, libsumo::INVALID_DOUBLE_VALUE, routeOffset, edges, SIMSTEP);
v->setPreviousSpeed(std::get<3>(p), std::numeric_limits<double>::min());
myTrajectory->erase(myTrajectory->begin());
if (myTrajectory->empty()) {
// TODO remove vehicle
return false;
}
return true;
}


// ---------------------------------------------------------------------------
// MSDevice_FCDReplay::FCDHandler-methods
// ---------------------------------------------------------------------------
void
MSDevice_FCDReplay::FCDHandler::myStartElement(int element, const SUMOSAXAttributes& attrs) {
bool ok = true;
switch (element) {
case SUMO_TAG_TIMESTEP:
myTime = attrs.getSUMOTimeReporting(SUMO_ATTR_TIME, "", ok);
return;
case SUMO_TAG_VEHICLE:
case SUMO_TAG_PERSON: {
const std::string id = attrs.getString(SUMO_ATTR_ID);
const double x = attrs.getOpt<double>(SUMO_ATTR_X, id.c_str(), ok, INVALID_DOUBLE);
const double y = attrs.getOpt<double>(SUMO_ATTR_Y, id.c_str(), ok, INVALID_DOUBLE);
const std::string type = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok, "");
const std::string lane = attrs.getOpt<std::string>(SUMO_ATTR_LANE, id.c_str(), ok, "");
const double speed = attrs.getOpt<double>(SUMO_ATTR_SPEED, id.c_str(), ok, INVALID_DOUBLE);
const double pos = attrs.getOpt<double>(SUMO_ATTR_POSITION, id.c_str(), ok, INVALID_DOUBLE);
myTrajectories[id].push_back({Position(x, y), lane, pos, speed});
const MSEdge* const edge = MSEdge::dictionary(SUMOXMLDefinitions::getEdgeIDFromLane(lane));
if (myRoutes.count(id) == 0) {
myRoutes[id] = {myTime, type, {edge}};
} else {
auto& route = std::get<2>(myRoutes[id]);
if (edge != route.back()) {
route.push_back(edge);
}
}
return;
}
default:
break;
}
}


void
MSDevice_FCDReplay::FCDHandler::addVehicles() {
for (const auto& vehDesc : myRoutes) {
const std::string& id = vehDesc.first;
const std::string dummyRouteID = "DUMMY_ROUTE_" + id;
Trajectory& t = myTrajectories[id];
const std::vector<SUMOVehicleParameter::Stop> stops;
ConstMSRoutePtr route = std::make_shared<MSRoute>(dummyRouteID, std::get<2>(vehDesc.second), true, nullptr, stops);
SUMOVehicleParameter* params = new SUMOVehicleParameter();
params->id = id;
params->depart = std::get<0>(vehDesc.second);
params->departPos = std::get<2>(t.front());
params->departSpeed = std::get<3>(t.front());
if (!MSRoute::dictionary(dummyRouteID, route)) {
throw ProcessError("Could not add route '" + dummyRouteID + "'.");
}
MSVehicleType* vehicleType = MSNet::getInstance()->getVehicleControl().getVType(std::get<1>(vehDesc.second));
SUMOVehicle* vehicle = MSNet::getInstance()->getVehicleControl().buildVehicle(params, route, vehicleType, false);
MSNet::getInstance()->getVehicleControl().addVehicle(id, vehicle);
MSNet::getInstance()->getInsertionControl().add(vehicle);
MSDevice_FCDReplay* device = static_cast<MSDevice_FCDReplay*>(vehicle->getDevice(typeid(MSDevice_FCDReplay)));
t.erase(t.begin());
device->setTrajectory(&t);
}
}


/****************************************************************************/
124 changes: 124 additions & 0 deletions src/microsim/devices/MSDevice_FCDReplay.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/****************************************************************************/
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
// Copyright (C) 2013-2024 German Aerospace Center (DLR) and others.
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0/
// This Source Code may also be made available under the following Secondary
// Licenses when the conditions for such availability set forth in the Eclipse
// Public License 2.0 are satisfied: GNU General Public License, version 2
// or later which is available at
// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
/****************************************************************************/
/// @file MSDevice_FCDReplay.h
/// @author Michael Behrisch
/// @date 01.03.2024
///
// A device which records floating car data
/****************************************************************************/
#pragma once
#include <config.h>

#include <utils/common/Command.h>
#include <utils/xml/SUMOSAXHandler.h>
#include "MSVehicleDevice.h"


// ===========================================================================
// class definitions
// ===========================================================================
/**
* @class MSDevice_FCDReplay
* @brief A device which replays a vehiucle trajectory from an fcd file
*
* @see MSDevice
*/
class MSDevice_FCDReplay : public MSVehicleDevice {
public:
/** @brief Inserts MSDevice_FCDReplay-options
* @param[filled] oc The options container to add the options to
*/
static void insertOptions(OptionsCont& oc);


/** @brief Build devices for the given vehicle, if needed
*
* The options are read and evaluated whether a FCDReplay-device shall be built
* for the given vehicle.
*
* The built device is stored in the given vector.
*
* @param[in] v The vehicle for which a device may be built
* @param[filled] into The vector to store the built device in
*/
static void buildVehicleDevices(SUMOVehicle& v, std::vector<MSVehicleDevice*>& into);

/** @brief Static intialization
*/
static void init();

public:
/// @brief Destructor.
~MSDevice_FCDReplay();

bool notifyMove(SUMOTrafficObject& veh,
double oldPos,
double newPos,
double newSpeed);

/// @brief return the name for this type of device
const std::string deviceName() const {
return "fcd-replay";
}

typedef std::vector<std::tuple<Position, std::string, double, double> > Trajectory;

void setTrajectory(Trajectory* const t) {
myTrajectory = t;
}

private:
/** @brief Constructor
*
* @param[in] holder The vehicle that holds this device
* @param[in] id The ID of the device
*/
MSDevice_FCDReplay(SUMOVehicle& holder, const std::string& id);

class FCDHandler : public SUMOSAXHandler {
public:
void addVehicles();

protected:
/// @name inherited from GenericSAXHandler
//@{

/** @brief Called on the opening of a tag
*
* @param[in] element ID of the currently opened element
* @param[in] attrs Attributes within the currently opened element
* @exception ProcessError If something fails
* @see GenericSAXHandler::myStartElement
*/
void myStartElement(int element, const SUMOSAXAttributes& attrs);
//@}

private:
SUMOTime myTime;
std::map<std::string, Trajectory> myTrajectories;
std::map<std::string, std::tuple<SUMOTime, std::string, ConstMSEdgeVector > > myRoutes;
};

private:
static FCDHandler myHandler;
Trajectory* myTrajectory = nullptr;

private:
/// @brief Invalidated copy constructor.
MSDevice_FCDReplay(const MSDevice_FCDReplay&) = delete;

/// @brief Invalidated assignment operator.
MSDevice_FCDReplay& operator=(const MSDevice_FCDReplay&) = delete;

};
3 changes: 3 additions & 0 deletions src/netload/NLBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
#include <microsim/devices/MSDevice.h>
#include <microsim/devices/MSDevice_ToC.h>
#include <microsim/devices/MSDevice_BTreceiver.h>
#include <microsim/devices/MSDevice_FCDReplay.h>
#include <microsim/MSEdgeControl.h>
#include <microsim/MSGlobals.h>
#include <microsim/output/MSDetectorControl.h>
Expand Down Expand Up @@ -274,6 +275,8 @@ NLBuilder::build() {
}
PROGRESS_TIME_MESSAGE(before);
}
// routes from FCD files
MSDevice_FCDReplay::init();
// load routes
if (myOptions.isSet("route-files") && string2time(myOptions.getString("route-steps")) <= 0) {
if (!load("route-files")) {
Expand Down

0 comments on commit 71c8d76

Please sign in to comment.