Project Air Breathing Turbojet Engine Model for Orbiter

Thunder Chicken

Fine Threads since 2008
Donator
Joined
Mar 22, 2008
Messages
4,418
Reaction score
3,331
Points
138
Location
Massachusetts
When defining the thrusters, is handle th_main understood to be assigned to the main engine throttle, or does that need to be specified in some way? It's a single thruster so I did not use CreateThrusterGroup.

EDIT: After RTFMing, I realize that these need to be established. Done. Still crashing.
 
Last edited:

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,664
Reaction score
2,385
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
It has to be specified, since Orbiter doesn't know how you named this variable. And it doesn't care about it. You could also name it Frank, and it would behave just the same.

When using a single thruster for a meshgroup, remember that it expects an array of thruster handles, which in C and C++ is equivalent to an pointer to the first element of the array. So you have two options:

A get a pointer to the thruster handle.

Code:
CreateThrusterGroup(THGROUP_MAIN, &th_main, 1);

B Write everything as an array of one element:

Code:
THRUSTER_HANDLE th_main[1];

th_main[0] = CreateThruster(.................);

CreateThrusterGroup(THGROUP_MAIN, th_main, 1);
 

Thunder Chicken

Fine Threads since 2008
Donator
Joined
Mar 22, 2008
Messages
4,418
Reaction score
3,331
Points
138
Location
Massachusetts
It has to be specified, since Orbiter doesn't know how you named this variable. And it doesn't care about it. You could also name it Frank, and it would behave just the same.

When using a single thruster for a meshgroup, remember that it expects an array of thruster handles, which in C and C++ is equivalent to an pointer to the first element of the array. So you have two options:

A get a pointer to the thruster handle.

Code:
CreateThrusterGroup(THGROUP_MAIN, &th_main, 1);

B Write everything as an array of one element:

Code:
THRUSTER_HANDLE th_main[1];

th_main[0] = CreateThruster(.................);

CreateThrusterGroup(THGROUP_MAIN, th_main, 1);
Yes. I also realized that I had my thruster inputs backwards. I have a dummy thruster that creates no thrust, but must take the main engine throttle input, so I had to associate it with THGROUP_MAIN. What I called the main thruster that actually produces the thrust has to go in as a user-defined thruster (THGROUP_USER).

I've tried commenting out all of the thrusters and engine calculations entirely and it still crashes on start. It briefly shows a rendering of the exterior mesh, so it's getting that far before crashing.
 

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,664
Reaction score
2,385
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
So, it likely fails either in your clbkPostCreation, clbkPreStep or clbkPostStep.
 

Thunder Chicken

Fine Threads since 2008
Donator
Joined
Mar 22, 2008
Messages
4,418
Reaction score
3,331
Points
138
Location
Massachusetts
I'm still struggling to learn to get human-readable information out of the debugger. It keeps throwing up exceptions named after Elon Musk's children, which helps me not at all.
 

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,664
Reaction score
2,385
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
Sorry, most people who defined C++ and its exception had been of a generation, which had learned to keep symbols in a compiler short, since the RAM for a symbol table was very limited.

Which kind of exception are you looking for, and do you already step through the (hopefully unoptimized) code of your callback in single step mode?
 

Thunder Chicken

Fine Threads since 2008
Donator
Joined
Mar 22, 2008
Messages
4,418
Reaction score
3,331
Points
138
Location
Massachusetts
Something is deeply strange. I set a breakpoint at the very top of main code, ran debugger, and it still is crashing?

I am getting this:

Exception thrown at 0x00513C7C in orbiter.exe: 0xC0000005: Access violation reading location 0xFB57F574.

Googling any of this gives me no results.

BTW I can load any other scenario without the Mirage2000 add-on, so it doesn't appear to be a problem with the Orbiter installation.
 
Last edited:

dbeachy1

O-F Administrator
Administrator
Orbiter Contributor
Addon Developer
Donator
Beta Tester
Joined
Jan 14, 2008
Messages
9,218
Reaction score
1,566
Points
203
Location
VA
Website
alteaaerospace.com
Preferred Pronouns
he/him
If you run your add-on under the Visual Studio debugger (as a Debug build, of course), the debugger will pop up on the line where that exception occurred. You can check out this thread for details about how to run your add-on in the debugger, enable Visual Studio's runtime memory heap checks to help catch bugs, and single-step through your code to narrow down bugs futher.
 

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,664
Reaction score
2,385
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
Let me help you read this:

"Exception thrown at"..., is just telling you what just happened. Something bad made your program fail so bad, that an uncaught! exception forced windows to terminate it.

The following "0x" tells you, the following data will be in hexadecimal, its an adress in the flat virtual memory of Orbiter.exe (Every process can essentially pretend in most operating systems, that its all alone in RAM). You can ignore it, unless its some very special hexadecimal number, like "0x0000000".

The next hexadecimal number 0xC0000005 is the error code that happened as defined by Windows, followed by its type in human readable form. You had an access violation, your program tried to read data from a memory location, that contained no data, but some virtual memory protection. For example, this exception is triggered if you try to read or write data, that is in a memory location marked as containing machine language instructions (So viruses have a much harder time).

So, what happened: Somewhere inside Orbiters memory (which can be Orbiter itself OR any DLL loaded by Orbiter), an instruction used a wrong adress.

Now the question is, what causes this? This can happen if you use a wrong handle or for example put a value as argument into a function, where an reference to the variable was expected (usually the compiler prevents this).
 

Thunder Chicken

Fine Threads since 2008
Donator
Joined
Mar 22, 2008
Messages
4,418
Reaction score
3,331
Points
138
Location
Massachusetts
If you run your add-on under the Visual Studio debugger (as a Debug build, of course), the debugger will pop up on the line where that exception occurred. You can check out this thread for details about how to run your add-on in the debugger and enable Visual Studio's runtime memory heap checks to help catch bugs.
To do this the project properties need to be established for a Debug build. It appears that what I entered for properties was for Release. Should those properties carry over to each build type? Did I enter them incorrectly?
 

dbeachy1

O-F Administrator
Administrator
Orbiter Contributor
Addon Developer
Donator
Beta Tester
Joined
Jan 14, 2008
Messages
9,218
Reaction score
1,566
Points
203
Location
VA
Website
alteaaerospace.com
Preferred Pronouns
he/him
You will need to set up properties for a Debug build and set the build target to Debug. There are separate project properties for Debug and Release builds, and the two do not conflict. Generally speaking, you will always want to run Debug builds during development and only switch to Release builds for final testing before you release your add-on.

One thing I forgot to mention: if the exception occurs in orbiter.exe itself, that usually means that your code passed some invalid value to it. When the exception occurs, open the Call Stack window in the Visual Studio debugger and double-click on the first frame in the window that is in your code; that will pop up the line in your code that called into Orbiter.exe (i.e., called that Orbiter SDK method).
 

Thunder Chicken

Fine Threads since 2008
Donator
Joined
Mar 22, 2008
Messages
4,418
Reaction score
3,331
Points
138
Location
Massachusetts
You will need to set up properties for a Debug build and set the build target to Debug. There are separate project properties for Debug and Release builds, and the two do not conflict. Generally speaking, you will always want to run Debug builds during development and only switch to Release builds for final testing before you release your add-on.

One thing I forgot to mention: if the exception occurs in orbiter.exe itself, that usually means that your code passed some invalid value to it. When the exception occurs, open the Call Stack window in the Visual Studio debugger and double-click on the first frame in the window that is in your code; that will pop up the line in your code that called into Orbiter.exe (i.e., called that Orbiter SDK method).
Here are the three lines (frames?) that pop up in the call stack:

orbiter.exe!00513c7c() Unknown
[Frames below may be incorrect and/or missing, no symbols loaded for orbiter.exe] Unknown
[External Code]

Double-clicking on any of them doesn't bring me to a line in my code. Doing so simply opens a tab in the IDE that says Symbol File Not Loaded in big letters.
 

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,664
Reaction score
2,385
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
Here are the three lines (frames?) that pop up in the call stack:

orbiter.exe!00513c7c() Unknown
[Frames below may be incorrect and/or missing, no symbols loaded for orbiter.exe] Unknown
[External Code]

Double-clicking on any of them doesn't bring me to a line in my code. Doing so simply opens a tab in the IDE that says Symbol File Not Loaded in big letters.

Then the problem likely happens between prestep and poststep. In that case, you should review, what you define and how you manipulate it until prestep is done. It can happen until then, For example, did you use uninitialized variables?
 

Thunder Chicken

Fine Threads since 2008
Donator
Joined
Mar 22, 2008
Messages
4,418
Reaction score
3,331
Points
138
Location
Massachusetts
Then the problem likely happens between prestep and poststep. In that case, you should review, what you define and how you manipulate it until prestep is done. It can happen until then, For example, did you use uninitialized variables?
I'm not sure what the pre- and poststep callbacks do to be honest. This code does not seem to have a Prestep. From the vessel class:

void DefineAnimations(void);
void Steering();
std: pair<double, double> GetJetEngineThrustIsp(double throttle, bool afterburner, double M_0, double T_0, double P_0, double rho);
void clbkSetClassCaps(FILEHANDLE cfg);
void clbkPostStep(double simt, double simdt, double mjd);
int clbkConsumeBufferedKey(DWORD key, bool down, char *kstate);
bool clbkLoadVC(int id);


EDIT: Adding an empty Prestep doesn't change anything.
 
Last edited:

kuddel

Donator
Donator
Joined
Apr 1, 2008
Messages
2,064
Reaction score
508
Points
113
The methods your Vessel class has are not only those defined there, but also all derived methods (public & protected ones to be more precise).
So the methods @Urwumpe mentioned must not neccessarily be defined/declared at that class.
Short introduction of "inheritance":

Let's assume a base class called "Mammal", that has (among others) a method called "walk"
A "specialized" Mammal is a Cat, therefore one can derive from class "Mammal" and provide a method called "meow". Which is sensible for cats, but not for all mammals.
Nevertheless any Cat can also "walk", so it derives that method from its Base-Class.

C++:
class Mammal { // ...left many needed lines to clarify...
  public:
    void walk ();
};

class Cat : Mammal {
  public:
    void meow ();
};
Any instance of a cat can walk and meow!

For details wikipedia might also shed some light (and / or add confusion ;) )

But that's just a side-note here, your immediate problem is an invalid memory access, that has almost nothing to do with inheritance :D
 
Last edited:

Thunder Chicken

Fine Threads since 2008
Donator
Joined
Mar 22, 2008
Messages
4,418
Reaction score
3,331
Points
138
Location
Massachusetts
The methods your Vessel class has are not only those defined there, but also all derived methods (public & protected ones to be more precise).
So the methods @Urwumpe mentioned must not neccessarily be defined/declared at that class.
Short introduction of "inheritance":

Let's assume a base class called "Mammal", that has (among others) a method called "walk"
A "specialized" Mammal is a Cat, therefore one can derive from class "Mammal" and provide a method called "meow". Which is sensible for cats, but not for all mammals.
Nevertheless any Cat can also "walk", so it derives that method from its Base-Class.

C++:
class Mammal { // ...left many needed lines to clarify...
  public:
    void walk ();
};

class Cat : Mammal {
  public:
    void meow ();
};
So, in this case, Mirage2000 inherits methods inherent in class Vessel, and then defines methods specific to Mirage2000 defined in the code. That make sense. So Vessel methods like clbkPreStep that don't need to be redefined aren't.
For details wikipedia might also shed some light (and / or add confusion ;) )

I'm drinking from a fire hose at the moment trying to sort out all these things, but thanks.

But that's just a side-note here, your immediate problem is an invalid memory access, that has almost nothing to do with inheritance :D
So I quess the question is, where do I go from here to sort out what this problem is?
 

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,664
Reaction score
2,385
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
If it only has a poststep, thats good news: Then the problem has one location less to manifest itself. Next in the row. Can you set a breakpoint at the first statement in the body of clbkPostStep() and stop there? You have the ability to inspect your own MIRAGE2000 instance there and see the contents of the variables. Maybe you can make a screenshot of it and we can try to search together, if there is something obviously wrong or what kind of data we can exclude as problem.

Kevin wasn't exactly a good C++ coder there, but he did learn it for making better add-ons, which by itself deserves a lot of respect.
 

Thunder Chicken

Fine Threads since 2008
Donator
Joined
Mar 22, 2008
Messages
4,418
Reaction score
3,331
Points
138
Location
Massachusetts
If it only has a poststep, thats good news: Then the problem has one location less to manifest itself. Next in the row. Can you set a breakpoint at the first statement in the body of clbkPostStep() and stop there? You have the ability to inspect your own MIRAGE2000 instance there and see the contents of the variables. Maybe you can make a screenshot of it and we can try to search together, if there is something obviously wrong or what kind of data we can exclude as problem.
Here's what I see. It looks like it is failing before if even gets into the clbkPostStep().

1657828396567.png

Kevin wasn't exactly a good C++ coder there, but he did learn it for making better add-ons, which by itself deserves a lot of respect.

He cranked out a LOT of light meshes with animations for some fun aircraft. No complaints here.
 

Thunder Chicken

Fine Threads since 2008
Donator
Joined
Mar 22, 2008
Messages
4,418
Reaction score
3,331
Points
138
Location
Massachusetts
If I put a breakpoint on the very first line of code, it still fails before it is reached?

1657828835454.png
 

dbeachy1

O-F Administrator
Administrator
Orbiter Contributor
Addon Developer
Donator
Beta Tester
Joined
Jan 14, 2008
Messages
9,218
Reaction score
1,566
Points
203
Location
VA
Website
alteaaerospace.com
Preferred Pronouns
he/him
You should be able to set a breakpoint in the debugger before even starting Oribter.exe -- check out https://docs.microsoft.com/en-us/visualstudio/debugger/using-breakpoints?view=vs-2022. Try putting a breakpoint at the start of clbkSetClassCaps, for example.

Then once you start Orbiter.exe in the debugger and load your scenario, you should still see a solid red dot on far left of the line where you put the breakpoint. If, however, it turns into a hollow red dot, that means that DLL containing that code was either not loaded by Orbiter.exe or the debugger can't find symbols for that code. If that happens, make sure you're building your code with full debug information for Debug builds; this is the default, but if you're sure that code is being hit and the breakpoint still won't activate, that points to the symbols not being loaded.

EDIT: you can check out this YouTube debugging tutorial for VS 2022 as well:

One other thing to check is that you are building the Debug version of your vessel's DLL into the proper Orbiter folder (e.g., C:\Orbiter\Modules) so that Orbiter loads that debug version. This is set in the linker properties for your project, or you can use a post-build event (which is the method I prefer) to copy your vessel DLL to your Orbiter\Modules folder -- check out https://docs.microsoft.com/en-us/vi...om-build-events-in-visual-studio?view=vs-2022 for details.
 
Last edited:
Top