23 posts
Posted 14 November 2012 - 09:03 AM
I was reading about the GPS API and thinking about how I might utilize it and I thought of something. If you require four GPS hosts to pinpoint where you are located, might it also be possible to pinpoint your location from only one GPS host but with four readings from four different places? For example, you set up a GPS host somewhere and tell it is the origin (0,0,0). Then a new turtle could take a reading where it is at, move forward and take another reading, move up and take a third reading, and finally move right one block and take a fourth reading. Could it take into account these four distances as well as the fact of where these four readings took place in it's own local coordinates system to determine where it is and which way it is facing? Maybe a minimum of two hosts would be required. Anyone know more about math that could say anything on this?
Also, if turtles can determine where they are and then track their position as they move, they could act as GPS hosts themselves for other turtles or computers wanting to determine their location. Right now, though, it doesn't seem like turtles have the ability to do GPS hosting while doing something else at the same time. Maybe I don't know enough about how all this works yet, though. Seems natural that you would want turtles out and about and on the move to provide GPS hosting though. I'm surprised there isn't an API built in that lets you set the current position and direction and automatically tracks updates whenever the turtle moves.
1548 posts
Location
That dark shadow under your bed...
Posted 14 November 2012 - 09:39 AM
the first Idea is possible but more than incredibly hard to work out. you could just manipulate the existing trilateration system I guess.
as for the second idea it is easily possible. all of my turtles constantly work out where they are and their facing. I overwrote the turtle moving commands in the startup to make them change position/face as they move, then you coroutine a GPS host into the normal functioning
23 posts
Posted 14 November 2012 - 10:46 AM
Heh, it seems like trilateration is incredibly hard to work out too. I looked at the code for it a little and it seems pretty complex. But once done and working, it's powerful and useful. I would think it would be incredibly useful for players to be able to just set up one GPS host computer somewhere and just call a GPS API turtle function to allow it to work out it's position automatically. Maybe I will tackle this challange someday if I can figure out the math behind it.
I'm not very familiar with coroutine so could you explain it a little more? The wiki says not to use it if you can avoid it so not sure what to think. C programmers shouldn't use pointers if they can help it either unless they are knowledgable enough with them, right? Is coroutine basically like running a seperate thread or something in other languages? What should I know regarding using them as far as things to watch out for? I am an experienced programmer so you can go ahead and get technical with me if you want. :P/>/> Thanks.
1548 posts
Location
That dark shadow under your bed...
Posted 14 November 2012 - 12:20 PM
coroutines are Lua's way of imitating parallel threads without actually running them completely simultaneously. it runs one code until that code yields (or in other words waits for information like when you wait for an event to happen etc) and then runs the other code and swaps back and forth like that so fast that it isn't noticeable. in order to use them you must familiarise yourself with the yielding process
look through all of the code you have written or look through other code you understand. every time the coroutine.yield() function is called the program yields (this includes when it is used in other functions like os.pullEventRaw and that is used in os.pullEvent and that in turn is used in sleep and rednet.receive) if that program was running in a coroutine then that is where it would swap over to the next thread/coroutine
a coroutine is created with the code
var=coroutine.create(myfunction)
this creates a new coroutine that can be resumed. when we resume the coroutine it will continue to run 'myfunction' until it yields. you cannot include parameters in it yet
we resume it with the code
coroutine.resume(var,events)
and 'events' is returned by the coroutine.yield function in 'myfunction'
that last step confuses a lot of people (it used to confuse me) so I will include a working example here
Spoiler
local function myfunction(params)
print(params)
param1,param2,param3=os.pullEvent()
print(param2)
end
local var=coroutine.create(myfunction)
coroutine.resume(var,'THIS WILL BE PASSED TO PARAMS')
print('nwe will now sleep for 5 seconds so you can easily see where the code has paused')
sleep(5)
coroutine.resume(var,'ONE','TWO','THREE')
print('nCODE COMPLETED')
so we start by defining our function and turning it into a coroutine, then we resume it and whatever we put into coroutine.resume after var is passed as myfunction's arguments the first time, never again.
the code runs and prints out what we gave it in coroutine.resume and then when it wants an event it yields so it stops running, we pause our code for 5 seconds so you can see exactly where it stopped. then we call coroutine.resume again and whatever we give it after var is passed to coroutine.yield() this time (this will happen until the coroutine is done)
SO… that is the basics of how it works. in most applications of this you will want to include a while true loop in the function and pass all events directly to the coroutines. here is a final example of it actually in use to do two things simultaneously (I know you could probably make it all 1 neat code but this is just to help you understand)
Spoiler
local tRecorded={}
local function show()
while true do
local args={os.pullEvent()} –it is useful to capture all results of a function in a table so you don't miss any
term.clear()
term.setCursorPos(1,1)
local fullevt=args[1]
for i=2,#args do
fullevt=fullevt..' - '..args
end
print(fullevt)
end
end
local function record()
while true do
table.insert(tRecorded,{os.pullEvent()})
end
end
local co_one=coroutine.create(show)
local co_two=coroutine.create(record)
local evts={} –make an empty table at first so we can start the coroutines off
while true do
coroutine.resume(co_one,unpack(evts)) –pass the events from the os.pullEvent below into the coroutines so their os.pullEvents get the real events
coroutine.resume(co_two,unpack(evts))
evts={os.pullEvent()} –capture events to pass to the coroutines
end
hope I helped :o/>/>
FTR: you can actually put coroutines inside other ones etc to make things ridiculously complicated :)/>/>
EDIT: I was forced to use spoilers rather than code tags because I realised too late that you cannot colour code things within code tags :P/>/>
8543 posts
Posted 14 November 2012 - 02:25 PM
I was reading about the GPS API and thinking about how I might utilize it and I thought of something. If you require four GPS hosts to pinpoint where you are located, might it also be possible to pinpoint your location from only one GPS host but with four readings from four different places? For example, you set up a GPS host somewhere and tell it is the origin (0,0,0). Then a new turtle could take a reading where it is at, move forward and take another reading, move up and take a third reading, and finally move right one block and take a fourth reading. Could it take into account these four distances as well as the fact of where these four readings took place in it's own local coordinates system to determine where it is and which way it is facing? Maybe a minimum of two hosts would be required. Anyone know more about math that could say anything on this?
One host is insufficient, even with four moves. Two hosts is still insufficient to tell with complete certainty. Three gets you much closer, and may actually work, but this system is going to be far more work to code than it's worth.
1054 posts
Posted 14 November 2012 - 03:21 PM
Actually, I believe one host is enough. Look at it this way. You let the turtle move to 4 coordinates relative to the start position. This could be (-2,1,0), (2,1,0), (0,-1,-2) and (0,-1,2). That would be the setup you'd also use for a regular gps system, only then those 4 coordinates have a host each. The turtle could occupy those 4 coordinates and act like each of the simulated hosts (with the single computer as the client). This way he can determine the position of the single computer relative to it's own starting position (just like regular gps). So that's the relative position to (0,0,0). Now all you need to do is to subtract this relative position from the known position of the single computer (as vectors) and you have the absolute position of the turtle's location (the projected (0,0,0)).
Did I overlook something here?
8543 posts
Posted 14 November 2012 - 05:40 PM
That's not what was suggested. That's effectively four hosts, though not simultaneously, and one client, which then reports its location back to the host. The suggestion was one host and one client in four different positions. What you are now suggesting would theoretically work.
Edit: No, that still doesn't work, I think. You don't know which way you are facing, so you don't know where you are, just the relationship between the two points.
23 posts
Posted 14 November 2012 - 05:44 PM
I'm not sure, Orwell. I didn't quite understand that. But thinking about it, you can just use trilateration slightly differently.
Initially you don't know where you are or what direction you are facing. You do a GPS check and only get one answer from a GPS host. Now you know where it is and how far you are from it. So you are on some sphere that distance from that point. Or, to look at it differently, that GPS host is on a sphere the given radius from your position. Now if you move up some number of meters and GPS check again, you get a new distance to the host. Lets arbitrarily call our initial position origin and our new position <0,y,0> with y being how meters up we moved. The host is both on the sphere centered at <0,0,0> with radius 1 and on the sphere centered at <0,y,0> with radius 2. This should narrow our solution set to a circle in 3d space. Next we could move to <x,y,0> and check again, which I think should narrow it down enough to only one point in our solution set (ignoring accuracy errors).
I see what you are getting at now Orwell. You can trilaterate the position of the host in our local coordinate system and then just subtract from it's stated position to deterine our position. There is still the issue of determining what direction you are facing, though.
Isn't this just the trilateration principle only is a sort of reverse application? If so, I don't think it would be all that difficult to extend the GPS code to handle this.
724 posts
Posted 16 November 2012 - 05:52 AM
Two hosts would be enough. But each coord should be different.
23 posts
Posted 18 November 2012 - 06:50 AM
I'm currently working on a modified version of the GPS code (API and gps command) to try and test out my ideas.
I think I've got the principle figured out, though. It should be possible to work with only one host. Here is basically how it would work:
First, you put down your first computer or turtle. With no GPS hosts around it would just establish itself as the anchor for the coordinate system. You could just have it arbitrarily call it's position the origin (0, 0, 0).
Next, you'd put down a turtle somewhere in rednet range of our first host. At this point, we only know the distance to the host and where the host says it is. This is our first fix. We can then move up one and get another fix. We will get a new distance but the host will still say it is at (0, 0, 0). Thing is, movement is relative. The turtle moved, but from the turtle's perspective the host moved down one. So now you have a distance to a second point (0, -1, 0). You can probably see what I am getting at now. With the turlte getting fixes in 4 different locations, you can trilaterate your position from a single fixed host. The only complication is the fact that moving forward is different from moving up or down because you don't know what way the turtle is facing. But again, that is just relative too. Just as you arbitrarily set the origin position, you can also arbitrarily set the X and Z axes. So this turtle would become the second host and establishes axes.
With a third turtle now (or second turtle if the first host is a computer instead of a turtle) you should be able to establish your position with only two fixes I think. Trick here is that because you don't know which way the turtle is facing you just have to start with an internal, arbitrary axes system. Once you establish your position in that system, you can look at where the hosts say they are and compare it to where the turtle's internal coordinate system says they are to see if the axes line up or need to be rotated.
Anyway, once I get the code working and successfully prove all this theory works I'll post up update here. Just wanted to share for anyone this stuff might interest.
724 posts
Posted 20 November 2012 - 03:47 AM
Of course you can setup your own coords starting with zeros. The only problem to know turtle coords with one GPS host is starting direction. If program knows current direction it is easy to get own coords from one host only. (I want each turtle to have internal compass and chunkloader if on)