6 #include <VP_Os/vp_os_print.h>
7 #include <VP_Com/vp_com.h>
9 #include <ardrone_api.h>
10 #include <ardrone_tool/ardrone_tool.h>
11 #include <ardrone_tool/Navdata/ardrone_navdata_client.h>
12 #include <ardrone_tool/Com/config_com.h>
15 #include <sys/socket.h>
16 #include <sys/ioctl.h>
17 #include <netinet/in.h>
18 #include <netinet/tcp.h>
22 // PROTO_THREAD_ROUTINE( navdata_update , nomParams );
24 static bool_t navdata_thread_in_pause = TRUE;
25 static bool_t bContinue = TRUE;
26 static uint32_t num_retries = 0;
27 static vp_os_cond_t navdata_client_condition;
28 static vp_os_mutex_t navdata_client_mutex;
30 static vp_com_socket_t navdata_socket;
31 static Read navdata_read = NULL;
32 static Write navdata_write = NULL;
34 static uint8_t navdata_buffer[NAVDATA_MAX_SIZE];
35 navdata_unpacked_t navdata_unpacked;
37 C_RESULT ardrone_navdata_client_init(void)
41 COM_CONFIG_SOCKET_NAVDATA(&navdata_socket, VP_COM_CLIENT, NAVDATA_PORT, wifi_ardrone_ip);
42 navdata_socket.protocol = VP_COM_UDP;
43 navdata_socket.is_multicast = 1; // enable multicast for Navdata
44 navdata_socket.multicast_base_addr = MULTICAST_BASE_ADDR;
46 vp_os_mutex_init(&navdata_client_mutex);
47 vp_os_cond_init(&navdata_client_condition, &navdata_client_mutex);
54 C_RESULT ardrone_navdata_client_suspend(void)
56 vp_os_mutex_lock(&navdata_client_mutex);
57 navdata_thread_in_pause = TRUE;
58 vp_os_mutex_unlock(&navdata_client_mutex);
63 C_RESULT ardrone_navdata_client_resume(void)
65 vp_os_mutex_lock(&navdata_client_mutex);
66 vp_os_cond_signal(&navdata_client_condition);
67 navdata_thread_in_pause = FALSE;
68 vp_os_mutex_unlock(&navdata_client_mutex);
73 C_RESULT ardrone_navdata_open_server(void)
78 int32_t flag = 1, len = sizeof(flag);
80 if( navdata_write != NULL )
82 if (navdata_socket.is_multicast == 1)
85 navdata_write(&navdata_socket, (const int8_t*) &flag, &len);
91 DEFINE_THREAD_ROUTINE( navdata_update, nomParams )
95 uint32_t cks, navdata_cks, sequence = NAVDATA_SEQUENCE_DEFAULT-1;
98 int timeout_for_windows=1000/*milliseconds*/;
102 navdata_t* navdata = (navdata_t*) &navdata_buffer[0];
104 tv.tv_sec = 1/*second*/;
109 if( VP_FAILED(vp_com_open(COM_NAVDATA(), &navdata_socket, &navdata_read, &navdata_write)) )
111 printf("VP_Com : Failed to open socket for navdata\n");
115 if( VP_SUCCEEDED(res) )
117 PRINT("Thread navdata_update in progress...\n");
120 setsockopt((int32_t)navdata_socket.priv, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout_for_windows, sizeof(timeout_for_windows));
121 /* Added by Stephane to force the drone start sending data. */
123 { int sizeinit = 5; navdata_write( (void*)&navdata_socket, (int8_t*)"Init", &sizeinit ); }
125 setsockopt((int32_t)navdata_socket.priv, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof(tv));
130 while( ardrone_navdata_handler_table[i].init != NULL )
132 // if init failed for an handler we set its process function to null
133 // We keep its release function for cleanup
134 if( VP_FAILED( ardrone_navdata_handler_table[i].init(ardrone_navdata_handler_table[i].data) ) )
135 ardrone_navdata_handler_table[i].process = NULL;
140 navdata_thread_in_pause = FALSE;
141 while( VP_SUCCEEDED(res)
142 && !ardrone_tool_exit()
145 if(navdata_thread_in_pause)
147 vp_os_mutex_lock(&navdata_client_mutex);
148 num_retries = NAVDATA_MAX_RETRIES + 1;
149 vp_os_cond_wait(&navdata_client_condition);
150 vp_os_mutex_unlock(&navdata_client_mutex);
153 if( navdata_read == NULL )
159 size = NAVDATA_MAX_SIZE;
160 navdata->header = 0; // Soft reset
161 res = navdata_read( (void*)&navdata_socket, (int8_t*)&navdata_buffer[0], &size );
170 PRINT("Timeout when reading navdatas - resending a navdata request on port %i\n",NAVDATA_PORT);
171 /* Resend a request to the drone to get navdatas */
172 ardrone_navdata_open_server();
173 sequence = NAVDATA_SEQUENCE_DEFAULT-1;
179 if( VP_SUCCEEDED( res ) )
181 if( navdata->header == NAVDATA_HEADER )
183 if( ardrone_get_mask_from_state(navdata->ardrone_state, ARDRONE_COM_WATCHDOG_MASK) )
185 // reset sequence number because of com watchdog
186 // This code is mandatory because we can have a com watchdog without detecting it on mobile side :
187 // Reconnection is fast enough (less than one second)
188 sequence = NAVDATA_SEQUENCE_DEFAULT-1;
190 if( ardrone_get_mask_from_state(navdata->ardrone_state, ARDRONE_NAVDATA_BOOTSTRAP) == FALSE )
191 ardrone_tool_send_com_watchdog(); // acknowledge
194 if( navdata->sequence > sequence )
198 ardrone_navdata_unpack_all(&navdata_unpacked, navdata, &navdata_cks);
199 cks = ardrone_navdata_compute_cks( &navdata_buffer[0], size - sizeof(navdata_cks_t) );
201 if( cks == navdata_cks )
203 while( ardrone_navdata_handler_table[i].init != NULL )
205 if( ardrone_navdata_handler_table[i].process != NULL )
206 ardrone_navdata_handler_table[i].process( &navdata_unpacked );
213 PRINT("[Navdata] Checksum failed : %d (distant) / %d (local)\n", navdata_cks, cks);
218 PRINT("[Navdata] Sequence pb : %d (distant) / %d (local)\n", navdata->sequence, sequence);
221 // remaining = sizeof(navdata);
223 sequence = navdata->sequence;
228 // Release resources alllocated by handlers
230 while( ardrone_navdata_handler_table[i].init != NULL )
232 ardrone_navdata_handler_table[i].release();
238 vp_com_close(COM_NAVDATA(), &navdata_socket);
240 DEBUG_PRINT_SDK("Thread navdata_update ended\n");
242 return (THREAD_RET)res;
245 uint32_t ardrone_navdata_client_get_num_retries(void)
250 C_RESULT ardrone_navdata_client_shutdown(void)