| @@ -0,0 +1,729 @@ |
| @@ -0,0 +1,729 @@ |
| |
1
| +/* |
| |
2
| + Copyright (C) 2014 Parrot SA |
| |
3
| + |
| |
4
| + Redistribution and use in source and binary forms, with or without |
| |
5
| + modification, are permitted provided that the following conditions |
| |
6
| + are met: |
| |
7
| + * Redistributions of source code must retain the above copyright |
| |
8
| + notice, this list of conditions and the following disclaimer. |
| |
9
| + * Redistributions in binary form must reproduce the above copyright |
| |
10
| + notice, this list of conditions and the following disclaimer in |
| |
11
| + the documentation and/or other materials provided with the |
| |
12
| + distribution. |
| |
13
| + * Neither the name of Parrot nor the names |
| |
14
| + of its contributors may be used to endorse or promote products |
| |
15
| + derived from this software without specific prior written |
| |
16
| + permission. |
| |
17
| + |
| |
18
| + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| |
19
| + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| |
20
| + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
| |
21
| + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
| |
22
| + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
| |
23
| + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| |
24
| + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS |
| |
25
| + OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
| |
26
| + AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| |
27
| + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT |
| |
28
| + OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| |
29
| + SUCH DAMAGE. |
| |
30
| +*/ |
| |
31
| +/** |
| |
32
| + * @file BebopSample.c |
| |
33
| + * @brief This file contains sources about basic arsdk example sending commands to a bebop drone to pilot it, |
| |
34
| + * receive its battery level and display the video stream. |
| |
35
| + * @date 15/01/2015 |
| |
36
| + */ |
| |
37
| + |
| |
38
| +/***************************************** |
| |
39
| + * |
| |
40
| + * include file : |
| |
41
| + * |
| |
42
| + *****************************************/ |
| |
43
| + |
| |
44
| +#include <stdio.h> |
| |
45
| +#include <stdlib.h> |
| |
46
| +#include <curses.h> |
| |
47
| +#include <string.h> |
| |
48
| +#include <unistd.h> |
| |
49
| +#include <signal.h> |
| |
50
| +#include <errno.h> |
| |
51
| + |
| |
52
| +#include <libARSAL/ARSAL.h> |
| |
53
| +#include <libARController/ARController.h> |
| |
54
| +#include <libARDiscovery/ARDiscovery.h> |
| |
55
| + |
| |
56
| +#include "BebopSample.h" |
| |
57
| +#include "ihm.h" |
| |
58
| + |
| |
59
| +/***************************************** |
| |
60
| + * |
| |
61
| + * define : |
| |
62
| + * |
| |
63
| + *****************************************/ |
| |
64
| +#define TAG "BebopSample" |
| |
65
| + |
| |
66
| +#define ERROR_STR_LENGTH 2048 |
| |
67
| + |
| |
68
| +#define BEBOP_IP_ADDRESS "192.168.42.1" |
| |
69
| +#define BEBOP_DISCOVERY_PORT 44444 |
| |
70
| + |
| |
71
| +#define DISPLAY_WITH_MPLAYER 1 |
| |
72
| + |
| |
73
| +#define FIFO_DIR_PATTERN "/tmp/arsdk_XXXXXX" |
| |
74
| +#define FIFO_NAME "arsdk_fifo" |
| |
75
| + |
| |
76
| +#define IHM |
| |
77
| +/***************************************** |
| |
78
| + * |
| |
79
| + * private header: |
| |
80
| + * |
| |
81
| + ****************************************/ |
| |
82
| + |
| |
83
| + |
| |
84
| +/***************************************** |
| |
85
| + * |
| |
86
| + * implementation : |
| |
87
| + * |
| |
88
| + *****************************************/ |
| |
89
| + |
| |
90
| +static char fifo_dir[] = FIFO_DIR_PATTERN; |
| |
91
| +static char fifo_name[128] = ""; |
| |
92
| + |
| |
93
| +int gIHMRun = 1; |
| |
94
| +char gErrorStr[ERROR_STR_LENGTH]; |
| |
95
| +IHM_t *ihm = NULL; |
| |
96
| + |
| |
97
| +FILE *videoOut = NULL; |
| |
98
| +int frameNb = 0; |
| |
99
| +ARSAL_Sem_t stateSem; |
| |
100
| +int isBebop2 = 0; |
| |
101
| + |
| |
102
| +static void signal_handler(int signal) |
| |
103
| +{ |
| |
104
| + gIHMRun = 0; |
| |
105
| +} |
| |
106
| + |
| |
107
| +int main (int argc, char *argv[]) |
| |
108
| +{ |
| |
109
| + // local declarations |
| |
110
| + int failed = 0; |
| |
111
| + ARDISCOVERY_Device_t *device = NULL; |
| |
112
| + ARCONTROLLER_Device_t *deviceController = NULL; |
| |
113
| + eARCONTROLLER_ERROR error = ARCONTROLLER_OK; |
| |
114
| + eARCONTROLLER_DEVICE_STATE deviceState = ARCONTROLLER_DEVICE_STATE_MAX; |
| |
115
| + pid_t child = 0; |
| |
116
| + |
| |
117
| + |
| |
118
| + /* Set signal handlers */ |
| |
119
| + struct sigaction sig_action = { |
| |
120
| + .sa_handler = signal_handler, |
| |
121
| + }; |
| |
122
| + |
| |
123
| + int ret = sigaction(SIGINT, &sig_action, NULL); |
| |
124
| + if (ret < 0) |
| |
125
| + { |
| |
126
| + ARSAL_PRINT(ARSAL_PRINT_ERROR, "ERROR", "Unable to set SIGINT handler : %d(%s)", |
| |
127
| + errno, strerror(errno)); |
| |
128
| + return 1; |
| |
129
| + } |
| |
130
| + ret = sigaction(SIGPIPE, &sig_action, NULL); |
| |
131
| + if (ret < 0) |
| |
132
| + { |
| |
133
| + ARSAL_PRINT(ARSAL_PRINT_ERROR, "ERROR", "Unable to set SIGPIPE handler : %d(%s)", |
| |
134
| + errno, strerror(errno)); |
| |
135
| + return 1; |
| |
136
| + } |
| |
137
| + |
| |
138
| + |
| |
139
| + if (mkdtemp(fifo_dir) == NULL) |
| |
140
| + { |
| |
141
| + ARSAL_PRINT(ARSAL_PRINT_ERROR, "ERROR", "Mkdtemp failed."); |
| |
142
| + return 1; |
| |
143
| + } |
| |
144
| + snprintf(fifo_name, sizeof(fifo_name), "%s/%s", fifo_dir, FIFO_NAME); |
| |
145
| + |
| |
146
| + if(mkfifo(fifo_name, 0666) < 0) |
| |
147
| + { |
| |
148
| + ARSAL_PRINT(ARSAL_PRINT_ERROR, "ERROR", "Mkfifo failed: %d, %s", errno, strerror(errno)); |
| |
149
| + return 1; |
| |
150
| + } |
| |
151
| + |
| |
152
| + ARSAL_Sem_Init (&(stateSem), 0, 0); |
| |
153
| + |
| |
154
| + ARSAL_PRINT(ARSAL_PRINT_INFO, TAG, "Select your Bebop : Bebop (1) ; Bebop2 (2)"); |
| |
155
| + char answer = '1'; |
| |
156
| + scanf(" %c", &answer); |
| |
157
| + if (answer == '2') |
| |
158
| + { |
| |
159
| + isBebop2 = 1; |
| |
160
| + } |
| |
161
| + |
| |
162
| + if(isBebop2) |
| |
163
| + { |
| |
164
| + ARSAL_PRINT(ARSAL_PRINT_INFO, TAG, "-- Bebop 2 Sample --"); |
| |
165
| + } |
| |
166
| + else |
| |
167
| + { |
| |
168
| + ARSAL_PRINT(ARSAL_PRINT_INFO, TAG, "-- Bebop Sample --"); |
| |
169
| + } |
| |
170
| + |
| |
171
| + if (!failed) |
| |
172
| + { |
| |
173
| + if (DISPLAY_WITH_MPLAYER) |
| |
174
| + { |
| |
175
| + // fork the process to launch mplayer |
| |
176
| + if ((child = fork()) == 0) |
| |
177
| + { |
| |
178
| + execlp("xterm", "xterm", "-e", "mplayer", "-demuxer", "h264es", fifo_name, "-benchmark", "-really-quiet", NULL); |
| |
179
| + ARSAL_PRINT(ARSAL_PRINT_ERROR, TAG, "Missing mplayer, you will not see the video. Please install mplayer and xterm."); |
| |
180
| + return -1; |
| |
181
| + } |
| |
182
| + } |
| |
183
| + |
| |
184
| + if (DISPLAY_WITH_MPLAYER) |
| |
185
| + { |
| |
186
| + videoOut = fopen(fifo_name, "w"); |
| |
187
| + } |
| |
188
| + } |
| |
189
| + |
| |
190
| +#ifdef IHM |
| |
191
| + ihm = IHM_New (&onInputEvent); |
| |
192
| + if (ihm != NULL) |
| |
193
| + { |
| |
194
| + gErrorStr[0] = '\0'; |
| |
195
| + ARSAL_Print_SetCallback (customPrintCallback); //use a custom callback to print, for not disturb ncurses IHM |
| |
196
| + |
| |
197
| + if(isBebop2) |
| |
198
| + { |
| |
199
| + IHM_PrintHeader (ihm, "-- Bebop 2 Sample --"); |
| |
200
| + } |
| |
201
| + else |
| |
202
| + { |
| |
203
| + IHM_PrintHeader (ihm, "-- Bebop Sample --"); |
| |
204
| + } |
| |
205
| + } |
| |
206
| + else |
| |
207
| + { |
| |
208
| + ARSAL_PRINT (ARSAL_PRINT_ERROR, TAG, "Creation of IHM failed."); |
| |
209
| + failed = 1; |
| |
210
| + } |
| |
211
| +#endif |
| |
212
| + |
| |
213
| + // create a discovery device |
| |
214
| + if (!failed) |
| |
215
| + { |
| |
216
| + ARSAL_PRINT(ARSAL_PRINT_INFO, TAG, "- init discovey device ... "); |
| |
217
| + eARDISCOVERY_ERROR errorDiscovery = ARDISCOVERY_OK; |
| |
218
| + |
| |
219
| + device = ARDISCOVERY_Device_New (&errorDiscovery); |
| |
220
| + |
| |
221
| + if (errorDiscovery == ARDISCOVERY_OK) |
| |
222
| + { |
| |
223
| + ARSAL_PRINT(ARSAL_PRINT_INFO, TAG, " - ARDISCOVERY_Device_InitWifi ..."); |
| |
224
| + // create a Bebop drone discovery device (ARDISCOVERY_PRODUCT_ARDRONE) |
| |
225
| + |
| |
226
| + if(isBebop2) |
| |
227
| + { |
| |
228
| + errorDiscovery = ARDISCOVERY_Device_InitWifi (device, ARDISCOVERY_PRODUCT_BEBOP_2, "bebop2", BEBOP_IP_ADDRESS, BEBOP_DISCOVERY_PORT); |
| |
229
| + } |
| |
230
| + else |
| |
231
| + { |
| |
232
| + errorDiscovery = ARDISCOVERY_Device_InitWifi (device, ARDISCOVERY_PRODUCT_ARDRONE, "bebop", BEBOP_IP_ADDRESS, BEBOP_DISCOVERY_PORT); |
| |
233
| + } |
| |
234
| + |
| |
235
| + if (errorDiscovery != ARDISCOVERY_OK) |
| |
236
| + { |
| |
237
| + failed = 1; |
| |
238
| + ARSAL_PRINT(ARSAL_PRINT_ERROR, TAG, "Discovery error :%s", ARDISCOVERY_Error_ToString(errorDiscovery)); |
| |
239
| + } |
| |
240
| + } |
| |
241
| + else |
| |
242
| + { |
| |
243
| + ARSAL_PRINT(ARSAL_PRINT_ERROR, TAG, "Discovery error :%s", ARDISCOVERY_Error_ToString(errorDiscovery)); |
| |
244
| + failed = 1; |
| |
245
| + } |
| |
246
| + } |
| |
247
| + |
| |
248
| + // create a device controller |
| |
249
| + if (!failed) |
| |
250
| + { |
| |
251
| + deviceController = ARCONTROLLER_Device_New (device, &error); |
| |
252
| + |
| |
253
| + if (error != ARCONTROLLER_OK) |
| |
254
| + { |
| |
255
| + ARSAL_PRINT (ARSAL_PRINT_ERROR, TAG, "Creation of deviceController failed."); |
| |
256
| + failed = 1; |
| |
257
| + } |
| |
258
| + else |
| |
259
| + { |
| |
260
| + IHM_setCustomData(ihm, deviceController); |
| |
261
| + } |
| |
262
| + } |
| |
263
| + |
| |
264
| + if (!failed) |
| |
265
| + { |
| |
266
| + ARSAL_PRINT(ARSAL_PRINT_INFO, TAG, "- delete discovey device ... "); |
| |
267
| + ARDISCOVERY_Device_Delete (&device); |
| |
268
| + } |
| |
269
| + |
| |
270
| + // add the state change callback to be informed when the device controller starts, stops... |
| |
271
| + if (!failed) |
| |
272
| + { |
| |
273
| + error = ARCONTROLLER_Device_AddStateChangedCallback (deviceController, stateChanged, deviceController); |
| |
274
| + |
| |
275
| + if (error != ARCONTROLLER_OK) |
| |
276
| + { |
| |
277
| + ARSAL_PRINT (ARSAL_PRINT_ERROR, TAG, "add State callback failed."); |
| |
278
| + failed = 1; |
| |
279
| + } |
| |
280
| + } |
| |
281
| + |
| |
282
| + // add the command received callback to be informed when a command has been received from the device |
| |
283
| + if (!failed) |
| |
284
| + { |
| |
285
| + error = ARCONTROLLER_Device_AddCommandReceivedCallback (deviceController, commandReceived, deviceController); |
| |
286
| + |
| |
287
| + if (error != ARCONTROLLER_OK) |
| |
288
| + { |
| |
289
| + ARSAL_PRINT (ARSAL_PRINT_ERROR, TAG, "add callback failed."); |
| |
290
| + failed = 1; |
| |
291
| + } |
| |
292
| + } |
| |
293
| + |
| |
294
| + // add the frame received callback to be informed when a streaming frame has been received from the device |
| |
295
| + if (!failed) |
| |
296
| + { |
| |
297
| + ARSAL_PRINT(ARSAL_PRINT_INFO, TAG, "- set Video callback ... "); |
| |
298
| + error = ARCONTROLLER_Device_SetVideoStreamCallbacks (deviceController, decoderConfigCallback, didReceiveFrameCallback, NULL , NULL); |
| |
299
| + |
| |
300
| + if (error != ARCONTROLLER_OK) |
| |
301
| + { |
| |
302
| + failed = 1; |
| |
303
| + ARSAL_PRINT(ARSAL_PRINT_ERROR, TAG, "- error: %s", ARCONTROLLER_Error_ToString(error)); |
| |
304
| + } |
| |
305
| + } |
| |
306
| + |
| |
307
| + if (!failed) |
| |
308
| + { |
| |
309
| + IHM_PrintInfo(ihm, "Connecting ..."); |
| |
310
| + ARSAL_PRINT(ARSAL_PRINT_INFO, TAG, "Connecting ..."); |
| |
311
| + error = ARCONTROLLER_Device_Start (deviceController); |
| |
312
| + |
| |
313
| + if (error != ARCONTROLLER_OK) |
| |
314
| + { |
| |
315
| + failed = 1; |
| |
316
| + ARSAL_PRINT(ARSAL_PRINT_ERROR, TAG, "- error :%s", ARCONTROLLER_Error_ToString(error)); |
| |
317
| + } |
| |
318
| + } |
| |
319
| + |
| |
320
| + if (!failed) |
| |
321
| + { |
| |
322
| + // wait state update update |
| |
323
| + ARSAL_Sem_Wait (&(stateSem)); |
| |
324
| + |
| |
325
| + deviceState = ARCONTROLLER_Device_GetState (deviceController, &error); |
| |
326
| + |
| |
327
| + if ((error != ARCONTROLLER_OK) || (deviceState != ARCONTROLLER_DEVICE_STATE_RUNNING)) |
| |
328
| + { |
| |
329
| + failed = 1; |
| |
330
| + ARSAL_PRINT(ARSAL_PRINT_ERROR, TAG, "- deviceState :%d", deviceState); |
| |
331
| + ARSAL_PRINT(ARSAL_PRINT_ERROR, TAG, "- error :%s", ARCONTROLLER_Error_ToString(error)); |
| |
332
| + } |
| |
333
| + } |
| |
334
| + |
| |
335
| + // send the command that tells to the Bebop to begin its streaming |
| |
336
| + if (!failed) |
| |
337
| + { |
| |
338
| + ARSAL_PRINT(ARSAL_PRINT_INFO, TAG, "- send StreamingVideoEnable ... "); |
| |
339
| + error = deviceController->aRDrone3->sendMediaStreamingVideoEnable (deviceController->aRDrone3, 1); |
| |
340
| + if (error != ARCONTROLLER_OK) |
| |
341
| + { |
| |
342
| + ARSAL_PRINT(ARSAL_PRINT_ERROR, TAG, "- error :%s", ARCONTROLLER_Error_ToString(error)); |
| |
343
| + failed = 1; |
| |
344
| + } |
| |
345
| + } |
| |
346
| + |
| |
347
| + if (!failed) |
| |
348
| + { |
| |
349
| + IHM_PrintInfo(ihm, "Running ... ('t' to takeoff ; Spacebar to land ; 'e' for emergency ; Arrow keys and ('r','f','d','g') to move ; 'q' to quit)"); |
| |
350
| + |
| |
351
| +#ifdef IHM |
| |
352
| + while (gIHMRun) |
| |
353
| + { |
| |
354
| + usleep(50); |
| |
355
| + } |
| |
356
| +#else |
| |
357
| + int i = 20; |
| |
358
| + ARSAL_PRINT(ARSAL_PRINT_INFO, TAG, "- sleep 20 ... "); |
| |
359
| + while (gIHMRun && i--) |
| |
360
| + sleep(1); |
| |
361
| +#endif |
| |
362
| + } |
| |
363
| + |
| |
364
| +#ifdef IHM |
| |
365
| + IHM_Delete (&ihm); |
| |
366
| +#endif |
| |
367
| + |
| |
368
| + // we are here because of a disconnection or user has quit IHM, so safely delete everything |
| |
369
| + if (deviceController != NULL) |
| |
370
| + { |
| |
371
| + |
| |
372
| + |
| |
373
| + deviceState = ARCONTROLLER_Device_GetState (deviceController, &error); |
| |
374
| + if ((error == ARCONTROLLER_OK) && (deviceState != ARCONTROLLER_DEVICE_STATE_STOPPED)) |
| |
375
| + { |
| |
376
| + IHM_PrintInfo(ihm, "Disconnecting ..."); |
| |
377
| + ARSAL_PRINT(ARSAL_PRINT_INFO, TAG, "Disconnecting ..."); |
| |
378
| + |
| |
379
| + error = ARCONTROLLER_Device_Stop (deviceController); |
| |
380
| + |
| |
381
| + if (error == ARCONTROLLER_OK) |
| |
382
| + { |
| |
383
| + // wait state update update |
| |
384
| + ARSAL_Sem_Wait (&(stateSem)); |
| |
385
| + } |
| |
386
| + } |
| |
387
| + |
| |
388
| + IHM_PrintInfo(ihm, ""); |
| |
389
| + ARSAL_PRINT(ARSAL_PRINT_INFO, TAG, "ARCONTROLLER_Device_Delete ..."); |
| |
390
| + ARCONTROLLER_Device_Delete (&deviceController); |
| |
391
| + |
| |
392
| + if (DISPLAY_WITH_MPLAYER) |
| |
393
| + { |
| |
394
| + fflush (videoOut); |
| |
395
| + fclose (videoOut); |
| |
396
| + |
| |
397
| + if (child > 0) |
| |
398
| + { |
| |
399
| + kill(child, SIGKILL); |
| |
400
| + } |
| |
401
| + } |
| |
402
| + } |
| |
403
| + |
| |
404
| + ARSAL_Sem_Destroy (&(stateSem)); |
| |
405
| + |
| |
406
| + unlink(fifo_name); |
| |
407
| + rmdir(fifo_dir); |
| |
408
| + |
| |
409
| + ARSAL_PRINT(ARSAL_PRINT_INFO, TAG, "-- END --"); |
| |
410
| + |
| |
411
| + return EXIT_SUCCESS; |
| |
412
| +} |
| |
413
| + |
| |
414
| +/***************************************** |
| |
415
| + * |
| |
416
| + * private implementation: |
| |
417
| + * |
| |
418
| + ****************************************/ |
| |
419
| + |
| |
420
| +// called when the state of the device controller has changed |
| |
421
| +void stateChanged (eARCONTROLLER_DEVICE_STATE newState, eARCONTROLLER_ERROR error, void *customData) |
| |
422
| +{ |
| |
423
| + ARSAL_PRINT(ARSAL_PRINT_INFO, TAG, " - stateChanged newState: %d .....", newState); |
| |
424
| + |
| |
425
| + switch (newState) |
| |
426
| + { |
| |
427
| + case ARCONTROLLER_DEVICE_STATE_STOPPED: |
| |
428
| + ARSAL_Sem_Post (&(stateSem)); |
| |
429
| + //stop |
| |
430
| + gIHMRun = 0; |
| |
431
| + |
| |
432
| + break; |
| |
433
| + |
| |
434
| + case ARCONTROLLER_DEVICE_STATE_RUNNING: |
| |
435
| + ARSAL_Sem_Post (&(stateSem)); |
| |
436
| + break; |
| |
437
| + |
| |
438
| + default: |
| |
439
| + break; |
| |
440
| + } |
| |
441
| +} |
| |
442
| + |
| |
443
| +static void cmdBatteryStateChangedRcv(ARCONTROLLER_Device_t *deviceController, ARCONTROLLER_DICTIONARY_ELEMENT_t *elementDictionary) |
| |
444
| +{ |
| |
445
| + ARCONTROLLER_DICTIONARY_ARG_t *arg = NULL; |
| |
446
| + ARCONTROLLER_DICTIONARY_ELEMENT_t *singleElement = NULL; |
| |
447
| + |
| |
448
| + if (elementDictionary == NULL) { |
| |
449
| + ARSAL_PRINT(ARSAL_PRINT_ERROR, TAG, "elements is NULL"); |
| |
450
| + return; |
| |
451
| + } |
| |
452
| + |
| |
453
| + // get the command received in the device controller |
| |
454
| + HASH_FIND_STR (elementDictionary, ARCONTROLLER_DICTIONARY_SINGLE_KEY, singleElement); |
| |
455
| + |
| |
456
| + if (singleElement == NULL) { |
| |
457
| + ARSAL_PRINT(ARSAL_PRINT_ERROR, TAG, "singleElement is NULL"); |
| |
458
| + return; |
| |
459
| + } |
| |
460
| + |
| |
461
| + // get the value |
| |
462
| + HASH_FIND_STR (singleElement->arguments, ARCONTROLLER_DICTIONARY_KEY_COMMON_COMMONSTATE_BATTERYSTATECHANGED_PERCENT, arg); |
| |
463
| + |
| |
464
| + if (arg == NULL) { |
| |
465
| + ARSAL_PRINT(ARSAL_PRINT_ERROR, TAG, "arg is NULL"); |
| |
466
| + return; |
| |
467
| + } |
| |
468
| + |
| |
469
| + // update UI |
| |
470
| + batteryStateChanged(arg->value.U8); |
| |
471
| +} |
| |
472
| + |
| |
473
| +static void cmdSensorStateListChangedRcv(ARCONTROLLER_Device_t *deviceController, ARCONTROLLER_DICTIONARY_ELEMENT_t *elementDictionary) |
| |
474
| +{ |
| |
475
| + FILE* fichier = NULL; |
| |
476
| + |
| |
477
| + |
| |
478
| + fichier = fopen("test.txt", "a"); |
| |
479
| + ARCONTROLLER_DICTIONARY_ARG_t *arg = NULL; |
| |
480
| + ARCONTROLLER_DICTIONARY_ELEMENT_t *dictElement = NULL; |
| |
481
| + ARCONTROLLER_DICTIONARY_ELEMENT_t *dictTmp = NULL; |
| |
482
| + |
| |
483
| + eARCOMMANDS_COMMON_COMMONSTATE_SENSORSSTATESLISTCHANGED_SENSORNAME sensorName = ARCOMMANDS_COMMON_COMMONSTATE_SENSORSSTATESLISTCHANGED_SENSORNAME_MAX; |
| |
484
| + int sensorState = 0; |
| |
485
| + |
| |
486
| + if (elementDictionary == NULL) { |
| |
487
| + ARSAL_PRINT(ARSAL_PRINT_ERROR, TAG, "elements is NULL"); |
| |
488
| + return; |
| |
489
| + } |
| |
490
| + |
| |
491
| + // get the command received in the device controller |
| |
492
| + HASH_ITER(hh, elementDictionary, dictElement, dictTmp) { |
| |
493
| + // get the Name |
| |
494
| + HASH_FIND_STR (dictElement->arguments, ARCONTROLLER_DICTIONARY_KEY_COMMON_COMMONSTATE_SENSORSSTATESLISTCHANGED_SENSORNAME, arg); |
| |
495
| + if (arg != NULL) { |
| |
496
| + ARSAL_PRINT(ARSAL_PRINT_ERROR, TAG, "arg sensorName is NULL"); |
| |
497
| + continue; |
| |
498
| + } |
| |
499
| + |
| |
500
| + sensorName = arg->value.I32; |
| |
501
| + |
| |
502
| + // get the state |
| |
503
| + HASH_FIND_STR (dictElement->arguments, ARCONTROLLER_DICTIONARY_KEY_COMMON_COMMONSTATE_SENSORSSTATESLISTCHANGED_SENSORSTATE, arg); |
| |
504
| + if (arg == NULL) { |
| |
505
| + ARSAL_PRINT(ARSAL_PRINT_ERROR, TAG, "arg sensorState is NULL"); |
| |
506
| + continue; |
| |
507
| + } |
| |
508
| + |
| |
509
| + sensorState = arg->value.U8; |
| |
510
| + ARSAL_PRINT(ARSAL_PRINT_INFO, TAG, "sensorName %d ; sensorState: %d", sensorName, sensorState); |
| |
511
| + fprintf(fichier, "sensorName %d ; sensorState: %d", sensorName, sensorState); |
| |
512
| + printf("sensorName %d ; sensorState: %d", sensorName, sensorState); |
| |
513
| + //sensorStateChanged(arg->value.I32, arg->value.U8); |
| |
514
| + } |
| |
515
| + sensorStateChanged(arg->value.I32, arg->value.U8); |
| |
516
| +} |
| |
517
| + |
| |
518
| +// called when a command has been received from the drone |
| |
519
| +void commandReceived (eARCONTROLLER_DICTIONARY_KEY commandKey, ARCONTROLLER_DICTIONARY_ELEMENT_t *elementDictionary, void *customData) |
| |
520
| +{ |
| |
521
| + ARCONTROLLER_Device_t *deviceController = customData; |
| |
522
| + |
| |
523
| + if (deviceController == NULL) |
| |
524
| + return; |
| |
525
| + |
| |
526
| + // if the command received is a battery state changed |
| |
527
| + switch(commandKey) { |
| |
528
| + case ARCONTROLLER_DICTIONARY_KEY_COMMON_COMMONSTATE_BATTERYSTATECHANGED: |
| |
529
| + cmdBatteryStateChangedRcv(deviceController, elementDictionary); |
| |
530
| + break; |
| |
531
| + case ARCONTROLLER_DICTIONARY_KEY_COMMON_COMMONSTATE_SENSORSSTATESLISTCHANGED: |
| |
532
| + cmdSensorStateListChangedRcv(deviceController, elementDictionary); |
| |
533
| + break; |
| |
534
| + default: |
| |
535
| + break; |
| |
536
| + } |
| |
537
| +} |
| |
538
| + |
| |
539
| +void batteryStateChanged (uint8_t percent) |
| |
540
| +{ |
| |
541
| + // callback of changing of battery level |
| |
542
| + |
| |
543
| + if (ihm != NULL) |
| |
544
| + { |
| |
545
| + IHM_PrintBattery (ihm, percent); |
| |
546
| + } |
| |
547
| +} |
| |
548
| + |
| |
549
| +void sensorStateChanged (uint8_t sensorName, uint8_t sensorValue) |
| |
550
| +{ |
| |
551
| + // callback of changing of battery level |
| |
552
| + |
| |
553
| + if (ihm != NULL) |
| |
554
| + { |
| |
555
| + IHM_PrintSensors(ihm, sensorName, sensorValue); |
| |
556
| + } |
| |
557
| +} |
| |
558
| + |
| |
559
| + |
| |
560
| +eARCONTROLLER_ERROR decoderConfigCallback (ARCONTROLLER_Stream_Codec_t codec, void *customData) |
| |
561
| +{ |
| |
562
| + if (videoOut != NULL) |
| |
563
| + { |
| |
564
| + if (codec.type == ARCONTROLLER_STREAM_CODEC_TYPE_H264) |
| |
565
| + { |
| |
566
| + if (DISPLAY_WITH_MPLAYER) |
| |
567
| + { |
| |
568
| + fwrite(codec.parameters.h264parameters.spsBuffer, codec.parameters.h264parameters.spsSize, 1, videoOut); |
| |
569
| + fwrite(codec.parameters.h264parameters.ppsBuffer, codec.parameters.h264parameters.ppsSize, 1, videoOut); |
| |
570
| + |
| |
571
| + fflush (videoOut); |
| |
572
| + } |
| |
573
| + } |
| |
574
| + |
| |
575
| + } |
| |
576
| + else |
| |
577
| + { |
| |
578
| + ARSAL_PRINT(ARSAL_PRINT_WARNING, TAG, "videoOut is NULL."); |
| |
579
| + } |
| |
580
| + |
| |
581
| + return ARCONTROLLER_OK; |
| |
582
| +} |
| |
583
| + |
| |
584
| + |
| |
585
| +eARCONTROLLER_ERROR didReceiveFrameCallback (ARCONTROLLER_Frame_t *frame, void *customData) |
| |
586
| +{ |
| |
587
| + if (videoOut != NULL) |
| |
588
| + { |
| |
589
| + if (frame != NULL) |
| |
590
| + { |
| |
591
| + if (DISPLAY_WITH_MPLAYER) |
| |
592
| + { |
| |
593
| + fwrite(frame->data, frame->used, 1, videoOut); |
| |
594
| + |
| |
595
| + fflush (videoOut); |
| |
596
| + } |
| |
597
| + } |
| |
598
| + else |
| |
599
| + { |
| |
600
| + ARSAL_PRINT(ARSAL_PRINT_WARNING, TAG, "frame is NULL."); |
| |
601
| + } |
| |
602
| + } |
| |
603
| + else |
| |
604
| + { |
| |
605
| + ARSAL_PRINT(ARSAL_PRINT_WARNING, TAG, "videoOut is NULL."); |
| |
606
| + } |
| |
607
| + |
| |
608
| + return ARCONTROLLER_OK; |
| |
609
| +} |
| |
610
| + |
| |
611
| + |
| |
612
| +// IHM callbacks: |
| |
613
| + |
| |
614
| +void onInputEvent (eIHM_INPUT_EVENT event, void *customData) |
| |
615
| +{ |
| |
616
| + // Manage IHM input events |
| |
617
| + ARCONTROLLER_Device_t *deviceController = (ARCONTROLLER_Device_t *)customData; |
| |
618
| + eARCONTROLLER_ERROR error = ARCONTROLLER_OK; |
| |
619
| + |
| |
620
| + switch (event) |
| |
621
| + { |
| |
622
| + case IHM_INPUT_EVENT_EXIT: |
| |
623
| + IHM_PrintInfo(ihm, "IHM_INPUT_EVENT_EXIT ..."); |
| |
624
| + gIHMRun = 0; |
| |
625
| + break; |
| |
626
| + case IHM_INPUT_EVENT_EMERGENCY: |
| |
627
| + if(deviceController != NULL) |
| |
628
| + { |
| |
629
| + // send a Emergency command to the drone |
| |
630
| + error = deviceController->aRDrone3->sendPilotingEmergency(deviceController->aRDrone3); |
| |
631
| + } |
| |
632
| + break; |
| |
633
| + case IHM_INPUT_EVENT_LAND: |
| |
634
| + if(deviceController != NULL) |
| |
635
| + { |
| |
636
| + // send a takeoff command to the drone |
| |
637
| + error = deviceController->aRDrone3->sendPilotingLanding(deviceController->aRDrone3); |
| |
638
| + } |
| |
639
| + break; |
| |
640
| + case IHM_INPUT_EVENT_TAKEOFF: |
| |
641
| + if(deviceController != NULL) |
| |
642
| + { |
| |
643
| + // send a landing command to the drone |
| |
644
| + error = deviceController->aRDrone3->sendPilotingTakeOff(deviceController->aRDrone3); |
| |
645
| + } |
| |
646
| + break; |
| |
647
| + case IHM_INPUT_EVENT_UP: |
| |
648
| + if(deviceController != NULL) |
| |
649
| + { |
| |
650
| + // set the flag and speed value of the piloting command |
| |
651
| + error = deviceController->aRDrone3->setPilotingPCMDGaz(deviceController->aRDrone3, 50); |
| |
652
| + } |
| |
653
| + break; |
| |
654
| + case IHM_INPUT_EVENT_DOWN: |
| |
655
| + if(deviceController != NULL) |
| |
656
| + { |
| |
657
| + error = deviceController->aRDrone3->setPilotingPCMDGaz(deviceController->aRDrone3, -50); |
| |
658
| + } |
| |
659
| + break; |
| |
660
| + case IHM_INPUT_EVENT_RIGHT: |
| |
661
| + if(deviceController != NULL) |
| |
662
| + { |
| |
663
| + error = deviceController->aRDrone3->setPilotingPCMDYaw(deviceController->aRDrone3, 50); |
| |
664
| + } |
| |
665
| + break; |
| |
666
| + case IHM_INPUT_EVENT_LEFT: |
| |
667
| + if(deviceController != NULL) |
| |
668
| + { |
| |
669
| + error = deviceController->aRDrone3->setPilotingPCMDYaw(deviceController->aRDrone3, -50); |
| |
670
| + } |
| |
671
| + break; |
| |
672
| + case IHM_INPUT_EVENT_FORWARD: |
| |
673
| + if(deviceController != NULL) |
| |
674
| + { |
| |
675
| + error = deviceController->aRDrone3->setPilotingPCMDPitch(deviceController->aRDrone3, 50); |
| |
676
| + error = deviceController->aRDrone3->setPilotingPCMDFlag(deviceController->aRDrone3, 1); |
| |
677
| + } |
| |
678
| + break; |
| |
679
| + case IHM_INPUT_EVENT_BACK: |
| |
680
| + if(deviceController != NULL) |
| |
681
| + { |
| |
682
| + error = deviceController->aRDrone3->setPilotingPCMDPitch(deviceController->aRDrone3, -50); |
| |
683
| + error = deviceController->aRDrone3->setPilotingPCMDFlag(deviceController->aRDrone3, 1); |
| |
684
| + } |
| |
685
| + break; |
| |
686
| + case IHM_INPUT_EVENT_ROLL_LEFT: |
| |
687
| + if(deviceController != NULL) |
| |
688
| + { |
| |
689
| + error = deviceController->aRDrone3->setPilotingPCMDRoll(deviceController->aRDrone3, -50); |
| |
690
| + error = deviceController->aRDrone3->setPilotingPCMDFlag(deviceController->aRDrone3, 1); |
| |
691
| + } |
| |
692
| + break; |
| |
693
| + case IHM_INPUT_EVENT_ROLL_RIGHT: |
| |
694
| + if(deviceController != NULL) |
| |
695
| + { |
| |
696
| + error = deviceController->aRDrone3->setPilotingPCMDRoll(deviceController->aRDrone3, 50); |
| |
697
| + error = deviceController->aRDrone3->setPilotingPCMDFlag(deviceController->aRDrone3, 1); |
| |
698
| + } |
| |
699
| + break; |
| |
700
| + case IHM_INPUT_EVENT_NONE: |
| |
701
| + if(deviceController != NULL) |
| |
702
| + { |
| |
703
| + error = deviceController->aRDrone3->setPilotingPCMD(deviceController->aRDrone3, 0, 0, 0, 0, 0, 0); |
| |
704
| + } |
| |
705
| + break; |
| |
706
| + default: |
| |
707
| + break; |
| |
708
| + } |
| |
709
| + |
| |
710
| + // This should be improved, here it just displays that one error occured |
| |
711
| + if (error != ARCONTROLLER_OK) |
| |
712
| + { |
| |
713
| + IHM_PrintInfo(ihm, "Error sending an event"); |
| |
714
| + } |
| |
715
| +} |
| |
716
| + |
| |
717
| +int customPrintCallback (eARSAL_PRINT_LEVEL level, const char *tag, const char *format, va_list va) |
| |
718
| +{ |
| |
719
| + // Custom callback used when ncurses is runing for not disturb the IHM |
| |
720
| + |
| |
721
| + if ((level == ARSAL_PRINT_ERROR) && (strcmp(TAG, tag) == 0)) |
| |
722
| + { |
| |
723
| + // Save the last Error |
| |
724
| + vsnprintf(gErrorStr, (ERROR_STR_LENGTH - 1), format, va); |
| |
725
| + gErrorStr[ERROR_STR_LENGTH - 1] = '\0'; |
| |
726
| + } |
| |
727
| + |
| |
728
| + return 1; |
| |
729
| +} |