1 #include <linux/joystick.h>
2 #include <ardrone_api.h>
3 #include <VP_Os/vp_os_print.h>
5 #include "ardrone_ini.h"
7 Controller_info *control;
8 Controller_info *default_control;
16 char name[MAX_NAME_LENGTH];
17 char handlers[MAX_NAME_LENGTH];
20 extern int32_t MiscVar[];
22 input_device_t control_device = {
25 update_control_device,
29 static int32_t joy_dev = 0;
31 C_RESULT open_control_device(void) {
32 C_RESULT res = C_FAIL;
34 printf("%s\n", default_control->filename);
35 if (default_control->serial) {
37 str = g_strsplit(default_control->filename, "/", -1);
38 strncpy(control_device.name, str[3], MAX_NAME_LENGTH);
40 strncpy(control_device.name, "strdup", MAX_NAME_LENGTH);
42 joy_dev = open(default_control->filename, O_NONBLOCK | O_RDONLY);
49 C_RESULT update_control_device(void) {
50 static int32_t stick1LR = 0, stick1UD = 0 , stick2LR = 0 , stick2UD = 0;
51 //static int32_t x = 0, y = 0;
52 static bool_t refresh_values = FALSE;
54 static struct js_event js_e_buffer[64];
55 static int32_t start = 0;
56 input_state_t* input_state;
58 static int center_x1=0;
59 static int center_y1=0;
60 static int center_x2=0;
61 static int center_y2=0;
63 /* static int32_t theta_trim = 0;
64 static int32_t phi_trim = 0;
65 static int32_t yaw_trim = 0;*/
67 if (default_control->config)
70 res = read(joy_dev, js_e_buffer, sizeof(struct js_event) * 64);
72 if( !res || (res < 0 && errno == EAGAIN) )
78 if (res < (int) sizeof(struct js_event)) // If non-complete bloc: ignored
81 // Buffer decomposition in blocs (if the last is incomplete, it's ignored)
83 refresh_values = FALSE;
84 input_state = ardrone_tool_get_input_state();
85 for (idx = 0; idx < res / sizeof(struct js_event); idx++) {
86 if (js_e_buffer[idx].type & JS_EVENT_INIT ) { // If Init, the first values are ignored
88 } else if(js_e_buffer[idx].type & JS_EVENT_BUTTON ) { // Event Button detected
89 if ((js_e_buffer[idx].number == default_control->commands[ROLL_LEFT].value) && (default_control->commands[ROLL_LEFT].type == BUTTON)) {
90 //printf("buttons.control_ag : %d => %d\n", js_e_buffer[idx].number, js_e_buffer[idx].value);
91 stick1LR = -32767 * js_e_buffer[idx].value;
92 } else if ((js_e_buffer[idx].number == default_control->commands[SPEED_DOWN].value) && (default_control->commands[SPEED_DOWN].type == BUTTON)) {
93 //printf("buttons.control_ab : %d => %d\n", js_e_buffer[idx].number, js_e_buffer[idx].value);
94 stick2UD = 32767 * js_e_buffer[idx].value;
95 } else if ((js_e_buffer[idx].number == default_control->commands[ROLL_RIGHT].value) && (default_control->commands[ROLL_RIGHT].type == BUTTON)) {
96 //printf("buttons.control_ad : %d => %d\n", js_e_buffer[idx].number, js_e_buffer[idx].value);
97 stick1LR = 32767 * js_e_buffer[idx].value;
98 } else if ((js_e_buffer[idx].number == default_control->commands[SPEED_UP].value) && (default_control->commands[SPEED_UP].type == BUTTON)) {
99 //printf("buttons.control_ah : %d => %d\n", js_e_buffer[idx].number, js_e_buffer[idx].value);
100 stick2UD = -32767 * js_e_buffer[idx].value;
101 } else if ((js_e_buffer[idx].number == default_control->commands[YAW_LEFT].value) && (default_control->commands[YAW_LEFT].type == BUTTON)) {
102 //printf("buttons.control_l1 : %d => %d\n", js_e_buffer[idx].number, js_e_buffer[idx].value);
103 stick2LR = -32767 * js_e_buffer[idx].value;
104 } else if ((js_e_buffer[idx].number == default_control->commands[YAW_RIGHT].value) && (default_control->commands[YAW_RIGHT].type == BUTTON)) {
105 //printf("buttons.control_r1 : %d => %d\n", js_e_buffer[idx].number, js_e_buffer[idx].value);
106 stick2LR = 32767 * js_e_buffer[idx].value;
107 } else if ((js_e_buffer[idx].number == default_control->commands[EMERGENCY].value) && (default_control->commands[EMERGENCY].type == BUTTON)) {
108 //printf("buttons.control_select : %d => %d\n", js_e_buffer[idx].number, js_e_buffer[idx].value);
109 ardrone_tool_set_ui_pad_select(js_e_buffer[idx].value);
110 } else if ((js_e_buffer[idx].number == default_control->commands[START].value) && (default_control->commands[START].type == BUTTON)) {
111 //printf("buttons.control_start : %d => %d\n", js_e_buffer[idx].number, js_e_buffer[idx].value);
112 if( js_e_buffer[idx].value ) {
114 ardrone_tool_set_ui_pad_start( start );
116 } else if ((js_e_buffer[idx].number == default_control->commands[PITCH_FRONT].value) && (default_control->commands[PITCH_FRONT].type == BUTTON)) {
117 //printf("buttons.pitch_front : %d => %d\n", js_e_buffer[idx].number, js_e_buffer[idx].value);
119 } else if ((js_e_buffer[idx].number == default_control->commands[PITCH_BACK].value) && (default_control->commands[PITCH_BACK].type == BUTTON)) {
120 //printf("buttons.pitch_back : %d => %d\n", js_e_buffer[idx].number, js_e_buffer[idx].value);
123 } else if(js_e_buffer[idx].type & JS_EVENT_AXIS ) { // Event Axis detected
124 refresh_values = TRUE;
125 int axis_value = (js_e_buffer[idx].number + 1) * (js_e_buffer[idx].value > 0 ? 1 : -1);
126 if ((axis_value == default_control->commands[PITCH_FRONT].value) && (default_control->commands[PITCH_FRONT].type == AXIS)) {
127 //printf("axis.pitch_front : %d => %d (%d)\n", js_e_buffer[idx].number, js_e_buffer[idx].value, ( js_e_buffer[idx].value + 1 ) >> 15);
128 stick1UD = ( js_e_buffer[idx].value );
129 } else if ((axis_value == default_control->commands[PITCH_BACK].value) && (default_control->commands[PITCH_BACK].type == AXIS)) {
130 //printf("axis.pitch_back : %d => %d (%d)\n", js_e_buffer[idx].number, js_e_buffer[idx].value, ( js_e_buffer[idx].value + 1 ) >> 15);
131 stick1UD = ( js_e_buffer[idx].value );
132 } else if ((axis_value == default_control->commands[ROLL_LEFT].value) && (default_control->commands[ROLL_LEFT].type == AXIS)) {
133 //printf("axis.roll_left : %d => %d (%d)\n", js_e_buffer[idx].number, js_e_buffer[idx].value, ( js_e_buffer[idx].value + 1 ) >> 15);
134 stick1LR = ( js_e_buffer[idx].value );
135 } else if ((axis_value == default_control->commands[ROLL_RIGHT].value) && (default_control->commands[ROLL_RIGHT].type == AXIS)) {
136 //printf("axis.roll_right : %d => %d (%d)\n", js_e_buffer[idx].number, js_e_buffer[idx].value, ( js_e_buffer[idx].value + 1 ) >> 15);
137 stick1LR = ( js_e_buffer[idx].value );
138 } else if ((axis_value == default_control->commands[SPEED_UP].value) && (default_control->commands[SPEED_UP].type == AXIS)) {
139 //printf("axis.speed_up : %d => %d (%d)\n", js_e_buffer[idx].number, js_e_buffer[idx].value, ( js_e_buffer[idx].value + 1 ) >> 15);
140 stick2UD = ( js_e_buffer[idx].value );
141 } else if ((axis_value == default_control->commands[SPEED_DOWN].value) && (default_control->commands[SPEED_DOWN].type == AXIS)) {
142 //printf("axis.speed_down : %d => %d (%d)\n", js_e_buffer[idx].number, js_e_buffer[idx].value, ( js_e_buffer[idx].value + 1 ) >> 15);
143 stick2UD = ( js_e_buffer[idx].value );
144 } else if ((axis_value == default_control->commands[YAW_LEFT].value) && (default_control->commands[YAW_LEFT].type == AXIS)) {
145 //printf("axis.yaw_left : %d => %d (%d)\n", js_e_buffer[idx].number, js_e_buffer[idx].value, ( js_e_buffer[idx].value + 1 ) >> 15);
146 stick2LR = ( js_e_buffer[idx].value );
147 } else if ((axis_value == default_control->commands[YAW_RIGHT].value) && (default_control->commands[YAW_RIGHT].type == AXIS)) {
148 //printf("axis.yaw_right : %d => %d (%d)\n", js_e_buffer[idx].number, js_e_buffer[idx].value, ( js_e_buffer[idx].value + 1 ) >> 15);
149 stick2LR = ( js_e_buffer[idx].value );
153 // TODO: default: ERROR (non-supported)
157 //if(refresh_values)// Axis values to refresh
159 //printf("roll : %f, pitch : %f, gaz : %f, yaw : %f\n",
160 // /*roll*/(float)(stick1LR-center_x1)/32767.0f,
161 // /*pitch*/(float)(stick1UD-center_y1)/32767.0f,
162 // /*gaz*/-(float)(stick2UD-center_x2)/32767.0f,
163 // /*yaw*/(float)(stick2LR-center_y2)/32767.0f);
165 if ( 327 > stick1LR && -327 < stick1LR &&
166 327 > stick1UD && -327 < stick1UD &&
167 327 > stick2LR && -327 < stick2LR &&
168 327 > stick2UD && -327 < stick2UD)
172 ardrone_at_set_progress_cmd( enable,
173 /*roll*/(float)(stick1LR-center_x1)/32767.0f,
174 /*pitch*/(float)(stick1UD-center_y1)/32767.0f,
175 /*gaz*/-(float)(stick2UD-center_x2)/32767.0f,
176 /*yaw*/(float)(stick2LR-center_y2)/32767.0f );
182 C_RESULT close_control_device(void) {
188 uint32_t uint32_atoi(char* buf){
191 while((*buf >= '0' && *buf <= '9') || (*buf >= 'a' && *buf <= 'f') || (*buf >= 'A' && *buf <= 'F')){
193 if(tmp >= 'a' && tmp <= 'f')
195 if(tmp >= 'A' && tmp <= 'F')
208 * Search all Joystick devices
210 gboolean search_devices(GList **list_controllers) {
212 Controller_info *ctrl_info;
214 struct udev_device *dev;
216 for(i = 0; i < 32; ++i) {
218 str = g_strdup_printf("/dev/input/js%d", i);
219 int fd = open(str, O_RDONLY);
221 //printf("Could not found joystick: %s\n", str->str);
224 ctrl_info = g_malloc(sizeof(Controller_info));
225 uint8_t num_axis = 0;
226 uint8_t num_button = 0;
227 ioctl(fd, JSIOCGAXES, &num_axis);
228 ioctl(fd, JSIOCGBUTTONS, &num_button);
229 ctrl_info->filename = g_strdup(str);
230 ctrl_info->num_axis = num_axis;
231 ctrl_info->num_buttons = num_button;
233 char name_c_str[1024];
234 if (ioctl(fd, JSIOCGNAME(sizeof(name_c_str)), name_c_str) < 0) {
235 printf("%s : %s", str, strerror(errno));
238 ctrl_info->name = g_convert_with_fallback(name_c_str, sizeof(name_c_str), "UTF-8", "ISO-8859-1", NULL, NULL, NULL, NULL);
241 /* Create the udev object */
244 printf("Can't create udev\n");
248 dev = udev_device_new_from_subsystem_sysname(udev, "input", g_strdup_printf("js%d", i));
252 ctrl_info->serial = uint32_atoi(g_strdup_printf("%s%s", udev_list_entry_get_value(udev_list_entry_get_by_name(udev_device_get_properties_list_entry(dev), "ID_VENDOR_ID")), udev_list_entry_get_value(udev_list_entry_get_by_name(udev_device_get_properties_list_entry(dev), "ID_MODEL_ID"))));
254 udev_device_unref(dev);
256 printf("%s : %d, %d, 0x%08x\n", ctrl_info->name, ctrl_info->num_axis, ctrl_info->num_buttons, ctrl_info->serial);
258 *list_controllers = g_list_append(*list_controllers, ctrl_info);
265 void parseControls(xmlDocPtr doc, xmlNodePtr cur) {
266 cur = cur->xmlChildrenNode;
267 while (cur != NULL) {
268 if ((!xmlStrcmp(cur->name, (const xmlChar *)"control"))) {
269 if ((!xmlStrcmp(xmlGetProp(cur, BAD_CAST "name"), (const xmlChar *) "takeoff"))) {
270 control->commands[START].value = atoi(g_strdup((const char *) xmlGetProp(cur, BAD_CAST "value")));
271 control->commands[START].type = atoi(g_strdup((const char *) xmlGetProp(cur, BAD_CAST "type")));
272 } else if ((!xmlStrcmp(xmlGetProp(cur, BAD_CAST "name"), (const xmlChar *) "emergency"))) {
273 control->commands[EMERGENCY].value = atoi(g_strdup((const char *) xmlGetProp(cur, BAD_CAST "value")));
274 control->commands[EMERGENCY].type = atoi(g_strdup((const char *) xmlGetProp(cur, BAD_CAST "type")));
275 } else if ((!xmlStrcmp(xmlGetProp(cur, BAD_CAST "name"), (const xmlChar *) "pitch_front"))) {
276 control->commands[PITCH_FRONT].value = atoi(g_strdup((const char *) xmlGetProp(cur, BAD_CAST "value")));
277 control->commands[PITCH_FRONT].type = atoi(g_strdup((const char *) xmlGetProp(cur, BAD_CAST "type")));
278 } else if ((!xmlStrcmp(xmlGetProp(cur, BAD_CAST "name"), (const xmlChar *) "pitch_back"))) {
279 control->commands[PITCH_BACK].value = atoi(g_strdup((const char *) xmlGetProp(cur, BAD_CAST "value")));
280 control->commands[PITCH_BACK].type = atoi(g_strdup((const char *) xmlGetProp(cur, BAD_CAST "type")));
281 } else if ((!xmlStrcmp(xmlGetProp(cur, BAD_CAST "name"), (const xmlChar *) "roll_left"))) {
282 control->commands[ROLL_LEFT].value = atoi(g_strdup((const char *) xmlGetProp(cur, BAD_CAST "value")));
283 control->commands[ROLL_LEFT].type = atoi(g_strdup((const char *) xmlGetProp(cur, BAD_CAST "type")));
284 } else if ((!xmlStrcmp(xmlGetProp(cur, BAD_CAST "name"), (const xmlChar *) "roll_right"))) {
285 control->commands[ROLL_RIGHT].value = atoi(g_strdup((const char *) xmlGetProp(cur, BAD_CAST "value")));
286 control->commands[ROLL_RIGHT].type = atoi(g_strdup((const char *) xmlGetProp(cur, BAD_CAST "type")));
287 } else if ((!xmlStrcmp(xmlGetProp(cur, BAD_CAST "name"), (const xmlChar *) "yaw_left"))) {
288 control->commands[YAW_LEFT].value = atoi(g_strdup((const char *) xmlGetProp(cur, BAD_CAST "value")));
289 control->commands[YAW_LEFT].type = atoi(g_strdup((const char *) xmlGetProp(cur, BAD_CAST "type")));
290 } else if ((!xmlStrcmp(xmlGetProp(cur, BAD_CAST "name"), (const xmlChar *) "yaw_right"))) {
291 control->commands[YAW_RIGHT].value = atoi(g_strdup((const char *) xmlGetProp(cur, BAD_CAST "value")));
292 control->commands[YAW_RIGHT].type = atoi(g_strdup((const char *) xmlGetProp(cur, BAD_CAST "type")));
293 } else if ((!xmlStrcmp(xmlGetProp(cur, BAD_CAST "name"), (const xmlChar *) "speed_up"))) {
294 control->commands[SPEED_UP].value = atoi(g_strdup((const char *) xmlGetProp(cur, BAD_CAST "value")));
295 control->commands[SPEED_UP].type = atoi(g_strdup((const char *) xmlGetProp(cur, BAD_CAST "type")));
296 } else if ((!xmlStrcmp(xmlGetProp(cur, BAD_CAST "name"), (const xmlChar *) "speed_down"))) {
297 control->commands[SPEED_DOWN].value = atoi(g_strdup((const char *) xmlGetProp(cur, BAD_CAST "value")));
298 control->commands[SPEED_DOWN].type = atoi(g_strdup((const char *) xmlGetProp(cur, BAD_CAST "type")));
305 void parseDevice(xmlDocPtr doc, xmlNodePtr cur) {
306 cur = cur->xmlChildrenNode;
307 while (cur != NULL) {
308 if ((!xmlStrcmp(cur->name, (const xmlChar *)"controls"))) {
309 parseControls(doc, cur);
315 void parseDevices(xmlDocPtr doc, xmlNodePtr cur) {
316 cur = cur->xmlChildrenNode;
317 while (cur != NULL) {
318 if ((!xmlStrcmp(cur->name, (const xmlChar *)"device"))) {
319 control = g_malloc(sizeof(Controller_info));
320 control->serial = atoi(g_strdup((const char *) xmlGetProp(cur, BAD_CAST "id")));
321 control->name = g_strdup((const char *) xmlGetProp(cur, BAD_CAST "name"));
322 control->def = xmlStrEqual(xmlGetProp(cur, BAD_CAST "default"), (const xmlChar *)"yes") ? TRUE : FALSE;
323 control->config = FALSE;
324 if (!control->serial)
325 control->filename = g_strdup("/dev/stdin");
327 control->filename = g_strdup("");
328 printf("Device 0x%08x : %s (%s) (%s)\n", control->serial, control->name, (control->def)?"yes":"no", control->filename);
329 parseDevice(doc, cur);
330 devices = g_list_append(devices, control);
332 default_control = control;
341 GList* list_controllers = NULL;
343 printf("Loading configuration file %s\n", FILENAME);
345 doc = xmlParseFile(FILENAME);
348 printf("Document not parsed successfully. \n");
353 cur = xmlDocGetRootElement(doc);
355 printf("Empty document\n");
361 if (xmlStrcmp(cur->name, (const xmlChar *) "ardrone")) {
362 printf("Document of the wrong type, root node != ardrone");
368 cur = cur->xmlChildrenNode;
369 while (cur != NULL) {
370 if ((!xmlStrcmp(cur->name, (const xmlChar *)"devices"))){
371 parseDevices (doc, cur);
380 search_devices(&list_controllers);
382 for (it = devices; it; it = it->next) {
384 c = (Controller_info *) it->data;
385 for (it2 = list_controllers; it2; it2 = it2->next) {
387 c2 = (Controller_info *) it2->data;
388 if (c->serial == c2->serial) {
389 c->filename = strdup(c2->filename);
394 for (it = list_controllers; it; it = it->next) {
396 c = (Controller_info *) it->data;
397 if (c->serial == default_control->serial)
401 default_control->def = FALSE;
402 default_control = devices->data;
403 default_control->def = TRUE;
406 printf("Loading complete\n");
409 void save_init(Controller_info *def) {
411 xmlNodePtr devices_xml, device_xml, controls_xml, control_xml;
413 printf("Beginning writing %s\n", FILENAME);
415 doc = xmlNewDoc(BAD_CAST "1.0");
416 doc->children = xmlNewDocNode(doc, NULL, BAD_CAST "ardrone", NULL);
417 devices_xml = xmlNewChild(doc->children, NULL, BAD_CAST "devices", NULL);
420 for (it = devices; it; it = it->next) {
422 c = (Controller_info *) it->data;
424 device_xml = xmlNewChild(devices_xml, NULL, BAD_CAST "device", NULL);
425 xmlSetProp(device_xml, BAD_CAST "id", BAD_CAST g_strdup_printf("%u", c->serial));
426 xmlSetProp(device_xml, BAD_CAST "name", BAD_CAST c->name);
427 xmlSetProp(device_xml, BAD_CAST "default", BAD_CAST (c == def ? "yes" : "no"));
428 controls_xml = xmlNewChild(device_xml, NULL, BAD_CAST "controls", NULL);
429 control_xml = xmlNewChild(controls_xml, NULL, BAD_CAST "control", NULL);
430 xmlSetProp(control_xml, BAD_CAST "name", BAD_CAST "takeoff");
431 xmlSetProp(control_xml, BAD_CAST "value", BAD_CAST g_strdup_printf("%d", c->commands[START].value));
432 xmlSetProp(control_xml, BAD_CAST "type", BAD_CAST g_strdup_printf("%d", c->commands[START].type));
433 control_xml = xmlNewChild(controls_xml, NULL, BAD_CAST "control", NULL);
434 xmlSetProp(control_xml, BAD_CAST "name", BAD_CAST "emergency");
435 xmlSetProp(control_xml, BAD_CAST "value", BAD_CAST g_strdup_printf("%d", c->commands[EMERGENCY].value));
436 xmlSetProp(control_xml, BAD_CAST "type", BAD_CAST g_strdup_printf("%d", c->commands[EMERGENCY].type));
437 control_xml = xmlNewChild(controls_xml, NULL, BAD_CAST "control", NULL);
438 xmlSetProp(control_xml, BAD_CAST "name", BAD_CAST "pitch_front");
439 xmlSetProp(control_xml, BAD_CAST "value", BAD_CAST g_strdup_printf("%d", c->commands[PITCH_FRONT].value));
440 xmlSetProp(control_xml, BAD_CAST "type", BAD_CAST g_strdup_printf("%d", c->commands[PITCH_FRONT].type));
441 control_xml = xmlNewChild(controls_xml, NULL, BAD_CAST "control", NULL);
442 xmlSetProp(control_xml, BAD_CAST "name", BAD_CAST "pitch_back");
443 xmlSetProp(control_xml, BAD_CAST "value", BAD_CAST g_strdup_printf("%d", c->commands[PITCH_BACK].value));
444 xmlSetProp(control_xml, BAD_CAST "type", BAD_CAST g_strdup_printf("%d", c->commands[PITCH_BACK].type));
445 control_xml = xmlNewChild(controls_xml, NULL, BAD_CAST "control", NULL);
446 xmlSetProp(control_xml, BAD_CAST "name", BAD_CAST "roll_left");
447 xmlSetProp(control_xml, BAD_CAST "value", BAD_CAST g_strdup_printf("%d", c->commands[ROLL_LEFT].value));
448 xmlSetProp(control_xml, BAD_CAST "type", BAD_CAST g_strdup_printf("%d", c->commands[ROLL_LEFT].type));
449 control_xml = xmlNewChild(controls_xml, NULL, BAD_CAST "control", NULL);
450 xmlSetProp(control_xml, BAD_CAST "name", BAD_CAST "roll_right");
451 xmlSetProp(control_xml, BAD_CAST "value", BAD_CAST g_strdup_printf("%d", c->commands[ROLL_RIGHT].value));
452 xmlSetProp(control_xml, BAD_CAST "type", BAD_CAST g_strdup_printf("%d", c->commands[ROLL_RIGHT].type));
453 control_xml = xmlNewChild(controls_xml, NULL, BAD_CAST "control", NULL);
454 xmlSetProp(control_xml, BAD_CAST "name", BAD_CAST "yaw_left");
455 xmlSetProp(control_xml, BAD_CAST "value", BAD_CAST g_strdup_printf("%d", c->commands[YAW_LEFT].value));
456 xmlSetProp(control_xml, BAD_CAST "type", BAD_CAST g_strdup_printf("%d", c->commands[YAW_LEFT].type));
457 control_xml = xmlNewChild(controls_xml, NULL, BAD_CAST "control", NULL);
458 xmlSetProp(control_xml, BAD_CAST "name", BAD_CAST "yaw_right");
459 xmlSetProp(control_xml, BAD_CAST "value", BAD_CAST g_strdup_printf("%d", c->commands[YAW_RIGHT].value));
460 xmlSetProp(control_xml, BAD_CAST "type", BAD_CAST g_strdup_printf("%d", c->commands[YAW_RIGHT].type));
461 control_xml = xmlNewChild(controls_xml, NULL, BAD_CAST "control", NULL);
462 xmlSetProp(control_xml, BAD_CAST "name", BAD_CAST "speed_up");
463 xmlSetProp(control_xml, BAD_CAST "value", BAD_CAST g_strdup_printf("%d", c->commands[SPEED_UP].value));
464 xmlSetProp(control_xml, BAD_CAST "type", BAD_CAST g_strdup_printf("%d", c->commands[SPEED_UP].type));
465 control_xml = xmlNewChild(controls_xml, NULL, BAD_CAST "control", NULL);
466 xmlSetProp(control_xml, BAD_CAST "name", BAD_CAST "speed_down");
467 xmlSetProp(control_xml, BAD_CAST "value", BAD_CAST g_strdup_printf("%d", c->commands[SPEED_DOWN].value));
468 xmlSetProp(control_xml, BAD_CAST "type", BAD_CAST g_strdup_printf("%d", c->commands[SPEED_DOWN].type));
470 xmlKeepBlanksDefault(0);
471 xmlSaveFormatFile(FILENAME, doc, 1);
473 default_control = def;
474 printf("Writing %s OK\n", FILENAME);
478 * Create the initial configuration file with default keyboard values
483 control = g_malloc(sizeof(Controller_info));
485 control->name = g_strdup("Keyboard");
487 control->config = FALSE;
488 control->filename = g_strdup("/dev/stdin");
489 control->commands[START].value = 13; // start decollage / atterissage
490 control->commands[EMERGENCY].value = 32; // emergency coupe les moteurs
491 control->commands[SPEED_DOWN].value = 88; // descendre
492 control->commands[SPEED_UP].value = 90; // monter
493 control->commands[ROLL_LEFT].value = 81; // tourner a gauche
494 control->commands[ROLL_RIGHT].value = 68; // tourner a droite
495 control->commands[YAW_LEFT].value = 65361; // pivoter a gauche
496 control->commands[YAW_RIGHT].value = 65363; // pivoter a droite
497 control->commands[PITCH_FRONT].value = 65362; // deplacement en avant
498 control->commands[PITCH_BACK].value = 65364; // deplacement en arriere
499 for (i = 0; i < NUM_COMMAND; i++) {
500 control->commands[i].type = NONE;
503 devices = g_list_append(devices, control);
504 default_control = control;
506 save_init(default_control);