GPS requests interfering with another resulting in NAN values
helpmyRF24isntworking opened this issue · 4 comments
Minecraft Version
1.20.1
Version
1.19.2-1.101.1.jar
Details
GPS is not reliable when using many turtles/computers at the same time. When the server/client starts, all my turtles (20+) send an initial GPS request to initialize their position before continuing.
All those requests are sent at the same time. (within 0-10 ms of another)
This results in the gps responses overlapping and interfering with each other.
Instead of returning NIL, three NAN values are returned by gps.locate
Further explanaition and theoretical fix below the screenshots.
example 1:
receives duplicate responses from the same gps
example 2:
received only 3 responses somehow (shouldnt be possible because turtles cannot remove a message from another computers queue? -> perhaps timeout due to lag when loading the world)
example 3:
received responses from the same gps, only 3 total
example 4:
received only 2 responses
good example:
example of a turtle that correctly determined its position
out of 20 turtles around 5 turtles receive a faulty/nan position
To verify that the messages are being sent at the same time and overlap, an independent computer sniffed the gps messages.
As can be seen in the screenshot below, some ping requests and their corresponding responses overlap and are out of order, which explains the duplicate responses seen in the examples. Logically, the more turtles I add, the more gps errors occur.
I can avoid this in my code by checking for NAN values in addition to the nil check.
However the gps.locate function should at least return a nil value in this case instead of nan values.
A possible fix to avoid NAN values would be to send the gps responses directly to the requesting computer instead of "broadcasting" them on the CHANNEL_GPS to every computer currently listening for gps messages.
The reason for the gps response being sent to every computer is probably due to the ping request naming the CHANNEL_GPS as the replyChannel instead of its own like in rednet.send.
_-- Send a ping to listening GPS hosts
modem.transmit(CHANNEL_GPS, CHANNEL_GPS, "PING")_
should be
_-- Send a ping to listening GPS hosts
modem.transmit(CHANNEL_GPS, id_as_channel(), "PING")_
or something like that
However i am quite new to lua and modding in particular so there might well be a better solution.
The code for this project resulting in the error can be found in my github in /turtle/classMiner.lua function initPosition.
The project heavily relies on rednet and sends a few hundred rednet messages each second, so directional messaging is a must.
ComputerCraft
From reading CC:T code i believe this is same issue as reported in #1344 was already fixed with eef67a0 . If i am reading tags right, it was 1.104.0+
I see you are using older CC:T release of 1.101.1. As this fix is purely lua sided fix, you could implement in in your ingame by downloading latest version of gps.lua api and loading it on your turtles instead of build in one then seeing if it solves your issue? It only has to be done on client/turtle as fix is only in locate call so you don't need to change anything about gps hosts. Alternative soltution would be updating CC:T .
As a side note - it is possible to get this exact error with just 1 turtle and 4 gps servers by spamming gps.locate(), but its way more rare this way. The fix used here makes gps locate discard responses that are too close to each other and would result in NaN when put into trilateration logic.
After reading some other issues i realized that this once was implemented exactly this way but was changed in this Issue:
Anonymized GPS #341
SquidDev already mentioned that this could result in a possible conflict.
One problem I see with this is that there is now no guarantee that the received message is for this computer. It's possible that two computers will open the same channel, and thus receive conflicting information.
I feel a better solution would be to send and receive on
CHANNEL_GPS
, and then tag each message with a random "query id".
The mentioned but not implemented query id would be a suitable solution to solve both issues without conflicts.
I have to create a new testworld anyways so i might as well update to the newest version as well. I´ll give an update on it tomorrow. Thanks for the hint.