一个具备科研可验证性的 LoRa 多跳算法评估基线。

This commit is contained in:
sinlatansen
2026-02-25 20:14:45 +08:00
parent 8537331c6f
commit 5ee1a16574
18 changed files with 1704 additions and 47 deletions

View File

@@ -27,6 +27,7 @@ def deploy_nodes(
num_nodes: int = None,
area_size: float = None,
metrics_collector: MetricsCollector = None,
routing_type: str = "gradient",
) -> list:
"""
Deploy nodes randomly in the area.
@@ -37,6 +38,7 @@ def deploy_nodes(
num_nodes: Number of nodes (default from config)
area_size: Area size (default from config)
metrics_collector: Metrics collector for observability
routing_type: Type of routing ("gradient", "flooding", "random")
Returns:
List of Node objects
@@ -60,6 +62,7 @@ def deploy_nodes(
channel=channel,
is_sink=True,
metrics_collector=metrics_collector,
routing_type=routing_type,
)
nodes.append(sink)
@@ -75,6 +78,7 @@ def deploy_nodes(
y=y,
channel=channel,
metrics_collector=metrics_collector,
routing_type=routing_type,
)
nodes.append(node)
@@ -105,6 +109,7 @@ def run_simulation(
area_size: float = None,
sim_time: float = None,
seed: int = None,
routing_type: str = "gradient",
) -> dict:
"""
Run the LoRa network simulation.
@@ -114,6 +119,7 @@ def run_simulation(
area_size: Area size in meters
sim_time: Simulation time in seconds
seed: Random seed for reproducibility
routing_type: Type of routing ("gradient", "flooding", "random")
Returns:
Simulation results including metrics
@@ -140,7 +146,7 @@ def run_simulation(
if sim_time is None:
sim_time = config.SIM_TIME
nodes = deploy_nodes(env, channel, num_nodes, area_size, metrics)
nodes = deploy_nodes(env, channel, num_nodes, area_size, metrics, routing_type)
# Setup receive callbacks
setup_receive_callback(nodes, channel)
@@ -175,6 +181,21 @@ def run_simulation(
metrics.add_collision(channel.collision_count - initial_collisions)
# Get efficiency metrics from channel
efficiency = channel.get_efficiency_metrics()
# Calculate derived efficiency metrics
total_tx = efficiency["total_transmissions"]
total_received = len(metrics.metrics.received_packet_ids)
# TX cost: transmissions per successful delivery
tx_per_success = total_tx / total_received if total_received > 0 else float("inf")
# Airtime usage: percentage of simulation time
airtime_usage = (
(efficiency["total_airtime"] / sim_time * 100) if sim_time > 0 else 0
)
# Get results
results = {
"config": {
@@ -182,8 +203,20 @@ def run_simulation(
"area_size": area_size,
"sim_time": sim_time,
"seed": seed,
"routing_type": routing_type,
},
"metrics": metrics.get_metrics().get_summary(),
"efficiency": {
"total_transmissions": total_tx,
"total_airtime": round(efficiency["total_airtime"], 3),
"airtime_usage_percent": round(airtime_usage, 2),
"tx_per_success": round(tx_per_success, 2)
if tx_per_success != float("inf")
else -1,
"hello_transmissions": efficiency["hello_transmissions"],
"data_transmissions": efficiency["data_transmissions"],
"ack_transmissions": efficiency["ack_transmissions"],
},
"topology": [],
}
@@ -219,6 +252,7 @@ def main():
f"Area: {results['config']['area_size']}m x {results['config']['area_size']}m"
)
print(f"Simulation time: {results['config']['sim_time']}s")
print(f"Routing: {results['config']['routing_type']}")
print("\n--- Metrics ---")
metrics = results["metrics"]
@@ -226,10 +260,16 @@ def main():
print(f"Total received: {metrics['total_received']}")
print(f"Packet Delivery Ratio: {metrics['pdr']}%")
print(f"Average hops: {metrics['avg_hop']}")
print(f"Average retries: {metrics['avg_retries']}")
print(f"Convergence time: {metrics['convergence_time']}s")
print(f"Collisions: {metrics['collisions']}")
print("\n--- Efficiency Metrics ---")
eff = results["efficiency"]
print(f"Total transmissions: {eff['total_transmissions']}")
print(f"Total airtime: {eff['total_airtime']:.3f}s")
print(f"Airtime usage: {eff['airtime_usage_percent']:.2f}%")
print(f"TX per success: {eff['tx_per_success']}")
print("\n--- Topology ---")
for node_info in results["topology"]:
parent_str = (