Skip to content

Conversation

RCGV1
Copy link
Member

@RCGV1 RCGV1 commented Sep 15, 2025

Currently, nodes that receive a packet with bad SNR are prioritized for retransmission, but they might not be the best transmitters, and their retransmissions might cancel out better clients. Therefore, I propose that we do not cancel a rebroadcast if we hear a bad SNR signal (for now, I chose worse than -4). Also, this change will help prevent bad routers from stopping retransmission, as a router with a bad transmitter will not be able to cancel the rebroadcast of a client. Based on preliminary simulator tests, this does create a higher delivery rate at the slight cost of more packets. The -4 number may need to be tuned in the future, and I am considering basing it on the current spreading factor.
Here is a scenario where this change could be useful (Also a testing scenario if anyone wants to try this change IRL)
image
In this scenario, the client can reach the recipient, but it will not retransmit the sender's packet because it heard another node go first. With my change, this will not happen, as the client will tell that the router has a bad SNR, either meaning it's far or it has a bad transmitter, so it rebroadcasts and delivers the packet to the recipient.

🤝 Attestations

  • I have tested that my proposed changes behave as described.
  • I have tested that my proposed changes do not cause any obvious regressions on the following devices:
    • Heltec (Lora32) V3
    • LilyGo T-Deck
    • LilyGo T-Beam
    • RAK WisBlock 4631
    • [ x ] Seeed Studio T-1000E tracker card
    • Other (please specify below)

@thebentern thebentern requested a review from GUVWAF September 15, 2025 10:45
@compumike
Copy link
Contributor

@RCGV1 Interesting -- I've had similar thoughts on this topic of "geographic diversity".

When deciding whether a CLIENT node should rebroadcast, currently the question is, "Have I heard anyone else rebroadcast this packet?"

But I think at a higher level, what we're trying to get at is, "Does it add value to the mesh for me to rebroadcast this packet?"

  • Positive value added is if the additional rebroadcast reaches more nodes that wouldn't have otherwise heard the packet.
  • Negative value if it only adds congestion without reaching additional nodes.

When I was penciling this out, I had one slight tweak: instead of just looking at p->rx_snr versus some absolute SNR cutoff, we might be able to look at the difference in SNR between the first time we heard the packet, versus the later copy: snr_difference = p->rx_snr - original_p->rx_snr.

  • If the second packet is significantly stronger than the first (i.e. say snr_difference > +4):
    • It's likely that the rebroadcast was closer to us than the original.
    • Our own rebroadcast would probably add relatively little value, as it would mostly be geographically overlapping with the rebroadcast we observed.
  • However, if the second packet is significantly weaker than the first (i.e. say snr_difference < -4):
    • then it's likely that the rebroadcast came from further away than the original (but still close enough for us to hear it).
    • In this case, it's much more likely that our rebroadcast would add geographic diversity, overlapping relatively little with the rebroadcast we heard.

I'm not sure what the cutoffs should be, or if it completely solves the case you proposed. But I think snr_difference could potentially be part of the heuristic for deciding whether to rebroadcast. And probably doesn't require too much to store the original rx_snr.

@wlockwood
Copy link

But I think at a higher level, what we're trying to get at is, "Does it add value to the mesh for me to rebroadcast this packet?"
Positive value added is if the additional rebroadcast reaches more nodes that wouldn't have otherwise heard the packet.

So much this! This is a fantastic reason to consider allowing neighbor info, even if it's just once a day. If I know roughly which nodes A can talk with, I can decide in a much more meaningful way whether transmitting helps

@GUVWAF
Copy link
Member

GUVWAF commented Sep 20, 2025

I've created this branch to test this with the discrete-event simulator. The SNR_THRESHOLD can be set in lib/config.py, and e.g. a value of -10000 mimics the current behaviour. Then you can run loraMesh.py as usual for different scenarios.

Initial results show indeed a higher channel utilization, but also a higher reach as the percentage of collisions is not changed a lot, see e.g.:
Current behaviour

Number of messages created: 160
Number of packets sent: 884 to 7956 potential receivers
Number of collisions: 741
Number of packets sensed: 3645
Number of packets received: 2878
Delay average (ms): 13597.52
Average Tx air utilization: 6.4 %
Percentage of packets that collided: 20.33
Average percentage of nodes reached: 92.36
Percentage of received packets containing new message: 46.21

SNR threshold of -4 dB

Number of messages created: 157
Number of packets sent: 993 to 8937 potential receivers
Number of collisions: 797
Number of packets sensed: 4049
Number of packets received: 3246
Delay average (ms): 16903.48
Average Tx air utilization: 7.22 %
Percentage of packets that collided: 19.68
Average percentage of nodes reached: 94.9
Percentage of received packets containing new message: 41.31

To test the SNR difference between the first received packet and the current one as suggested by @compumike, it should be as easy as changing this:
self.snrsReceived[packet.seq][-1] >= self.conf.SNR_THRESHOLD into something that considers self.snrsReceived[packet.seq][0] - self.snrsReceived[packet.seq][-1].

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants