def _initialize_vehicle(self): vrec = journal.VehicleInfoRecord() vrec.vehicle_id = self.vehicle_id vrec.created_at = pyons.time() vrec.destroyed_at = None vrec.direction = self.direction vrec.lane = self.lane vrec.speed = self.speed vrec.n_read = 0 journal.Journal().write_vehicle_created(vrec) self._created_at = pyons.time() if self.front_tag is not None: self.front_tag.vehicle = self vrec.front_tag_epc = self.front_tag.epc vrec.front_tag_tid = self.front_tag.tid pyons.get_model().add_tag(self.front_tag) if self.back_tag is not None: self.back_tag.vehicle = self vrec.back_tag_epc = self.back_tag.epc vrec.back_tag_tid = self.back_tag.tid pyons.get_model().add_tag(self.back_tag) pyons.debug( f"created vehicle {self.vehicle_id} with " f"front tag epc={self.front_tag.epc if self.front_tag else '-'}, " f"back tag epc={self.back_tag.epc if self.back_tag else '-'}")
def update_transmitter_power(self, power): self._tx_power.append((pyons.time(), power)) received_power = self.channel.get_rx_power(sender=self.sender, receiver=self.receiver, tx_power=power) self._rx_power.append((pyons.time(), received_power)) if power is None or received_power is None: self.broken = True
def receive_finished(self, frame, rx_power, snr=None, ber=None): if frame is None: # pyons.fine("receive error {snr}{ber}".format( # snr=('' if snr is None else ' snr={:.2f}dB'.format(snr)), # ber=('' if ber is None else ' ber={:.2f}'.format(ber))), # sender=self.name) self._reply_timeout_id = pyons.create_timeout( gen2.max_t2(self.blf), Reader.REPLY_TIMEOUT_EVENT) return assert isinstance(frame, gen2.TagFrame) # pyons.fine("received: {reply}, power={power}dBm{snr}{ber}".format( # reply=frame.reply, power=rx_power, # snr=('' if snr is None else ' snr={:.2f}dB'.format(snr)), # ber=('' if ber is None else ' ber={:.2f}'.format(ber))), # sender=self.name) self._cancel_reply_timeout() self._cancel_delayed_send() self._last_rx_end = pyons.time() reply = frame.reply if isinstance(reply, gen2.Rn16Reply): self._handle_rn16_reply(reply) elif isinstance(reply, gen2.AckReply): self._handle_ack_reply(reply) elif isinstance(reply, gen2.ReqRnReply): self._handle_reqrn_reply(reply) elif isinstance(reply, gen2.ReadReply): self._handle_read_reply(reply) else: raise RuntimeError("reader doesn't support reply {}".format( type(reply)))
def build_channel_state_record(reader, tag, channel, tag_rx_power=None): r_trans = reader.transceiver t_trans = tag.transceiver rt_path_loss = channel.get_path_loss(r_trans, t_trans) tr_path_loss = channel.get_path_loss(t_trans, r_trans) if tag_rx_power is None: tag_rx_power = tag.received_power reader_rx_power = channel.get_rx_power(t_trans, r_trans, tr_path_loss) r_decider = r_trans.decider assert isinstance(r_decider, phy.ReaderDecider) reader_snr = r_decider.get_snr(reader_rx_power, tag.m, tag.preamble_duration, tag.blf) reader_ber = r_decider.get_ber(reader_snr) rec = journal.ChannelStateRecord() rec.timestamp = pyons.time() rec.reader_position = np.array(reader.antenna.position) rec.reader_side = reader.antenna.side rec.reader_lane = reader.antenna.lane rec.tag_position = np.array(tag.antenna.position) rec.tag_location = tag.location rec.tag_lane = tag.vehicle.lane if tag.vehicle is not None else None rec.tag_speed = tag.speed rec.channel_lifetime = channel.get_channel_lifetime() rec.tag_rx_power = tag_rx_power rec.reader_rx_power = reader_rx_power rec.reader_snr = reader_snr rec.reader_ber = reader_ber rec.rt_path_loss = rt_path_loss rec.tr_path_loss = tr_path_loss rec.vehicle_id = tag.vehicle_id return rec
def _vehicle_finalizer(self): t = pyons.time() journal.Journal().write_vehicle_destroyed(self.vehicle_id, t) if self.front_tag is not None: pyons.get_model().remove_tag(self.front_tag) if self.back_tag is not None: pyons.get_model().remove_tag(self.back_tag) pyons.get_model().remove_vehicle(self) pyons.debug(f"removed vehicle {self.vehicle_id}")
def _power_up(self): if self._state != Tag.State.OFF: return # 1) Updating state self._state = Tag.State.READY # 2) Updating sessions flags and SL dt = pyons.time() - self._last_power_down self._last_power_up = pyons.time() self._sessions[gen2.Session.S0] = gen2.InventoryFlag.A if dt > self.s1_persistence: self._sessions[gen2.Session.S1] = gen2.InventoryFlag.A if dt > self.s2_persistence: self._sessions[gen2.Session.S2] = gen2.InventoryFlag.A if dt > self.s3_persistence: self._sessions[gen2.Session.S3] = gen2.InventoryFlag.A if dt > self.sl_persistence: self._sl = False
def _handle_slot_start(self): # pyons.fine("start slot #{}".format(self._slot), sender=self.name) # STATISTICS ====> self.tag_read_data = self._create_tag_read_data() self._slot_started_at = pyons.time() # <===== END OF STATISTICS if not self.is_powered_on: raise RuntimeError("slot begin during power-off") qrep = gen2.QueryRep(session=self.session) self._send(qrep)
def _handle_round_end(self): # STATISTICS ====> assert isinstance(self.round_info, journal.InventoryRoundRecord) self.round_info.duration = pyons.time() - self._round_started_at self.round_info.min_slot_duration = np.min(self._slot_durations) self.round_info.max_slot_duration = np.max(self._slot_durations) self.round_info.avg_slot_duration = np.average(self._slot_durations) journal.Journal().write_inventory_round(self.round_info) self.round_info = None self._slot_durations = None # <===== END OF STATISTICS self._handle_round_start()
def _create_tag_read_data(self): trd = journal.TagReadRecord() trd.slot_index = self._slot trd.slot_timestamp = pyons.time() trd.reader_antenna_lane = self.antenna.lane trd.reader_antenna_side = self.antenna.side trd.round_index = self._round_index trd.epc = None trd.tid = None trd.vehicle_lane = None trd.location = None return trd
def _power_down(self): if self.state == Tag.State.OFF: return self._cancel_command_timeout() self._last_power_down = pyons.time() self.state = Tag.State.OFF self._slot = None self._rn = None self._m = None self._blf = None self._trext = None self._session = None
def _initialize(self): self._power_down() self.created_at = pyons.time() self._last_position_update = pyons.time() pyons.add_entity(self.transceiver) tag_info = journal.TagInfoRecord() tag_info.created_at = pyons.time() tag_info.vehicle_id = self.vehicle_id tag_info.epc = self.epc tag_info.tid = self.tid tag_info.location = self.location tag_info.antenna_forward_dir = np.array(self.antenna.dir_forward) tag_info.antenna_right_dir = np.array(self.antenna.dir_right) tag_info.antenna_gain = self.antenna.gain tag_info.antenna_polarization = self.antenna.polarization tag_info.antenna_rp = self.antenna.rp tag_info.sensitivity = self.sensitivity tag_info.lane = self.lane tag_info.n_epc_read = 0 tag_info.n_tid_read = 0 tag_info.modulation_loss = self.transceiver.modulation_loss journal.Journal().write_tag_created(tag_info)
def get_channel_lifetime(self, default=0.0): if self.use_doppler: if self.active_transceiver is None: return default elif self.active_transceiver.node is None: return default else: last_powered_on = self.active_transceiver.node.last_powered_on if last_powered_on is None or last_powered_on < 0: return default else: return pyons.time() - last_powered_on else: return default
def power_on(self): if self.is_powered_on: return # pyons.fine("powered on", sender=self.name) self._cancel_power_timeout() self._power = self.max_tx_power self._last_powered_on = pyons.time() self._inventory_flag = gen2.InventoryFlag.A self.transceiver.set_power(self._power) for transceiver in self.channel.passive_transceivers: transceiver.node.update_received_power() if self.power_on_interval is not None: self._power_off_timeout_id = pyons.create_timeout( self.power_on_interval, Reader.POWER_OFF_TIMEOUT_EVENT) self._handle_round_start()
def power_off(self): if not self.is_powered_on: return # pyons.fine("powered off", sender=self.name) self._power = None self._last_powered_off = pyons.time() self._inventory_flag = None self._cancel_power_timeout() self._cancel_delayed_send() self._cancel_reply_timeout() self.transceiver.set_power(None) self.transceiver.clear() for transceiver in self.channel.passive_transceivers: transceiver.node.update_received_power() if self.power_off_interval is not None: self._power_on_timeout_id = pyons.create_timeout( self.power_off_interval, Reader.POWER_ON_TIMEOUT_EVENT)
def _handle_slot_end(self): # STATISTICS ====> assert isinstance(self.tag_read_data, journal.TagReadRecord) assert isinstance(self.round_info, journal.InventoryRoundRecord) if self.tag_read_data.epc is not None: if self.tag_read_data.tid is not None: self.round_info.n_tid_reads += 1 else: self.round_info.n_epc_only_reads += 1 journal.Journal().write_tag_read(self.tag_read_data) pyons.info("** received tag: EPC={}, TID={}".format( self.tag_read_data.epc, self.tag_read_data.tid)) self._slot_durations.append(pyons.time() - self._slot_started_at) self.tag_read_data = None # <===== END OF STATISTICS self._slot += 1 if self._slot < 2**self.q: self._handle_slot_start() else: self._handle_round_end()
def _send(self, cmd): if isinstance(cmd, gen2.Query): preamble = gen2.ReaderFrame.Preamble(tari=self.tari, rtcal=self.rtcal, trcal=self.trcal) else: preamble = gen2.ReaderFrame.Sync(tari=self.tari, rtcal=self.rtcal) frame = gen2.ReaderFrame(preamble=preamble, cmd=cmd) # pyons.fine("send: {cmd}, duration={duration:.2f}us".format( # cmd=cmd, duration=frame.duration*1e6), sender=self.name) self._cancel_delayed_send() t2 = gen2.min_t2(self.blf) time_from_rx_end = pyons.time() - self._last_rx_end if time_from_rx_end >= t2: self.transceiver.send(frame) else: dt = t2 - time_from_rx_end self._delayed_send_timeout_id = pyons.create_timeout( dt, (Reader.DELAYED_SEND_EVENT, frame))
def update_position(self): dt = pyons.time() - self._last_position_update self.position += self.velocity * dt self._last_position_update = pyons.time()
def _vehicle_suicide(self): return pyons.time() - self._created_at > self.lifetime
def _finish(self): self._power_down() self.transceiver.clear() journal.Journal().write_tag_destroyed(self.epc, pyons.time()) pyons.remove_entity(self.transceiver)
def check_simulation_time(): return pyons.time() >= 100
def send_finished(self): self._last_tx_end = pyons.time() dt = gen2.max_t1(rtcal=self.rtcal, blf=self.blf) + gen2.t3() self._reply_timeout_id = pyons.create_timeout( dt, Reader.REPLY_TIMEOUT_EVENT)
def _handle_round_start(self): if not self.is_powered_on: raise RuntimeError("round start during power-off") self._round_index += 1 self._slot = 0 # # Switching antenna if needed # if self.rounds_per_antenna is not None and ( self._round_index % self.rounds_per_antenna == 0): n_antennas = len(self.antennas) self._antenna_index = (self._antenna_index + 1) % n_antennas # # Switching inventory flag if needed # if self.session_strategy == Reader.SessionStrategy.ALTER: if (self.rounds_per_inventory_flag is not None) and \ (self._round_index % self.rounds_per_inventory_flag == 0): self._inventory_flag = self._inventory_flag.invert() # pyons.fine(("\n\t*---------- NEW ROUND ------------*" # "\n\t* round index : {round_index}" # "\n\t* antenna index: {antenna_index}" # "\n\t* Q : {q}" # "\n\t* session : {session}" # "\n\t* target : {target}").format( # round_index=self._round_index, antenna_index=self._antenna_index, # q=self.q, session=self.session, target=self._inventory_flag), # sender=self.name) for transceiver in self.channel.passive_transceivers: transceiver.node.update_position() transceiver.node.update_received_power() # # Refresh statistics # # STATISTICS ====> self.tag_read_data = self._create_tag_read_data() self.round_info = self._create_round_info() self._slot_durations = [] self._slot_started_at = pyons.time() self._round_started_at = pyons.time() model = pyons.get_model() self.round_info.n_tags = len( [tag for tag in model.tags if tag.energized]) self.round_info.n_vehicles_registered = len(model.vehicles) self.round_info.antenna_index = self._antenna_index # <===== END OF STATISTICS # # Generating and sending Query # query = gen2.Query(dr=self.dr, m=self.m, trext=self.trext, sel=self.sl, session=self.session, target=self._inventory_flag, q=self.q) self._send(query)