-
-
Notifications
You must be signed in to change notification settings - Fork 10
/
telemetry.clj
153 lines (125 loc) · 4.02 KB
/
telemetry.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
(ns iss-sim-auto-docking.telemetry
(:require [iss-sim-auto-docking.calc :as calc]
[clojure.string :as str]
[etaoin.keys :as k]
[etaoin.api :refer :all]
[clojure.math.numeric-tower :as math])
(:gen-class))
(def telem (atom {:x 200
:y 12
:z 30
:t (System/currentTimeMillis)}))
(def deg (new String "°"))
(def emptystr (new String ""))
(def poll-interval 150) ;; ms
;; Internal functions
(defn parse-delta
[delta]
(-> delta
(.split deg)
first
Float/parseFloat))
(defn parse-metric
"Parse a telemetry metric"
[metric metric-type]
(Float/parseFloat (str/replace metric (case metric-type
:roll-rate #" °/s"
:range #" m"
:vel #" m/s") emptystr)))
;; Roll
(defn get-roll-delta
"Get the roll displacement in degrees"
[driv]
(let [roll-delta-q (query driv {:css "#roll > div.error"})
roll-delta (get-element-text-el driv roll-delta-q)]
(parse-delta roll-delta)))
(defn get-roll-rate
"Get the roll rate in °/s"
[driv]
(let [roll-rate-q (query driv {:css "#roll > div.rate"})
roll-rate (get-element-text-el driv roll-rate-q)]
(parse-metric roll-rate :roll-rate)))
;; Pitch
(defn get-pitch-delta
"Get the pitch displacement in degrees"
[driv]
(let [pitch-delta-q (query driv {:css "#pitch > div.error"})
pitch-delta (get-element-text-el driv pitch-delta-q)]
(parse-delta pitch-delta)))
(defn get-pitch-rate
"docstring"
[driv]
(let [pitch-rate-q (query driv {:css "#pitch > div.rate"})
pitch-rate (get-element-text-el driv pitch-rate-q)]
(parse-metric pitch-rate :roll-rate)))
;; Yaw
(defn get-yaw-delta
""
[driv]
(let [yaw-delta-q (query driv {:css "#yaw > div.error"})
yaw-delta (get-element-text-el driv yaw-delta-q)]
(parse-delta yaw-delta)))
(defn get-yaw-rate
""
[driv]
(let [yaw-rate-q (query driv {:css "#yaw > div.rate"})
yaw-rate (get-element-text-el driv yaw-rate-q)]
(parse-delta yaw-rate)))
;; Distance
(defn get-range
"Get the Euclidian distance to the ISS in meters."
[driv]
(let [range (->> {:css "#range > div.rate"}
(query driv)
(get-element-text-el driv))]
(parse-metric range :range)))
(defn get-dist
"Get the distance to ISS on a given axis."
[driv axis]
(let [sel (str "#" axis "-range > div")
dist (->> {:css sel}
(query driv)
(get-element-text-el driv))]
(parse-metric dist :range)))
(defn get-approach-rate
"Get the approach rate relative to ISS."
[driv]
(let [v (->> {:css "#rate > div.rate"}
(query driv)
(get-element-text-el driv))]
(-> v
(parse-metric :vel)
(math/abs))))
(defn poll
"Poll telemetry and update the state."
[driv]
(if true ;; TODO add proper termination of telemetry poller by checking if driver is active
(do
(Thread/sleep poll-interval)
(let [t (System/currentTimeMillis)
dt (* (+ poll-interval (- t (@telem :t))) 0.001)
x (get-dist driv "x")
y (get-dist driv "y")
z (get-dist driv "z")
dx (- x (@telem :x))
dy (- y (@telem :y))
dz (- z (@telem :z))
vx (calc/get-vx dt dx)
vy (calc/get-vy dt dy)
vz (calc/get-vz dt dz)]
(swap! telem assoc
:roll (get-roll-delta driv)
:pitch (get-pitch-delta driv)
:yaw (get-yaw-delta driv)
:roll-rate (get-roll-rate driv)
:pitch-rate (get-pitch-rate driv)
:yaw-rate (get-yaw-rate driv)
:range (get-range driv)
:x x
:y y
:z z
:vx vx
:vy vy
:vz vz
:t (System/currentTimeMillis)))
(recur driv))))