View difference between Paste ID: qYUwj0LR and 0gsKnS4u
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
]]--