This repository has been archived by the owner on Oct 14, 2023. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmp.go
347 lines (291 loc) · 7.67 KB
/
mp.go
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
package main
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"log"
"net/http"
"strings"
)
/**
* Gets the current route ("Queue" of Waypoints) that constitute the path the drone is following, from Mission Planner
*
* Returns: - Pointer to a Queue struct containing Waypoints generated from the Waypoint data
* given in the response from Mission Planner
* - Error if anything goes wrong
*/
func GetQueue() (*Queue, error) {
var endpoint = getEnvVariable("MP_ROUTE") + "/queue"
req, err := http.NewRequest("GET", endpoint, nil)
req.Header.Set("Content-Type", "application/json")
if err != nil {
log.Fatal(err)
return nil, err
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
return nil, err
}
defer resp.Body.Close()
fmt.Println("response status:", resp.Status)
fmt.Println("response headers", resp.Header)
body, _ := io.ReadAll(resp.Body)
fmt.Println("response Body", string(body))
if resp.Status != "200 OK" {
return nil, errors.New("response not OK: " + resp.Status)
}
var queue []Waypoint
err = json.Unmarshal(body, &queue)
if err != nil {
log.Fatal(err)
return nil, err
}
return &Queue{Queue: queue}, nil
}
/**
* Overrides the current route ("Queue" of Waypoints) that the drone is following with a new Queue
*
* Param: queue - a pointer to a Queue struct containing the new sequence of Waypoints to follow
*
* Returns: - Error if anything goes wrong
*/
// take a pointer to a Queue struct and post those waypoints to MP
func PostQueue(queue *Queue) error {
var endpoint = getEnvVariable("MP_ROUTE") + "/queue"
fmt.Println("posting to endpoint: ", endpoint)
jsonString, err := json.Marshal(queue.Queue)
if err != nil {
log.Fatal(err)
return err
}
req, err := http.NewRequest("POST", endpoint, strings.NewReader(string(jsonString)))
req.Header.Set("Content-Type", "application/json")
if err != nil {
log.Fatal(err)
return err
}
request_body, _ := json.MarshalIndent(queue.Queue, "", " ")
fmt.Println("request body:\n", string(request_body))
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
return err
}
defer resp.Body.Close()
fmt.Println("response status:", resp.Status)
if b, err := io.ReadAll(resp.Body); err == nil {
fmt.Println(string(b))
}
if resp.Status != "200 OK" {
return errors.New("response not OK: " + resp.Status)
}
return nil
}
//TODO: Maybe follow singleton design pattern for AircraftStatus? -> make this method callable only on an instance
// of AircraftStatus struct
/**
* Gets the current aircraft status from Mission Planner
*
* Returns: - Pointer to an AircraftStatus struct with field info pulled from Mission Planner
* - Error if anything goes wrong
*/
func GetAircraftStatus() (*AircraftStatus, error) {
var endpoint = getEnvVariable("MP_ROUTE") + "/status"
req, err := http.NewRequest("GET", endpoint, nil)
req.Header.Set("Content-Type", "application/json")
if err != nil {
log.Fatal(err)
return nil, err
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
return nil, err
}
defer resp.Body.Close()
fmt.Println("response status:", resp.Status)
fmt.Println("response headers", resp.Header)
body, _ := io.ReadAll(resp.Body)
fmt.Println("response Body", string(body))
if resp.Status != "200 OK" {
return nil, errors.New("response not OK: " + resp.Status)
}
stat := AircraftStatus{}
err = json.Unmarshal(body, &stat)
if err != nil {
log.Fatal(err)
return nil, err
}
return &stat, nil
}
/**
* Locks the aircraft (prevent the aircraft from moving based on the MP queue)
*
* Returns: - Error if anything goes wrong (ex. if the aircraft is already locked)
*/
func LockAircraft() error {
var endpoint = getEnvVariable("MP_ROUTE") + "/lock"
req, err := http.NewRequest("GET", endpoint, nil)
req.Header.Set("Content-Type", "application/json")
if err != nil {
Error.Println(err)
return err
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
Error.Println(err)
return err
}
defer resp.Body.Close()
if resp.Status != "200 OK" {
Error.Println("Aircraft already locked: " + resp.Status)
return errors.New("Aircraft already locked: " + resp.Status)
}
return nil
}
/**
* Unlocks the aircraft (resume aircraft movement based on the MP queue)
*
* Returns: - Error if anything goes wrong (ex. if the aircraft is already unlocked)
*/
func UnlockAircraft() error {
var endpoint = getEnvVariable("MP_ROUTE") + "/unlock"
req, err := http.NewRequest("GET", endpoint, nil)
req.Header.Set("Content-Type", "application/json")
if err != nil {
Error.Println(err)
return err
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
Error.Println(err)
return err
}
defer resp.Body.Close()
if resp.Status != "200 OK" {
Error.Println("Aircraft already unlocked: " + resp.Status)
return errors.New("Aircraft already unlocked: " + resp.Status)
}
return nil
}
/**
* Send the aircraft back to the original launch site
*
* Returns: - Error if anything goes wrong
*/
func ReturnToLaunch() error {
var endpoint = getEnvVariable("MP_ROUTE") + "/rtl"
req, err := http.NewRequest("GET", endpoint, nil)
req.Header.Set("Content-Type", "application/json")
if err != nil {
Error.Println(err)
return err
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
Error.Println(err)
return err
}
defer resp.Body.Close()
if resp.Status != "200 OK" {
Error.Println("Failed to return to launch: " + resp.Status)
return errors.New("Failed to return to launch: " + resp.Status)
}
return nil
}
/**
* Immediately descend the aircraft and land over current position
*
* Returns: - Error if anything goes wrong
*/
func LandImmediately() error {
var endpoint = getEnvVariable("MP_ROUTE") + "/land"
req, err := http.NewRequest("GET", endpoint, nil)
req.Header.Set("Content-Type", "application/json")
if err != nil {
Error.Println(err)
return err
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
Error.Println(err)
return err
}
defer resp.Body.Close()
if resp.Status != "200 OK" {
Error.Println("Failed to land " + resp.Status)
return errors.New("Failed to land" + resp.Status)
}
return nil
}
/**
* Sets the 'home' waypoint of the aircraft
*
* Returns: - Error if anything goes wrong
*/
func PostHome(home *Waypoint) error {
var endpoint = getEnvVariable("MP_ROUTE") + "/home"
reqBody, err := json.Marshal(home)
if err != nil {
Error.Println(err)
return err
}
req, err := http.NewRequest("POST", endpoint, bytes.NewBuffer(reqBody))
req.Header.Set("Content-Type", "application/json")
if err != nil {
Error.Println(err)
return err
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
Error.Println(err)
return err
}
defer resp.Body.Close()
if resp.Status != "200 OK" {
Error.Println("Failed to set home: " + resp.Status)
return errors.New("Failed to set home: " + resp.Status)
}
return nil
}
func Takeoff(altitude float64) error {
var endpoint = getEnvVariable("MP_ROUTE") + "/takeoff"
jsonMap := map[string]interface{}{
"altitude": altitude,
}
reqBody, err := json.Marshal(jsonMap)
if err != nil {
Error.Println(err)
return err
}
req, err := http.NewRequest("POST", endpoint, bytes.NewBuffer(reqBody))
req.Header.Set("Content-Type", "application/json")
if err != nil {
Error.Println(err)
return err
}
fmt.Println(string(reqBody))
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
Error.Println(err)
return err
}
defer resp.Body.Close()
if resp.Status != "200 OK" {
Error.Println("Failed to takeoff: " + resp.Status)
return errors.New("Failed to takeoff: " + resp.Status)
}
return nil
}