Beispiel #1
0
    def __init__(self, wait_dict, serve_dict, finish_dict, cancel_dict):
        self.__logger = Logger("RiderStatusTracker")

        self.__wait_dict = wait_dict
        self.__serve_dict = serve_dict
        self.__finish_dict = finish_dict
        self.__cancel_dict = cancel_dict
Beispiel #2
0
    def __init__(self, readings_conn):

        #   get to the ip address of the single base unit
        try:
            ip_addr = SysWideConfig.prop_val('deployment', 'wbu_ip')
        except:
            Logger.err(
                f"Failed to determine the ip addr of the base unit.  Aborting."
            )
            sys.exit()

        try:
            port = SysWideConfig.prop_val('deployment', 'wbu_port')
        except:
            Logger.err(
                f"Failed to determine the port of the base unit.  Aborting.")
            sys.exit()

        #   make the base unit connection object.  the connection handle will reside with it.
        self.wbu_conn = WBUConn(wbu_ip=ip_addr, wbu_port=port)

        self.readings_conn = readings_conn

        #   prep the sensors
        self.sensors = []
        self._prep_sensors()
    def __init__(self, uID, sT, sZ, dZ, dP, pat, srcX, srcY, destX, destY):
        # logger in Dispatcher
        self.__logger = Logger('Rider')
        #self.__logger.setLevel(logging.DEBUG)
        self.__logger.info(Rider.timestamp, "__INIT__", None, None, "Create A Rider Object")

        self.__id = uID
        self.__request_timestamp = sT
        self.__srcZone = sZ
        self.__destZone = dZ
        self.__default_price = dP
        self.__price = math.inf
        self.__patience = pat
        self.__dirID = self.__assignDirID(srcX, srcY, destX, destY)
        self.__shortest_time = Graph.queryTravelCost(sZ, dZ)
        self.__arrival_timestamp = None
        self.__groupID = None

        self.__status = WAITING
        self.__wait_time = 0
        self.__detour_time = -1
        self.__sat = 0

        if self.__default_price > 100:
            self.__logger.warning(Rider.timestamp, "__INIT__", None, self.getID(), str(self))
Beispiel #4
0
 def connect(self):
     if self.wbu_conn_handle is not None:
         try:
             self.wbu_conn_handle = self.wbu_conn.open()
             return True
         except:
             Logger.err(f"failed to open the connection")
             return False
Beispiel #5
0
    def __init__(self, wbu_ip, wbu_port):
        self.wbu_ip = wbu_ip
        self.wbu_conn_handle = None  # the handle made within the connection upon making the connection

        try:
            self.wbu_conn = ModbusClient(host=wbu_ip, port=502)
        except Exception as e:
            Logger.err(f"unable to make the connection to WBU: {e}")
            sys.exit()
Beispiel #6
0
    def connect(self):

        #   make the connection to the db
        try:
            self.handle = sqlite3.connect(self.db_file)
        except sqlite3.Error as e:
            Logger.err(
                f'Failed to make the connection to the SQLite3 db: {e}.  Aborting.'
            )
            sys.exit()
 def __init__(self):
     self.__logger = Logger('Simulation')
     #self.__logger.setLevel(logging.DEBUG)
     self.__logger.info(-1, "__INIT__", None, None,
                        "Create Simulation Object.")
     self.__driver_list = RequestList()
     self.__rider_list = RequestList()
     self.__dispatcher = Dispatcher()
     self.__cycle = 0
     self.__sim_time = []
    def __init__(self):
        #logger in Dispatcher
        self.__logger = Logger('Dispatcher')
        self.__logger.setLevel(logging.DEBUG)
        self.__logger.info(Dispatcher.timestamp, "__INIT__", None, None, "Create A Dispatcher Object")

        #Storage for drivers and riders
        self.__driver_dict = {}
        self.__rider_wait_dict = {}
        self.__rider_serve_dict = {}
        self.__rider_finish_dict = {}
        self.__rider_cancel_dict = {}

        #Performance of driver and rider
        self.wait_rider={}
        self.no_work_driver={}
        self.idle_driver_before_match={}

        self.grp_in_4=0
        self.grp_in_3=0
        self.grp_in_2=0
        self.grp_in_1=0

        #Cluser Strategy
        self.__cluster_strategy = ClusteringByDir(self.__rider_wait_dict)

        #Matching Strategy
        self.__match_strategy = MatchingInQueue(self.__driver_dict, self.__rider_wait_dict, self.__rider_serve_dict)

        #Driver Status Tracker
        self.__driver_tracker = DriverStatusTracker(self.__driver_dict)

        #Rider Status tracker
        self.__rider_tracker = RiderStatusTracker(self.__rider_wait_dict, self.__rider_serve_dict, self.__rider_finish_dict, self.__rider_cancel_dict)

        #Driver Dict
        for zone_id in range(1,78):
            self.__driver_dict[zone_id] = {}

        #Rider Dict
        for zone_id in range(1,78):
            self.__rider_wait_dict[zone_id] = {}
            for dir_id in range(-1, 12):
                self.__rider_wait_dict[zone_id][dir_id] = defaultdict(dict)

        #
        for cycle in range(SIMULATION_CYCLE_START, SIMULATION_CYCLE_END):
            self.wait_rider[cycle] = []
            self.no_work_driver[cycle] = []
            for zone_id in range(0,78):
                self.wait_rider[cycle].append(0)
                self.no_work_driver[cycle].append(0)
    def __init__(self, rider_waiting_dict):
        self.logger = Logger('ClusteringStrategy')
        # self.logger.setLevel(logging.DEBUG)
        self.logger.info(ClusteringStrategy.timestamp, "__INIT__", None, None,
                         "Initialize ClusteringStrategy")
        self.__assign_gid_dict = {}
        self.__rider_dict = rider_waiting_dict

        # Assign Group ID
        for zone_id in range(1, 78):
            self.__assign_gid_dict[zone_id] = {}
            for dir_id in range(-1, 12):
                self.__assign_gid_dict[zone_id][dir_id] = 1
Beispiel #10
0
    def execute(self):

        # Current working directory for project
        Logger.info(f'Current directory: {os.getcwd()}')

        while True:

            #   acquire and store the readings of all sensors
            self.acquirer.execute()

            #   generate and publish the output.
            self.outputter.execute(self.acquirer.sensors)

            time.sleep(self.sleep_secs)
Beispiel #11
0
    def __init__(self, sleep_secs):

        #   make the connection to the sqlite3 db
        try:
            readings_db_path = SysWideConfig.prop_val('readings_db', 'sqlite_path')
        except:
            Logger.err(f"Failed to determine the path of the readings db.  Aborting.")
            sys.exit()

        self.readings_conn = SQLiteConn(db_path=readings_db_path)

        self.acquirer = Acquirer(readings_conn=self.readings_conn)

        self.outputter = Outputter(sensors=self.acquirer.sensors, readings_conn=self.readings_conn)

        self.sleep_secs = sleep_secs
    def __init__(self, id, pCurr):
        # logger in Dispatcher
        self.__logger = Logger('Driver')
        #self.__logger.setLevel(logging.DEBUG)
        self.__logger.info(Driver.timestamp, "__INIT__", None, None,
                           "Create A Driver Object")

        self.__id = id
        self.__pos = pCurr

        self.__status = IDLE
        self.__riders = {}
        self.__trip_route = []
        self.__trip_effort = 0
        self.__trip_profit = 0
        self.__idle_time = 0
        self.__finish_trip_time = -1
Beispiel #13
0
class DriverStatusTracker:

    timestamp = -1

    def __init__(self, driver_dict):
        self.__logger = Logger("DriverStatusTracker")
        self.__driver_dict = driver_dict

    def updateDriverStatusAfterMatching(self, driver):
        driver.setStatus(INSERVICE)
        driver.calcTripRoute()
        driver.calcTripEffort()
        driver.notifyRiderPrice()
        driver.calcTripProfit()

    def updateDriverStatusWhenInService(self, driver, rider_tracker):
        for elem in driver.getTripRoute().copy():
            if  elem.getEventTime() <= DriverStatusTracker.timestamp:
                #handle rider on board
                curr_elem = driver.popTripRoute()
                if curr_elem.getEvent() == DROPOFF:
                    rider = driver.getRider(curr_elem.getRiderID())
                    rider_tracker.notifyRiderToFinishTrip(rider)
                    driver.removeRider(curr_elem.getRiderID())
                #handle driver
                del self.__driver_dict[driver.getPos()][driver.getID()]
                self.__driver_dict[curr_elem.getZoneID()][driver.getID()] = driver
                driver.setPos(curr_elem.getZoneID())

        if len(driver.getTripRoute()) == 0:
            driver.setStatus(IDLE)
            driver.setFinishTripTime(DriverStatusTracker.timestamp)

    def updateDriverStatusWhenIdle(self, driver, no_work_dict):
        if driver.getStatus() == IDLE:
            if driver.getFinishTripTime() != DriverStatusTracker.timestamp:
                driver.tickIdleTime()
                no_work_dict[DriverStatusTracker.timestamp][driver.getPos()] += 1
        else:
            self.__logger.error(DriverStatusTracker.timestamp, "updateDriverStatusWhenIdle", driver.getID(), None, "Driver Status is Wrong.")
            raise Exception("The driver status and dict not match.")
Beispiel #14
0
    def acquire_readings(self):

        #   acquire and record (locally) readings from this sensor
        no_of_regs_to_read = 1
        #   what does the wbu say is the time of the last reading of ?
        try:
            self.time_of_last_update = self.wbu_conn.wbu_conn_handle.read_input_registers(self.reg_last_updated, no_of_regs_to_read)
        except Exception as e:
            Logger.err(f"Unable to access Modbus {e}")
            status = False

        #   record the time of latest acquisition from the wbu
        self.time_last_acquired = datetime.now()

        if self.time_of_last_update is None:
            #   TODO: this is just strange.
            self.co2_reading = 99
        else:
            self.co2_reading = self.wbu_conn.wbu_conn_handle.read_input_registers(self.reg_co2, no_of_regs_to_read)

        self._assess_sensor_status()
Beispiel #15
0
    def _prep_sensors(self):

        #   prep the sensors from the sensors config

        #   get hold of the locations info from the global config
        if 'locations' in SysWideConfig.loaded_config:
            locations_config = SysWideConfig.loaded_config('locations')
        else:
            Logger.err(
                f"Failed to find the locations within the site configuration.  Aborting."
            )
            sys.exit()

        Logger.info(f"Creating and adding the sensors")

        for location, config in locations_config:

            #   exclude inactive sensors
            state = config['state']
            if not state:
                continue

            # TODO: add try-excepts are all of these calls as we cannot assume that the config is correct.
            sensor_id = config['sensor_id']
            reg_temp = config['reg_temp']
            reg_humidity = config['reg_humidity']
            reg_co2 = config['reg_co2']
            reg_last_updated = config['reg_last_updated']

            #   make and record the sensor
            sensor = Sensor(wbu_conn=self.wbu_conn,
                            location=location,
                            sensor_id=sensor_id,
                            reg_temp=reg_temp,
                            reg_humidity=reg_humidity,
                            reg_co2=reg_co2,
                            reg_last_updated=reg_last_updated)

            self.sensors.append(sensor)
Beispiel #16
0
class RiderStatusTracker:
    timestamp = -1

    def __init__(self, wait_dict, serve_dict, finish_dict, cancel_dict):
        self.__logger = Logger("RiderStatusTracker")

        self.__wait_dict = wait_dict
        self.__serve_dict = serve_dict
        self.__finish_dict = finish_dict
        self.__cancel_dict = cancel_dict

    def checkRiderStatusIfTimeOut(self, rider):
        if RiderStatusTracker.timestamp - rider.getRequestTimeStamp(
        ) >= rider.getPatience():
            rider.setStatus(CANCEL)
            self.__cancel_dict[rider.getID()] = rider
            zone_id = rider.getSrcZone()
            dir = rider.getDirID()
            group_id = rider.getGroupID()
            del self.__wait_dict[zone_id][dir][group_id][rider.getID()]
            if len(self.__wait_dict[zone_id][dir][group_id]) == 0:
                del self.__wait_dict[zone_id][dir][group_id]
            #cancel_dict[RiderStatusTracker.timestamp][rider.getSrcZone()] += 1
        else:
            self.__logger.debug(
                RiderStatusTracker.timestamp, "updateRiderStatusWhenTimeOut",
                None, rider.getID(), "Cancel Time Should be: ",
                str(rider.getRequestTimeStamp() + rider.getPatience()))

    def updateRiderStatusAfterMatching(self, rider):
        rider.calcSat()
        rider.setStatus(SERVING)
        self.__serve_dict[rider.getID()] = rider

    def notifyRiderToFinishTrip(self, rider):
        if rider.getStatus() == SERVING:
            self.__finish_dict[rider.getID()] = rider
            rider.setStatus(FINISHED)
            del self.__serve_dict[rider.getID()]
        else:
            self.__logger.error(RiderStatusTracker.timestamp,
                                "updateRiderStatusWhenInService", None,
                                rider.getID(),
                                "The status and dict not match.")
            raise Exception("The rider status and dict not match.")

    def updateRiderStatusWhenWait(self, rider, wait_rider_dict):
        if rider.getStatus() == WAITING:
            rider.tickWaitTime()
            wait_rider_dict[RiderStatusTracker.timestamp][
                rider.getSrcZone()] += 1
        else:
            self.__logger.error(RiderStatusTracker.timestamp,
                                "updateDriverStatusWhenIdle", None,
                                rider.getID(), "Rider Status is Wrong.")
            raise Exception("The rider status and dict not match.")
class RequestList:

    timestamp = -1

    def __init__(self):
        self.__logger = Logger("RequestList")
        #self.__logger.setLevel(logging.INFO)
        self.__logger.info(RequestList.timestamp, "__INIT__", None, None,
                           "Create RequestList Object.")
        self.__items = []

    def __str__(self):
        ret = "["
        for i in range(0, len(self.__items)):
            ret = ret + str(self.__items[i]) + ", "
        ret = ret + "]"
        return ret

    def first_element(self):
        if self.is_empty():
            self.__logger.error(RequestList.timestamp, "__INIT__", None, None,
                                "No First element exists.")
            raise Exception("No First element exists.")
        return self.__items[0]

    def remove(self):
        item = self.__items.pop(0)
        self.__logger.info(RequestList.timestamp, "remove", None, None,
                           str(item))
        return item

    def is_empty(self):
        return len(self.__items) == 0

    def __len__(self):
        return len(self.__items)

    def add(self, item):
        self.__logger.info(RequestList.timestamp, "add", None, None, str(item))
        self.__items.append(item)
class Rider:
    timestamp = -1

    def __init__(self, uID, sT, sZ, dZ, dP, pat, srcX, srcY, destX, destY):
        # logger in Dispatcher
        self.__logger = Logger('Rider')
        #self.__logger.setLevel(logging.DEBUG)
        self.__logger.info(Rider.timestamp, "__INIT__", None, None, "Create A Rider Object")

        self.__id = uID
        self.__request_timestamp = sT
        self.__srcZone = sZ
        self.__destZone = dZ
        self.__default_price = dP
        self.__price = math.inf
        self.__patience = pat
        self.__dirID = self.__assignDirID(srcX, srcY, destX, destY)
        self.__shortest_time = Graph.queryTravelCost(sZ, dZ)
        self.__arrival_timestamp = None
        self.__groupID = None

        self.__status = WAITING
        self.__wait_time = 0
        self.__detour_time = -1
        self.__sat = 0

        if self.__default_price > 100:
            self.__logger.warning(Rider.timestamp, "__INIT__", None, self.getID(), str(self))

    def __str__(self):
        ret = "{" + str(self.__id) + ', ' + str(self.__request_timestamp) +  ", " + str(self.__srcZone) + ", " + str(self.__destZone) + ", " + \
              str(self.__default_price) + ", "  + str(self.__price) +  ", " + str(self.__patience) + ", " + str(self.__dirID) +", " + \
              str(self.__shortest_time) + ", " +  str(self.__arrival_timestamp) + ", " + str(self.__groupID) + ", " +\
              str(self.__status) + ", " + str(self.__wait_time) + ", " + str(self.__detour_time) +  ", " +  str(self.__sat) + "}"
        return ret

    #https://stackoverflow.com/questions/13226038/calculating-angle-between-two-vectors-in-python
    #The range is [-180, 180)
    def __calcDirection(self, srcX, srcY, destX, destY):
        p1 = [srcX, srcY]
        p0 = [destX, destY]
        p2 = p1 + np.array([1, 0])

        v0 = np.array(p0) - np.array(p1)
        v1 = np.array(p2) - np.array(p1)
        angle = np.math.atan2(np.linalg.det([v0, v1]), np.dot(v0, v1))
        return np.degrees(angle)*(-1)

    #Tansfer from [-180,180) to [0,360).
    #calculate DirID by dividing the DIR_THRESHOLD
    def __assignDirID(self, srcX, srcY, destX, destY):
        dir = self.__calcDirection(srcX, srcY, destX, destY)
        return int((dir+180)/DIR_THRESHOLD)

    def setDirID(self, dir):
        self.__dirID = dir

    def getDirID(self):
        return self.__dirID

    def setGroupID(self, grpID):
        self.__groupID = grpID

    def getGroupID(self):
        return self.__groupID

    def tickWaitTime(self):
        self.__wait_time += 1

    def getWaitTime(self):
        return self.__wait_time

    def getShortestTime(self):
        return self.__shortest_time

    def calcDetourTime(self, time):
        self.__detour_time = time - self.__shortest_time

    def getDetourTime(self):
        return self.__detour_time

    def setArrivalTimestamp(self, time):
        self.__arrival_timestamp = time

    def getArrivalTimestamp(self):
        return self.__arrival_timestamp

    #prerequest: calc detour time first
    def calcPrice(self, n_shared):
        if self.__detour_time < 0:
            self.__logger.error(Rider.timestamp, "calcPrice", None, self.getID(), "Detour time is unreasonable.")
            raise Exception("Detour time is unreasonable.")
        self.__price = self.__default_price * math.exp(DETOUR_WEIGH * -self.__detour_time)
        if n_shared == 1:
            self.__price = self.__price * DISCOUNT_1
        elif n_shared == 2:
            self.__price = self.__price * DISCOUNT_2
        elif n_shared == 3:
            self.__price = self.__price * DISCOUNT_3
        elif n_shared == 4:
            self.__price = self.__price * DISCOUNT_4
        else:
            self.__logger.error(Rider.timestamp, "calcPrice", None, self.getID(), "Shared number is incorret.")
            raise Exception("Shared number is incorret.")

    def getPrice(self):
        return self.__price

    def getDefaultPrice(self):
        return self.__default_price

    def calcSat(self):
        if self.__detour_time < 0:
            self.__logger.error(Rider.timestamp, "calcSat", None, self.getID(), "Detour time is unreasonable.")
            raise Exception("Detour time is unreasonable.")
        elif self.__price > self.__default_price:
            self.__logger.error(Rider.timestamp, "calcSat", None, self.getID(), "Price is unreasonable.")
            raise Exception("Price is unreasonable.")
        else:
            self.__sat = (self.__default_price-self.__price)*SAT_PRICE - math.expm1(self.__detour_time)
            if self.__sat > 10000000:
                self.__logger.warning(Rider.timestamp, "calcPrice", None, self.getID(), "SAT is too large", str(self))


    def getSat(self):
        return self.__sat

    def getID(self):
        return self.__id

    def getRequestTimeStamp(self):
        return self.__request_timestamp

    def getSrcZone(self):
        return self.__srcZone

    def getDestZone(self):
        return self.__destZone

    def getPatience(self):
        return self.__patience

    def setStatus(self, status):
        self.__status = status

    def getStatus(self):
        return self.__status
class Simulation:
    def __init__(self):
        self.__logger = Logger('Simulation')
        #self.__logger.setLevel(logging.DEBUG)
        self.__logger.info(-1, "__INIT__", None, None,
                           "Create Simulation Object.")
        self.__driver_list = RequestList()
        self.__rider_list = RequestList()
        self.__dispatcher = Dispatcher()
        self.__cycle = 0
        self.__sim_time = []

    def importData(self, ):
        ImportData.importDriverData(FILENAME_D, self.__driver_list)
        ImportData.importRiderData(FILENAME_R, self.__rider_list)

    def run(self):
        #Run simulation cycle
        for self.__cycle in range(SIMULATION_CYCLE_START,
                                  SIMULATION_CYCLE_END):
            # Synchronization the time with Modules(Driver, Dispatcher, Rider, and so on)
            self.__logger.info(self.__cycle, "RUN", None, None,
                               "1. Synchronizing Time With Each Module.")
            #Dispatcher Module
            Dispatcher.timestamp = self.__cycle
            ClusteringStrategy.timestamp = self.__cycle
            MatchingStrategy.timestamp = self.__cycle
            DriverStatusTracker.timestamp = self.__cycle
            RiderStatusTracker.timestamp = self.__cycle
            #Driver Module
            Driver.timestamp = self.__cycle
            RoutingStrategy.timestamp = self.__cycle
            #Rider Module
            Rider.timestamp = self.__cycle
            #Import Module
            RequestList.timestamp = self.__cycle
            ImportDemandEvaluation.timestamp = self.__cycle

            # Start simulation time of this cycle
            print("The Cycle Number: ", self.__cycle)
            #print("Time: ", ImportDemandEvaluation.time)

            # Put the driver requests to dispatcher (The Driver List)
            self.__logger.info(
                self.__cycle, "RUN", None, None,
                "2. Put Drivers' Requests To Dispatcher From RequestList.")
            while not self.__driver_list.is_empty():
                curr_driver = self.__driver_list.remove()
                self.__logger.debug(
                    self.__cycle, "RUN", None, None,
                    "Current Driver Moved into Dict of Dispatcher: ",
                    str(curr_driver))
                self.__dispatcher.handleDriverIntoDict(curr_driver)
            self.__dispatcher.countDriverNumberEachZone(
            )  #count idle driver number before match

            # Put the rider requests to dispatcher (The Rider List)
            self.__logger.info(
                self.__cycle, "RUN", None, None,
                "3. Put Rider' Requests To Dispatcher From RequestList.")
            while not self.__rider_list.is_empty(
            ) and self.__rider_list.first_element().getRequestTimeStamp(
            ) == self.__cycle:
                curr_rider = self.__rider_list.remove()
                self.__logger.debug(
                    self.__cycle, "RUN", None, None,
                    "Current Rider Moved into Dict of Dispatcher: ",
                    str(curr_rider))
                self.__dispatcher.handleRiderIntoDict(curr_rider)

            #Show dispatch dicts
            print("waiting, serving, finished, canceled: ",
                  self.__dispatcher.countRiderNumberInWaitDict(),
                  self.__dispatcher.countRiderNumberInServeDict(),
                  self.__dispatcher.countRiderNumberInFinishDict(),
                  self.__dispatcher.countRiderNumberInCancelDict())

            #match driver and rider by dispatcher
            self.__logger.info(
                self.__cycle, "RUN", None, None,
                "4. Match Riders' Request to AN Appropriate Driver.")
            self.__dispatcher.matchRidertoDriver()

            # Update simulator's states
            self.__logger.info(self.__cycle, "RUN", None, None,
                               "5. Update State of Simulator.")
            self.__dispatcher.updateDriverInDict()
            self.__dispatcher.updateRidersInWaitDict()

            #Show up results
            self.__logger.info(self.__cycle, "RUN", None, None,
                               "6. Show Up All Results of this Cycle.")
            #print(self.__dispatcher.cancel_rider)
            #print(self.__dispatcher.no_work_driver)
            #if self.__cycle % SHOWN_INTERVAL == 0 and self.__cycle != SIMULATION_CYCLE_START:
            #    self.showPerformanceMetrics()
            #print("\n")
        self.showPerformanceMetrics()
        print("Simulation Terminated.\n")

        #self.drawMonitorDict(self.__dispatcher.wait_rider, self.__dispatcher.no_work_driver)

    def drawMonitorDict(self, monitor_dict1, monitor_dict2):
        for time1, item1 in monitor_dict1.items():
            for time2, item2 in monitor_dict2.items():
                if time1 == time2:
                    #plt.figure(figsize=(30, 20))
                    fig, (ax1, ax2) = plt.subplots(2, figsize=(30, 20))
                    fig.suptitle(str(time1))
                    ax1.plot(item1[0:78],
                             label='Wait Rider# after match',
                             color='r')
                    ax1.plot(item2[0:78],
                             label='Idle Driver# after match',
                             color='b')
                    ax1.set_xticks(np.arange(0, 78, step=1))
                    ax1.set_yticks(np.arange(0, 300, step=20))
                    ax1.set_ylabel("driver#")
                    ax1.legend()
                    ax2.plot(self.__dispatcher.idle_driver_before_match[time1],
                             label='Idle Driver# before match',
                             color='b')
                    ax2.set_xticks(np.arange(0, 78, step=1))
                    ax2.set_yticks(np.arange(0, 300, step=20))
                    ax2.set_xlabel("zones")
                    ax2.set_ylabel("driver#")
                    ax2.legend()
                    plt.savefig(SAVE_PATH.format(time1))
                    plt.close()

    def showPerformanceMetrics(self):
        print("\n")

        print("The Number of Riders occured so far: ",
              self.__dispatcher.countCurrentTotalRiderNumber())
        print("The Number of Drivers: ",
              self.__dispatcher.countTotalDriverNumber())
        print("The Number of Cycles: ", self.__cycle)

        print(
            "***************************************************************")
        print("Driver Performace Metrics:")
        print("Average Revenue: ",
              round(self.__dispatcher.calcAverageProfitOfDrivers(), 2))
        print("Average Trip Effort: ",
              round(self.__dispatcher.calcAverageTripEffortOfDrivers(), 2))
        print(
            "Average Profit: ",
            round(
                self.__dispatcher.calcAverageProfitOfDrivers() -
                COST_PER_CYCLE *
                self.__dispatcher.calcAverageTripEffortOfDrivers(), 2))
        print(
            "Average Utilization: ",
            round(
                (260 - self.__dispatcher.calcAverageIdleTimeOfDrivers()) / 260,
                2))

        print(
            "***************************************************************")
        print("Rider Performace Metrics:")
        print("Average Waiting Time (Cycles): ",
              round(self.__dispatcher.calcAverageWaitTimeOfRiders(), 2))
        print("Average Detour Time (Cycles): ",
              round(self.__dispatcher.calcAverageDetourTimeOfRiders(), 2))
        print("Average Fare: ",
              round(self.__dispatcher.calcAverageFareOfRiders(), 2))
        print("Average Default Fare: ",
              round(self.__dispatcher.calcAverageDefaultFareRiders(), 2))

        print(
            "***************************************************************")
        print("System Performace Metrics:")
        print(
            "Serving Rate: ",
            round(
                1 - self.__dispatcher.countRiderNumberInCancelDict() /
                self.__dispatcher.countCurrentTotalRiderNumber(), 2))

        total = self.__dispatcher.countRiderNumberInServeDict(
        ) + self.__dispatcher.countRiderNumberInFinishDict()
        print("Pooling Rate in 4: ",
              round(self.__dispatcher.grp_in_4 * 4 / total, 3))
        print("Pooling Rate in 3: ",
              round(self.__dispatcher.grp_in_3 * 3 / total, 3))
        print("Pooling Rate in 2: ",
              round(self.__dispatcher.grp_in_2 * 2 / total, 3))
        print("Pooling Rate in 1: ",
              round(self.__dispatcher.grp_in_1 / total, 3))
        print(
            "***************************************************************")
 def __init__(self):
     self.logger = Logger('MatchingStrategy')
class Dispatcher:
    # Sync timestamp for logging
    timestamp = -1

    def __init__(self):
        #logger in Dispatcher
        self.__logger = Logger('Dispatcher')
        self.__logger.setLevel(logging.DEBUG)
        self.__logger.info(Dispatcher.timestamp, "__INIT__", None, None, "Create A Dispatcher Object")

        #Storage for drivers and riders
        self.__driver_dict = {}
        self.__rider_wait_dict = {}
        self.__rider_serve_dict = {}
        self.__rider_finish_dict = {}
        self.__rider_cancel_dict = {}

        #Performance of driver and rider
        self.wait_rider={}
        self.no_work_driver={}
        self.idle_driver_before_match={}

        self.grp_in_4=0
        self.grp_in_3=0
        self.grp_in_2=0
        self.grp_in_1=0

        #Cluser Strategy
        self.__cluster_strategy = ClusteringByDir(self.__rider_wait_dict)

        #Matching Strategy
        self.__match_strategy = MatchingInQueue(self.__driver_dict, self.__rider_wait_dict, self.__rider_serve_dict)

        #Driver Status Tracker
        self.__driver_tracker = DriverStatusTracker(self.__driver_dict)

        #Rider Status tracker
        self.__rider_tracker = RiderStatusTracker(self.__rider_wait_dict, self.__rider_serve_dict, self.__rider_finish_dict, self.__rider_cancel_dict)

        #Driver Dict
        for zone_id in range(1,78):
            self.__driver_dict[zone_id] = {}

        #Rider Dict
        for zone_id in range(1,78):
            self.__rider_wait_dict[zone_id] = {}
            for dir_id in range(-1, 12):
                self.__rider_wait_dict[zone_id][dir_id] = defaultdict(dict)

        #
        for cycle in range(SIMULATION_CYCLE_START, SIMULATION_CYCLE_END):
            self.wait_rider[cycle] = []
            self.no_work_driver[cycle] = []
            for zone_id in range(0,78):
                self.wait_rider[cycle].append(0)
                self.no_work_driver[cycle].append(0)

    def showDriverDict(self, zone_id):
        ret = str(zone_id) + ": {"
        for driver_id in OrderedDict(sorted(self.__driver_dict[zone_id].items(), key=lambda t: t[0])).keys():
            ret = ret + driver_id + ", "
        ret = ret + "}"
        return ret

    def getDriverFromDriverDict(self, zone_id, driver_id):
        for id, driver in self.__driver_dict[zone_id].items():
            if id == driver_id:
                return driver
        return None

    def getDriverNumberOfZone(self, zone_id):
        return len(self.__driver_dict[zone_id])


    def showRiderWaitDict(self, zone_id):
        ret = str(zone_id) + ": {"
        for dir_id in self.__rider_wait_dict[zone_id].keys():
            ret = ret + str(dir_id) + ": {"
            for group_id in self.__rider_wait_dict[zone_id][dir_id].keys():
                ret = ret + str(group_id) + ": ["
                for rider_id in OrderedDict(sorted(self.__rider_wait_dict[zone_id][dir_id][group_id].items(), key=lambda t: t[0])).keys():
                    ret = ret + str(rider_id) + ", "
                ret = ret + "], "
            ret = ret + "}, "
        ret = ret + "}"
        return ret

    def getRiderFromWaitDict(self, zone_id, dir_id, group_id, rider_id):
        for id, rider in self.__rider_wait_dict[zone_id][dir_id][group_id].items():
            if id == rider_id:
                return rider
        return None

    def getGroupFromWaitDict(self, zone_id, dir_id, group_id):
        for id, group in self.__rider_wait_dict[zone_id][dir_id].items():
            if id == group_id:
                return group
        return None

    def getRequestNumberOfZone(self, zone_id):
        total_num = 0
        for dir_id in self.__rider_wait_dict[zone_id].keys():
            for group_id in self.__rider_wait_dict[zone_id][dir_id].keys():
                total_num += len(self.__rider_wait_dict[zone_id][dir_id][group_id])
        return total_num


    def showRiderServedDict(self):
        ret = "{"
        for rider_id in OrderedDict(sorted(self.__rider_serve_dict.items(), key=lambda t: t[0])).keys():
            ret=ret+str(rider_id)+", "
        ret=ret+"}"
        return ret

    def getRiderFromServedDict(self, rider_id):
        for id, rider in self.__rider_serve_dict.items():
            if id == rider_id:
                return rider
        return None

    def showRiderFinishedDict(self):
        ret = "{"
        for rider_id in OrderedDict(sorted(self.__rider_finish_dict.items(), key=lambda t: t[0])).keys():
            ret = ret + str(rider_id) + ", "
        ret = ret + "}"
        return ret

    def getRiderFromFinishedDict(self, rider_id):
        for id, rider in self.__rider_finish_dict.items():
            if id == rider_id:
                return rider
        return None

    def showRiderCanceledDict(self):
        ret = "{"
        for rider_id in OrderedDict(sorted(self.__rider_cancel_dict.items(), key=lambda t: t[0])).keys():
            ret = ret + str(rider_id) + ", "
        ret = ret + "}"
        return ret

    def getRiderFromCanceledDict(self, rider_id):
        for id, rider in self.__rider_cancel_dict.items():
            if id == rider_id:
                return rider
        return None

    #put driver into Driver Dict at start
    def handleDriverIntoDict(self, driver):
        if isinstance(driver, Driver):
            if driver.getID() not in self.__driver_dict[driver.getPos()].keys():
                self.__driver_dict[driver.getPos()][driver.getID()] = driver
            else:
                self.__logger.error(Dispatcher.timestamp, "handleDriverRequest", driver.getID(), None, "Driver has been in the Pool.")
                raise Exception("Driver has been in the Pool.")
        else:
            self.__logger.error(Dispatcher.timestamp, "handleDriverRequest", None, None, "Driver's type is wrong.")
            raise Exception("Driver's type is wrong.")

    def handleRiderIntoDict(self, rider):
        if isinstance(rider, Rider):
            self.__cluster_strategy.cluster(rider)
        else:
            self.__logger.error(Dispatcher.timestamp, "handleRiderRequest", None, None, "Rider's type is wrong.")
            raise Exception("Rider's type is wrong.")

    def matchRidertoDriver(self):
        for zone_id in self.__rider_wait_dict.keys():
            for dir_id in self.__rider_wait_dict[zone_id].keys():
                for group_id in self.__rider_wait_dict[zone_id][dir_id].copy().keys():
                    driver = self.__match_strategy.match(zone_id)
                    if driver is not None:
                        self.__logger.info(Dispatcher.timestamp, "matchRidertoDriver", driver.getID(), None, "Driver be Chosen to Serve Riders.")
                        self.__logger.debug(Dispatcher.timestamp, "matchRidertoDriver", None, None, "Driver Zone ===> Rider Zone: ", str(driver.getPos()) + "===>" + str(zone_id))
                        # update driver status
                        driver.setRiders(self.__rider_wait_dict[zone_id][dir_id][group_id])
                        self.__driver_tracker.updateDriverStatusAfterMatching(driver)
                        self.__logger.debug(Dispatcher.timestamp, "matchRidertoDriver", driver.getID(), None, str(driver))

                        #update rider status
                        if len(self.__rider_wait_dict[zone_id][dir_id][group_id]) == 4:
                            self.grp_in_4 += 1
                        elif len(self.__rider_wait_dict[zone_id][dir_id][group_id]) == 3:
                            self.grp_in_3 += 1
                        elif len(self.__rider_wait_dict[zone_id][dir_id][group_id]) == 2:
                            self.grp_in_2 += 1
                        elif len(self.__rider_wait_dict[zone_id][dir_id][group_id]) == 1:
                            self.grp_in_1 += 1
                        else:
                            self.__logger.warning(Dispatcher.timestamp, "calcPoolingPerformanceInWaitDict", None, None, "Grp len is 0.")

                        for rider in self.__rider_wait_dict[zone_id][dir_id][group_id].values():
                            self.__rider_tracker.updateRiderStatusAfterMatching(rider)
                            self.__logger.debug(Dispatcher.timestamp, "matchRidertoDriver", driver.getID(), rider.getID(), str(rider))
                        del self.__rider_wait_dict[zone_id][dir_id][group_id]
                    else:
                        self.__logger.info(Dispatcher.timestamp, "matchRidertoDriver", None, None, "No Driver is available.")
                        break


    def updateDriverInDict(self):
        for zone_id in self.__driver_dict.keys():
            for driver in self.__driver_dict[zone_id].copy().values():
                if driver.getStatus() == IDLE:
                    self.__logger.info(Dispatcher.timestamp, "updateDriverStatus", driver.getID(), None, "Update Driver when IDLE.")
                    self.__driver_tracker.updateDriverStatusWhenIdle(driver, self.no_work_driver)
                elif driver.getStatus() == INSERVICE:
                    self.__logger.info(Dispatcher.timestamp, "updateDriverStatus", driver.getID(), None, "Update Driver Who is INSERVICE.")
                    self.__driver_tracker.updateDriverStatusWhenInService(driver, self.__rider_tracker)
                    self.__logger.debug(Dispatcher.timestamp, "updateDriverStatus", driver.getID(), None, str(driver))
                else:
                    self.__logger.error(Dispatcher.timestamp, "updateDriverStatus", driver.getID(), None, "Driver Status is Wrong.")
                    raise Exception("Driver Status is Wrong.")


    def updateRidersInWaitDict(self):
        for zone_id in self.__rider_wait_dict.keys():
            for dir_id in self.__rider_wait_dict[zone_id].keys():
                for group_id in self.__rider_wait_dict[zone_id][dir_id].copy().keys():
                    for rider in self.__rider_wait_dict[zone_id][dir_id][group_id].copy().values():
                        if rider.getStatus() == WAITING:
                            self.__rider_tracker.updateRiderStatusWhenWait(rider, self.wait_rider)
                            self.__rider_tracker.checkRiderStatusIfTimeOut(rider)

    def countTotalDriverNumber(self):
        total_len = 0
        for zone_id in self.__driver_dict.keys():
            total_len = total_len + len(self.__driver_dict[zone_id])
        return total_len

    def countDriverNumberEachZone(self):
        self.idle_driver_before_match[Dispatcher.timestamp] = [0]
        for zone_id in self.__driver_dict.keys():
            cnt=0
            for driver in self.__driver_dict[zone_id].values():
                if driver.getStatus() == IDLE:
                    cnt+=1
            self.idle_driver_before_match[Dispatcher.timestamp].append(cnt)

    def countRiderNumberInWaitDict(self):
        total_len = 0
        for zone_id in self.__rider_wait_dict.keys():
            for dir_id in self.__rider_wait_dict[zone_id].keys():
                for group_id in self.__rider_wait_dict[zone_id][dir_id].keys():
                    total_len = total_len + len(self.__rider_wait_dict[zone_id][dir_id][group_id])
        return total_len

    def countRiderNumberInServeDict(self):
        return len(self.__rider_serve_dict)

    def countRiderNumberInFinishDict(self):
        return len(self.__rider_finish_dict)

    def countRiderNumberInCancelDict(self):
        return len(self.__rider_cancel_dict)

    def countCurrentTotalRiderNumber(self):
        return self.countRiderNumberInWaitDict() + self.countRiderNumberInServeDict() + self.countRiderNumberInFinishDict() + self.countRiderNumberInCancelDict()

    def calcAverageProfitOfDrivers(self):
        totalProfit = 0
        for zone_id in self.__driver_dict.keys():
            for driver in self.__driver_dict[zone_id].values():
                totalProfit += driver.getTripProfit()
        return totalProfit / self.countTotalDriverNumber()

    def calcAverageIdleTimeOfDrivers(self):
        totalIdleTime = 0
        for zone_id in self.__driver_dict.keys():
            for driver in self.__driver_dict[zone_id].values():
                totalIdleTime += driver.getIdleTime()
        return totalIdleTime / self.countTotalDriverNumber()

    def calcAverageTripEffortOfDrivers(self):
        totalTripEffort = 0
        for zone_id in self.__driver_dict.keys():
            for driver in self.__driver_dict[zone_id].values():
                totalTripEffort += driver.getTripEffort()
        return totalTripEffort / self.countTotalDriverNumber()

    def calcAverageWaitTimeOfRiders(self):
        totalWaitTime = 0
        riders = {**self.__rider_serve_dict, **self.__rider_finish_dict, **self.__rider_cancel_dict}
        for rider in riders.values():
            totalWaitTime +=rider.getWaitTime()
        return totalWaitTime/(self.countRiderNumberInFinishDict()+self.countRiderNumberInServeDict()+self.countRiderNumberInCancelDict())

    def calcAverageDetourTimeOfRiders(self):
        totalDetourTime = 0
        riders = {**self.__rider_serve_dict, **self.__rider_finish_dict}
        for rider in riders.values():
            totalDetourTime += rider.getDetourTime()
        return totalDetourTime/(self.countRiderNumberInFinishDict()+self.countRiderNumberInServeDict())

    def calcAverageFareOfRiders(self):
        totalFare = 0
        riders = {**self.__rider_serve_dict, **self.__rider_finish_dict}
        for rider in riders.values():
            totalFare += rider.getPrice()
        return totalFare/(self.countRiderNumberInFinishDict()+self.countRiderNumberInServeDict())

    def calcAverageDefaultFareRiders(self):
        totalDefaultFare = 0
        riders = {**self.__rider_serve_dict, **self.__rider_finish_dict}
        for rider in riders.values():
            totalDefaultFare += rider.getDefaultPrice()
        return totalDefaultFare/(self.countRiderNumberInFinishDict()+self.countRiderNumberInServeDict())

    def calcAverageSatOfRiders(self):
        totalSat = 0
        riders = {**self.__rider_serve_dict, **self.__rider_finish_dict, **self.__rider_cancel_dict}
        for rider in riders.values():
            totalSat += rider.getSat()
        return totalSat/(self.countRiderNumberInFinishDict()+self.countRiderNumberInServeDict()+self.countRiderNumberInCancelDict())
Beispiel #22
0
 def __init__(self, riders, route):
     self.logger = Logger('RoutingStrategy')
     self.riders = riders
     self.route = route
 def __init__(self):
     self.__logger = Logger("RequestList")
     #self.__logger.setLevel(logging.INFO)
     self.__logger.info(RequestList.timestamp, "__INIT__", None, None,
                        "Create RequestList Object.")
     self.__items = []
class ClusteringStrategy(ABC):

    timestamp = -1

    def __init__(self, rider_waiting_dict):
        self.logger = Logger('ClusteringStrategy')
        # self.logger.setLevel(logging.DEBUG)
        self.logger.info(ClusteringStrategy.timestamp, "__INIT__", None, None,
                         "Initialize ClusteringStrategy")
        self.__assign_gid_dict = {}
        self.__rider_dict = rider_waiting_dict

        # Assign Group ID
        for zone_id in range(1, 78):
            self.__assign_gid_dict[zone_id] = {}
            for dir_id in range(-1, 12):
                self.__assign_gid_dict[zone_id][dir_id] = 1

    def showAssignGidDict(self):
        ret = "{"
        for zone_id in self.__assign_gid_dict.keys():
            ret = ret + str(zone_id) + ": {"
            for dir_id in self.__assign_gid_dict[zone_id].keys():
                ret = ret + str(dir_id) + ": [" + str(
                    self.__assign_gid_dict[zone_id][dir_id]) + "], "
            ret = ret + "}, \n"
        ret = ret + "}"
        return ret

    def getGroupID(self, zone_id, dir_id):
        return self.__assign_gid_dict[zone_id][dir_id]

    def tickGroupID(self, zone_id, dir_id):
        self.__assign_gid_dict[zone_id][dir_id] += 1

    def groupRiderByDir(self, rider, group_vulumn):
        # Rider's zone ID and dir ID
        zone_id = rider.getSrcZone()
        dir_id = rider.getDirID()
        group_id = self.getGroupID(zone_id, dir_id)

        # self.__rider_waiting_dict[rider.getSrcZone()][rider.getDirID()] is defaultdict(dict)
        # group_num is the dict
        if rider.getID(
        ) not in self.__rider_dict[zone_id][dir_id][group_id].keys():
            self.__rider_dict[zone_id][dir_id][group_id][rider.getID()] = rider
            rider.setGroupID(group_id)
        else:
            self.logger.error(ClusteringStrategy.timestamp, "groupRiderByDir",
                              None, rider.getID(),
                              "Rider has been in the Pool")

        # check how many riders in the zone&direction&group_num to determine group id
        rider_num = len(self.__rider_dict[zone_id][dir_id][group_id])
        # When the number of rider in group up to VEHICLE_CAPACITY
        if rider_num == group_vulumn:
            self.tickGroupID(zone_id, dir_id)

    @abstractmethod
    def cluster(self, rider):
        pass
Beispiel #25
0
 def sensor_status(self, value):
     if value in (Sensor.SENSOR_OK, Sensor.SENSOR_NOK):
         self._sensor_status = value
     else:
         Logger.err(f"Passed an unexpected value of sensor status: {value}.  Aborting.")
         sys.exit()
Beispiel #26
0
 def __init__(self, driver_dict):
     self.__logger = Logger("DriverStatusTracker")
     self.__driver_dict = driver_dict
class Driver:

    timestamp = -1

    def __init__(self, id, pCurr):
        # logger in Dispatcher
        self.__logger = Logger('Driver')
        #self.__logger.setLevel(logging.DEBUG)
        self.__logger.info(Driver.timestamp, "__INIT__", None, None,
                           "Create A Driver Object")

        self.__id = id
        self.__pos = pCurr

        self.__status = IDLE
        self.__riders = {}
        self.__trip_route = []
        self.__trip_effort = 0
        self.__trip_profit = 0
        self.__idle_time = 0
        self.__finish_trip_time = -1

    def __str__(self):
        ret = "{" + str(self.__id) + ", " + str(self.__pos) + ", " + str(
            self.__status) + ", " + str(self.__trip_effort) + ", "
        ret = ret + str(self.__trip_profit) + ", "
        ret = ret + "Riders: " + self.showRidersOnBoard() + ", "
        ret = ret + "Route: " + self.showTripRoute() + "}"
        return ret

    def showRidersOnBoard(self):
        ret = "["
        if len(self.__riders):
            for rider_id in OrderedDict(
                    sorted(self.__riders.items(), key=lambda t: t[0])).keys():
                ret = ret + rider_id + ", "
            ret = ret[0:len(ret) - 2] + "]"
        else:
            ret = ret + "]"
        return ret

    def showTripRoute(self):
        ret = "["
        if len(self.__trip_route):
            for elem in self.__trip_route:
                ret = ret + str(elem.getZoneID()) + ", "
            ret = ret[0:len(ret) - 2] + "]"
        else:
            ret = ret + "]"
        return ret

    def getID(self):
        return self.__id

    def setRiders(self, riders):
        for rider_id, rider in riders.items():
            self.__riders[rider_id] = rider

    def getRider(self, id):
        if id in self.__riders.keys():
            return self.__riders[id]
        else:
            self.__logger.error(Driver.timestamp, "getRider", self.getID(), id,
                                "Rider not in vehicle.")
            raise Exception("Rider not in vehicle.")

    def removeRider(self, id):
        if id in self.__riders.keys():
            del self.__riders[id]
        else:
            self.__logger.error(Driver.timestamp, "removeRider", self.getID(),
                                id, "Rider not in vehicle.")
            raise Exception("Rider not in vehicle.")

    def calcTripRoute(self):
        if len(self.__trip_route) == 0:
            route_strategy = RoutingInDistance(self.__riders,
                                               self.__trip_route)
            route_strategy.planRoute()
        else:
            self.__logger.error(Driver.timestamp, "calcTripRoute",
                                self.getID(), None, "Trip route is empty.")
            raise Exception("Trip route is empty.")

    def popTripRoute(self):
        if len(self.__trip_route) > 0:
            return self.__trip_route.pop(0)
        else:
            self.__logger.error(Driver.timestamp, "popTripRoute", self.getID(),
                                None, "Nothing to be poped.")
            raise Exception("Nothing to be poped.")

    def getTripRoute(self):
        return self.__trip_route

    #must calc route first
    def calcTripEffort(self):
        trip_time = 0
        trip_effort = 0
        pos = self.getPos()
        for elem in self.__trip_route:
            if Graph.queryTravelCost(pos, elem.getZoneID()) != 0:
                trip_effort = trip_effort + Graph.queryTravelCost(
                    pos, elem.getZoneID())
            else:
                trip_effort += 0.5
            trip_time = trip_time + Graph.queryTravelCost(
                pos, elem.getZoneID())
            elem.setEventTime(Driver.timestamp + trip_time)
            if elem.getEvent() == DROPOFF:
                rider = self.__riders[elem.getRiderID()]
                rider.setArrivalTimestamp(Driver.timestamp + trip_time)
                rider.calcDetourTime(
                    trip_time
                )  #detour time is b/w the rerquest accepted and arrive at destination.
            pos = elem.getZoneID()

        if trip_effort < 0:
            self.__logger.warning(Driver.timestamp, "calcTripEffort",
                                  self.getID(), None,
                                  "Trip effort value is unresonable ")
            raise Exception("Trip effort value is unresonable ")
        else:
            self.__trip_effort += trip_effort

    def tickTripEffort(self):
        self.__trip_effort += 1

    def getTripEffort(self):
        return self.__trip_effort

    def notifyRiderPrice(self):
        shared_number = len(self.__riders)
        for rider in self.__riders.values():
            rider.calcPrice(shared_number)

    #must calc route effort and rider price first
    def calcTripProfit(self):
        trip_revenue = 0
        if len(self.__riders) > 0:
            for rider in self.__riders.values():
                if rider.getPrice() is not math.inf:
                    trip_revenue += rider.getPrice()
                else:
                    self.__logger.error(Driver.timestamp, "calcTripEffort",
                                        self.getID(), None,
                                        "Price value is unresonable ")
                    raise Exception("Price value is unresonable ")
            self.__trip_profit += trip_revenue
        else:
            self.__logger.error(Driver.timestamp, "calcTripEffort",
                                self.getID(), None, "No riders in vehicle.")
            raise Exception("No riders in vehicle.")

    def getTripProfit(self):
        return self.__trip_profit

    def setPos(self, zid):
        self.__pos = zid

    def getPos(self):
        return self.__pos

    def setStatus(self, status):
        self.__status = status

    def getStatus(self):
        return self.__status

    def tickIdleTime(self):
        self.__idle_time += 1

    def getIdleTime(self):
        return self.__idle_time

    def setFinishTripTime(self, time):
        self.__finish_trip_time = time

    def getFinishTripTime(self):
        return self.__finish_trip_time