达到“研究级技术报告”水准

This commit is contained in:
sinlatansen
2026-02-25 19:40:42 +08:00
parent d357a25076
commit 8537331c6f
3 changed files with 387 additions and 24 deletions

View File

@@ -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):