Skip to content
Snippets Groups Projects
traci-manager.h 6.66 KiB
Newer Older
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2012 Fraunhofer ESK
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation;
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Author: Karsten Roscher <karsten.roscher@esk.fraunhofer.de>
 */
#ifndef TRACI_MANAGER_H
#define TRACI_MANAGER_H

#include <ns3/object.h>
#include <ns3/ptr.h>
#include <ns3/simple-ref-count.h>
#include <ns3/nstime.h>

#include "traci-types.h"
#include "traci-vehicle.h"

namespace ns3 {

class TraCi;

/*!
 * @brief Class managing simulation steps and arrival and departure of vehicles.
 *
 * The manager will schedule an update event for every simulation step and
 * inform handlers about arrived and departed vehicles.
 */
class TraCiManager : public Object {
public:
  static TypeId GetTypeId (void);

  TraCiManager ();
  ~TraCiManager ();

  void Start (Time when = Seconds (0));
  void Stop (Time when);

  //! Set TraCi instance to use.
  void SetTraCi (Ptr<TraCi> traci);

  //! Set time for one simulation step.
  void SetSimulationStep (Time step);

  /*!
   * @brief Enable/disable automatic time sync on start.
   *
   * This will adjust for an offset in times between ns-3 and SUMO in the
   * beginning in case SUMO was started with a custom beginning time.
   *
   * @param enabled	True to enable
   */
  void SetTimeSyncOnStart (bool enabled);

  /*!
   * @brief Enable/disable automatic departure of vehicles already running on start.
   *
   * This will help in case a simulation state was loaded and all vehicles
   * already on their way should be handles as well.
   *
   * @param enabled	True to enable
   */
  void SetDepartAlreadyRunningOnStart (bool enabled);

  /*!
   * @brief Enable/disable automatic detection of the simulation step size
   * @param enabled 	True to enable
   */
  void SetUseStepSizeFromTraciHost (bool enabled);

  /*!
   * @brief Base class for node departure/arrival handlers.
   *
   * Multiple handlers can be registered at the manager and will be
   * called in order of their priority. If a handler took care of a
   * vehicle (HandleDeparture returned true) the process will stop.
   *
   * HandleArrival will be called for all registered handlers, even if
   * they did not indicate that the took care of the object. This allows
   * multiple handlers to track the lifetime of a vehicle even if they
   * do not want to terminate further mapping.
   */
  class VehicleHandler : public SimpleRefCount<VehicleHandler>
  {
  public:
    virtual ~VehicleHandler () {}

    /*!
     * @brief Handle the departure of a vehicle.
     * @param vehicle	Departed vehicle
     * @return True if this handler took care of the vehicle.
     */
    virtual bool HandleDeparture (Ptr<traci::Vehicle> vehicle) = 0;

    /*!
     * @brief Handle the arrival of a vehicle.
     * @param vehicleId Id of the arrived vehicle
     */
    virtual void HandleArrival (std::string vehicleId) = 0;

    /*!
     * @brief Handle the execution of a simulation step
     *
     * This will be invoked after a simulation step executed by the
     * remote TraCI instance. It is not mandatory to implement this.
     */
    virtual void HandleSimulationStep (Ptr<TraCi> traci) {}

  };


  /*!
   * @brief Add a vehicle handler with the provided priority.
   *
   * Higher values mean a higher priority. The order of invocation
   * for handlers with the same priority is undefined.
   *
   * @param handler   Handler to add.
   * @param priority  Priority for the handler.
   */
  void AddHandler (Ptr<VehicleHandler> handler, int priority);

  /*!
   * @brief Remove the provided handler.
   * @param handler   Handler to remove.
   */
  void RemoveHandler (Ptr<VehicleHandler> handler);

private:

  void DoStart ();
  void DoStop ();

  /*!
   * @brief Execute a simulation step (will be invoked as event callback).
   */
  void ExecuteSimulationStep ();

  /*!
   * @brief Update available nodes.
   */
  void UpdateAvailableNodes ();


  /*!
   * @brief Handle arrived vehicles.
   * @param arrived List of identifiers of arrived vehicles.
   */
  void HandleArrivedVehicles (const traci::StringList& arrived);

  /*!
   * @brief Handle a single arrived vehicle
   * @param objectId	Id of the arrived vehicle
   */
  void HandleArrivedVehicle (std::string objectId);

  /*!
   * @brief Handle departed vehicles.
   * @param departed List of identifiers of departed vehicles.
   */
  void HandleDepartedVehicles (const traci::StringList& departed);

  /*!
   * @brief Handle a single departed vehicle
   * @param objectId	Id of the departed vehicle
   * @return True if the vehicle found a handler
   */
  bool HandleDepartedVehicle (std::string objectId);

  //! Time for one simulation step
  Time m_simulationStep;

  //! Flag indicating if the time should be synced on start.
  bool m_syncTimeOnStart;

  //! Flag indicating if nodes already running at the beginning should be treated as departed now.
  bool m_departAlreadyRunningOnStart;

  //! Flag indicating if the step size of the traci host should be used
  bool m_useStepSizeFromTraciHost;

  //! Time SUMO is ahead of ns-3
  Time m_sumoOffset;

  //! Traci instance used.
  Ptr<TraCi> m_traci;

  //! Event for a simulation step
  EventId m_simulationEvent;

  EventId m_startEvent;
  EventId m_stopEvent;

  //! A vehicle handler entry consisting of a priority and a pointer to the handler.
  typedef std::pair<int, Ptr<VehicleHandler> > HandlerEntry;
  typedef std::vector<HandlerEntry> HandlerList;
  HandlerList m_handlers;
};



/*!
 * @brief A simple vehicle handler providing a callback based interface.
 *
 * If you prefer using callbacks, you can use this handler. It will
 * forward the requests to the provided callbacks.
 */
class CallbackVehicleHandler : public TraCiManager::VehicleHandler
{
public:
  virtual bool HandleDeparture (Ptr<traci::Vehicle> vehicle);
  virtual void HandleArrival (std::string vehicleId);

  typedef Callback<bool, Ptr<traci::Vehicle> > DepartureCallback;
  typedef Callback<void, std::string> ArrivalCallback;

  void SetArrivalCallback (ArrivalCallback cb);
  void SetDepartureCallback (DepartureCallback cb);

private:
  ArrivalCallback m_arrived;
  DepartureCallback m_departed;
};



}  // namespace ns3


#endif