Project New Waypoint MFD

Code:
BEGIN_POINTS
    -80.68293401534778 28.59767009415995
    -80.70617220949629 28.63219633933067
    -80.6209119036223 28.62760682133923
    -80.60476529545372 28.60806496816723 
    -80.65128676992974 28.58546036272783
END_POINTS

BEGIN_RUNWAYS
    #ID_STARTPOINT ID_ENDPOINT
    0 1
END_RUNWAYS


BEGIN_WAYPOINTS
    #CLASS ID TASK SIZE [ALT SPD] ["DESCRIPTION"]
    RUNWAY 0 TAKEOFF 0 0 0 "Take Off Here"    
    POINT 2    TURN 500 500 300
    POINT 3    TURN 500 1500 300
    POINT 4    TURN 500 1500 300
    RUNWAY 0 TAKEOFF 0 0 0 "Land Here"    
END_WAYPOINTS

result:
runway.png


:cheers:
 
Code:
BEGIN_POINTS
    -80.68293401534778 28.59767009415995
    -80.70617220949629 28.63219633933067
    -80.6209119036223 28.62760682133923
    -80.60476529545372 28.60806496816723 
    -80.65128676992974 28.58546036272783
END_POINTS

BEGIN_RUNWAYS
    #ID_STARTPOINT ID_ENDPOINT
    0 1
END_RUNWAYS


BEGIN_WAYPOINTS
    #CLASS ID TASK SIZE [ALT SPD] ["DESCRIPTION"]
    RUNWAY 0 TAKEOFF 0 0 0 "Take Off Here"    
    POINT 2    TURN 500 500 300
    POINT 3    TURN 500 1500 300
    POINT 4    TURN 500 1500 300
    RUNWAY 0 TAKEOFF 0 0 0 "Land Here"    
END_WAYPOINTS
I still don't like this syntax; but never mind, it is your choice ;) :thumbup:
 
I still don't like this syntax; but never mind, it is your choice ;) :thumbup:
Sorry but i've chosen it ;-)
I think i will public the code so it's possible to create an alternative pareser...

Does it is ok to save the route files in the folder
C:\Orbiter\Orbiter2010 P1 clean\Config\WPMFD\routes ?
and to call the files *.route ?

P.S.
The list mode is completed:
listmode.png
 
You can directly create a new folder inside Orbiter. (like "<Orbiter>\Waypoints"). And you can perfectly call a file *.route, as well as you can remane in "*.txt" an image ! ;)
 
what about just adding a waypoint type of 'runway' with a slightly elongated box and letting the user put in the lat/lon of the middle bit of the runway? Saves you the effort of parsing config files.

Parsing the code is really easy. I recently had to do it for the OBSP landing autopilot.
 
Parsing the code is really easy. I recently had to do it for the OBSP landing autopilot.

Are you talking about parsing the code from the .cfg - files?
By the way, whats the usal way to do this?
So my idea ist:

- get the Name of VESSELSTATUS.rbody
- parse the NAME.cfg file and get baes directories
- go to each of this directory and parse all the .cfg - files
- get the location of the base
- get the x/y position of the runways
- calculate runways position by this values
... ?
 
Doesn't the Orbiter API give you a list of bases? Might be a bit easier/safer to get the list from there, as base objects can differ with "CONTEXT" options in a scenario.

EDIT: after a quick look-over the oapi, it looks like one could easily get Lon/Lat for the landing pads of a base, but not for the runway.
 
Last edited:
Can someone test this beta version?

First, i've got some ctd's, only in this release version.
But after restarting Orbiter, it seems to be working...?

Thanks!

[EDIT]
File moved the to the first post of this topic
 
Last edited:
"CapTbHab.route" gives me a Runtime Error, probably because of the "#" used in comments
"cape_tour.route" makes Orbiter CTD ...
Test and test ...

Maybe a little check in the code ?
 
Last edited:
"CapTbHab.route" gives me a Runtime Error, probably because of the "#" used in comments
"cape_tour.route" makes Orbiter CTD ...
Test and test ...

Maybe a little check in the code ?
Hi,
ok i've found my bug, there was an error in a route file, but the publiced version here does not have this error.
So your CTD's must have another reson...

The code is ok, because in the "debug version" i don't get any CTD...
So i will look if there is somethink wrong in the compiler settings.

Does the MFD works if you don't load any route?
 
Yes it is. ;)
All work perfectly until I press "LDT" 2 times ...

Do you still get the error now if you press one times?

Do you have used mouse or keyboard?
 
I have used the mouse. And when I press one time, it shows the "route file selection". The second time I press "LDT" I think it loads the file ... And have an error.
 
Ah ok,

the problem is, i cannot reproduce this bug.

So does this file change anything?

To try, just replace the dll file in \Modules\Plugin ...

[EDIT]
File moved the to the first post of this topic
 
Last edited:
No, it doesn't changes anything.
For all the tests, I took the "DG-S ready to Take-off"
 
The code is ok, because in the "debug version" i don't get any CTD...

I wouldn't go that far.

If debug works, and release CTDs, I would look for a buffer overrun. Usually when writing to local variables.

For instance this will run fine with the usual "Debug" compiler settings, but will cause problems with usual "Release" settings:
Code:
void SomeFunction(SomeClass *inputAddress)
{    
    char buffer1[10];
    char buffer2[1];
    SomeClass *someClassPointer = inputAddress;

    for(char i = 0; i <= 10; ++i)
    {
        buffer1[i] = i;
    }
    
    someClassPointer->SomeClassFunction(buffer1);
}

The reason for that is because the "for loop" overruns buffer1. In the "Debug" build that doesn't cause problems, because it writes into buffer2. The way that local function variables appear in memory is contiguous on the stack.
I.e.:
Code:
char buffer1[10];
char buffer2[1];
SomeClass *someClassPointer = inputAddress;

Is the same (memory-structure-wise) as:
Code:
char buffer1[11];
SomeClass *someClassPointer = inputAddress;

The "Release" build will likely recognize buffer2 isn't used, and optimize it out of the function, leaving the last buffer write in the "for loop" (where i = 10) writing into the memory location of someClassPointer.

Does that make sense?
 
Do you can select the "list mode" (Even is no track is loaded)?
I just ask beause after parsesing the track the MFD change automaticly to list mode... maybe there could be an error...

---------- Post added at 04:03 PM ---------- Previous post was at 03:58 PM ----------

Ok so here is the code of my verry simple parser...
maybe i don't have catched all error conditions (it's a beta version), but because the files are ok, there don't should be an error

maybe someone can see the bug...?
Code:
//#include <stdafx.h>
#include <string>
#include <vector>
#include <windows.h>
#include <fstream> 
#include <windows.h>
#include "baseland.h" //TODO: Rename
using namespace std;

double parser2::myatof(string s)
{
    double d = atof(s.c_str());
    if (d == 0 && s.at(0) != '0')
    {
        errorOut("error converting " + s + " to double.");
        return -1;
    }
    return d;
}
vector<waypoint> parser2::getRoute(string fileName)
{
    //this->readFileLocal(fileName.c_str());
    
    fileString = readFileLocal(fileName.c_str());
    fileString = this->replaceAll();
    vector<point> points = getPoints();
    runways = getRunways(points);
    meineroute = getRoute(points,runways);

    return meineroute;
}
int parser2::myatoi(string s)
{
    int i = atoi(s.c_str());
    if (i == 0 && s.at(0) != '0')
    {
        errorOut("error converting " + s + " to int.");
        return -1;
    }
    return i;
}

vector<waypoint> parser2::getRoute(vector<point> points, vector<runway> runways)
{
    vector<waypoint> waypoints;
    string str = getElements("WAYPOINTS");
    if (str.size() == 0)
    {
        errorOut("Error parsing file!\nEND_WAYPOINTS not found after BEGIN_WAYPOINTS?\n");
        return waypoints;
    }
    vector<string> ptbuff = split(str,"\n");
    for (int ip =0; ip<ptbuff.size(); ip++)
    {
        waypoint wp;
        //parse comment
        int startComment = ptbuff.at(ip).find("\"");
        if (startComment > 0)
        {
            int endComment = ptbuff.at(ip).find("\"",startComment+1);
            if (endComment > startComment)
            {
                wp.comment = ptbuff.at(ip).substr(startComment+1,endComment-startComment-1);
                printf("gut!");
            }
            
        }
        else
            wp.comment = "";
        vector<string> elementStr = split(ptbuff.at(ip)," ");
        int id = myatoi(elementStr.at(1));        
        if (elementStr.at(2) == "TURN") wp.type =  0;
        else if (elementStr.at(2) == "LOOP") wp.type = 1;
        else if (elementStr.at(2) == "TAKEOFF") wp.type=  2;
        else if (elementStr.at(2) == "LAND") wp.type=  3;

        wp.radius = myatof (elementStr.at(3));

        if (elementStr.size() > 4)
        {
            
            wp.alt = myatof(elementStr.at(4));
            wp.speed = myatof(elementStr.at(5));
        }
        else
        {
            wp.alt = 0;
            wp.speed = 0;
        }
        if (elementStr.at(0) == "RUNWAY")
        {
            wp.lat = (runways.at(id).center.lat);
            wp.lon = (runways.at(id).center.lon);            
            //runways.at(id).wpIds.push_back(ip);            
        }
        else if (elementStr.at(0) == "POINT")
        {
            wp.lat = degToRad(points.at(id).lat);
            wp.lon = degToRad(points.at(id).lon);
        }
        waypoints.push_back(wp);
    }
    printf("%s",str.c_str());
    return waypoints;
}

void parser2::errorOut(string errormessage)
{
    printf(errormessage.c_str());
}
vector<runway> parser2::getRunways(vector<point> points)
{
    vector<runway> runways;
    string runwaysStr = getElements("RUNWAYS");
    if (runwaysStr.size() == 0)
    {
        errorOut("Error parsing file!\nEND_RUNWAYS not found after BEGIN_RUNWAYS?\n");
        return runways;
    }
    vector<string> ptbuff = split(runwaysStr,"\n");
    for (int ip =0; ip<ptbuff.size(); ip++)
    {
        vector<string> elementStr = split(ptbuff.at(ip)," ");
        int ip1 = myatoi(elementStr.at(0));
        int ip2 = myatoi(elementStr.at(1));
        if (ip1 == -1|| ip2 == -1) 
            return runways;
        point p1,p2;
        p1.lon = degToRad(points.at(ip1).lon);
        p1.lat = degToRad(points.at(ip1).lat);
        p2.lon = degToRad(points.at(ip2).lon);
        p2.lat = degToRad(points.at(ip2).lat);
        runway rw;
        rw.p1 = p1;
        rw.p2 = p2;
        double delta = 0;

        if (rw.p1.lat > rw.p2.lat)
        {
            delta = rw.p1.lat - rw.p2.lat;
            rw.center.lat = rw.p2.lat + (delta / 2);
        }
        if (rw.p1.lat < rw.p2.lat)
        {
            delta = rw.p2.lat - rw.p1.lat;
            rw.center.lat = rw.p1.lat + (delta / 2);
        }

        if (rw.p1.lon > rw.p2.lon)
        {
            delta = rw.p1.lon - rw.p2.lon;
            rw.center.lon = rw.p2.lon + (delta / 2);
        }
        if (rw.p1.lon < rw.p2.lon)
        {
            delta = rw.p2.lon - rw.p1.lon;
            rw.center.lon = rw.p1.lon + (delta / 2);
        }
/*
        rw.center.lat = p1.lat; //TODO: Calculateting Centerpoint
        rw.center.lon = p1.lon; //TODO: Calculateting Centerpoint
    */
        runways.push_back(rw);
    }
    return runways;
}
vector<point> parser2::getPoints()
{
    string allpoints = getElements("POINTS");
    vector<point> points;
    if (allpoints.size() == 0)
    {
        errorOut("Error parsing file!\nEND_POINTS not found after BEGIN_POINTS?\n");
        return points;
    }
    vector<string> ptbuff = split(allpoints,"\n");
    
    vector<runway> runways;
    for (int ip =0; ip<ptbuff.size(); ip++)
    {
        point p;
        vector<string> elementStr = split(ptbuff.at(ip)," ");
        p.lon = myatof(elementStr.at(0));
        p.lat = myatof(elementStr.at(1));
        points.push_back(p);
    }
    return points;
}
void parser2::readFile(std::string fileName)
{
    this->readFileLocal(fileName.c_str());
}
parser2::parser2()
{
}
parser2::parser2(string fileName)
{
    string testStr = "0";
    fileString = readFileLocal(fileName.c_str());
    fileString = this->replaceAll();
    vector<point> points = getPoints();
    runways = getRunways(points);
    meineroute = getRoute(points,runways);

}
string parser2::replaceAll()
{
    fileString = this->replace(fileString,"\t"," ");
    fileString = this->replace(fileString,"  "," ");
    fileString = this->replace(fileString,"\n ","\n");
    fileString = this->replace(fileString,"\n\n","\n");    
    return fileString;
}
string parser2::readFileLocal(const char* filename)
{
    try
    {
        string fstring;
        ifstream fin(filename);
        if (fin == NULL)
        {
            throw 0;
        }
        string zeile;
        getline(fin, zeile);
        
        fstring = fstring + zeile;
        do 
        {
            getline(fin, zeile);
            zeile = zeile.substr(0,zeile.find("#"));
            fstring = fstring + zeile + "\n";
        } while (!fin.eof());
        return fstring;
    }
    catch(...)
    {
        return "";
    }
}

string parser2::replace(string source,string replace, string by)
{
    int pos = source.find(replace); 
    while (pos >= 0)
    {    
        source = source.replace(pos,replace.length(),by);
        pos = source.find(replace); 
    }
    return source;
}

vector<string> parser2::split(string sourceString,string delimitter) 
{
    std::vector<std::string> elements;
    char * pch;
    char * buffer1 = new char[sourceString.length()];
    strcpy(buffer1,sourceString.c_str());
    char * buffer2 = new char[delimitter.length()];
    strcpy(buffer2,delimitter.c_str());
    pch = strtok (buffer1,buffer2);
    if (pch != NULL) 
    {
        std::string buffer3(pch);
        elements.push_back(buffer3);
    }
    while(pch != NULL)
    {
        pch = strtok (NULL,buffer2);
        if (pch != NULL)
        {
            std::string buffer4(pch);
            elements.push_back(buffer4);
        }
    }
    return elements;
}


string parser2::getElements(string name)
{
    try
    {
        string nodename = name;
        string nodenameStart = "BEGIN_" + nodename;
        string nodenameEnd = "END_" + nodename;
        int start = fileString.find(nodenameStart) + nodenameStart.length();
        int end = fileString.find(nodenameEnd);
        if (end<start) throw 1;
        if (end==-1 && start >= 0) throw 1;
        string elements = fileString.substr(start,end-start);
        if (elements.find("\n") == 0)
            elements = elements.substr(1,elements.length());
        
        int test1 =  elements.find("\n");
        if(elements.at(elements.length()-1) == '\n')
            elements = elements.substr(0,elements.length()-1);
        return elements;
    }
    catch(...)
    {
        return "";
    }
}
/*
int _tmain(int argc, _TCHAR* argv[])
{
    parser2 parser("C:\\Orbiter\\2 2.txt");
    system("pause");    
    return 0;
}
*/
 
Do you can select the "list mode" (Even is no track is loaded)?
I just ask beause after parsesing the track the MFD change automaticly to list mode... maybe there could be an error...

Yes I can, I I've noticed one thing: when I pass by the List mode, load a route doesn't get any CTD. Using directly "LDT' causes problems.
 
So the route is loaded or not(but without ctd)?
 
Back
Top