one shot and other fixes
[swamp-bikeopera:code.git] / lib / gps.lua
1 -- Swamp Bike Opera embedded system for Kaffe Matthews
2 -- Copyright (C) 2012 Wolfgang Hauptfleisch, Dave Griffiths
3 --
4 -- This program is free software: you can redistribute it and/or modify
5 -- it under the terms of the GNU General Public License as published by
6 -- the Free Software Foundation, either version 3 of the License, or
7 -- (at your option) any later version.
8 --
9 -- This program is distributed in the hope that it will be useful,
10 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
11 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 -- GNU General Public License for more details.
13 --
14 -- You should have received a copy of the GNU General Public License
15 -- along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
17 module("gps", package.seeall)
18
19 require 'posix'
20 require 'socket'
21 require 'std'
22
23 local testing=true
24 local testing_pos={lat=41.147387819527,lng=-8.6317899816589}
25 --{lat=41.140157986104,lng=-8.6173141712656}
26 --{lat=51.04790318580878,lng=3.7287747859954834}
27 --{lat=51.04803133876788,lng=3.730437755584717}
28 -- {lat=50.1729952601643,lng=-5.106239318847656}
29 -- {lat=50.16647031001818,lng=-5.097473859786987}
30
31 local test_time=0
32
33 ---
34 -- convert wgs data to location
35 function wgs_to_dec(lat, sign1, lon, sign2)
36
37     local d,m,r = string.match(lat, "(%d%d)(%d%d).(%d%d%d%d)")
38     local s = ( 60 / 10000 ) * r
39     local lat_deg = d + (m/60) + (s/3600)
40
41     local d,m,r = string.match(lon, "(%d%d)(%d%d).(%d%d%d%d)")
42     local s = ( 60 / 10000 ) * r
43     local lon_deg = d + (m/60) + (s/3600)
44
45     if sign2 == "W" then
46        lon_deg = lon_deg * - 1
47     end
48
49     local file = io.open("/tmp/swamp_gps", "w")
50     if testing then
51         file:write(std.round(testing_pos.lat, 10).." "..
52                    std.round(testing_pos.lng, 10))
53
54         testing_pos.lat=testing_pos.lat+0.0001*math.cos(test_time)
55         --(math.random()-0.5)*0.0001
56         testing_pos.lng=testing_pos.lng+0.0001*math.sin(test_time)
57         --(math.random()-0.5)*0.0001
58
59         test_time=test_time+0.1
60     else
61         file:write(std.round(lat_deg, 10).." "..std.round(lon_deg, 10))
62     end
63
64     file:close()
65 end
66
67 --- main loop
68 --@param device number
69 function loop(device)
70     for line in io.open("/dev/ttyACM"..device):lines() do
71       local no, lat, sign1, lon, sign2  =
72           string.match(line, "GPGGA,(.-),(.-),(%w),(.-),(%w)")
73       if lat and sign1 then
74           wgs_to_dec(lat, sign1, lon, sign2)
75       end
76     end
77     return false
78 end
79
80 ---
81 --@return device number or false
82 function detect_device()
83     for i=0,20 do
84        if io.open("/dev/ttyACM"..i) then
85          return i
86        end
87     end
88     return false
89 end
90
91
92 ---
93 function startup()
94     posix.mkfifo("/tmp/swamp_gps")
95     while true do
96         local dev = detect_device()
97         if dev then
98             print("found gps device "..dev)
99             loop(dev)
100         else
101             print("no gps device found")
102             os.execute("sleep 5")
103         end
104     end
105 end