/****************************************************************************** menu.h - Created by Peter Mauger 25/07/01 Last Modified 12/10/01 menu provides the Startup menu functions. The menu will provide the ability to modify servo limits, download a new set of waypoints, check the values of the GPS and compass, and possibly some other functions. ******************************************************************************/ #include "menu.h" /* Start_Menu is the function which initialises the menu system for the aircraft * before takeoff. When it returns the plane will either be ready for automatic * flight, or the program will be terminated. Once the plane is ready for flight * it is only waiting for the autopilot to be activated by the pilot. * inputs: plane->contains the required structures and data * returns: GO if the program should proceed * TERMINATE if the program should be finished */ programstate Start_Menu(planestate *plane) { int key = 0; while(TRUE) { key = 0; LCDClear(); LCDMenu("FLY","SET","TST","END"); LCDPrintf("FLY begins auto\n"); LCDPrintf("SET hardware\n"); LCDPrintf("TST sensors\n"); LCDPrintf("END terminates\n"); while(key == 0) { key = Check_Input(); } switch(key) { case KEY1: /* Begin Flight */ return GO; case KEY2: /* Set Menu */ Set_Menu(plane); break; case KEY3: /* Test sensors */ Test_Menu(plane); break; case KEY4: /* Check for termination then finish program */ if(Confirmation_Menu() == TERMINATE) return TERMINATE; else break; default: break; } } } /* Set_Menu provides further sub-menues to set servos, the compass, or upload new * waypoints. * inputs: plane->control struct contains the servo handles */ void Set_Menu(planestate *plane) { int key; while(TRUE) { key = 0; LCDClear(); LCDMenu("SVO","CMP","WP","END"); LCDPrintf("SVO servo limits"); LCDPrintf("CMP init compass"); LCDPrintf("WP upload wps\n"); LCDPrintf("END returns\n"); while(key == 0) { key = Check_Input(); } switch(key) { case KEY1: /* Set the servos */ Servo_Set_Menu(plane); break; case KEY2: /* Initialise the compass */ Compass_Set_Menu(); break; case KEY3: /* Upload new waypoints */ Upload_Waypoints_Menu(plane); break; case KEY4: /* Return to the main menu */ return; default: break; } } } /* Servo_Set_Menu provides the ability to set the limits and neutral points of * all of the servos controlled by the eyebot. * inputs: plane->control struct contains the servo handles */ void Servo_Set_Menu(planestate *plane) { bool test; int key; error error_type = NOERROR; ctrlsurface ctrl_surface; while(TRUE) { key = 0; LCDClear(); LCDMenu("RUD","","","END"); LCDPrintf("RUD rudder set\n"); LCDPrintf("END returns\n"); while(key == 0) { key = Check_Input(); } switch(key) { case KEY1: /* Set the rudder servo */ test = FALSE; error_type = Get_Ctrl_Surface(*plane, RUDDER, &ctrl_surface); if(error_type == NOERROR) { error_type = Establish_Servo_Limits(&ctrl_surface); if(error_type == NOERROR) { error_type = Test_Servo_Limits(ctrl_surface, &test); if(error_type != NOERROR) { LCDPrintf("Error %d in test process\n", error_type); OSWait(LONG); break; } } else { LCDPrintf("Error %d in set process\n", error_type); OSWait(LONG); break; } } else { LCDPrintf("cs RUDDER not found!\n"); break; } if(error_type == NOERROR && test == TRUE) Set_Ctrl_Surface(plane, ctrl_surface, RUDDER); break; case KEY4: /* Return to the set menu */ return; default: break; } } } /* Compass_Set_Menu allows the compass to be reinitialised (if it is incorrectly * aligned) */ void Compass_Set_Menu() { bool valid; valid = Calibrate_Compass(); if(valid == FALSE) { LCDPrintf("No compass data.Recalibrate"); } } /* Upload_Waypoints_Menu allows the user to overwrite the old set of waypoints *with a new set. *inputs: plane->position struct contains the waypoint list */ void Upload_Waypoints_Menu(planestate *plane) { wplist waypoints; error error_type; int num_waypoints; int key = 0; while(TRUE) { key = 0; LCDClear(); LCDMenu("UPL","","","END"); LCDPrintf("Connect SERIAL1\n"); LCDPrintf("Then press UPL\n"); LCDPrintf("END returns\n"); while(key == 0) { key = Check_Input(); } switch(key) { case KEY1: /* Begin uploading new waypoints */ waypoints = Init_Wplist(); /* initialise a new waypoint list */ LCDClear(); error_type = Obtain_Wplist_From_File(&waypoints); /* receive the file and store the waypoints */ OSWait(LONG); if(error_type != NOERROR) { LCDPrintf("Upload error\n"); LCDPrintf("No wps saved\n"); OSWait(LONG); return; } Store_Wplist(plane, waypoints); /* store the waypoints in the plane structure */ LCDClear(); LCDPrintf("Wps received\n"); num_waypoints = Get_Wplist_Total(waypoints); LCDPrintf("Number wps= %d\n",num_waypoints); OSWait(LONG); return; case KEY4: /* Return to the set menu */ return; default: break; } } } /* Test_Menu allows the user to read the values of the two sensors used, the * GPS and the compass. * inputs: plane->plane struct required to obtain GPS position */ void Test_Menu(planestate *plane) { position pos; double latitude, longitude; char *cardinallat, *cardinallong; bool check; int key; LCDClear(); LCDMenu("","","","END"); LCDSetPrintf(0,0,"END returns"); while(TRUE) { key = 0; key = Check_Input(); if(key != KEY4) /* Keep printing data until END is pressed */ { check = Obtain_GPS_Position(plane); if(check == TRUE) { pos = Get_Curr_Pos(*plane); latitude = Get_Latitude(pos); if(latitude <= 0) cardinallat = "S"; else cardinallat = "N"; longitude = Get_Longitude(pos); if(longitude <= 0) cardinallong = "W"; else cardinallong = "E"; LCDSetPrintf(1,0,"GPS Pos:\n%f %s,\n%f %s\n",(float)latitude,cardinallat,(float)longitude,cardinallong); } check = Obtain_Heading(plane); if(check == FALSE) { LCDPrintf("Compass failed\n"); } } else return; OSWait(SHORT); } } /* Flight_Menu is the menu that will be available while the flight algorithm is * underway. It allows the algorithm to be stopped (probably won't be able to * restart once stopped) * inputs: plane->contains all the data recorded during flight * returns: GO->continue the flight * TERMINATE->finish the program */ programstate Flight_Menu(planestate *plane) { int key = 0; LCDMenu("STOP","","","END"); key = Check_Input(); switch(key) { case KEY1: /* Download data to a PC */ Download_Menu(plane); return TERMINATE; case KEY4: /* END program without downloading data */ return Confirmation_Menu(); /* Must be confirmed */ default: return GO; } } /* Download_Menu allows the user to download the error log before terminating * the program. * inputs: plane->contains the error log */ void Download_Menu( planestate *plane ) { int key = 0; error error_type; while(TRUE) { key = 0; LCDClear(); LCDMenu("TIME","EVNT","","END"); LCDPrintf("Connect externalserial port\n"); LCDPrintf("Then press TIME for chronological dload\n"); LCDPrintf("Or EVNT for event based dload\n"); LCDPrintf("END terminates\n"); while(key == 0) { key = Check_Input(); } LCDClear(); switch(key) { case KEY1: /* Begin downloading data in chronological order */ error_type = Upload_Error_Log(*plane, TIME); if(error_type == NOERROR) { LCDPrintf("Logfile dload\nsuccess!\nPress ctrl-c\n"); OSWait(LONG); break; } else { LCDPrintf("Logfile download\nincomplete.\nTry again\n"); OSWait(LONG); break; } case KEY2: /* Begin downloading data in event grouped order */ error_type = Upload_Error_Log(*plane, EVENT); if(error_type == NOERROR) { LCDPrintf("Logfile dload\nsuccess!\nPress ctrl-c\n"); OSWait(LONG); break; } else { LCDPrintf("Logfile download\nincomplete.\nTry again\n"); OSWait(LONG); break; } case KEY4: /* END finishes the program (must confirm) */ if(Confirmation_Menu() == TERMINATE) return; else break; default: break; } } } /* Confirmation_Menu is used when you want to confirm that the user wants to exit * the program * returns: TERMINATE if they confirm exit * GO if they say they don't want to exit */ programstate Confirmation_Menu(void) { int key = 0; LCDClear(); LCDMenu("YES","NO","NO","NO"); LCDPrintf("Do you really \nwant to quit?\n"); while(key == 0) { key = Check_Input(); } if(key == KEY1) { return TERMINATE; } else return GO; }