3 #include <VP_Os/vp_os_print.h>
4 #include <VP_Com/vp_com.h>
6 #include <ardrone_api.h>
7 #include <ardrone_tool/ardrone_tool.h>
8 #include <ardrone_tool/Control/ardrone_control.h>
9 #include <ardrone_tool/Control/ardrone_control_configuration.h>
10 #include <ardrone_tool/Control/ardrone_control_soft_update.h>
11 #include <ardrone_tool/Control/ardrone_control_ack.h>
12 #include <ardrone_tool/Com/config_com.h>
13 #include <ardrone_tool/Com/config_wifi.h>
16 #include <sys/socket.h>
17 #include <sys/ioctl.h>
18 #include <netinet/in.h>
19 #include <netinet/tcp.h>
23 static vp_com_socket_t control_socket;
24 static Read control_read = NULL;
25 static Write control_write = NULL;
27 static vp_os_mutex_t control_mutex;
28 static vp_os_cond_t control_cond;
30 static bool_t control_waited;
31 static bool_t bContinue = TRUE;
32 static uint32_t ardrone_state;
34 static int32_t start_index_in_queue;
35 static int32_t end_index_in_queue;
36 static ardrone_control_event_ptr_t ardrone_control_event_queue[ARDRONE_CONTROL_MAX_NUM_EVENTS_IN_QUEUE];
38 static vp_os_mutex_t event_queue_mutex;
40 C_RESULT ardrone_control_init(void)
42 COM_CONFIG_SOCKET_CONTROL(&control_socket, VP_COM_CLIENT, CONTROL_PORT, wifi_ardrone_ip);
44 control_waited = FALSE;
47 vp_os_mutex_init(&control_mutex);
48 vp_os_cond_init(&control_cond, &control_mutex);
50 vp_os_mutex_init(&event_queue_mutex);
52 start_index_in_queue = 0;
53 end_index_in_queue = (start_index_in_queue - 1) & (ARDRONE_CONTROL_MAX_NUM_EVENTS_IN_QUEUE - 1);
58 C_RESULT ardrone_control_shutdown(void)
60 ardrone_control_resume_on_navdata_received(0);
61 /*BUG FIX : Dont destroy the mutexes here,
62 they are still being used by the ardrone_control thread,
63 while this function is called by another thread.*/
65 vp_os_mutex_destroy(&event_queue_mutex);
66 vp_os_cond_destroy(&control_cond);
67 vp_os_mutex_destroy(&control_mutex);*/
75 C_RESULT ardrone_control_connect_to_drone()
80 int timeout_windows=1000;/*milliseconds*/
85 vp_com_close(COM_CONTROL(), &control_socket);
87 res_open_socket = vp_com_open(COM_CONTROL(), &control_socket, &control_read, &control_write);
88 if( VP_SUCCEEDED(res_open_socket) )
93 setsockopt((int32_t)control_socket.priv,
97 (const char*)&timeout_windows, sizeof(timeout_windows)
99 (const char*)&tv, sizeof(tv)
103 control_socket.is_disable = FALSE;
108 DEBUG_PRINT_SDK("VP_Com : Failed to open socket for control\n");
116 * \brief Signals the client control thread that new navdata were received.
117 * Called by one of the navdata callbacks.
119 C_RESULT ardrone_control_resume_on_navdata_received(uint32_t new_ardrone_state)
121 vp_os_mutex_lock(&control_mutex);
124 ardrone_state = new_ardrone_state;
125 vp_os_cond_signal(&control_cond);
127 vp_os_mutex_unlock(&control_mutex);
131 C_RESULT ardrone_control_read(int8_t* buffer, int32_t* size)
133 C_RESULT res = C_FAIL;
135 if( control_read != NULL )
137 res = control_read(&control_socket, (int8_t*) buffer, size);
147 C_RESULT ardrone_control_write(const int8_t* buffer, int32_t* size)
149 C_RESULT res = C_FAIL;
151 if( control_write != NULL )
153 res = control_write(&control_socket, buffer, size);
159 C_RESULT ardrone_control_send_event( ardrone_control_event_t* event )
162 int32_t next_index_in_queue;
166 vp_os_mutex_lock(&event_queue_mutex);
167 next_index_in_queue = (start_index_in_queue + 1) & (ARDRONE_CONTROL_MAX_NUM_EVENTS_IN_QUEUE - 1);
168 if( next_index_in_queue != end_index_in_queue )
170 ardrone_control_event_queue[start_index_in_queue] = event;
171 start_index_in_queue = next_index_in_queue;
176 vp_os_mutex_unlock(&event_queue_mutex);
181 DEFINE_THREAD_ROUTINE( ardrone_control, nomParams )
183 C_RESULT res_wait_navdata = C_OK;
185 uint32_t retry, current_ardrone_state;
186 int32_t next_index_in_queue;
187 ardrone_control_event_ptr_t current_event;
190 current_event = NULL;
192 DEBUG_PRINT_SDK("Thread control in progress...\n");
193 control_socket.is_disable = TRUE;
195 ardrone_control_connect_to_drone();
198 && !ardrone_tool_exit() )
200 vp_os_mutex_lock(&control_mutex);
201 control_waited = TRUE;
203 /* Wait for new navdata to be received. */
204 res_wait_navdata = vp_os_cond_timed_wait(&control_cond, 1000);
205 vp_os_mutex_unlock(&control_mutex);
208 * In case of timeout on the navdata, we assume that there was a problem
209 * with the Wifi connection.
210 * It is then safer to close and reopen the control socket (TCP 5559) since
211 * some OS might stop giving data but not signal any disconnection.
213 if(VP_FAILED(res_wait_navdata))
215 DEBUG_PRINT_SDK("Timeout while waiting for new navdata.\n");
216 if(!control_socket.is_disable)
217 control_socket.is_disable = TRUE;
220 if(control_socket.is_disable)
222 ardrone_control_connect_to_drone();
225 if(VP_SUCCEEDED(res_wait_navdata) && (!control_socket.is_disable))
227 vp_os_mutex_lock(&control_mutex);
228 current_ardrone_state = ardrone_state;
229 control_waited = FALSE;
230 vp_os_mutex_unlock(&control_mutex);
232 if( ardrone_tool_exit() ) // Test if we received a signal because we are quitting the application
233 THREAD_RETURN( res );
235 if( current_event == NULL )
237 vp_os_mutex_lock(&event_queue_mutex);
238 next_index_in_queue = (end_index_in_queue + 1) & (ARDRONE_CONTROL_MAX_NUM_EVENTS_IN_QUEUE - 1);
240 if( next_index_in_queue != start_index_in_queue )
241 { // There's an event to process
242 current_event = ardrone_control_event_queue[next_index_in_queue];
243 if( current_event != NULL )
245 if( current_event->ardrone_control_event_start != NULL )
247 current_event->ardrone_control_event_start( current_event );
250 end_index_in_queue = next_index_in_queue;
255 vp_os_mutex_unlock(&event_queue_mutex);
258 if( current_event != NULL )
260 switch( current_event->event )
262 case ARDRONE_UPDATE_CONTROL_MODE:
263 res = ardrone_control_soft_update_run( current_ardrone_state, (ardrone_control_soft_update_event_t*) current_event );
266 case PIC_UPDATE_CONTROL_MODE:
267 res = ardrone_control_soft_update_run( current_ardrone_state, (ardrone_control_soft_update_event_t*) current_event );
270 case LOGS_GET_CONTROL_MODE:
273 case CFG_GET_CONTROL_MODE:
274 case CUSTOM_CFG_GET_CONTROL_MODE: /* multiconfiguration support */
275 res = ardrone_control_configuration_run( current_ardrone_state, (ardrone_control_configuration_event_t*) current_event );
278 case ACK_CONTROL_MODE:
279 res = ardrone_control_ack_run( current_ardrone_state, (ardrone_control_ack_event_t *) current_event);
289 if( retry > current_event->num_retries)
290 current_event->status = ARDRONE_CONTROL_EVENT_FINISH_FAILURE;
297 if( current_event->status & ARDRONE_CONTROL_EVENT_FINISH )
299 if( current_event->ardrone_control_event_end != NULL )
300 current_event->ardrone_control_event_end( current_event );
302 /* Make the thread read a new event on the next loop iteration */
303 current_event = NULL;
307 /* Not changing 'current_event' makes the loop process the same
308 * event when the next navdata packet arrives. */
314 /* Stephane : Bug fix - mutexes were previously detroyed by another thread,
315 which made ardrone_control crash.*/
316 vp_os_mutex_destroy(&event_queue_mutex);
317 vp_os_cond_destroy(&control_cond);
318 vp_os_mutex_destroy(&control_mutex);
320 vp_com_close(COM_CONTROL(), &control_socket);
322 THREAD_RETURN( res );