ArDrone SDK 1.8 added
[mardrone] / mardrone / ARDrone_SDK_Version_1_8_20110726 / Examples / Android / ardrone / project / jni / android.c
1 /*
2  * AR Drone demo
3  *
4  * code originally nased on:"San Angeles" Android demo app
5  */
6
7 #include <jni.h>
8 #include <sys/time.h>
9 #include <time.h>
10 #include <android/log.h>
11 #include <stdint.h>
12
13 #include <ardrone_tool/UI/ardrone_input.h>
14
15 #include "navdata.h"
16 #include "app.h"
17
18 /*
19 *
20 *  Command passed down from Java UI layer
21 *
22 */
23 #define  COMMAND_TAKEOFF_LAND                           1
24 #define  COMMAND_EMERGLAND      2
25 #define  COMMAND_MOVEUP                         3
26 #define  COMMAND_MOVEDOWN               4
27 #define  COMMAND_USE_ACCELEROMETER              5
28
29 typedef struct _private_data
30 {
31         float32_t pitch; 
32    float32_t roll; 
33    float32_t yaw; 
34    float32_t gaz;
35    bool_t isRefresh; 
36 } private_data;
37
38 static private_data data = { 0 };
39 static int  sWindowWidth  = 800; 
40 static int  sWindowHeight = 850;
41 static int  sDemoStopped  = 0;
42 static long sTimeOffset   = 0;
43 static int  sTimeOffsetInit = 0;
44 static long sTimeStopped  = 0;
45 static instance_navdata_t nav;
46
47 /**
48  *  Returns time in milliseconds
49  */
50 static long
51 _getTime(void)
52 {
53     struct timeval  now;
54
55     gettimeofday(&now, NULL);
56     return (long)(now.tv_sec*1000 + now.tv_usec/1000);
57 }
58    
59 /* Call to initialize the graphics state */
60 void
61 Java_com_parrot_ARDrone_DemoRenderer_nativeInit( JNIEnv*  env )
62 {
63     //importGLInit();
64     appInit();
65     ardrone_navdata_reset_data( &nav );
66     sDemoStopped = 0;
67     sTimeOffsetInit = 0;
68 }
69
70 void
71 Java_com_parrot_ARDrone_DemoRenderer_nativeResize( JNIEnv*  env, jobject  thiz, jint w, jint h )
72 {
73    // sWindowWidth  = w;
74    // sWindowHeight = h;
75     __android_log_print(ANDROID_LOG_INFO, "ARDrone", "resize w=%d h=%d", w, h);
76 }
77
78 /* Call to finalize the graphics state */
79 void
80 Java_com_parrot_ARDrone_DemoRenderer_nativeDone( JNIEnv*  env )
81 {
82     //appDeinit();
83     //importGLDeinit();
84 }
85
86 /* Call to render the next GL frame */
87 void
88 Java_com_parrot_ARDrone_DemoRenderer_nativeRender( JNIEnv*  env )
89 {
90     long   curTime;
91
92     /* NOTE: if sDemoStopped is TRUE, then we re-render the same frame
93      *       on each iteration.
94      */
95     if (sDemoStopped) {
96         curTime = sTimeStopped + sTimeOffset;
97     } else {
98         curTime = _getTime() + sTimeOffset;
99         if (sTimeOffsetInit == 0) {
100             sTimeOffsetInit = 1;
101             sTimeOffset     = -curTime;
102             curTime         = 0;
103         }
104
105         ardrone_navdata_get_data( &nav ); 
106
107                   if( data.isRefresh )
108                   {
109                           ardrone_at_set_progress_cmd( 1,
110                                           data.roll/25000.0,
111                                           data.pitch/25000.0,
112                                           -data.gaz/25000.0,
113                                           data.yaw/25000.0);
114                   }
115                   else
116                   {
117            data.roll = 0;
118            data.pitch = 0;
119            data.gaz = 0;
120            data.yaw = 0;
121
122                           ardrone_at_set_progress_cmd( 1,
123                                           data.roll/25000.0,
124                                           data.pitch/25000.0,
125                                           -data.gaz/25000.0,
126                                           data.yaw/25000.0);
127   
128                   }
129 /*
130                   INFO( "roll=%f, pitch=%f, gaz=%f, yaw=%f\n", 
131                                   data.roll/25000.0,
132                                   data.pitch/25000.0,
133                                   -data.gaz/25000.0,
134                                   data.yaw/25000.0);
135 */
136          }
137
138     appRender(curTime, sWindowWidth, sWindowHeight);
139 }
140
141 /* This is called to indicate to the render loop that it should
142  * stop as soon as possible.
143  */
144 void
145 Java_com_parrot_ARDrone_DemoGLSurfaceView_nativePause( JNIEnv*  env )
146 {
147     sDemoStopped = !sDemoStopped;
148     if (sDemoStopped) {
149         /* we paused the animation, so store the current
150          * time in sTimeStopped for future nativeRender calls */
151         sTimeStopped = _getTime();
152     } else {
153         /* we resumed the animation, so adjust the time offset
154          * to take care of the pause interval. */
155         sTimeOffset -= _getTime() - sTimeStopped;
156     }
157 }
158
159 #define TRACKBALL_THRESHOLD 32
160
161 void
162 Java_com_parrot_ARDrone_DemoGLSurfaceView_nativeTrackballEvent(JNIEnv *env,
163                                                                jobject thiz,
164                                                                jlong eventTime,
165                                                                jint action,
166                                                                jfloat x,
167                                                                jfloat y) {
168         static int nx = 0;
169
170         if( action == 1 )
171    {
172                 data.isRefresh = FALSE;
173    }
174    else
175         {
176            /* horizontal gestures = YAW control
177                  * x = 0: left
178                  * x = 1: idle position
179                  * x = 2: right
180                  */
181                 nx += (int)(100.0*x);
182       INFO( "nx=%d\n", nx );
183
184                 // FIXME: use trackball to control yaw in a better way
185                 if (nx <= -TRACKBALL_THRESHOLD) {
186          data.yaw = 10000;
187                         nx = 0;
188                 }
189                 else if (nx >= TRACKBALL_THRESHOLD) {
190          data.yaw = -10000;
191                         nx = 0;
192                 }
193       data.isRefresh = TRUE;
194         }
195
196 }
197
198 void
199 Java_com_parrot_ARDrone_DemoGLSurfaceView_nativeMotionEvent(JNIEnv *env,
200                                                             jobject thiz,
201                                                             jlong eventTime,
202                                                             jint action,
203                                                             jfloat x,
204                                                             jfloat y) {
205         /*
206         if (motion_info.state == 1) {
207                 INFO("touch %ld @(%d,%d)\n", (long)eventTime,(int)x, (int)y);
208         }
209         */
210 }
211 /*
212 void
213 Java_com_parrot_ARDrone_DemoGLSurfaceView_nativeKeyEvent(JNIEnv *env,
214                                                                                                                  jobject thiz,
215                                                                                                                  jint action) {
216         //FIXME: thread synchronization required here !!
217         trackball_info.state = (int)action;
218         INFO("KEY %d\n", (int)action);
219 }
220 */
221
222 void
223 Java_com_parrot_ARDrone_DemoActivity_nativeSensorEvent(JNIEnv *env,
224                                                                                                            jobject thiz,
225                                                                                                            jfloat x,
226                                                                                                            jfloat y,
227                                                                                                            jfloat z) 
228 {
229         struct orientation_info orientation;
230
231         if( data.isRefresh )
232         {
233                 orientation.values[0] = (int)x;
234                 orientation.values[1] = (int)y;
235                 orientation.values[2] = (int)z;
236                 // orientation values in degrees
237
238                 data.pitch = -(orientation.values[2]+20)*600;
239                 if (data.pitch >= 25000) {
240                         data.pitch = 25000;
241                 }
242                 if (data.pitch <= -25000) {
243                         data.pitch = -25000;
244                 }
245                 data.roll = orientation.values[1]*600;
246                 if (data.roll >= 25000) {
247                         data.roll = 25000;
248                 }
249                 if (data.roll <= -25000) {
250                         data.roll = -25000;
251                 }
252         }
253 }
254
255 void
256 Java_com_parrot_ARDrone_DemoActivity_nativeStop( JNIEnv*  env )
257 {
258     appDeinit();
259 }
260 void Java_com_parrot_ARDrone_DemoActivity_nativeCommand( JNIEnv*  env,  jobject thiz, jint commandId,  jint iparam1, jfloat fparam1, jfloat fparam2, jfloat fparam3, jfloat fparam4 )
261 {
262    static uint8_t select = 0;
263
264         __android_log_print(ANDROID_LOG_INFO, "ARDrone", "command received %d with iparam1=%d\n", commandId, iparam1 );
265
266         switch( (int)commandId )
267         {
268         case COMMAND_TAKEOFF_LAND:
269       if( !nav.startPressed )
270       {
271          ardrone_tool_set_ui_pad_start( 1 );
272       }
273       else
274                 {
275          ardrone_tool_set_ui_pad_start( 0 );
276                 }
277                 break;
278         case COMMAND_EMERGLAND:
279       select ^= 1;
280       ardrone_tool_set_ui_pad_select( select );
281                 break;
282         case  COMMAND_MOVEUP:
283                 if( iparam1 )
284                 {
285          data.gaz = -10000;
286            data.isRefresh = TRUE;
287       }
288            else 
289       {
290            data.isRefresh = FALSE;
291       }
292                 break;
293         case COMMAND_MOVEDOWN:
294                 if( iparam1 )
295                 {
296          data.gaz = 10000;
297            data.isRefresh = TRUE;
298       }
299       else
300       {
301            data.isRefresh = FALSE;
302       }
303       break;
304         case COMMAND_USE_ACCELEROMETER:
305                 if( iparam1 )
306                 {
307            data.isRefresh = TRUE;
308                 }
309                 else
310                 {
311            data.isRefresh = FALSE;
312                 }
313                 break;
314         default:
315                  __android_log_print(ANDROID_LOG_INFO, "ARDrone", "unrecognized command received %d", commandId );
316       break;
317         }
318 }
319
320