public ProjectKmlReadUtility(XmlTextReader tr, ref COVERAGE_TYPE coverageTypeFromKML) { //FlightPlanFolder folder containing the mission plans -- hardwired to: @"C:\_Waldo_FCS\"; //ProjectName name of the project that was selected by the user: flight plan kml filename //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //the above structures are filled when a mission is selected from the initial Waldo_FCS screen //Mission data folders are set up for each mission under the polygon (project) name folder //as a mission is flown (sim or actual), the .imu, .gps, .trg files are prepared with Waldo_FCS along with a new file //saving endpoints of flown flight lines. //the flightline files will be denoted as being either from a sim or an actual mission (.fla or .fls) //The .fla/.fls files will normally have the identical endpoints as the plan -- when flight lines are completed. //but they may also have a truncated flight line if the system was shutdown in the middle of the flight line. //When Waldo_FCS is started/restarted, and a mission is selected, the .fla or fls file will be accessed. //Only.fls or only .fla files will be access depending on if the Waldo_FCS was started in sim or actual (non-sim). // the procedure performed in this utility is: // read the kml file abd get the FlightLineOriginalPlan List // read ALL the appropriate .fla or .fls files and compile the FlightLinesFlown List // define the FlightLinesCurrentPlan List as the remaining flight lines to be flown //Waldo_FCS must compute (and write) the flight endpoints (as the images are triggered) so that these endpoints fall on a grid. //This grid is spaced laterally by the flight line spacing (set in FlightLinesOriginalPlan) and the downrangeTriggerSpacingMeters. //Nominally, the endpoints will identically match the plan endpoints. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //The Waldo_FCS Hard Drive will have a top-level folder called _FlightPlans //The _FlightPlans folder will contain sub-folders that represent "Jobs" -- a Job would be considered "GoogleCities" //beneath the jobs Folder will be Project Folders; e.g., Perth, Melbourne, Brisbane, ... will be called "Projects" //within each Project Folder will be a .kml that contains a polygon defining the coverage area defined by the client // The pilot will select a Job on the first Waldo_FCS Screen, and then will select a Project. //The pilot will be presented with the Project polygon outline showing how the polygon is broken into groups of flight lines. //An individual group of flight lines will be called a "Mission" -- usually, a Mission will be completed in a single takeoff and landing //in the below utility, we first read in all the data for all the missions for the Project. //The to-be-flown-mission will be selected by the user using mission polygons as hotspots //user clicks inside the polygon to select the mission (flightlines) //this is not required for a "Linear feature" flight plan coverageTypeFromKML = COVERAGE_TYPE.notSet; //first interogate the kml header information for several information tags //the mission planner software places "Waldo_FCS Mission Plan" into the document name tag bool completedReadingKMLheader = false; while (tr.Read() && !completedReadingKMLheader) { if (tr.IsStartElement() && tr.Name == "coverageType") { tr.Read(); String coverageType = tr.Value; if (coverageType == "Polygon") { coverageTypeFromKML = COVERAGE_TYPE.polygon; } else if (coverageType == "LinearFeature") coverageTypeFromKML = COVERAGE_TYPE.linearFeature; else { return; // we will check on the coverage type in the calling program } //header contains two tags that are checked: name and CoverageType completedReadingKMLheader = true; } if (tr.IsStartElement() && tr.Name == "name") { tr.Read(); String documentName = tr.Value; if (documentName != "Waldo_FCS Mission Plan") { //need to rethink this ... MessageBox.Show("The selected Project KML \n does not have the correct format"); return; //we will detect this in the callin gprogram cause the coverage type is not set } } } }
//constructor for the linearFeature coverage form public Mission(String _FlightPlanFolder, String _MissionDataFolder, String MissionDateStringNameIn, int _missionNumber, linearFeatureCoverageSummary _LFSum, LogFile _logFile, NavInterfaceMBed navIF_In, SDKHandler cameraIn, bool simulatedMission_, bool hardwareAttached_, Image _projectImage) { InitializeComponent(); coverageType = COVERAGE_TYPE.linearFeature; this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; posVel_ = new PosVel(); //set the mission image this.Width = (int)(mapScaleFactor * mapWidth); this.Height = (int)(mapScaleFactor * mapHeight); //this.Width = 640; //pixel height of the form //this.Height = 480; //pixel width of the form //retrieve local variables from the arguments missionNumber = _missionNumber; LFSum = _LFSum; MissionDataFolder = _MissionDataFolder; FlightPlanFolder = _FlightPlanFolder; navIF_ = navIF_In; camera = cameraIn; logFile = _logFile; MissionDateStringName = MissionDateStringNameIn; projectImage = _projectImage; //NOTE: if the simulatedMission=true, we will always generate the platform state from the software // If hardwareAttached=true, we will collect the IMU and GPS simulatedMission = simulatedMission_; hardwareAttached = hardwareAttached_; //st up the form to allow keydown events only in the simulation if (simulatedMission) { this.KeyPreview = true; } timeFromTrigger = new Stopwatch(); //showMessage = new Stopwatch(); elapsedTime = new Stopwatch(); getPosVelTimer = new Stopwatch(); //placeholder for the first of the path image bounds ib = LFSum.paths[0].imageBounds[0]; //placeholder for the project image bounds //multiplier used for pix-to-geodetic conversion for the project map -- scales lat/lon to pixels //NOTE -- we do the drawing on top of a bitmap sized to the mapWidth, mapHeight -- then stretch to fit the actual screen lon2PixMultiplier = mapWidth / (ib.eastDeg - ib.westDeg); lat2PixMultiplier = -mapHeight / (ib.northDeg - ib.southDeg); //"-" cause vertical map direction is positive towards the south //lon2PixMultiplier = mapWidth / (ib.eastDeg - ib.westDeg); //lat2PixMultiplier = -mapHeight / (ib.northDeg - ib.southDeg); //"-" cause vertical map direction is positive towards the south platFormPosVel = new PosVel(); platFormPosVel.GeodeticPos = new PointD(0.0, 0.0); platFormPosVel.UTMPos = new PointD(0.0, 0.0); //this will hold the locations of the aircraft over a period of time crumbTrail = new Point[numberCrumbTrailPoints]; labelPilotMessage.Visible = false; //form the along-Path distance at each point (vertex) //will be used for interpolating the commanded altitude along the path for (int j = 0; j < LFSum.paths.Count; j++ ) { LFSum.paths[j].alongPathDistanceAtVertex = new List<double>(); double cumulativeDistance = 0; for (int i=0; i<LFSum.paths[j].pathUTM.Count; i++) if (i == 0) LFSum.paths[j].alongPathDistanceAtVertex.Add(0.0); else { double delX = LFSum.paths[j].pathUTM[i].X - LFSum.paths[j].pathUTM[i - 1].X; double delY = LFSum.paths[j].pathUTM[i].Y - LFSum.paths[j].pathUTM[i - 1].Y; cumulativeDistance += Math.Sqrt(delX * delX + delY * delY); LFSum.paths[j].alongPathDistanceAtVertex.Add(cumulativeDistance); } } }
//constructor for MissionSelection Form for polygon mission public MissionSelection(ProjectSummary _ps, String _FlightPlanFolder, LogFile _logFile, NavInterfaceMBed navIF_In, SDKHandler cameraIn, bool hardwareAttached_, SettingsManager _settings, String _MissionDateString) { InitializeComponent(); posVel_ = new PosVel(); //set the flight plans folder and the Project Summary structure from the prior Project Selection FlightPlanFolder = _FlightPlanFolder; ps = _ps; navIF_ = navIF_In; camera = cameraIn; hardwareAttached = hardwareAttached_; settings = _settings; MissionDateString = _MissionDateString; logFile = _logFile; projectName = ps.ProjectName; //there is a separate constructor for the linearFeature coverage type coverageType = COVERAGE_TYPE.polygon; //getPosVelTimer = new Stopwatch(); utm = new UTM2Geodetic(); ///////////////////////////////////////////////////////////////////////////////////// //set up the project polygon and the individual Mission polygons in pixel units ///////////////////////////////////////////////////////////////////////////////////// //set of points in Pixels that we use to draw the project polygon onto the project map //creats space for an array of Point structures tha will hold the project polygon projectPolyPointsPix = new Point[ps.ProjectPolygon.Count]; //lat/lon image bounds from the mission plan ib = ps.ProjectImage; //placeholder for the project image bounds NOTE: this is also used elsewhere //multiplier used for pix-to-geodetic conversion for the project map -- scales lat/lon to pixels // TODO: ugly --- cant we do this exactly??? //lon2PixMultiplier = mapScaleFactor * mapWidth / (ib.eastDeg - ib.westDeg); //lat2PixMultiplier = -mapScaleFactor * mapHeight / (ib.northDeg - ib.southDeg); //"-" cause vertical map direction is positive towards the south lon2PixMultiplier = mapWidth / (ib.eastDeg - ib.westDeg); lat2PixMultiplier = -mapHeight / (ib.northDeg - ib.southDeg); //"-" cause vertical map direction is positive towards the south //create the project polygon in pixel units -- once for (int i = 0; i < ps.ProjectPolygon.Count; i++) projectPolyPointsPix[i] = GeoToPix(ps.ProjectPolygon[i]); //just uses a linear scaling //create the mission polygons (one per mission) in pixel units //used to form the clickable region on the project map missionPolysInPix = new List<Point[]>(); for (int i = 0; i < ps.msnSum.Count; i++) { Point [] pts = new Point[ps.msnSum[i].missionGeodeticPolygon.Count]; for (int j = 0; j < ps.msnSum[i].missionGeodeticPolygon.Count; j++) pts[j] = GeoToPix(ps.msnSum[i].missionGeodeticPolygon[j]); missionPolysInPix.Add(pts); } }
//constructor for the polygon coverage form public Mission(String _FlightPlanFolder, String _MissionDataFolder, String MissionDateStringNameIn, int _missionNumber, ProjectSummary _ps, bool[] _priorFlownFLs, LogFile _logFile, NavInterfaceMBed navIF_In, SDKHandler cameraIn, bool _simulatedMission, bool _hardwareAttached, StreamWriter _reflyFile, Image _projectImage) { InitializeComponent(); coverageType = COVERAGE_TYPE.polygon; //we use a separate constructor for the linearFeature mission this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; //set the mission image -- mapWidth & mapHeight = 640 X 480 based on the Google Earth map download limits this.Width = (int)(mapScaleFactor * mapWidth); //mapscaleFactor scales the map to fit a screen size of 1024 X 768 this.Height = (int)(mapScaleFactor * mapHeight); //this.Width = 640; //pixel height of the form //this.Height = 480; //pixel width of the form posVel_ = new PosVel(); //retrieve local variables from the arguments missionNumber = _missionNumber; ps = _ps; MissionDataFolder = _MissionDataFolder; FlightPlanFolder = _FlightPlanFolder; priorFlownFLs = _priorFlownFLs; //this contains the completed flight lines so they arent reflown reflyFile = _reflyFile; //write the completed flight line indices to this file projectImage = _projectImage; //contains the complete project image in case the display runs off the smaller maps navIF_ = navIF_In; camera = cameraIn; logFile = _logFile; MissionDateStringName = MissionDateStringNameIn; //NOTE: if the simulatedMission=true, we will always generate the platform state from the software // If hardwareAttached=true, we will collect the IMU and GPS simulatedMission = _simulatedMission; hardwareAttached = _hardwareAttached; timeFromTrigger = new Stopwatch(); elapsedTime = new Stopwatch(); getPosVelTimer = new Stopwatch(); timePastEndfFlightline = new Stopwatch(); ////ib is used internally to the GeoToPix procedures ////we will need to reset the ib & PixMultipliers if we have to use the Project map (plane exits mission map) //ib = ps.msnSum[missionNumber].MissionImage; //placeholder for the Mission image bounds ////multiplier used for pix-to-geodetic conversion for the project map -- scales lat/lon to pixels ////NOTE -- we do the drawing on top of a bitmap sized to the mapWidth, mapHeight -- then stretch to fit the actual screen //lon2PixMultiplier = mapWidth / (ib.eastDeg - ib.westDeg); //lat2PixMultiplier = -mapHeight / (ib.northDeg - ib.southDeg); //"-" cause vertical map direction is positive towards the south platFormPosVel = new PosVel(); platFormPosVel.GeodeticPos = new PointD(0.0, 0.0); platFormPosVel.UTMPos = new PointD(0.0, 0.0); //this will hold the locations of the aircraft over a period of time crumbTrail = new Point[numberCrumbTrailPoints]; //shows the "waiting sats" message labelPilotMessage.Visible = false; //get the max flight line length for this mission -- should come from the missionPlan //used to establish a region before and after the flightlines where flightlinecapture is allowed for (int i = 0; i < ps.msnSum[missionNumber].FlightLinesCurrentPlan.Count; i++) { if (ps.msnSum[missionNumber].FlightLinesCurrentPlan[i].FLLengthMeters > maxFlightLineLength) maxFlightLineLength = ps.msnSum[missionNumber].FlightLinesCurrentPlan[i].FLLengthMeters; } }
//constructor for MissionSelection Form Linear Feature mission public MissionSelection(linearFeatureCoverageSummary _LFSum, String _FlightPlanFolder, LogFile _logFile, NavInterfaceMBed navIF_In, SDKHandler cameraIn, bool hardwareAttached_, SettingsManager _settings, String _MissionDateString) { InitializeComponent(); posVel_ = new PosVel(); //set the flight plans folder and the Project Summary structure from the prior Project Selection FlightPlanFolder = _FlightPlanFolder; LFSum = _LFSum; navIF_ = navIF_In; camera = cameraIn; hardwareAttached = hardwareAttached_; settings = _settings; MissionDateString = _MissionDateString; logFile = _logFile; projectName = LFSum.ProjectName; //this is a specific constructor for the linear feature coverage type coverageType = COVERAGE_TYPE.linearFeature; getPosVelTimer = new Stopwatch(); utm = new UTM2Geodetic(); //lat/lon image bounds from the mission plan ib = LFSum.ProjectImage; //placeholder for the project image bounds NOTE: this is also used elsewhere //multiplier used for pix-to-geodetic conversion for the project map -- scales lat/lon to pixels // TODO: ugly --- cant we do this exactly??? //lon2PixMultiplier = mapScaleFactor * mapWidth / (ib.eastDeg - ib.westDeg); //lat2PixMultiplier = -mapScaleFactor * mapHeight / (ib.northDeg - ib.southDeg); //"-" cause vertical map direction is positive towards the south lon2PixMultiplier = mapWidth / (ib.eastDeg - ib.westDeg); lat2PixMultiplier = -mapHeight / (ib.northDeg - ib.southDeg); //"-" cause vertical map direction is positive towards the south }