示例#1
0
        //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);
            }
        }
示例#2
0
        public PriorFlownMissions(String FlightPlanFolder, ProjectSummary _projSum)
        {
            projUpdate = new ProjectUpdateFlightLines();        //this is the struct containing all missions that will be prepared herein
            projUpdate.msnUpdate = new List<MissionUpdateFlightlines>(); //flight line structure for an individual mission
            projSum = _projSum; //input mission planning file extracted from the project plan kml

            debugFile = new StreamWriter(@"C:\temp\priorMissisons.txt");
            debugFile.WriteLine("Analyzing the pre-flown missions ");

            int missionCounter = 0;

            //loop through all the missions for this project
            foreach (MissionSummary msnSum in projSum.msnSum)
            {
                //mission folder definition
                String MissionDataFolder = FlightPlanFolder + projSum.ProjectName + @"\Mission_" + missionCounter.ToString("D3") + @"\Data\";

                debugFile.WriteLine("testing for missionFolder:  " + MissionDataFolder);

                //is there are no prior missions flown, continue to the next mission
                if (!Directory.Exists(MissionDataFolder)) { missionCounter++; continue; }

                debugFile.WriteLine(" folder found");

                //NOTE:  we only add to the structure if there is a prior-flown folder
                // if there are no prior flown missions, there will be nothing inthe structure;

                //temporary mission structure filled below and added to projUpdate
                MissionUpdateFlightlines missionUpdate = new MissionUpdateFlightlines();

                missionUpdate.missionNumber = missionCounter;

                //flight line List to be filled and added to the structure
                missionUpdate.flightLineUpdate = new List<FirstLastUnflownPhotocenter>();

                //get the String Collection of as-flown kml file names in each of the mission data folders
                //we sould make these trigger file -- need to separate the simulated mssions and the live missions
                String[] kmlFlightFiles = Directory.GetFiles(MissionDataFolder, "*Triggers.kml");

                debugFile.WriteLine("Found" + kmlFlightFiles.ToString() + "  .kml files");

                //this will become a collection of all the photocenters names for all prior flown missions with this mission number
                List<String> collectedImages = new List<String>();

                //loop through each of the pre-flown kml files that recorded photocenters
                //st is the name of a preflown flight line
                foreach (String st in kmlFlightFiles)
                {
                    debugFile.WriteLine("getting prior flown photocenters from: " + st);

                    /////////////////////////////////////////////////////////////////////////////////////
                    ///Read the kml file and get the photocenter names ...........
                    /////////////////////////////////////////////////////////////////////////////////////

                    XmlTextReader tr = new XmlTextReader(st);
                    int imagesTaken = 0;

                    while (!tr.EOF && tr.Read())  //loop through all the kml elements
                    {
                        if (tr.Name == "Placemark" && tr.IsStartElement())  //locate each placemark -- these contain the photocenters
                        {
                            while (!tr.EOF && tr.Read())
                            {
                                if (tr.IsStartElement() && tr.Name == "name")  //photocenter name stores the MissionNumber_FlightLine_photocenterNumber
                                {
                                    if (!tr.EOF)
                                    {
                                        tr.Read();
                                        collectedImages.Add(tr.Value);  //for the collection of all photocenters
                                        imagesTaken++;
                                    }
                                }
                            }
                        }
                    }

                    if (imagesTaken == 0)
                    {
                        //MessageBox.Show("poorly formed kml file -- deleting " + st);
                        debugFile.WriteLine("deleted Bad kml Triggers file --- delete.");
                        tr.Close();
                        File.Delete(st);
                    }
                }

                debugFile.WriteLine("found " + collectedImages.Count.ToString() + " total photocenters for all kml files");

                //sort the collection in ascending order  "Mission#_FL#_pohto#"
                //photocenter names increase from Start-to-End (e.g., start at South for NS lines)
                collectedImages.Sort();

                debugFile.WriteLine();
                foreach (String s in collectedImages) debugFile.WriteLine(s);
                debugFile.WriteLine();

                debugFile.WriteLine("Completed Sort of the image strings");

                //compute the total photocenters to be collected for this mission -- used to compute the percent complete
                int totalPhotoCentersRequiredThisMission = 0;
                foreach (endPoints ep in projSum.msnSum[missionCounter].FlightLinesCurrentPlan)
                    totalPhotoCentersRequiredThisMission += Convert.ToInt32(ep.FLLengthMeters / projSum.downrangeTriggerSpacing) + 1;

                debugFile.WriteLine("Total photocenters required to complete this mission: " + totalPhotoCentersRequiredThisMission.ToString());

                //we will compute this below to get the overall percent completion based on all prior-flown missions
                int photoCentersCollectedThisMission = 0;

                //do this for flight line zero and then do again when we get a new flight line
                int currentFlightLine = 0;
                int numPhotoCenters = 1 + Convert.ToInt32(projSum.msnSum[missionCounter].FlightLinesCurrentPlan[currentFlightLine].FLLengthMeters / projSum.downrangeTriggerSpacing);
                int[] photoCentersCollected = new int[10*numPhotoCenters];

                /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                //now we have a sorted list of all images collected for this mission  and for all flightlines
                //go through the list selecting each flight line in order to assess the earliest and latest uncollected images
                /////////////////////////////////////////////////////////////////////////////////////////////////////////////////

                int totalPhotoCentersCollected = 0;   // this includes repeated photos --- may collect some PCs multiple times
                // this value  photoCentersCollectedThisMission --- counts the uniquely collected photocenters
                foreach (String st in collectedImages)
                {
                    int missionNumber=0; int flightlineNumber=0; int photoCenter=0;
                    //these values are placed into a string that is the image name in the kml file
                    try
                    {
                        missionNumber = Convert.ToInt32(st.Substring(0, 3));  //this will always be a constant
                    }
                    catch
                    {
                        MessageBox.Show(" bad missionNumber in kml file: " + st.Substring(0, 3));
                    }

                    try
                    {
                        flightlineNumber = Convert.ToInt32(st.Substring(4, 2));
                    }
                    catch
                    {
                        MessageBox.Show(" bad flightlineNumber in kml file: " + st.Substring(4, 2));

                    }
                    try
                    {
                        photoCenter = Convert.ToInt32(st.Substring(7, 3));
                    }
                    catch
                    {
                        MessageBox.Show(" bad photoCenter in kml file: " + st.Substring(7, 3));

                    }

                    //the "currentFlightLine" starts at zero and increments when we observe a new flight line number
                    //NOTE: we must exit this at the very last record in the collection so that FL record will be processed
                    try
                    {
                        if (currentFlightLine == flightlineNumber)
                        {
                            totalPhotoCentersCollected++;
                            photoCentersCollected[photoCenter] += 1;
                            if (st != collectedImages.Last()) continue;
                        }
                    }
                    catch
                    {
                        MessageBox.Show(" bad photoCenter value:  " + photoCenter);
                    }

                    //here we have detected a new flight that was previously flown -- so process the last one

                    int early = 999;   //if no photos collected for this flight line, earliest is zero
                    int late  = 0;     //if no photos collected for this flight line, latest is at the end

                    if (totalPhotoCentersCollected > 0)
                    {
                        //when we get here we have completed the assessment of currentFlightLine
                        //now get the earliest uncollected image and the latest uncollected image.
                        for (int pc = 0; pc < numPhotoCenters; pc++)
                        {
                            if (photoCentersCollected[pc] == 0)
                            {
                                if (pc < early) early = pc;
                                if (pc > late)  late  = pc;
                            }
                        }  //break when we find an uncollected image
                        // if early (earliest uncollected image) is = numPhotoCenters-1, we have a complete flight line

                    }

                    //for (int j = 0; j < numPhotoCenters; j++)
                    //{
                    //    debugFile.WriteLine(currentFlightLine.ToString("D2") + "  " + j.ToString("D2") + "  " + photoCentersCollected[j].ToString("D2"));
                    //}

                    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                    //refly partial flight line strategy
                    //we may have deviated fro the line in the middle and got back on.
                    //we would need to refly ony the center portion
                    //note this could have happened twice on a long line
                    //for example, we got image 0-10, missed 11-15, got 16-30,  missed 31-35, and gotthe remainder 36-55
                    //we would refly photocenters: 11-35 for this case. Starting with the earliest miss and ending with the latest miss
                    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

                    FirstLastUnflownPhotocenter elPC;
                    if (early == 999) early = 0;  //early == 999 means ALL expected images were collected -- completed flight line
                    elPC.early = early;   //earliest of the unflown images
                    elPC.late  = late;    //latest of the unflown images

                    debugFile.WriteLine("expected photos " + numPhotoCenters.ToString("D3") + "  Earliest uncollected " + early.ToString("D3") + "  Latest uncollected " + late.ToString("D3"));

                    if (early == (numPhotoCenters - 1)) photoCentersCollectedThisMission += numPhotoCenters;
                    else photoCentersCollectedThisMission += numPhotoCenters - (late - early);

                    //the updated flightline must cover images from "early to "late"

                    elPC.FLNumber = currentFlightLine;

                    //fill the early/late structure for this flightline
                    missionUpdate.numberOfFlightLines = projSum.msnSum[missionNumber].numberOfFlightlines;
                    missionUpdate.flightLineUpdate.Add(elPC);

                    currentFlightLine++;
                    if (currentFlightLine >= projSum.msnSum[missionCounter].numberOfFlightlines) break;

                    numPhotoCenters = Convert.ToInt32(projSum.msnSum[missionCounter].FlightLinesCurrentPlan[currentFlightLine].FLLengthMeters / projSum.downrangeTriggerSpacing) + 1;
                    photoCentersCollected = new int[10*numPhotoCenters];

                    //why do this?  we found a new flight line and need to accept the first of its images
                    totalPhotoCentersCollected++;
                    photoCentersCollected[photoCenter] += 1;
                }

                //completed the flight line asFlown analysis for this Mission
                //fill the mission update structure
                projUpdate.numberOfMissions = projSum.numberOfMissions;
                missionUpdate.percentCompleted = 100.0 * (double)photoCentersCollectedThisMission / (double)totalPhotoCentersRequiredThisMission;
                projUpdate.msnUpdate.Add(missionUpdate);

                debugFile.WriteLine("completed the prior flown analysis for mission " + missionCounter);

                missionCounter++;

            }   // end of the per mission loop

            debugFile.WriteLine("completed the prior flown analysis for all missions ");
            debugFile.Close();
        }
        public ProjectSummary readPolygonCoverageData(XmlReader tr, String ProjectName)
        {
            ///////////////////////////////////////////////////////////////////////
            //read in the original client polygon outline of the site
            ///////////////////////////////////////////////////////////////////////

            bool completedProjectPolygon        = false;
            bool completedProjectData           = false;
            bool completedMissionImageBounds    = false;

            ProjectSummary projSum = new ProjectSummary();

            projSum.coverageType = COVERAGE_TYPE.polygon;

            projSum.ProjectName = ProjectName;  //this is the name of the kml file -- maybe should use the name of the placemark???
            projSum.ProjectPolygon = new List<PointD>();
            projSum.msnSum = new List<MissionSummary>();

            //photocenters are on a regular grid with a fixed origin -- redined from the input file
            projSum.gridOrigin = new PointD(0.0, 0.0);

            //inspecting the header is complete --- new interrogate the remainder
            while (tr.Read() && !completedProjectData)
            {
                if (tr.IsStartElement() && tr.Name == "Placemark")
                {
                    while (tr.Read() && !completedProjectPolygon)
                    {
                        if (tr.IsStartElement() && tr.Name == "name")
                        {
                            tr.Read();
                            //the Placemark name should be the same as the mission plan kml name
                            if (tr.Value == ProjectName) //here we check to see if the placemark name is the input kml filename
                            {
                                while (tr.Read() && !completedProjectPolygon)
                                {
                                    if (tr.IsStartElement() && tr.Name == "coordinates")
                                    {
                                        tr.Read();
                                        char[] delimiterChars = { ',', ' ', '\t', '\n', '\r' };   //these delimiters were determined by looking at a file ...
                                        string[] coordinateValues = tr.Value.ToString().Split(delimiterChars);

                                        //the "value" is the text between the <coordinates> and </coordinates>
                                        //below we read the complete string value and split it into separate substrings -- ugly but it works
                                        //the substrings contain the individual coordinate values with some ""s and the heigts are "0".

                                        //get the quantitative lat/long values from the text array ... there are a number of ""s in the text file ...
                                        //each Google point has three values : longitude, Latitude, height -- we assume the height is zero here
                                        int k = 0; int i = 0;
                                        while (i < coordinateValues.Count())
                                        {
                                            if (coordinateValues[i] != "")
                                            {

                                                double lat = Convert.ToDouble(coordinateValues[i + 1]);
                                                double lon = Convert.ToDouble(coordinateValues[i]);
                                                projSum.ProjectPolygon.Add(new PointD(lon, lat));
                                                k++;  //index of the storage array

                                                //increment the split array by 3 because the points are lat,lon,height
                                                i += 3;  //increment by 3 to get the next coordinate
                                            }
                                            else i++;  //here we skip the ""s in the text array
                                        }
                                        completedProjectPolygon = true;

                                    }
                                }
                            }
                            else
                            {
                                MessageBox.Show("The mission plan file has the wrong format \n The Placemark name is not the same as the kml file name");
                            }
                        }
                    }
                }  //end of getting projectPolygon stored as a Placemark

                //////////////////////////////////////////////////////////////////////////////////
                //read in the Project-specific Data for this Project
                //////////////////////////////////////////////////////////////////////////////////

                //get the geodetic bopunds of the project polygon
                if (tr.IsStartElement() && tr.Name == "north" && !completedProjectData)
                {
                    tr.Read();
                    projSum.ProjectImage.northDeg = Convert.ToDouble(tr.Value);
                }
                if (tr.IsStartElement() && tr.Name == "south" && !completedProjectData)
                {
                    tr.Read();
                    projSum.ProjectImage.southDeg = Convert.ToDouble(tr.Value);
                }
                if (tr.IsStartElement() && tr.Name == "east" && !completedProjectData)
                {
                    tr.Read();
                    projSum.ProjectImage.eastDeg = Convert.ToDouble(tr.Value);
                }
                if (tr.IsStartElement() && tr.Name == "west" && !completedProjectData)
                {
                    tr.Read();
                    projSum.ProjectImage.westDeg = Convert.ToDouble(tr.Value);
                }

                if (tr.IsStartElement() && tr.Name == "downRangePhotoSpacingMeters" && !completedProjectData)
                {
                    tr.Read();
                    projSum.downrangeTriggerSpacing = Convert.ToDouble(tr.Value);
                }

                if (tr.IsStartElement() && tr.Name == "crossRangeSwathWidth" && !completedProjectData)
                {
                    tr.Read();
                    projSum.crossRangeSwathWidth = Convert.ToDouble(tr.Value);
                }

                if (tr.IsStartElement() && tr.Name == "numberOfMissons" && !completedProjectData)
                {
                    tr.Read();
                    projSum.numberOfMissions = Convert.ToInt32(tr.Value);
                }

                if (tr.IsStartElement() && tr.Name == "UTMZone" && !completedProjectData)
                {
                    tr.Read();
                    projSum.UTMZone = tr.Value;
                }

                if (tr.IsStartElement() && tr.Name == "gridOriginUTMNorthing" && !completedProjectData)
                {
                    tr.Read();
                    projSum.gridOrigin.Y = 1.0;
                    projSum.gridOrigin.Y = Convert.ToDouble(tr.Value);
                }
                if (tr.IsStartElement() && tr.Name == "gridOriginUTMEasting" && !completedProjectData)
                {
                    tr.Read();
                    projSum.gridOrigin.X = Convert.ToDouble(tr.Value);
                    ///////////////////////////////////////////////////////////////////////////////////
                    completedProjectData = true;   ///Easting is the last one of the data elements
                    ///////////////////////////////////////////////////////////////////////////////////
                }
            }

            //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            //read in the bounds of the mission images -- images are stored separately in a folder: ProjectName_Background\background_YY.jpg
            //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

            List<ImageBounds> MissionImage = new List<ImageBounds>(); // we will use this later to fill the mission Summarys

            while (tr.Read() && !completedMissionImageBounds)
            {
                if (tr.IsStartElement() && tr.Name == "name")  //takes us to the folder containing the mission images
                {
                    tr.Read();
                    if (tr.Value == " Summary Images")  //verifies that this is the correct folder
                    {
                        int missionImageBoundRead = 0;
                        while (tr.Read() && missionImageBoundRead < projSum.numberOfMissions)  //loop over all image bounds in the folder
                        {
                            if (tr.IsStartElement() && tr.Name == "name")  //found the name element for next mission image bounds
                            {
                                while (tr.Read() && missionImageBoundRead < projSum.numberOfMissions)
                                {
                                    if (tr.Value == " Summary_" + missionImageBoundRead.ToString("D3") + " ")  //found correct mission name
                                    {
                                        ImageBounds ib = new ImageBounds(); // fill an image bounds structure
                                        while (tr.Read())
                                        {
                                            if (tr.IsStartElement() && tr.Name == "north")
                                            {
                                                tr.Read();
                                                ib.northDeg = Convert.ToDouble(tr.Value);
                                            }

                                            if (tr.IsStartElement() && tr.Name == "east")
                                            {
                                                tr.Read();
                                                ib.eastDeg = Convert.ToDouble(tr.Value);
                                            }

                                            if (tr.IsStartElement() && tr.Name == "south")
                                            {
                                                tr.Read();
                                                ib.southDeg = Convert.ToDouble(tr.Value);
                                            }

                                            if (tr.IsStartElement() && tr.Name == "west")
                                            {
                                                tr.Read();
                                                ib.westDeg = Convert.ToDouble(tr.Value);

                                                MissionImage.Add(ib);  //fill the image bounds structure

                                                missionImageBoundRead++;  //the west is always the last element
                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        completedMissionImageBounds = true;
                    }
                }
            }

            /////////////////////////////////////////////////////////////////////////////
            //  read in the per-mission data
            //  the sets of information
            //  (1)  mission-specific parameters
            //  (2)  mission-specfic polygon
            //  (3)  flight line ends
            /////////////////////////////////////////////////////////////////////////////

            //////////////////////////////////////////////////////////////////////
            //read in the mission-specific data values for this mission
            //////////////////////////////////////////////////////////////////////

            int missionNumberCounter = 0;
            int flightLineNumber = 0;   //flight line number increment sequentially across each mission --- are not renumbered at a mission

            while (missionNumberCounter < projSum.numberOfMissions)
            {

                bool completedPerMissionData = false;
                //we are at the top of a mission summary dataset
                MissionSummary msnSum = new MissionSummary();

                while (tr.Read() && !completedPerMissionData)  //loop here til finished the mission-specific parameters
                {
                    if (tr.IsStartElement() && tr.Name == "missionNumber")
                    {
                        tr.Read();
                        int missionNumber = Convert.ToInt32(tr.Value);
                        while (tr.Read() && !completedPerMissionData)
                        {
                            if (tr.IsStartElement() && tr.Name == "numFLs")
                            {
                                tr.Read();
                                msnSum.numberOfFlightlines = Convert.ToInt32(tr.Value);
                            }

                            if (tr.IsStartElement() && tr.Name == "flightAltMSL")
                            {
                                tr.Read();
                                msnSum.flightAltMSLft = Convert.ToDouble(tr.Value);
                                completedPerMissionData = true;
                            }

                        }
                    }
                }

                ////////////////////////////////////////////////////////////////////////////////////////////////
                //read in the mission-specific polygon formed from flight line endpoints
                ////////////////////////////////////////////////////////////////////////////////////////////////

                bool completedThisMissionPolygon = false;
                while (tr.Read() && !completedThisMissionPolygon)  //loop here til finished the mission-specific polygon
                {
                    msnSum.missionGeodeticPolygon = new List<PointD>();

                    while (tr.Read() && !completedThisMissionPolygon)
                    {

                        //first get the mission polygon
                        if (tr.IsStartElement() && tr.Name == "name")
                        {
                            tr.Read();
                            if (tr.Value == " MissionPolygon_" + missionNumberCounter.ToString("D2") + " ")
                            {
                                while (tr.Read())
                                {
                                    if (tr.IsStartElement() && tr.Name == "coordinates")
                                    {
                                        tr.Read();
                                        char[] delimiterChars = { ',', ' ', '\t', '\n', '\r' };   //these delimiters were determined by looking at a file ...
                                        string[] coordinateValues = tr.Value.ToString().Split(delimiterChars);

                                        //the "value" is the text between the <coordinates> and </coordinates>
                                        //below we read the complete string value and split it into separate substrings -- ugly but it works
                                        //the substrings contain the individual coordinate values with some ""s and the heigts are "0".

                                        //get the quantitative lat/long values from the text array ... there are a number of ""s in the text file ...
                                        //each Google point has three values : longitude, Latitude, height -- we assume the height is zero here
                                        int k = 0; int i = 0;
                                        while (i < coordinateValues.Count())
                                        {
                                            if (coordinateValues[i] != "")
                                            {

                                                double lat = Convert.ToDouble(coordinateValues[i + 1]);
                                                double lon = Convert.ToDouble(coordinateValues[i]);

                                                msnSum.missionGeodeticPolygon.Add(new PointD(lon, lat));

                                                k++;  //index of the storage array

                                                //increment the split array by 3 because the points are lat,lon,height
                                                i += 3;  //increment by 3 to get the next coordinate
                                            }
                                            else i++;  //here we skip the ""s in the text array
                                        }
                                        completedThisMissionPolygon = true;
                                        break;
                                    }
                                }
                            }

                        }

                    }
                }  //end of completedThisMissionPolygon

                ////////////////////////////////////////////////////////////////
                //read the flight line data for each mission
                ////////////////////////////////////////////////////////////////

                bool completedThisMissionFlightLines = false;
                int flightlinesCounterInMission = 0;
                double FLLengthMeters = 0;
                msnSum.FlightLinesCurrentPlan = new List<endPoints>();
                while (tr.Read() && !completedThisMissionFlightLines)  //loop here til read in all the flight lines for this mission
                {
                        //first get the mission polygon
                    if (tr.IsStartElement() && tr.Name == "name")
                    {

                        tr.Read();
                        // FlightlineNumber_000
                        if (tr.Value == " FlightlineNumber_" + flightLineNumber.ToString("D3") + " ")
                        {
                            while (tr.Read())
                            {
                                //  <lengthMeters>25266.9</lengthMeters>
                                if (tr.IsStartElement() && tr.Name == "lengthMeters")
                                {
                                    tr.Read();
                                    FLLengthMeters = Convert.ToDouble(tr.Value);
                                }

                                if (tr.IsStartElement() && tr.Name == "coordinates")
                                {
                                    tr.Read();
                                    char[] delimiterChars = { ',', ' ', '\t', '\n', '\r' };   //these delimiters were determined by looking at a file ...
                                    string[] coordinateValues = tr.Value.ToString().Split(delimiterChars);

                                    //the "value" is the text between the <coordinates> and </coordinates>
                                    //below we read the complete string value and split it into separate substrings -- ugly but it works
                                    //the substrings contain the individual coordinate values with some ""s and the heigts are "0".

                                    //get the quantitative lat/long values from the text array ... there are a number of ""s in the text file ...
                                    //each Google point has three values : longitude, Latitude, height -- we assume the height is zero here
                                    int k = 0; int i = 0;
                                    PointD[] ends = new PointD[2];
                                    while (i < coordinateValues.Count())
                                    {
                                        if (coordinateValues[i] != "")
                                        {

                                            double lat = Convert.ToDouble(coordinateValues[i + 1]);
                                            double lon = Convert.ToDouble(coordinateValues[i]);
                                            ends[k] = new PointD(lon, lat);

                                            k++;  //index of the storage array

                                            //increment the split array by 3 because the points are lat,lon,height
                                            i += 3;  //increment by 3 to get the next coordinate
                                        }
                                        else i++;  //here we skip the ""s in the text array
                                    }

                                    //NOTE:  the structure for the flight line info includes the original sequally-numbered flight line numbers
                                    //       But the FlightLinesCurrentPlan List is indexed from [0] to numFlightLinesThis mission
                                    //photocenter offset (0) added to allow numbering adjustment for reflown lines
                                    msnSum.FlightLinesCurrentPlan.Add(new endPoints(flightLineNumber, ends[0], ends[1],FLLengthMeters,0));

                                    flightlinesCounterInMission++;
                                    flightLineNumber++;
                                    if (flightlinesCounterInMission == msnSum.numberOfFlightlines)
                                    {
                                        completedThisMissionFlightLines = true;

                                        msnSum.MissionImage = MissionImage[missionNumberCounter];  //MissionImage was filled earlier

                                        missionNumberCounter++;  //increment the mission counter
                                    }

                                    //completedThisMissionFlightLines = true;
                                    break;
                                }
                            }
                        }

                    }
                }

                //at this time declare the mission as zero-percent complete
                //fill this in when we anayze the prior flown missions
                msnSum.percentComplete = 0;

                projSum.msnSum.Add(msnSum);

            }  //end of collectiong the mission data

            return projSum;

            //////////////////////////////////////////////////////////////
            // the Project Summary for Waldo_FCS is Complete
            //////////////////////////////////////////////////////////////
        }
示例#4
0
        //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;
            }
        }
示例#5
0
        public CurrentFlightLineGeometry( int missionNumber, int flightLineNumber, ProjectSummary _ps, bool[] _priorFlownFLs)
        {
            ////////////////////////////////////////////////////////////////////
            //do all the stuff that does not vary with the aircraft location
            ////////////////////////////////////////////////////////////////////

            ps = _ps;
            priorFlownFLs = _priorFlownFLs;

            UTM2Geodetic utm = new UTM2Geodetic();
            Rad2Deg = 180.0 / Math.Acos(-1.0);
            Deg2Rad = Math.Acos(-1.0) / 180.0;

            FLendUTM        = new PointD(0.0, 0.0);
            FLstartUTM      = new PointD(0.0, 0.0);
            FLP1endUTM      = new PointD(0.0, 0.0);
            FLP1startUTM    = new PointD(0.0, 0.0);

            //set up the parameters of the flight line independent of the aircraft Platform
            FLendGeo = ps.msnSum[missionNumber].FlightLinesCurrentPlan[flightLineNumber].end;
            FLstartGeo = ps.msnSum[missionNumber].FlightLinesCurrentPlan[flightLineNumber].start;

            //utm flight line endpoints
            utm.LLtoUTM(FLstartGeo.Y * Deg2Rad, FLstartGeo.X * Deg2Rad, ref FLstartUTM.Y, ref FLstartUTM.X, ref ps.UTMZone, true);
            utm.LLtoUTM(FLendGeo.Y   * Deg2Rad, FLendGeo.X   * Deg2Rad, ref FLendUTM.Y,   ref FLendUTM.X,   ref ps.UTMZone, true);

            // the number 10 means that the semi-infinite line extensions are 10 times longer than the flightline ....
            PointD del = 10 * (FLendGeo - FLstartGeo);  //semi-infinite line use for drawing a line extending beyond the FL ends
            semiInfiniteFLstartGeo = FLstartGeo - del;
            semiInfiniteFLendGeo   = FLendGeo   + del;

            FLlengthSq = (FLendUTM.X - FLstartUTM.X) * (FLendUTM.X - FLstartUTM.X) + (FLendUTM.Y - FLstartUTM.Y) * (FLendUTM.Y - FLstartUTM.Y);

            FLlengthMeters = Math.Sqrt(FLlengthSq);
            start2EndFlightLineUnit = new PointD((FLendUTM.X - FLstartUTM.X) / FLlengthMeters, (FLendUTM.Y - FLstartUTM.Y) / FLlengthMeters);

            //next flight line data -- what happens on the last flightlne ??
            if (flightLineNumber < (ps.msnSum[missionNumber].numberOfFlightlines-1) )
            {
                //this is redundant with code where the currentFlightLine is switched
                //  nextFlightlineNumber should be kept as a part of flightline geometry
                nextFlightlineNumber = flightLineNumber + 1;
                while (priorFlownFLs[nextFlightlineNumber])
                {
                    if (nextFlightlineNumber >= priorFlownFLs.Count() - 1) break;
                    nextFlightlineNumber++;
                }

                PointD FLP1endGeo = ps.msnSum[missionNumber].FlightLinesCurrentPlan[nextFlightlineNumber].end;
                PointD FLP1startGeo = ps.msnSum[missionNumber].FlightLinesCurrentPlan[nextFlightlineNumber].start;
                utm.LLtoUTM(FLP1startGeo.Y * Deg2Rad, FLP1startGeo.X * Deg2Rad, ref FLP1startUTM.Y, ref FLP1startUTM.X, ref ps.UTMZone, true);
                utm.LLtoUTM(FLP1endGeo.Y   * Deg2Rad, FLP1endGeo.X   * Deg2Rad, ref FLP1endUTM.Y,   ref FLP1endUTM.X,   ref ps.UTMZone, true);

                //works for all flightline aspects -- assumes the flightlines are parallel
                //project start-to-start (RS) and end-to-end (RE) vectors onto current flightline start-to-end unit vector
                double delSX = FLP1startUTM.X - FLstartUTM.X;
                double delSY = FLP1startUTM.Y - FLstartUTM.Y;
                double RS = start2EndFlightLineUnit.X * delSX + start2EndFlightLineUnit.Y * delSY;
                double delEX = FLP1endUTM.X - FLendUTM.X;
                double delEY = FLP1endUTM.Y - FLendUTM.Y;
                double RE = start2EndFlightLineUnit.X * delEX + start2EndFlightLineUnit.Y * delEY;
                if (RS < 0.0) ExtensionBeforeStart = -RS;
                if (RE > 0.0) ExtensionBeyondEnd   =  RE;

                //below works for only NS missions
                //if (FLP1endUTM.Y > FLendUTM.Y) ExtensionBeyondEnd = FLP1endUTM.Y - FLendUTM.Y;
                //if (FLP1startUTM.Y < FLstartUTM.Y) ExtensionBeforeStart = FLstartUTM.Y - FLP1startUTM.Y;
            }

               //the "+1" ensures a photocenter at the start of the flight line and at the end of the flight line.
            //The start/ends of the line have been placed on a grid with fixed downrange spacing for the complete project
            numPhotoCenters = Convert.ToInt32( FLlengthMeters / ps.downrangeTriggerSpacing) + 1;

            //used to record the successful completion of a photocenter
            //set to true after we have recorded the image on the storage media
            successfulImagesCollected = new bool[numPhotoCenters+10];
            //store the photocenter locations in pixel coordinates
            TriggerPoints = new Point[numPhotoCenters + 10];
            for (int i = 0; i < numPhotoCenters + 10; i++)
            {
                successfulImagesCollected[i] = false;
                TriggerPoints[i] = new Point();
            }
        }