达到“研究级技术报告”水准
This commit is contained in:
@@ -273,6 +273,10 @@ class MetricsCollector:
|
||||
"""Record hop count for a packet."""
|
||||
self.metrics.hop_counts.append(hops)
|
||||
|
||||
def record_packet_received(self, src: int, seq: int):
|
||||
"""Record a packet received at sink (for PDR calculation)."""
|
||||
self.metrics.received_packet_ids.add((src, seq))
|
||||
|
||||
# =========================================================================
|
||||
# Channel Utilization Tracking
|
||||
# =========================================================================
|
||||
|
||||
@@ -208,11 +208,15 @@ class Node:
|
||||
# If we're the sink, receive the packet
|
||||
if self.is_sink:
|
||||
self.stats.data_received += 1
|
||||
# print(f"[DEBUG] Sink received DATA from node {packet.src}, hop={packet.hop}, seq={packet.seq}")
|
||||
|
||||
# Record hop count for analysis
|
||||
# Record unique packet received (for PDR)
|
||||
if self.metrics_collector:
|
||||
# print(f"SINK received packet with hop={packet.hop}")
|
||||
self.metrics_collector.record_packet_received(packet.src, packet.seq)
|
||||
self.metrics_collector.record_hop_count(packet.hop)
|
||||
|
||||
# Send ACK back to source
|
||||
self._send_ack(packet.src, packet.seq)
|
||||
return
|
||||
|
||||
# If not sink, check if we should forward
|
||||
@@ -226,6 +230,19 @@ class Node:
|
||||
if next_hop is not None and next_hop != self.node_id:
|
||||
self._forward_data(packet)
|
||||
|
||||
def _send_ack(self, dst: int, seq: int):
|
||||
"""Send ACK packet to destination."""
|
||||
ack = Packet(
|
||||
type=PacketType.ACK,
|
||||
src=self.node_id,
|
||||
dst=dst,
|
||||
seq=seq,
|
||||
hop=0,
|
||||
payload=None,
|
||||
)
|
||||
# Send directly to the node (unreliable, no MAC queue)
|
||||
self.channel.transmit(ack, self.node_id)
|
||||
|
||||
def _process_ack(self, packet: Packet):
|
||||
"""Process received ACK packet."""
|
||||
if self.mac.ack_received(packet.seq):
|
||||
@@ -277,6 +294,10 @@ class Node:
|
||||
def mac_task(self):
|
||||
"""
|
||||
MAC layer task - handles sending queue and retries.
|
||||
|
||||
Simplified: No ACK waiting for DATA packets to improve throughput.
|
||||
ACK is still sent from sink but sender doesn't wait for it.
|
||||
This is more realistic for LoRa mesh where end-to-end ACK is problematic.
|
||||
"""
|
||||
while True:
|
||||
# Check if there's something to send
|
||||
@@ -294,29 +315,13 @@ class Node:
|
||||
self.channel.transmit(packet, self.node_id)
|
||||
self.mac.record_send()
|
||||
|
||||
# For DATA packets, wait for ACK
|
||||
if packet.is_data:
|
||||
# Start tracking for ACK
|
||||
self.mac.start_pending_ack(packet, dst)
|
||||
# For DATA packets, we don't wait for ACK
|
||||
# This is a simplification - in production, you'd want some form of
|
||||
# local ACK or implicit reliability through lower layers
|
||||
# The packet is either received or lost - no retry for simplicity
|
||||
pass
|
||||
|
||||
# Wait for ACK or timeout
|
||||
timeout = self.mac.calculate_ack_timeout(packet)
|
||||
|
||||
# Note: In this simplified model, ACK is handled
|
||||
# through the receive path. We just wait.
|
||||
yield self.env.timeout(timeout)
|
||||
|
||||
# Check if ACK received (would be in pending_acks)
|
||||
if packet.seq in self.mac.pending_acks:
|
||||
# No ACK, should retry
|
||||
if self.mac.should_retry(packet.seq):
|
||||
self.mac.increment_retry(packet.seq)
|
||||
# Re-enqueue for retry
|
||||
retry_pkt = self.mac.get_retry_packet(packet.seq)
|
||||
if retry_pkt:
|
||||
self.mac.enqueue(retry_pkt, dst)
|
||||
|
||||
# Nothing to do, wait a bit
|
||||
# Small wait to prevent busy loop
|
||||
yield self.env.timeout(0.1)
|
||||
|
||||
def send_packet(self, packet: Packet, dst: int):
|
||||
|
||||
Reference in New Issue
Block a user