SHOW:
|
|
- or go back to the newest paste.
| 1 | function getAccessPoints() | |
| 2 | - | -- Code by minecraft: montana_1 |
| 2 | + | |
| 3 | - | -- please send comments or questions to [email protected] with a subject I might read |
| 3 | + | |
| 4 | - | -- |
| 4 | + | |
| 5 | - | -- Description of code: |
| 5 | + | |
| 6 | - | -- This is a program written for use in minecraft with the mod "OpenComputers" |
| 6 | + | |
| 7 | - | -- This is the server side or host code for a single computer or possible micro-controller to broadcast |
| 7 | + | |
| 8 | - | -- a signal from a minimum of 4 (possibly more but not tested) access points containing there predetermined |
| 8 | + | |
| 9 | - | -- co-ordinates which are entered into the program upon first run and saved in a file for later use. |
| 9 | + | |
| 10 | - | -- The co-ordinates can then be determined by a client program from this information |
| 10 | + | |
| 11 | - | -- Note: |
| 11 | + | |
| 12 | - | -- Because the co-ordinates are calculated by the distance from each access point, |
| 12 | + | |
| 13 | - | -- it is very important that all other access points within range are set to NOT REPEAT. |
| 13 | + | |
| 14 | - | -- Which by default is ON. If you do not know how to change this, there is another program |
| 14 | + | |
| 15 | - | -- on my pastebin account (montana_1) that will first find all access points on a network |
| 15 | + | |
| 16 | - | -- and second set there range to zero and turn Repeating OFF. This is good practice with any programs |
| 16 | + | |
| 17 | - | -- to turn the access points effectively off when not being immediately used to save power and |
| 17 | + | |
| 18 | - | -- prevent errors. |
| 18 | + | |
| 19 | - | -- Also Note: |
| 19 | + | |
| 20 | - | -- The timings for this program are set so that there are no processors placed within the access points |
| 20 | + | |
| 21 | - | ]]-- |
| 21 | + | |
| 22 | print(component.proxy(accessPoints[i]).isRepeater()) | |
| 23 | end | |
| 24 | end | |
| 25 | ||
| 26 | function testPointEquality(p1,p2) | |
| 27 | if(p1[2] == p2[2] and p1[3] == p2[3] and p1[4] == p2[4]) then | |
| 28 | return true | |
| 29 | else return false | |
| 30 | end | |
| 31 | end | |
| 32 | ||
| 33 | function getGPSCoordinates(timeOut) | |
| 34 | local computer = require("computer")
| |
| 35 | local timer = computer.uptime() | |
| 36 | while(computer.uptime() - timer < timeOut*4) do | |
| 37 | local event = require("event")
| |
| 38 | local points = {}
| |
| 39 | local eventType, recieverAddress, senderAddress, port, distenace, x,y,z = event.pull(timeOut, "modem_message") | |
| 40 | if(eventType ~= nil) then | |
| 41 | points[1] = {distenace, x,y,z}
| |
| 42 | --print(points[1][1]) | |
| 43 | else | |
| 44 | return nil | |
| 45 | end | |
| 46 | while #points < 4 and computer.uptime() - timer < timeOut*4 do | |
| 47 | local eventType, recieverAddress, senderAddress, port, distenace, x,y,z = event.pull(timeOut, "modem_message") | |
| 48 | local tmp = {distenace, x,y,z}
| |
| 49 | local same = false | |
| 50 | for i=1, #points do | |
| 51 | if(testPointEquality(points[i], tmp)) then | |
| 52 | same = true | |
| 53 | --print("Same point!")
| |
| 54 | break | |
| 55 | end | |
| 56 | end | |
| 57 | if(not same) then | |
| 58 | - | local t={} ; i=0
|
| 58 | + | points[#points+1] = tmp |
| 59 | --print("Point added:".. tostring(tmp[1]))
| |
| 60 | end | |
| 61 | end | |
| 62 | return points | |
| 63 | end | |
| 64 | end | |
| 65 | ||
| 66 | function split(inputstr, sep) | |
| 67 | if(inputstr == nil or inputstr == "") then | |
| 68 | return nil | |
| 69 | - | turnOffRepeaters(accessPoints) |
| 69 | + | |
| 70 | if sep == nil then | |
| 71 | sep = "," | |
| 72 | end | |
| 73 | - | if(#accessPoints+1 < 4) then |
| 73 | + | local t={} ; i=1
|
| 74 | - | print("Insuficient access_points, 4 are required you have (".. #accessPoints+1 ..")")
|
| 74 | + | |
| 75 | - | error() |
| 75 | + | |
| 76 | i = i + 1 | |
| 77 | end | |
| 78 | return t | |
| 79 | end | |
| 80 | ||
| 81 | function addVector(p1,p2) | |
| 82 | --p1 + p2 | |
| 83 | return {p1[1]+p2[1], p1[2]+p2[2], p1[3]+p2[3]}
| |
| 84 | end | |
| 85 | ||
| 86 | function subtractVector(p1,p2) | |
| 87 | --p1 - p2 | |
| 88 | return {p1[1]-p2[1], p1[2]-p2[2], p1[3]-p2[3]}
| |
| 89 | end | |
| 90 | ||
| 91 | function scaleVector(p1, scalar) | |
| 92 | --p1 * scalar | |
| 93 | return {p1[1]*scalar, p1[2]*scalar, p1[3]*scalar}
| |
| 94 | - | print("Enter coordinates (x,y,z) for access_point: " .. accessPoints[i])
|
| 94 | + | |
| 95 | - | local tmp = term.read() |
| 95 | + | |
| 96 | - | hostCoordinates[i] = split(accessPoints[i]..","..tmp,",") |
| 96 | + | function dotVector(p1,p2) |
| 97 | - | file:write(accessPoints[i]..","..tmp) |
| 97 | + | return p1[1]*p2[1] + p1[2]*p2[2] + p1[3]*p2[3] |
| 98 | end | |
| 99 | ||
| 100 | function crossVector(p1,p2) | |
| 101 | return {p1[2]*p2[3] - p1[3]*p2[2], p1[3]*p2[1] - p1[1]*p2[3], p1[1]*p2[2] - p1[2]*p2[1]}
| |
| 102 | end | |
| 103 | ||
| 104 | - | for i=0, #hostCoordinates do |
| 104 | + | function magnitudeVector(p1) |
| 105 | - | io.write(i..": "..hostCoordinates[i][0].." "..hostCoordinates[i][1]..","..hostCoordinates[i][2]..","..hostCoordinates[i][3]) |
| 105 | + | return math.sqrt(math.pow(p1[1], 2) + math.pow(p1[2], 2) + math.pow(p1[3], 2)) |
| 106 | - | component.setPrimary("access_point",hostCoordinates[i][0])
|
| 106 | + | |
| 107 | - | print("Primary set")
|
| 107 | + | |
| 108 | - | component.proxy(hostCoordinates[i][0]).setStrength(signal_strength) |
| 108 | + | function normalizeVector(p1) |
| 109 | - | component.modem.broadcast(gps_port, tonumber(hostCoordinates[i][1]),tonumber(hostCoordinates[i][2]),tonumber(hostCoordinates[i][3])) |
| 109 | + | return p1/magnitudeVector(p1) |
| 110 | - | os.sleep(0.25) |
| 110 | + | |
| 111 | - | component.getPrimary("access_point").setStrength(0)
|
| 111 | + | |
| 112 | - | os.sleep(1) |
| 112 | + | function rotateVectorZAxis(p1,theta) |
| 113 | return {p1[1]*math.cos(theta) - p1[2]*math.sin(theta), p1[1]*math.sin(theta) + p1[2]*math.cos(theta), p1[3]}
| |
| 114 | - | end |
| 114 | + | |
| 115 | ||
| 116 | function rotateVectorXAxis(p1,theta) | |
| 117 | return {p1[1], p1[2]*math.cos(theta) - p1[3]*math.sin(theta), p1[2]*math.sin(theta) + p1[3]*math.cos(theta)}
| |
| 118 | end | |
| 119 | ||
| 120 | function rotateVectorYAxis(p1,theta) | |
| 121 | return {p1[1]*math.cos(theta) + p1[3]*math.sin(theta), p1[2], p1[3]*math.cos(theta) - p1[1]*math.sin(theta)}
| |
| 122 | end | |
| 123 | ||
| 124 | function tostringVector(p1) | |
| 125 | return tostring(p1[1]) .. "," .. tostring(p1[2]) .. "," .. tostring(p1[3]) | |
| 126 | end | |
| 127 | ||
| 128 | function tonumberVector(p1) | |
| 129 | return {tonumber(p1[1]), tonumber(p1[2]), tonumber(p1[3])}
| |
| 130 | end | |
| 131 | ||
| 132 | function distanceBetweenPoints(p1,p2) | |
| 133 | return math.sqrt(math.pow(p1[1]-p2[1],2) + math.pow(p1[2]-p2[2],2) + math.pow(p1[3]-p2[3],2)) | |
| 134 | end | |
| 135 | ||
| 136 | function findPossiblePoints2D(d1,p1,d2,p2) | |
| 137 | local distance = distanceBetweenPoints(p1,p2) | |
| 138 | local a = (math.pow(d1, 2) - math.pow(d2, 2) + math.pow(distance, 2)) / (2 * distance) | |
| 139 | --print(a) | |
| 140 | local intersect = addVector(p1,scaleVector(scaleVector(subtractVector(p2,p1), a), (1/distance))) | |
| 141 | --print(tostringVector(intersect)) | |
| 142 | local h = math.sqrt(math.pow(d1, 2) - math.pow(a, 2)) | |
| 143 | --print(h) | |
| 144 | local x_plus = intersect[1] + ((h*(p2[2]-p1[2]))/distance) | |
| 145 | local x_minus = intersect[1] - ((h*(p2[2]-p1[2]))/distance) | |
| 146 | local y_plus = intersect[2] + ((h*(p2[1]-p1[1]))/distance) | |
| 147 | local y_minus = intersect[2] - ((h*(p2[1]-p1[1]))/distance) | |
| 148 | return {x_plus,y_minus,0}, {x_minus,y_plus,0}
| |
| 149 | end | |
| 150 | ||
| 151 | function findPossiblePoints3D(d1,p1,d2,p2,d3,p3) | |
| 152 | ||
| 153 | --print(tostringVector(p1)..";"..tostringVector(p2)..";"..tostringVector(p3)) | |
| 154 | ||
| 155 | --offset vectors such that p1 is at 0,0,0 | |
| 156 | local offset = scaleVector(p1, -1) | |
| 157 | --print("Offset: "..tostringVector(offset))
| |
| 158 | local p1p = addVector(p1, offset) | |
| 159 | --print("p1p: "..tostringVector(p1p))
| |
| 160 | local p2p = addVector(p2, offset) | |
| 161 | --print("p2p: "..tostringVector(p2p))
| |
| 162 | local p3p = addVector(p3, offset) | |
| 163 | --print("p3p: "..tostringVector(p3p))
| |
| 164 | ||
| 165 | --print("Offset vectors: "..tostringVector(p1p).."; "..tostringVector(p2p).."; "..tostringVector(p3p))
| |
| 166 | ||
| 167 | ||
| 168 | --find the equation of the plane | |
| 169 | local p12 = subtractVector(p2p,p1p) | |
| 170 | --print("p12: "..tostringVector(p12))
| |
| 171 | local p13 = subtractVector(p3p,p1p) | |
| 172 | --print("p13: "..tostringVector(p13))
| |
| 173 | local plane = crossVector(p12,p13) | |
| 174 | --print("Plane: "..tostringVector(plane))
| |
| 175 | ||
| 176 | -- checked up to here -- | |
| 177 | ||
| 178 | --rotate first about the y axis | |
| 179 | local angle1 = math.atan(plane[1]/plane[3]) | |
| 180 | --print("Angle1: "..angle1)
| |
| 181 | local plane_ry = rotateVectorYAxis(plane, angle1) | |
| 182 | --print("plane_ry: "..tostringVector(plane_ry))
| |
| 183 | local p1p_ry = rotateVectorYAxis(p1p, angle1) | |
| 184 | --print("p1p_ry: "..tostringVector(p1p_ry))
| |
| 185 | local p2p_ry = rotateVectorYAxis(p2p, angle1) | |
| 186 | --print("p2p_ry: "..tostringVector(p2p_ry))
| |
| 187 | local p3p_ry =rotateVectorYAxis(p3p, angle1) | |
| 188 | --print("p3p_ry: "..tostringVector(p3p_ry))
| |
| 189 | ||
| 190 | --rotate second about the x axis | |
| 191 | local angle2 = math.atan(plane_ry[2]/plane_ry[3]) | |
| 192 | --print("Angle2: "..angle2)
| |
| 193 | local plane_ryx = rotateVectorXAxis(plane_ry, angle2) | |
| 194 | --print("plane_ryx: "..tostringVector(plane_ryx))
| |
| 195 | local p1p_ryx = rotateVectorXAxis(p1p_ry, angle2) | |
| 196 | --print("p1p_ryx: "..tostringVector(p1p_ryx))
| |
| 197 | local p2p_ryx = rotateVectorXAxis(p2p_ry, angle2) | |
| 198 | --print("p2p_ryx: "..tostringVector(p2p_ryx))
| |
| 199 | local p3p_ryx = rotateVectorXAxis(p3p_ry, angle2) | |
| 200 | --print("p3p_ryx: "..tostringVector(p3p_ryx))
| |
| 201 | ||
| 202 | --at this point, the plane should lie such that all z=0 | |
| 203 | ||
| 204 | --rotate plane about the z axis such that p2 is at x = 0 | |
| 205 | local angle3 = (-1) * math.atan(p2p_ryx[2]/p2p_ryx[1]) | |
| 206 | --print("Angle3: "..angle3)
| |
| 207 | local plane_ryxz = rotateVectorZAxis(plane_ryx, angle3) | |
| 208 | local p1p_ryxz = rotateVectorZAxis(p1p_ryx, angle3) | |
| 209 | local p2p_ryxz = rotateVectorZAxis(p2p_ryx, angle3) | |
| 210 | local p3p_ryxz = rotateVectorZAxis(p3p_ryx, angle3) | |
| 211 | ||
| 212 | --at this point, p1 should be at 0,0,0; p2 should be such that y=0,z=0; and p3 should be such that z=0 | |
| 213 | ||
| 214 | --calculations for finding rotated, offset points | |
| 215 | local xp_ryxz = (math.pow(d1,2) - math.pow(d2,2) + math.pow(p2p_ryxz[1],2))/(2*p2p_ryxz[1]) | |
| 216 | local yp_ryxz = ((math.pow(d1,2) - math.pow(d3,2) + math.pow(p3p_ryxz[1],2) + math.pow(p3p_ryxz[2],2))/(2*p3p_ryxz[2])) - ((p3p_ryxz[1]/p3p_ryxz[2])*xp_ryxz) | |
| 217 | local z1p_ryxz = math.sqrt(math.pow(d1,2)-math.pow(xp_ryxz,2)-math.pow(yp_ryxz,2)) | |
| 218 | local z2p_ryxz = (-1) * math.sqrt(math.pow(d1,2)-math.pow(xp_ryxz,2)-math.pow(yp_ryxz,2)) | |
| 219 | ||
| 220 | --possible rotated, offset points | |
| 221 | local point1p_ryxz = {xp_ryxz, yp_ryxz, z1p_ryxz}
| |
| 222 | local point2p_ryxz = {xp_ryxz, yp_ryxz, z2p_ryxz}
| |
| 223 | ||
| 224 | --rotate back around the z axis | |
| 225 | plane_ryx = rotateVectorZAxis(plane_ryxz, (-1)*angle3) | |
| 226 | local point1p_ryx = rotateVectorZAxis(point1p_ryxz, (-1)*angle3) | |
| 227 | local point2p_ryx = rotateVectorZAxis(point2p_ryxz, (-1)*angle3) | |
| 228 | ||
| 229 | --rotate back around the x axis | |
| 230 | plane_ry = rotateVectorXAxis(plane_ryx, (-1)*angle2) | |
| 231 | local point1p_ry = rotateVectorXAxis(point1p_ryx, (-1)*angle2) | |
| 232 | local point2p_ry = rotateVectorXAxis(point2p_ryx, (-1)*angle2) | |
| 233 | ||
| 234 | --rotate back around the y axis | |
| 235 | plane = rotateVectorYAxis(plane_ry, (-1)*angle1) | |
| 236 | local point1p = rotateVectorYAxis(point1p_ry, (-1)*angle1) | |
| 237 | local point2p = rotateVectorYAxis(point2p_ry, (-1)*angle1) | |
| 238 | --print(tostringVector(plane)) | |
| 239 | ||
| 240 | --remove offset | |
| 241 | local point1 = addVector(point1p, scaleVector(offset,-1)) | |
| 242 | local point2 = addVector(point2p, scaleVector(offset,-1)) | |
| 243 | ||
| 244 | --print("Possible points are either: "..tostringVector(point1).." or "..tostringVector(point2))
| |
| 245 | return point1, point2 | |
| 246 | ||
| 247 | end | |
| 248 | ||
| 249 | function narrow(p1,p2,d4,p4) | |
| 250 | if(distanceBetweenPoints(p1,p4) == d4) then | |
| 251 | return p1 | |
| 252 | end | |
| 253 | if(distanceBetweenPoints(p2,p4) == d4) then | |
| 254 | return p2 | |
| 255 | end | |
| 256 | end | |
| 257 | ||
| 258 | function getLocation(timeout) | |
| 259 | local timeout = timeout or 2 | |
| 260 | local coords = getGPSCoordinates(timeout) | |
| 261 | if(coords == nil) then | |
| 262 | print("could not obtain")
| |
| 263 | return nil | |
| 264 | end | |
| 265 | if(#coords < 4) then | |
| 266 | print("Not enough points")
| |
| 267 | return nil | |
| 268 | end | |
| 269 | local d1 = coords[1][1] | |
| 270 | local p1 = {coords[1][2],coords[1][3],coords[1][4]}
| |
| 271 | local d2 = coords[2][1] | |
| 272 | local p2 = {coords[2][2],coords[2][3],coords[2][4]}
| |
| 273 | local d3 = coords[3][1] | |
| 274 | local p3 = {coords[3][2],coords[3][3],coords[3][4]}
| |
| 275 | local d4 = coords[4][1] | |
| 276 | local p4 = {coords[4][2],coords[4][3],coords[4][4]}
| |
| 277 | local point1, point2 = findPossiblePoints3D(d1,p1,d2,p2,d3,p3) | |
| 278 | local location = narrow(point1,point2,d4,p4) | |
| 279 | return location | |
| 280 | end | |
| 281 | ||
| 282 | local term = require("term")
| |
| 283 | local component = require("component")
| |
| 284 | local event = require("event")
| |
| 285 | local fileSystem = require("filesystem")
| |
| 286 | local shell = require("shell")
| |
| 287 | ||
| 288 | local accessPoints = getAccessPoints() | |
| 289 | local gps_port = 3665 | |
| 290 | local signal_strength = 400 | |
| 291 | local sleep = 0.001 | |
| 292 | local hostCoordinates = {}
| |
| 293 | ||
| 294 | component.modem.open(gps_port) | |
| 295 | ||
| 296 | if(fileSystem.exists(shell.resolve("gpsHostData"))) then
| |
| 297 | local file = io.open(shell.resolve("gpsHostData"), "r")
| |
| 298 | local i = 0 | |
| 299 | for line in io.lines(shell.resolve("gpsHostData")) do
| |
| 300 | hostCoordinates[i] = split(line,",") | |
| 301 | hostCoordinates = tonumberVector({hostCoordinates[i][2],hostCoordinates[i][3],hostCoordinates[i][4]})
| |
| 302 | print(line) | |
| 303 | i=i+1 | |
| 304 | end | |
| 305 | file:close() | |
| 306 | elseif(getLocation() ~= nil) then | |
| 307 | local location = getLocation() | |
| 308 | print(tostringVector(location)) | |
| 309 | local file = io.open(shell.resolve("gpsHostData"), "a")
| |
| 310 | local address = component.getPrimary("modem").address
| |
| 311 | file:write(tostring(address)..","..tostringVector(location)) | |
| 312 | print("File written")
| |
| 313 | file:close() | |
| 314 | hostCoordinates = location | |
| 315 | else | |
| 316 | local file = io.open(shell.resolve("gpsHostData"), "a")
| |
| 317 | print("Location data could not be obtained, please enter in (x,y,z) coords of modem: ")
| |
| 318 | local tmp = term.read() | |
| 319 | hostCoordinates = tonumberVector(split(tmp,",")) | |
| 320 | local address = component.getPrimary("modem").address
| |
| 321 | file:write(tostring(address)..","..tmp) | |
| 322 | print("File written")
| |
| 323 | file:close() | |
| 324 | end | |
| 325 | ||
| 326 | print(hostCoordinates[1]..type(hostCoordinates[1])) | |
| 327 | print(hostCoordinates[2]..type(hostCoordinates[2])) | |
| 328 | print(hostCoordinates[3]..type(hostCoordinates[3])) | |
| 329 | ||
| 330 | ||
| 331 | while true do | |
| 332 | component.modem.setStrength(signal_strength) | |
| 333 | component.modem.broadcast(gps_port, hostCoordinates[1], hostCoordinates[2],hostCoordinates[3]) | |
| 334 | os.sleep(sleep) | |
| 335 | end | |
| 336 | --[[ | |
| 337 | if(getLocation() == nil) then | |
| 338 | local location = getLocation() | |
| 339 | ||
| 340 | print("Location of this station has been found to be: "..location)
| |
| 341 | local file = io.open(shell.resolve("gpsHostData"), "a")
| |
| 342 | file:write(tostring(component.getPrimary("modem").address)..","..tostringVector(location))
| |
| 343 | hostCoordinates[0] = location | |
| 344 | else | |
| 345 | local file = io.open(shell.resolve("gpsHostData"), "a")
| |
| 346 | print("Enter coordinates (x,y,z) for modem: ")
| |
| 347 | local tmp = term.read() | |
| 348 | hostCoordinates[0] = split(tmp,",") | |
| 349 | file:write(tostring(component.getPrimary("modem").address)..","..tmp)
| |
| 350 | file:close() | |
| 351 | end | |
| 352 | ||
| 353 | component.modem.open(gps_port) | |
| 354 | while true do | |
| 355 | io.write(i..": "..hostCoordinates[i][0].." "..hostCoordinates[i][1]..","..hostCoordinates[i][2]..","..hostCoordinates[i][3]) | |
| 356 | component.modem.setStrength(signal_strength) | |
| 357 | component.modem.broadcast(gps_port, tonumber(hostCoordinates[0][1]),tonumber(hostCoordinates[0][2]),tonumber(hostCoordinates[0][3])) | |
| 358 | end | |
| 359 | ]]-- |