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 | ]]-- |