def _do_disembark_pax_finish(self, pax, vehicle, cmd_msg_id): # Error if vehicle is not still parked in berth if not vehicle.is_parked_between(self.start_pos, self.end_pos, self.platform.track_segment): raise VehicleOutOfPositionError(vehicle, cmd_msg_id) # Move the passenger from the vehicle to the station vehicle.disembark(pax) pax.loc = self.station # Note if the passenger has arrived at final dest (may not be # the case with non-PRT systems) if self.station.ID == pax.dest_station.ID: pax.trip_end = Sim.now() pax.trip_success = True common.delivered_pax.add(pax) self.station._pax_arrivals_count += 1 self.station._all_passengers.append(pax) logging.info( "T=%4.3f %s delivered to platform %s in %s by %s (%d out of %d), disembarked in berth %s", Sim.now(), pax, self.platform.ID, self.station.ID, vehicle.ID, vehicle.get_pax_count(), vehicle.max_pax_capacity, self.ID) else: self.station.add_passenger(pax) self.station._arrivals_count += 1 # Notify that disembark of this passenger is complete end_msg = api.SimNotifyPassengerDisembarkEnd() end_msg.vID = vehicle.ID end_msg.sID = self.station.ID end_msg.platformID = self.platform.ID end_msg.pID = pax.ID end_msg.berthID = self.ID end_msg.time = Sim.now() common.interface.send(api.SIM_NOTIFY_PASSENGER_DISEMBARK_END, end_msg)
def _do_embark_pax_finish(self, pax, vehicle, cmd_msg_id): # Error if vehicle is not still parked in berth if not vehicle.is_parked_between(self.start_pos, self.end_pos, self.platform.track_segment): raise VehicleOutOfPositionError(vehicle, cmd_msg_id) # Move passenger's location to the vehicle vehicle.embark(pax) pax.loc = vehicle self.station._pax_departures_count += 1 self.station.remove_passenger(pax) pax.trip_boarded = Sim.now() logging.info( "T=%4.3f %s loaded into Vehicle %s (%d out of %d) at station %s, platform %s, berth %s ", Sim.now(), pax, vehicle.ID, vehicle.get_pax_count(), vehicle.max_pax_capacity, self.station.ID, self.platform.ID, self.ID) # Notify that embark of this passenger is complete end_msg = api.SimNotifyPassengerEmbarkEnd() end_msg.vID = vehicle.ID end_msg.sID = self.station.ID end_msg.platformID = self.platform.ID end_msg.pID = pax.ID end_msg.berthID = self.ID end_msg.time = Sim.now() common.interface.send(api.SIM_NOTIFY_PASSENGER_EMBARK_END, end_msg)
def launch(self): while True: print("Launch at %2.4f; wallclock: %2.4f" % (SimulationRT.now(), time.clock() - startTime)) yield SimulationRT.hold, self, uniform(1, maxFlightTime) print("Boom!!! Aaaah!! at %2.4f; wallclock: %2.4f" % (SimulationRT.now(), time.clock() - startTime))
def transmitPacket(self, sample): packet = Packet(txHost=self.source.host, txTime=simpy.now(), \ seqNumber=self.seqNumber, data=sample) self.seqNumber += 1 for i, sink in enumerate(self.source.sinks): newPacket = copy(packet) newPacket.rxHost = sink.host link = self.network.findLink(hostFrom=self.source.host, \ hostTo=sink.host) link.simTransmission(sink.receiver, newPacket) sink.session.transmittedPackets.append(newPacket) print "%7.4f Transmitting packet %1d: %s -> %s" % \ (simpy.now(), newPacket.seqNumber, newPacket.txHost.name, newPacket.rxHost.name)
def update(self): if self._last_update_time == Sim.now(): return self.pax_report.update() self.vehicle_report.update() self.station_report.update() self.power_report.update() self.summary_report.update(self.pax_report, self.vehicle_report, self.station_report, self.power_report) self._last_update_time = Sim.now()
def tick(self, nrTicks): oldratio = ratio for i in range(nrTicks): tLastSim = SimulationRT.now() tLastWallclock = SimulationRT.wallclock() yield SimulationRT.hold, self, 1 diffSim = SimulationRT.now() - tLastSim diffWall = SimulationRT.wallclock() - tLastWallclock print("now(): %s, sim. time elapsed: %s, wall clock elapsed: " "%6.3f, sim/wall time ratio: %6.3f" % (SimulationRT.now(), diffSim, diffWall, diffSim / diffWall)) if not ratio == oldratio: print("At simulation time %s: ratio simulation/wallclock " "time now changed to %s" % (SimulationRT.now(), ratio)) oldratio = ratio
def _request_vehicle(self, pos, loc): """Request that a vehicle be moved to pos on loc. The effect takes place immediately. To simulate a delay, see reserve_vehicle. """ v = None if len(self._storage_track.vehicles): v = self._storage_track.vehicles[0] v._move_to(pos, loc) v._operational_times.append((Sim.now(), True)) else: # create a new vehicle v_id = max(vehicle.ID for vehicle in common.vehicles.itervalues()) + 1 v = common.vehicle_models[self.model_name](ID=v_id, loc=loc, position=pos, vel=0) common.vehicles[v_id] = v common.vehicle_list.append(v) Sim.activate(v, v.ctrl_loop()) self._num_pending_exit -= 1 self._num_vehicles -= 1 assert 0 <= self._num_vehicles - self._num_pending_exit <= self.max_capacity return v
def add_events(self, evts): """PrtEvent objects should be contained in a iterable container.""" self.list.extend(evts) heapq.heapify(self.list) # If adding events during the sim, if self.active() or Sim.now() > 0: Sim.reactivate(self, prior=True)
def walk_time(self): # in seconds total = 0 for start, end in self._walk_times: if end is None: total += Sim.now() - start else: total += end - start return total
def ride_time(self): # in seconds total = 0 for start, end, vehicle in self._ride_times: if end is None: total += Sim.now() - start else: total += end - start return total
def walk(self, origin_station, dest_station, travel_time, cmd_msg, cmd_id): assert self._loc is origin_station assert travel_time >= 0 assert isinstance(cmd_msg, api.CtrlCmdPassengerWalk) assert isinstance(cmd_id, int) self.loc = None common.AlarmClock(Sim.now() + travel_time, self._post_walk, dest_station, cmd_msg, cmd_id)
def set_loc(self, loc): """Changes the loc, and keeps track of how much time is spent in each mode of transit: waiting, riding, or walking.""" ### Track time spent in each mode of transit ### if self._loc is None: # Was walking self._walk_times[-1][1] = Sim.now() elif hasattr(self._loc, 'vehicle_mass'): # was in vehicle self._ride_times[-1][1] = Sim.now() elif hasattr(self._loc, 'platforms'): # was at station self._wait_times[-1][1] = Sim.now() else: raise Exception("Unknown loc type") ### Note if trip is completed. ### if loc is self.dest_station: self._end_time = Sim.now() self.trip_success = True ### More time tracking ### if not self.trip_success: if loc is None: self._walk_times.append([Sim.now(), None]) elif hasattr(loc, 'vehicle_mass'): self._ride_times.append([Sim.now(), None, loc]) # isinstance(loc, BaseVehicle) elif hasattr(loc, 'platforms'): self._wait_times.append([Sim.now(), None, loc]) # isinstance(loc, TrackSegment) else: raise Exception("Unknown loc type") self._loc = loc
def run(self, data, txRate): print "%7.4f Starting transmitter: %s" % (simpy.now(), self.name) lastTx = -1000 for sample in data: time = sample[0] if time >= lastTx + txRate: lastTx = time self.transmitPacket(sample) yield simpy.hold, self, txRate
def _do_exit_storage(self, position, model_name, cmd_msg, cmd_msg_id): storage = self.station._storage_dict[model_name] storage._reserve_vehicle() self._busy = True yield self.station.storage_exit_delay vehicle = storage._request_vehicle(position, self.platform.track_segment) self._busy = False # Notify controller that vehicle exiting storage is done. cmd_complete = api.SimCompleteStorageExit() cmd_complete.msgID = cmd_msg_id cmd_complete.cmd.CopyFrom(cmd_msg) cmd_complete.time = Sim.now() vehicle.fill_VehicleStatus(cmd_complete.v_status) common.interface.send(api.SIM_COMPLETE_STORAGE_EXIT, cmd_complete) logging.info( "T=%4.3f Exit from Storage: Vehicle: %s, Berth: %s, Platform: %s, Station: %s", Sim.now(), vehicle.ID, self.ID, self.platform.ID, self.station.ID)
def _post_walk(self, dest_station, cmd_msg, cmd_id): """Updates stats, changes location, and sends a SimCompletePassengerWalk message. To be called once the walk is complete.""" assert self._loc is None self.loc = dest_station msg = api.SimCompletePassengerWalk() msg.msgID = cmd_id msg.cmd.CopyFrom(cmd_msg) msg.time = Sim.now() common.interface.send(api.SIM_COMPLETE_PASSENGER_WALK, msg)
def all_pax_wait_times(self): """Returns a list of wait times for all passengers, not just the current ones.""" times = [] for pax in self._all_passengers: for start, end, loc in pax._wait_times: if loc is self: if end is None: times.append(Sim.now() - start) else: times.append(end - start) return times
def curr_pax_wait_times(self): """Returns a list of wait times for passengers currently waiting in the station.""" times = [] for pax in self._passengers: for start, end, loc in pax._wait_times: if loc is self: if end is None: times.append(Sim.now() - start) else: times.append(end - start) return times
def update_statusbar(self, evt): if not common.sim_ended: # calc some passenger stats pax_waiting = 0 total_wait = 0 max_wait = 0 trip_success = 0 trip_failed = 0 for stat in common.station_list: # collected in 'seconds' for pax in stat._passengers: pax_waiting += 1 pax_wait = pax.wait_time # don't force it to calc the wait time twice total_wait += pax_wait max_wait = max(pax_wait, max_wait) for pax in stat._all_passengers: if pax.trip_success: trip_success += 1 else: trip_failed += 1 if pax_waiting == 0: pax_ave_wait = 0 else: pax_ave_wait = total_wait / pax_waiting # calc some vehicle stats seats_occupied = 0 vehicles_occupied = 0 total_vehicles = len(common.vehicles) total_seats = 0 for vehicle in common.vehicle_list: total_seats += vehicle.max_pax_capacity if vehicle.passengers: vehicles_occupied += 1 seats_occupied += len(vehicle.passengers) v_avail = total_vehicles - vehicles_occupied if total_vehicles > 0: v_pct_utilized = vehicles_occupied / total_vehicles * 100 else: v_pct_utilized = 0 if total_seats > 0: seats_pct_utilized = seats_occupied / total_seats * 100 else: seats_pct_utilized = 0 self.statusbar.SetFields([ 'SimTime: %.3f RealTime: %.3f' % (SimPy.now(), time.time() - self.start_time), # timers 'PAX Waiting: %d Avg: %.1f Max: %.1f Trips: done %d active %d' % (pax_waiting, pax_ave_wait / 60, max_wait / 60, trip_success, trip_failed), # report in minutes 'VEHICLES Avail: %d %%Utilized: %.1f %%Seats Utilized: %.1f' % (v_avail, v_pct_utilized, seats_pct_utilized) ])
def validate_spline(self, spline): """A simple check that the message data is not malformed. See: vehicle._validate_spline for more thorough testing of the resulting cubic_spline.CubicSpline object. """ assert isinstance(spline, api.Spline) # Check that the times for the spline are in non-decreasing order if len(spline.times) == 0: raise common.InvalidTime(0) for t1, t2 in pairwise(spline.times): if t2 < t1: logging.info("T=%4.3f Spline times are not in non-decreasing order: %s", Sim.now(), spline.times) raise common.InvalidTime(t2)
def spawn_events(self): while True: try: while self.list[0].time <= Sim.now(): evt = heapq.heappop(self.list) if isinstance(evt, Passenger): assert not common.passengers.get(evt.ID) common.passengers[evt.ID] = evt # add to common dict evt.loc = evt.src_station # set pax loc evt.loc.add_passenger(evt) msg = api.SimEventPassengerCreated() evt.fill_PassengerStatus(msg.p_status) msg.time = Sim.now() common.interface.send(api.SIM_EVENT_PASSENGER_CREATED, msg) else: raise NotImplementedError if self.list[0].time > Sim.now(): yield Sim.hold, self, self.list[0].time - Sim.now() except IndexError: yield Sim.passivate, self # will be reactivated if new items added
def _do_embark(self, vehicle, passengers, cmd_msg, cmd_msg_id): self._busy = True while passengers: pax = passengers.pop() self._do_embark_pax_start(pax, vehicle, cmd_msg_id) yield pax.load_delay self._do_embark_pax_finish(pax, vehicle, cmd_msg_id) self._busy = False # Notify controller that all passenger embarkments are done. cmd_complete = api.SimCompletePassengersEmbark() cmd_complete.msgID = cmd_msg_id cmd_complete.cmd.CopyFrom(cmd_msg) cmd_complete.time = Sim.now() common.interface.send(api.SIM_COMPLETE_PASSENGERS_EMBARK, cmd_complete)
def __init__(self, ID, label, track_segments, storage_entrance_delay, storage_exit_delay, storage_dict): traits.HasTraits.__init__(self) self.ID = ID self.label = label self.platforms = [] self.track_segments = track_segments self.storage_entrance_delay = storage_entrance_delay self.storage_exit_delay = storage_exit_delay # Keyed by the VehicleModel name (string) with FIFO queues as the values. self._storage_dict = storage_dict self._pax_arrivals_count = 0 self._pax_departures_count = 0 self._pax_times = [(Sim.now(), len(self._passengers)) ] # elements are (time, num_pax) self._all_passengers = []
def _store_vehicle(self, vehicle): """Request that vehicle be moved into storage. The effect takes place immediately. To simulate a delay, see reserve_slot """ assert vehicle.model_name == self.model_name assert abs(vehicle.vel ) < 0.1 # loose sanity check, vehicle should be stopped. try: pos = self._storage_track.vehicles[ 0].pos + vehicle.length + 1 # arbitrary 1 meter spacing except IndexError: pos = vehicle.length + 1 vehicle._move_to(pos, self._storage_track) vehicle._operational_times.append((Sim.now(), False)) self._num_pending_entry -= 1 self._num_vehicles += 1 assert 0 <= self._num_pending_entry + self._num_vehicles <= self.max_capacity
def _do_disembark_pax_start(self, pax, vehicle, cmd_msg_id): # Error if vehicle not parked in berth if not vehicle.is_parked_between(self.start_pos, self.end_pos, self.platform.track_segment): raise VehicleOutOfPositionError(vehicle, cmd_msg_id) # Error if pax not in the vehicle if pax not in vehicle.passengers: raise PassengerNotAvailableError(pax, vehicle, cmd_msg_id) # Notify controller that disembark of this passenger is starting start_msg = api.SimNotifyPassengerDisembarkStart() start_msg.vID = vehicle.ID start_msg.sID = self.station.ID start_msg.platformID = self.platform.ID start_msg.pID = pax.ID start_msg.berthID = self.ID start_msg.time = Sim.now() common.interface.send(api.SIM_NOTIFY_PASSENGER_DISEMBARK_START, start_msg)
def _do_enter_storage(self, vehicle, cmd_msg, cmd_msg_id): if not vehicle.is_parked_between(self.start_pos, self.end_pos, self.platform.track_segment): raise VehicleOutOfPositionError(vehicle, cmd_msg_id) storage = self.station._storage_dict[vehicle.model_name] storage._reserve_slot() self._busy = True yield self.station.storage_entrance_delay if not vehicle.is_parked_between(self.start_pos, self.end_pos, self.platform.track_segment): raise VehicleOutOfPositionError(vehicle, cmd_msg_id) storage._store_vehicle(vehicle) self._busy = False # Notify controller that vehicle entering storage is done. cmd_complete = api.SimCompleteStorageEnter() cmd_complete.msgID = cmd_msg_id cmd_complete.cmd.CopyFrom(cmd_msg) cmd_complete.time = Sim.now() common.interface.send(api.SIM_COMPLETE_STORAGE_ENTER, cmd_complete)
class Series(SimulationRT.Process): def tick(self, nrTicks): oldratio = ratio for i in range(nrTicks): tLastSim = SimulationRT.now() tLastWallclock = SimulationRT.wallclock() yield SimulationRT.hold, self, 1 diffSim = SimulationRT.now() - tLastSim diffWall = SimulationRT.wallclock() - tLastWallclock print("now(): %s, sim. time elapsed: %s, wall clock elapsed: " "%6.3f, sim/wall time ratio: %6.3f" % (SimulationRT.now(), diffSim, diffWall, diffSim / diffWall)) if not ratio == oldratio: print("At simulation time %s: ratio simulation/wallclock " "time now changed to %s" % (SimulationRT.now(), ratio)) oldratio = ratio SimulationRT.initialize() ticks = 15 s = Series() SimulationRT.activate(s, s.tick(nrTicks=ticks)) c = Changer() SimulationRT.activate(c, c.change(5, 5)) c = Changer() SimulationRT.activate(c, c.change(10, 10)) ratio = 1 print("At simulation time %s: set ratio simulation/wallclock time to %s" % (SimulationRT.now(), ratio)) SimulationRT.simulate(until=100, real_time=True, rel_speed=ratio)
def ms_now(): """Return Sim.now() in integer form, rounded to milliseconds. This is the form that is used for communication with the Control modules.""" return int(round(Sim.now()*1000))
def handle_msg(self): """Expects a numeric msg_type and a msg_str in the format specified by api.proto """ comm_idx, msg_type, msgID, msg_time, msg_str = self.receiveQ.get(block=True) if msg_time == ms_now(): try: # COMMANDS if msg_type == api.CTRL_RESUME: # No response, just resume Simulation msg = api.CtrlResume() msg.ParseFromString(msg_str) self.log_rcvd_msg( msg_type, msgID, msg_time, msg ) # Ignore Resume if ctrl hasn't seen latest msg from Sim if msg.last_sim_msgID == common.msg_id_widget.last_id(): # set the 'resume' that corresponds to the controller to True self.resume_list[comm_idx] = True ## logging.debug("Processed current resume. msgID:%s, msg_time:%s", msgID, msg_time ) else: pass ## logging.debug("Processed stale resume. msgID:%s, msg_time:%s", msgID, msg_time ) elif msg_type == api.CTRL_CMD_VEHICLE_TRAJECTORY: msg = api.CtrlCmdVehicleTrajectory() msg.ParseFromString(msg_str) self.log_rcvd_msg( msg_type, msgID, msg_time, msg ) v = self.get_vehicle(msg.vID) self.validate_spline(msg.spline) v.process_spline_msg(msg.spline ) elif msg_type == api.CTRL_CMD_VEHICLE_ITINERARY: msg = api.CtrlCmdVehicleItinerary() msg.ParseFromString(msg_str) self.log_rcvd_msg( msg_type, msgID, msg_time, msg ) v = self.get_vehicle(msg.vID) if msg.clear: v.clear_path() self.validate_itinerary(v, msg.trackIDs) # raises InvalidTrackSegmentID if not valid locs = [self.get_trackSeg(id) for id in msg.trackIDs] if locs: v.extend_path(locs) elif msg_type == api.CTRL_CMD_SWITCH: msg = api.CtrlCmdSwitch() msg.ParseFromString(msg_str) self.log_rcvd_msg( msg_type, msgID, msg_time, msg ) ts = self.get_trackSeg(msg.trackID) next_ts = self.get_trackSeg(msg.nextID) # If not a valid track segment to switch to or it's already # switching, then complain. if next_ts not in common.digraph.neighbors(ts) or ts.next_loc is None: raise common.InvalidTrackSegID, msg.nextID ts.switch(next_ts, msgID) elif msg_type == api.CTRL_CMD_PASSENGERS_EMBARK: msg = api.CtrlCmdPassengersEmbark() msg.MergeFromString(msg_str) self.log_rcvd_msg( msg_type, msgID, msg_time, msg ) v = self.get_vehicle(msg.vID) b = self.get_berth(msg.sID, msg.platformID, msg.berthID) passengers = map(self.get_passenger, msg.passengerIDs) if b.loading and not b.is_busy(): b.embark(v, passengers, msg, msgID) else: raise common.InvalidBerthID, b elif msg_type == api.CTRL_CMD_PASSENGERS_DISEMBARK: msg = api.CtrlCmdPassengersDisembark() msg.MergeFromString(msg_str) self.log_rcvd_msg( msg_type, msgID, msg_time, msg ) v = self.get_vehicle(msg.vID) b = self.get_berth(msg.sID, msg.platformID, msg.berthID) passengers = map(self.get_passenger, msg.passengerIDs) if b.unloading and not b.is_busy(): b.disembark(v, passengers, msg, msgID) else: raise common.InvalidBerthID, b elif msg_type == api.CTRL_CMD_PASSENGER_WALK: msg = api.CtrlCmdPassengerWalk() msg.MergeFromString(msg_str) self.log_rcvd_msg( msg_type, msgID, msg_time, msg ) pax = self.get_passenger(msg.passengerID) origin = self.get_station(msg.origin_stationID) if origin is not pax.loc: raise common.InvalidStationID, msg.origin_stationID dest = self.get_station(msg.dest_stationID) travel_time = msg.travel_time if travel_time < 0: raise common.InvalidTime, travel_time pax.walk(origin, dest, travel_time, msg, msgID) elif msg_type == api.CTRL_CMD_STORAGE_ENTER: msg = api.CtrlCmdStorageEnter() msg.MergeFromString(msg_str) self.log_rcvd_msg( msg_type, msgID, msg_time, msg ) v = self.get_vehicle(msg.vID) b = self.get_berth(msg.sID, msg.platformID, msg.berthID) if b.storage_entrance and not b.is_busy() : b.enter_storage(v, msg, msgID) else: raise common.InvalidBerthID, b.ID elif msg_type == api.CTRL_CMD_STORAGE_EXIT: msg = api.CtrlCmdStorageExit() msg.MergeFromString(msg_str) self.log_rcvd_msg( msg_type, msgID, msg_time, msg ) try: model = common.vehicle_models[msg.model_name] except KeyError: raise common.MsgError b = self.get_berth(msg.sID, msg.platformID, msg.berthID) position = msg.position if b.storage_exit \ and not b.is_busy() \ and position - model.length >= b.start_pos \ and position <= b.end_pos: b.exit_storage(position, model.model_name, msg, msgID) else: raise common.InvalidBerthID(" bad berth %s busy %s veh_len %d berth %s station %s plat %s " % (b.ID, b.is_busy(), model.length, msg.berthID, msg.sID, msg.platformID)) # REQUESTS elif msg_type == api.CTRL_REQUEST_VEHICLE_STATUS: msg = api.CtrlRequestVehicleStatus() msg.ParseFromString(msg_str) self.log_rcvd_msg( msg_type, msgID, msg_time, msg ) v = self.get_vehicle(msg.vID) resp = api.SimResponseVehicleStatus() resp.msgID = msgID resp.time = Sim.now() v.fill_VehicleStatus(resp.v_status) self.send(api.SIM_RESPONSE_VEHICLE_STATUS, resp) elif msg_type == api.CTRL_REQUEST_STATION_STATUS: msg = api.CtrlRequestStationStatus() msg.ParseFromString(msg_str) self.log_rcvd_msg( msg_type, msgID, msg_time, msg ) stat = self.get_station(msg.sID) resp = api.SimResponseStationStatus() resp.msgID = msgID resp.time = Sim.now() stat.fill_StationStatus(resp.s_status) self.send(api.SIM_RESPONSE_STATION_STATUS, resp) elif msg_type == api.CTRL_REQUEST_PASSENGER_STATUS: msg = api.CtrlRequestPassengerStatus() msg.ParseFromString(msg_str) self.log_rcvd_msg( msg_type, msgID, msg_time, msg ) p = self.get_passenger(msg.pID) resp = api.SimResponsePassengerStatus() resp.msgID = msgID resp.time = Sim.now() p.fill_PassengerStatus(resp.p_status) self.send(api.SIM_RESPONSE_PASSENGER_STATUS, resp) elif msg_type == api.CTRL_REQUEST_SWITCH_STATUS: msg = api.CtrlRequestSwitchStatus() msg.ParseFromString(msg_str) self.log_rcvd_msg( msg_type, msgID, msg_time, msg ) sw = self.get_switch(msg.swID) resp = api.SimResponseSwitchStatus() resp.msgID = msgID resp.time = Sim.now() sw.fill_SwitchStatus(resp.sw_status) self.send(api.SIM_RESPONSE_SWITCH_STATUS, resp) elif msg_type == api.CTRL_REQUEST_TRACKSEGMENT_STATUS: msg = api.CtrlRequestTrackSegmentStatus() msg.ParseFromString(msg_str) self.log_rcvd_msg( msg_type, msgID, msg_time, msg ) ts = self.get_trackSeg(msg.eID) resp = api.SimResponseTrackSegmentStatus() resp.time = Sim.now() resp.msgID = msgID ts.fill_TrackSegmentStatus(resp.ts_status) self.send(api.SIM_RESPONSE_TRACKSEGMENT_STATUS, resp) # NOTIFICATIONS elif msg_type == api.CTRL_SETNOTIFY_TIME: msg = api.CtrlSetnotifyTime() msg.ParseFromString(msg_str) self.log_rcvd_msg( msg_type, msgID, msg_time, msg ) if utility.time_lt(msg.time, Sim.now()): raise common.InvalidTime, msg.time resp = api.SimNotifyTime() resp.msgID = msgID resp.time = msg.time alarm = common.AlarmClock(msg.time, self.send, api.SIM_NOTIFY_TIME, resp) elif msg_type == api.CTRL_SETNOTIFY_VEHICLE_POSITION: msg = api.CtrlSetnotifyVehiclePosition() msg.ParseFromString(msg_str) self.log_rcvd_msg( msg_type, msgID, msg_time, msg ) v = self.get_vehicle(msg.vID) # send error message if vehicle has already passed the notification pos # or if pos is beyond the end of the track if utility.dist_gt(v.pos, msg.pos) or utility.dist_gt(msg.pos, v.loc.length): raise common.InvalidPosition(msg.pos) try: v.notify_position(msg, msgID) except OutOfBoundsError: # Spline does not reach position raise common.InvalidPosition(msg.pos) elif msg_type == api.CTRL_SCENARIO_ERROR: msg = api.CtrlScenarioError() msg.ParseFromString(msg_str) self.log_rcvd_msg( msg_type, msgID, msg_time, msg ) logging.error("Controller reports the following Scenario Error: " + str(msg)) if not common.config_manager.get_disable_gui(): common.gui.GetTopWindow().show_message('Controller reports the following Scenario Error:\n' + msg.error_message) main.stop_sim() else: resp = api.SimUnimplemented() resp.msgID = msgID self.send(api.SIM_UNIMPLEMENTED, resp) logging.debug("Msg type %d received, but not yet implemented.", msg_type) except common.InvalidMsgType as e: logging.exception(e) err_msg = api.SimMsgHdrInvalidType() err_msg.msgID = msgID err_msg.msg_type = msg_type self.send(api.SIM_MSG_HDR_INVALID_TYPE, err_msg) logging.error("Received invalid msg type: %s", msg_type) common.errors += 1 except common.InvalidPosition as e: logging.exception(e) err_msg = api.SimMsgBodyInvalid() # TODO: Set up a specific msg type? err_msg.msgID = msgID self.send(api.SIM_MSG_BODY_INVALID, err_msg) except common.InvalidTrackSegID as e: logging.exception(e) err_msg = api.SimMsgBodyInvalidId() err_msg.msgID = msgID err_msg.id_type = api.TRACK_SEGMENT err_msg.ID = e.args[0] self.send(api.SIM_MSG_BODY_INVALID_ID, err_msg) except common.InvalidSwitchID as e: logging.exception(e) err_msg = api.SimMsgBodyInvalidId() err_msg.msgID = msgID err_msg.id_type = api.SWITCH err_msg.ID = e.args[0] self.send(api.SIM_MSG_BODY_INVALID_ID, err_msg) except common.InvalidStationID as e: logging.exception(e) err_msg = api.SimMsgBodyInvalidId() err_msg.msgID = msgID err_msg.id_type = api.STATION err_msg.ID = e.args[0] self.send(api.SIM_MSG_BODY_INVALID_ID, err_msg) except common.InvalidPlatformID as e: logging.exception(e) err_msg = api.SimMsgBodyInvalidId() err_msg.msgID = msgID err_msg.id_type = api.PLATFORM err_msg.ID = e.args[0] self.send(api.SIM_MSG_BODY_INVALID_ID, err_msg) except common.InvalidBerthID as e: logging.exception(e) err_msg = api.SimMsgBodyInvalidId() err_msg.msgID = msgID err_msg.id_type = api.BERTH err_msg.ID = e.args[0] self.send(api.SIM_MSG_BODY_INVALID_ID, err_msg) except common.InvalidVehicleID as e: logging.exception(e) err_msg = api.SimMsgBodyInvalidId() err_msg.msgID = msgID err_msg.id_type = api.VEHICLE err_msg.ID = e.args[0] self.send(api.SIM_MSG_BODY_INVALID_ID, err_msg) except common.InvalidPassengerID as e: logging.exception(e) err_msg = api.SimMsgBodyInvalidId() err_msg.msgID = msgID err_msg.id_type = api.PASSENGER err_msg.ID = e.args[0] self.send(api.SIM_MSG_BODY_INVALID_ID, err_msg) except common.InvalidTime as e: logging.exception(e) err_msg = api.SimMsgBodyInvalidTime() err_msg.msgID = msgID err_msg.time = e.args[0] self.send(api.SIM_MSG_BODY_INVALID_TIME, err_msg) except common.MsgRangeError as e: logging.exception(e) err_msg = api.SimMsgBodyInvalid() err_msg.msgID = msgID self.send(api.SIM_MSG_BODY_INVALID, err_msg) except common.MsgError: logging.exception(e) err_msg = api.SimMsgBodyInvalid() err_msg.msgID = msgID self.send(api.SIM_MSG_BODY_INVALID, err_msg) # if packet time is in future, set an alarm to wake up interface # at the time, and revive the message then. elif msg_time > ms_now(): common.AlarmClock(msg_time/1000.0, AlarmClock.delayed_msg, (comm_idx, msg_type, msgID, msg_time, msg_str)) else: # msg_time < ms_now() # This check should clearly go away once latency is introduced. err = api.SimMsgHdrInvalidTime() err.msgID = msgID err.msg_time = msg_time self.send(api.SIM_MSG_HDR_INVALID_TIME, err) logging.error("Time stamp for RCVD message %s type %s in the past. Stamp: %s Now: %s ", msgID, msg_type, msg_time, ms_now()) common.errors += 1 return msg_type
def run(self): station = common.stations[self.station_id] while True: # Unloading if self._unload: for pax in reversed(self.vehicle.passengers): self._unload = False self._busy = True yield Sim.hold, self, pax.unload_delay del self.vehicle.passengers[-1] # pax that left vehicle pax.loc = self.station pax.trip_end = Sim.now() if self.station_id == pax.dest_station.ID: pax.trip_success = True common.delivered_pax.add(pax) logging.info("T=%4.3f %s delivered to %s by %s. Unloaded in berth %s", Sim.now(), pax, self.station_id, self.vehicle, self.label) self._busy = False if station.passive(): Sim.reactivate(station, prior = True) # Loading elif self._load: for pax in self._pax: self._load = False self._busy = True s_notify = api.SimNotifyPassengerLoadStart() s_notify.vID = self.vehicle.ID s_notify.sID = self.station_id s_notify.pID = pax.ID common.interface.send(api.SIM_NOTIFY_PASSENGER_LOAD_START, s_notify) yield Sim.hold, self, pax.load_delay self.vehicle.passengers.append(pax) pax.trip_boarded = Sim.now() pax.loc = self.vehicle logging.info("T=%4.3f %s loaded into %s at station %s", Sim.now(), pax, self.vehicle, self.station_id) e_notify = api.SimNotifyPassengerLoadEnd() e_notify.vID = self.vehicle.ID e_notify.sID = self.station_id e_notify.pID = pax.ID common.interface.send(api.SIM_NOTIFY_PASSENGER_LOAD_END, e_notify) # If using the LOBBY policy, notify that passenger load command # has completed. if self._load_msgID: cmd_notify = api.SimCompletePassengerLoadVehicle() cmd_notify.msgID = self._msgID cmd_notify.vID = self.vehicle.ID cmd_notify.sID = self.station_id cmd_notify.pID = pax.ID common.interface.send(api.SIM_COMPLETE_PASSENGER_LOAD_VEHICLE, cmd_notify) self._load_msgID = None self._busy = False if station.passive(): Sim.reactivate(station, prior = True) else: assert not self._busy yield Sim.passivate, self
def receivePacket(self, packet): print "%7.4f Receiving packet %1d: %s -> %s" % \ (simpy.now(), packet.seqNumber, packet.txHost.name, packet.rxHost.name) self.plotter.time.append(simpy.now()) #self.plotter.data.append(simpy.now()) self.plotter.data.append(packet.data[1])