예제 #1
0
    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 '-'}")
예제 #2
0
 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
예제 #3
0
    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)))
예제 #4
0
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
예제 #5
0
 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}")
예제 #6
0
    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
예제 #7
0
    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)
예제 #8
0
 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()
예제 #9
0
 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
예제 #10
0
 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
예제 #11
0
    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)
예제 #12
0
 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
예제 #13
0
 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()
예제 #14
0
 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)
예제 #15
0
 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()
예제 #16
0
    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))
예제 #17
0
 def update_position(self):
     dt = pyons.time() - self._last_position_update
     self.position += self.velocity * dt
     self._last_position_update = pyons.time()
예제 #18
0
 def _vehicle_suicide(self):
     return pyons.time() - self._created_at > self.lifetime
예제 #19
0
 def _finish(self):
     self._power_down()
     self.transceiver.clear()
     journal.Journal().write_tag_destroyed(self.epc, pyons.time())
     pyons.remove_entity(self.transceiver)
예제 #20
0
def check_simulation_time():
    return pyons.time() >= 100
예제 #21
0
 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)
예제 #22
0
    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)