This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
raineth's profile picture

Please expose gps.trilaterate and gps.narrow

Started by raineth, 19 January 2013 - 04:44 PM
raineth #1
Posted 19 January 2013 - 05:44 PM
Hello!

Please expose gps.trilaterate and gps.narrow in the GPS API.

I have an application where a wireless turtle is in regular contact with enough computers to enable location calculation. I can provide the computers' coordinates and distances myself, and I would like to do so to avoid broadcasting and waiting for responses. Right now, I have to copy trilaterate() and narrow() to my code because the methods aren't public, but I would much rather reuse the existing code.
1lann #2
Posted 19 January 2013 - 05:58 PM
Not public? They are

local function trilaterate( A, B, C )
local a2b = B.position - A.position
local a2c = C.position - A.position
 
if math.abs( a2b:normalize():dot( a2c:normalize() ) ) > 0.999 then
  return nil
end

local d = a2b:length()
local ex = a2b:normalize( )
local i = ex:dot( a2c )
local ey = (a2c - (ex * i)):normalize()
local j = ey:dot( a2c )
local ez = ex:cross( ey )
local r1 = A.distance
local r2 = B.distance
local r3 = C.distance
 
local x = (r1*r1 - r2*r2 + d*d) / (2*d)
local y = (r1*r1 - r3*r3 - x*x + (x-i)*(x-i) + j*j) / (2*j)
 
local result = A.position + (ex * x) + (ey * y)
local zSquared = r1*r1 - x*x - y*y
if zSquared > 0 then
  local z = math.sqrt( zSquared )
  local result1 = result + (ez * z)
  local result2 = result - (ez * z)
 
  local rounded1, rounded2 = result1:round(), result2:round()
  if rounded1.x ~= rounded2.x or rounded1.y ~= rounded2.y or rounded1.z ~= rounded2.z then
   return result1, result2
  else
   return rounded1
  end
end
return result:round()

end
local function narrow( p1, p2, fix )
local dist1 = math.abs( (p1 - fix.position):length() - fix.distance )
local dist2 = math.abs( (p2 - fix.position):length() - fix.distance )

if math.abs(dist1 - dist2) < 0.05 then
  return p1, p2
elseif dist1 < dist2 then
  return p1:round()
else
  return p2:round()
end
end
function locate( _nTimeout, _bDebug )
if _bDebug then
  print( "Finding position..." )
end
rednet.broadcast( "PING" )

local startTime = os.clock()
local timeOut = _nTimeout
local timeElapsed = 0

local tFixes = {}
local p1, p2 = nil
while timeElapsed < timeOut and (p1 == nil or p2 ~= nil) do
  local sender, message, distance = rednet.receive( timeOut - timeElapsed )
  if sender and distance then
   local result = textutils.unserialize( message )
   if type(result) == "table" and #result == 3 then
    local tFix = { id = sender, position = vector.new( result[1], result[2], result[3] ), distance = distance }
    if _bDebug then
	 print( tFix.distance.." metres from "..tostring( tFix.position ) )
    end
    table.insert( tFixes, tFix )
   
    if #tFixes >= 3 then
	 if not p1 then
	  p1, p2 = trilaterate( tFixes[1], tFixes[2], tFixes[#tFixes] )
	 else
	  p1, p2 = narrow( p1, p2, tFixes[#tFixes] )
	 end
    end
   end
  end
  timeElapsed = os.clock() - startTime
end

if p1 and p2 then
  if _bDebug then
   print( "Ambiguous position" )
   print( "Could be "..p1.x..","..p1.y..","..p1.z.." or "..p2.x..","..p2.y..","..p2.z )
  end
  return nil
elseif p1 then
  if _bDebug then
   print( "Position is "..p1.x..","..p1.y..","..p1.z )
  end
  return p1.x, p1.y, p1.z
else
  if _bDebug then
   print( "Could not determine position" )
  end
  return nil
end
end
Copied from mods/ComputerCraft1.48/lua/rom/apis/gps
Cranium #3
Posted 19 January 2013 - 06:07 PM
Those functions are not global, and as such, they can't be used outside of the API. I thought you would have known that…..
Bubba #4
Posted 19 January 2013 - 06:46 PM
Just make the functions global and you'll be able to use them just as you would any other api.
immibis #5
Posted 20 January 2013 - 03:07 PM
Just make the functions global and you'll be able to use them just as you would any other api.
The suggestion was to make the functions global. Does this mean you support it?
Bubba #6
Posted 20 January 2013 - 04:15 PM
Just make the functions global and you'll be able to use them just as you would any other api.
The suggestion was to make the functions global. Does this mean you support it?

The suggestion was to 'expose' the api functions, which I translated as the OP not being aware of how apis work and asking for Dan/Cloudy to do something which he/she could easily do themselves (If the OP does know how APIs work, then I apologize :)/> Looking back at it now, it seems to me more likely that the OP wants the change for server usage and actually does know what they are talking about.

I suppose I see no reason not to make the functions global seeing as how they are easily copy/pasted anyway.
raineth #7
Posted 20 January 2013 - 07:48 PM
I did say "I [had] to copy trilaterate() and narrow() to my code" :)/>

But yes, I'd like the functions to be global so that I can use them without copying them. If I end up distributing what I'm working on, that's 54 lines I don't need to reproduce.
1lann #8
Posted 20 January 2013 - 09:22 PM
Those functions are not global, and as such, they can't be used outside of the API. I thought you would have known that…..
I wasn't think that when he said public and to be exposed, that he meant he wanted the functions to be global.