/**************************************************************************** waypoint.c - Created by Peter Mauger 03/04/01 Last Modified 12/10/01 waypoint contains all functions required to determine bearing and distance to a given waypoint from the current position and heading ****************************************************************************/ #include "waypoint.h" /* Init_Wplist initialises a wplist struct * returns: an empty wplist structure */ wplist Init_Wplist() { wplist wps; int i; wps.total_wps = 0; for(i=0;iwaypoint list * returns: total number of waypoints in list */ int Get_Wplist_Total(wplist waypoints) { return waypoints.total_wps; } /* Get_Wp gets the current waypoint from the waypoint list * inputs: waypoints->struct containing list of all waypoints * curr_wpnum->the number of the current wp (variable for returning the position of the waypoint * returns: INVALIDWPNUM if curr_wpnum out of range of list * NOERROR otherwise */ error Get_Wp(wplist waypoints, int curr_wpnum, position *pos) { if(curr_wpnum < waypoints.total_wps) { *pos = waypoints.wps[curr_wpnum]; return NOERROR; } else { LCDClear(); LCDPrintf("Invalid wp num\n"); OSWait(LONG); return INVALIDWPNUM; } } /* At_Wp determines whether the current GPS position is within the * tolerance of a given waypoint * inputs: GPSpos->GPS position (lat,long) * tolerance->radial distance around waypoint considered to be the * waypoint (unsure of the dimensions of this variable) * not_at_wp->variable for returning whether plane is at waypoint * TRUE means the plane is not at the waypoint * returns: DIVZERO if a divide by zero occured * NOERROR otherwise */ error At_Wp(planestate plane, double tolerance, bool *not_at_wp) { double dist; error error_type; error_type = Calc_Distance(Get_Curr_Pos(plane), Get_Curr_Wp(plane), &dist); if(distthe communications port used for transfer * waypoints->the set of waypoints passed back * returns: WPFILEERROR if the file could not be received * NOERROR otherwise */ error Obtain_Wplist_From_File(wplist *waypoints) { int result = 0, timeout; char file_string[MAX_FILE_LENGTH]; /* a character string representing the file input stream */ int file_ptr = 0, file_length = 0; char n_s, e_w, temp_char; /* set up the Eyebot->PC RS232 connection for data receiving */ result = OSInitRS232( PC_BAUDRATE, RTSCTS, PC_PORTNUM ); if( result != 0 ) return WPFILEERROR; result = OSFlushInRS232( PC_PORTNUM ); if( result != 0 ) return WPFILEERROR; /* port has been initialized and flushed, wait for user to press go on PC and for data to arrive */ timeout = 0; LCDPrintf("Port init\nTimeout in: "); do { result = OSRecvRS232( &temp_char, PC_PORTNUM ); if(result == 0) { file_string[0] = temp_char; file_ptr++; } timeout++; LCDPrintf("%d ",(WPFILE_TIMEOUT - timeout)); }while(result == 1 && timeout < WPFILE_TIMEOUT); if( timeout >= WPFILE_TIMEOUT ) { LCDPrintf(" Timed Out\n"); OSWait(LONG); return WPFILEERROR; } if( result != 0 ) { LCDPrintf("didn't get file!%d ",result); return WPFILEERROR; } /* if we get here, file_string now has something in it i.e. we have begun to receive data, store it all */ do { timeout = 0; do { result = OSRecvRS232( &temp_char, PC_PORTNUM ); if (result) { LCDPrintf("upload error%d\n",result); OSWait(SHORT); } else { file_string[file_ptr] = temp_char; file_ptr++; timeout = 0; LCDPrintf("."); } timeout++; OSWait(VSHORT); }while(result != 0 && timeout < GPS_TIMEOUT); if(timeout == GPS_TIMEOUT) { LCDPrintf("upload timed out\n"); OSWait(LONG); return WPFILEERROR; } }while( file_ptr < MAX_FILE_LENGTH && file_string[file_ptr-1] != '*' ); LCDPrintf("\nLoop-End\n"); if(file_ptr >= MAX_FILE_LENGTH) { LCDPrintf("File too large\n"); return WPFILEERROR; } file_string[file_ptr] = '\0'; file_length = file_ptr; LCDPrintf("File received:\nlength %d\n",file_length); OSWait(LONG); LCDClear(); file_ptr = 0; waypoints->total_wps = 0; while(file_ptr < file_length) { if(file_ptr < file_length) { if((file_string[file_ptr] != EOF) && (file_string[file_ptr] != '*')) { if( Parse_Waypoint( file_string, &file_ptr, waypoints ) != NOERROR ) return WPFILEERROR; /* otherwise, the waypoint was correct and has been stored, increment the number of waypoints */ if(waypoints->wps[waypoints->total_wps].latitude <= 0) n_s = 'S'; else n_s = 'N'; if(waypoints->wps[waypoints->total_wps].longitude <= 0) e_w = 'W'; else e_w = 'E'; waypoints->total_wps++; LCDClear(); LCDPrintf( "Waypoint %d:\n%f %c\n%f %c\n", waypoints->total_wps, (float)waypoints->wps[waypoints->total_wps-1].latitude, n_s, (float)waypoints->wps[waypoints->total_wps-1].longitude, e_w ); OSWait(LONG); } else { LCDPrintf( "All waypoints\nparsed.\n" ); return NOERROR; } } else { if((file_string[file_ptr] != EOF) && (file_string[file_ptr] != '*')) { LCDPrintf( "WPfile too long\n" ); return WPFILEERROR; } else { LCDPrintf("All waypoints\nparsed.\n"); return NOERROR; } } } return WPFILEERROR; } /* Obtain_Wplist_From_HFile finds the default waypoint list stored in the planeconst.h file * Currently this is not implemented, however should an emergency default set of * waypoints be required, they should be retrieved by this function. (This would only * occur in the event of a power down and would require knowledge that the power down * had actually occured so that the menus could be bypassed! Possibly some kind of * mechanical latch which is set on flight start and only reset by successful completion * of the program) * inputs: waypoints->passes the list of waypoints so they can be returned */ void Obtain_Wplist_From_HFile(wplist *waypoints) { waypoints->total_wps = 0; } /* Parse_Waypoint parses each waypoint in the waypoint file. Basis by Nathan Hines. * Modifed by Peter Mauger. * inputs: file_string->the set of characters from the file * file_ptr->marks character currently being looked at in string * WPpos->is the position found * returns: WPFILEERROR if there was an invalid string in the file * NOERROR otherwise */ error Parse_Waypoint( char *file_string, int *file_ptr, wplist *wps ) { char *next_char; double curr_lat = 0, curr_long = 0; /* waypoint latitude and longitude */ int curr_lat_dir = 0, curr_lon_dir = 0; /* waypoint lat/long direction (-1 or +1) */ /* strtod converts the first 'double looking' number it finds in the string to a double then returns the */ /* next character after that number (next_char) */ curr_lat = strtod(&file_string[*file_ptr],&next_char); /* next_char is returned by strtod and points to the next character after the converted number. */ /* Finding the difference between the address of the input and the next_char gives the increment required */ /* to update file_ptr so that it points to the correct character */ (*file_ptr) += (next_char - &file_string[*file_ptr]); /* latitude value was fine, get direction (N or S) */ if( (file_string[*file_ptr] == 'N') || (file_string[*file_ptr] == 'S') || (file_string[*file_ptr] == 'n') || (file_string[*file_ptr] == 's') ) { if( file_string[*file_ptr] == 'n' || file_string[*file_ptr] == 'N' ) curr_lat_dir = NORTH; if( file_string[*file_ptr] == 's' || file_string[*file_ptr] == 'S' ) curr_lat_dir = SOUTH; (*file_ptr)++; } else return WPFILEERROR; /* strtod converts the first 'double looking' number it finds in the string to a double then returns the */ /* next character after that number (next_char) */ curr_long = strtod(&file_string[*file_ptr],&next_char); /* next_char is returned by strtod and points to the next character after the converted number. */ /* Finding the difference between the address of the input and the next_char gives the increment required */ /* to update file_ptr so that it points to the correct character */ (*file_ptr) += (next_char - &file_string[*file_ptr]); /* longtitude value was fine, get direction (E (converted to t) or W (still W or w)) */ if( (file_string[*file_ptr] == 'W') || (file_string[*file_ptr] == 'w') || (file_string[*file_ptr] == 'E') || (file_string[*file_ptr] == 'e') ) { if( (file_string[*file_ptr] == 'W') || (file_string[*file_ptr] == 'w') ) curr_lon_dir = WEST; if( (file_string[*file_ptr] == 'E') || (file_string[*file_ptr] == 'e') ) curr_lon_dir = EAST; (*file_ptr)++; } else return WPFILEERROR; /* if we get here, waypoint is good, store it */ if(curr_lat_dir != 0) { wps->wps[wps->total_wps].latitude = curr_lat*curr_lat_dir; } else return WPFILEERROR; if(curr_lon_dir != 0) { wps->wps[wps->total_wps].longitude = curr_long*curr_lon_dir; } else return WPFILEERROR; /* if we get here, waypoint was good and has been stored, return with NOERROR */ (*file_ptr)++; /* There will be a \n in the file at the end of each waypoint */ return NOERROR; /* which must be skipped over */ }