>> Rodney Roberts IS & Education Professional Homepage   >> Model Rockets & Boost/Gliders Programming







Discover Engineering


Science makes it known,
Engineering makes it work,
Art makes it beautiful.


 

Model Rockets & Boost/Gliders D Programming

D modules are also being developed to process model rockets, boost/gliders, rocket/gliders, lifting bodies, and
Rogallo flexwing gliders.  These rely on D, FORTRAN, Pascal, and XBLite backends for file I/O, calculations, etc.

    Files:
  1. aero030.d - a 'quick-n-dirty' D Windows testing program to calculate CD (Drag Coefficient) for model rockets,
    parallel stages, boost/gliders, and rocket/gliders.  Creates edit controls at runtime; edit control in bottom third
    of screen is used as a program message area.  Reads files saved by MRmain and glider01 (through calls to
    Pascal libraries), has limited data entry capability.  Since this is a testing program, it is somewhat 'rough' and
    incomplete.
      Additional functionality will be added as needed.


    Airflow Turbulence - discussed in MODEL ROCKET SIMULATION WITH DRAG ANALYSIS
    (Brent_Cannon-Capstone.pdf), p. 7.  Valid range is 0.01 (nearly fully laminar) - 0.80 (nearly fully turbulent)
    Rs - Surface Roughness, measured in microns.  Valid range is 0.5 (finished & polished surface) - 500 (raw wooden
    boards).  Discussed in OpenRocket Technical Documentation, pp. 43 - 45; used in calculating critical Reynolds
    Number
    and turbulent coefficient of frictionAirflow Turbulence, laminar coefficient of friction, and turbulent
    coefficient of friction are used to estimate actual coefficient of friction.  Actual coefficient of friction is used in
    estimating friction drag and interference drag.
  2. module aero010 (aero010.di and aero010.d) - designed to be general purpose reusable module for creating & I/O
    some edit controls, calculating critical Reynolds Number, boost/glider, and rocket/glider Drag Coefficient (via calls to
    missle13.dll1; requires DMD implib utility (file bup.zip) to create DMD compatible import library missle13.lib).
    Defines model rocket & glider constants.  Compiled as a .dll; use the import2 statement in calling program to access
    aero010.def - describes Win32 library characteristics, used by optlink and/or implib.
  3. XBCRANK.X - This started as an experiment to port Numerical Recipes to XBLite and determine if possible to call a
    XBLite .dll from various programming languages.
    D module aero030 calls XBCRANK.dll CFUNCTIONs xbEntryc ( ) and NewNumEdtCtrl (...) (to be D callable,
    the XBLite functions must be declared as CFUNCTION and receive their arguments by value)
    NewNumEdtCtrl (...)
    is used to create some edit controls (this was an experiment to see if possible).
    XBCRANK.dll - produced by XBLite generated XBCRANK.bat (see Compiling XBasic Lite Library (DLL) for an example).
    XBCRANK.lib - import library; use DMD utility implib with /system switch to create from XBCRANK.dll.
    xbl.dll - basic startup initialization .dll; Standard libraries
    xma.dll - Math library
    xsx.dll - Standard libraries
    XBLite is case sensitive.
  4. aero020.pas - source code for Object Pascal Library aero020.dll (rocket & glider related functions/procedures); also
    called by aero030 and aero010.  Uses include files genetyp.inc, nrtyp.inc, missle.inc, and aero021.inc;
    fin/wing area pre-processing procedures, fin/wing plane area calculation, boost/glider & rocket/glider file I/O, etc.
    Can call procedures in hwndio.dll (Object Pascal or D Windows main programs only), mathproc.dll, missle02.dll,
    & missle13.dll
    aero020.dll - aero020.pas dynamic link library; compile with fpcdll.bat
    aero020.lib - DMD compatible import library
    Free Pascal is case insensitive; procedure names must be uppercase to be D callable.
  5. hedtio files (hedtio.d, hedtio.di, chedtio.bat) - general purpose Windows Edit Controls I/O, Windows error message
    procedures.  Used by both aero030 and aero010.  Will need module definition file (described on page).


Module aero030 main program initializing .dll's.  Notice that both the D and XBLite .dll's need to be initialized but not the
Pascal .dll's.  Also, when aero010.dll terminates [aeDLL_Terminate( )], so does hedtio.dll (aero010.dll uses hedtio.dll).
Function aeWinMain(...) registers the window class and its callback procedure, creates the main and child windows,
GetMessageA(...) loop processing.


aero010 function BGcd (...) (calculates boost/glider total CD) calling missle13.dll procedure BGEPCD (...) (calculates
boost/glider engine pod CD).  Note that the passed arguments are passed in reverse order.    Required for
functions/procedures/subprograms declared as extern (Pascal) (see below).
  Despite correctly calculating boost/glider
engine pod CD, upon exit procedure BGEPCD (...) may generate Access Violation Exception.3  Have verified passed
parameters' values, types, etc.  Current solution is to use try { } catch { } block as shown; catch { } processing reports
error and queries user whether to continue.



extern (...) {...}

An extern (...) {...} declaration with a linkage attribute is needed since gc_getProxy, xbEntryc, NewNumEdtCtrl,
BGREADFL, RGREADFL, LDRCKTFL, RDPSTAGE, FSLGLENCAL, RCKTAREA, WINGAREAS, FLLSTAGE, and
FMAC are defined in non-D object files.

It may help to think of it as:
extern (<calling model>)
{<returned data type> <external procedure name> (<passed parameter data types list>)}
4

extern (C)
{
  void* gc_getProxy();
// XBCRANK.dll CFUNCTIONs (XBasic Lite .dll)
  int xbEntryc () nothrow;
  HWND NewNumEdtCtrl (int, int, int, int, int, HINSTANCE, HWND, int) nothrow;
}

extern (Pascal)
{
 void BGREADFL (ref short, ref short, ref short, ref short, ref short, 
		ref short, ref short, ref short, ref short, ref short,
		ref float, ref float, ref float, ref float, ref float, ref float,
		ref float, ref float, ref float, ref float, ref float, ref float,
		ref float, ref float, ref float, ref float, ref float, ref float,
		ref float, ref short[MaxStageSerl], ref short[MaxStageSerl], 
		ref short[MaxStageSerl], ref short[MaxStageSerl], ref short[MaxStageSerl],
		ref float[MaxStageSerl], ref float[MaxStageSerl], ref float[MaxStageSerl],  
		ref float[MaxStageSerl], ref float[MaxStageSerl], ref float[MaxStageSerl],  
		ref float[MaxStageSerl], ref float[MaxStageSerl], ref float[MaxStageSerl],  
		ref float[MaxStageSerl], ref float[MaxStageSerl], ref float[MaxStageSerl],  
		ref float[MaxStageSerl], ref float[MaxStageSerl], ref float[MaxStageSerl],
		ref float[maxBTstage][MaxStageSerl], ref float[maxBTstage][MaxStageSerl], 
		ref float[maxBTstage][MaxStageSerl], ref char[bTlen], ref char[MAX_PATH],
		short, HWND, HWND) nothrow;
 void RGREADFL (ref short, ref short, ref short, ref short, ref short,
		ref short, ref short, ref short, ref short, ref short, ref short,
		ref float, ref float, ref float, ref float, ref float, ref float,
		ref float, ref float, ref float, ref float, ref float, ref float,
		ref float, ref float, 
		ref short[MaxStageSerl], ref short[MaxStageSerl], ref short[MaxStageSerl], ref short[MaxStageSerl],
		ref short[MaxStageSerl], ref short[MaxStageSerl], ref short[MaxStageSerl], ref short[MaxStageSerl],
		ref short[MaxStageSerl],
		ref float[MaxStageSerl], ref float[MaxStageSerl], ref float[MaxStageSerl], 
		ref float[MaxStageSerl], ref float[MaxStageSerl], ref float[MaxStageSerl], ref float[MaxStageSerl], 
		ref float[MaxStageSerl], ref float[MaxStageSerl], ref float[MaxStageSerl], 
		ref float[MaxStageSerl], ref float[MaxStageSerl], ref float[MaxStageSerl], 
		ref float[MaxStageSerl], ref float[MaxStageSerl], ref float[MaxStageSerl], 
		ref float[MaxStageSerl], ref float[MaxStageSerl], ref float[MaxStageSerl], ref float[MaxStageSerl], 
		ref float[maxBTstage][MaxStageSerl], ref float[maxBTstage][MaxStageSerl], ref float[maxBTstage][MaxStageSerl], 
		ref float[maxCTstage][MaxStageSerl], ref float[maxCTstage][MaxStageSerl], ref float[maxCTstage][MaxStageSerl], 
		ref float[maxCTstage][MaxStageSerl], ref float[maxCTstage][MaxStageSerl],
		ref char[bTlen], ref char[MAX_PATH], short, HWND, HWND) nothrow;
 void LDRCKTFL (ref short, ref short, ref short, ref short, ref short, ref short, ref short, 
		ref float, ref float, ref float, ref float, ref float, ref float, 
		ref short[MaxStageSerl], ref short[MaxStageSerl], ref short[MaxStageSerl], 
		ref short[MaxStageSerl], ref short[MaxStageSerl], ref float[MaxStageSerl], ref float[MaxStageSerl], ref float[MaxStageSerl], 
		ref float[MaxStageSerl], ref float[MaxStageSerl], ref float[MaxStageSerl], 
		ref float[MaxStageSerl], ref float[MaxStageSerl], ref float[MaxStageSerl], 
		ref float[maxBTstage][MaxStageSerl], ref float[maxBTstage][MaxStageSerl],
		ref float[maxCTstage][MaxStageSerl], ref float[maxCTstage][MaxStageSerl], ref float[maxCTstage][MaxStageSerl], 
		ref float[maxCTstage][MaxStageSerl],
		ref char[bTlen],
		ref char[MAX_PATH],
		short,
		HWND, HWND) nothrow;
 short RDPSTAGE (ref short, ref short, ref short,
	ref float, ref float, ref float, ref float, ref float, ref float, ref float, ref float, ref float,
	ref char[bTlen],
	ref char[MAX_PATH],
	short,
	HWND, HWND) nothrow;
 void FSLGLENCAL (ref short, 
		ref float[maxBTstage][MaxStageSerl], ref float[maxBTstage][MaxStageSerl],
		ref float[maxCTstage][MaxStageSerl], 
		ref short[MaxStageSerl], ref short[MaxStageSerl],
		ref float[MaxStageSerl], ref float[MaxStageSerl], ref float[MaxStageSerl],  
			ref float[MaxStageSerl], ref float[MaxStageSerl], ref float[MaxStageSerl],
		ref float) nothrow;
 void RCKTAREA (ref short, ref short, ref short, 
		ref float[maxBTstage][MaxStageSerl], ref float[maxBTstage][MaxStageSerl], 
			ref float[maxBTstage][MaxStageSerl], ref float[maxBTstage][MaxStageSerl],
		ref float[maxCTstage][MaxStageSerl], ref float[maxCTstage][MaxStageSerl], 
			ref float[maxCTstage][MaxStageSerl], ref float[maxCTstage][MaxStageSerl],
		ref short[MaxStageSerl], ref short[MaxStageSerl],
		ref float, ref float, ref float, ref float, ref float,
		short,
		HWND, HWND) nothrow;
 void WINGAREAS (ref short,
		ref short[MaxStageSerl],
		ref float[MaxStageSerl], ref float[MaxStageSerl], ref float[MaxStageSerl], ref float[MaxStageSerl],
			ref float[MaxStageSerl], ref float[MaxStageSerl], ref float[MaxStageSerl],
			ref float[MaxStageSerl], ref float[MaxStageSerl], ref float[MaxStageSerl],
		ref float, ref float,
		int, short, short,
		HWND, HWND) nothrow;
 short FLLSTAGE (ref short, ref short,
		ref float[MaxStageSerl], 
		ref float, ref float) nothrow;
 float FMAC (ref short, short, 
			ref float, float, float, float, float, float) nothrow;
// C function maximum number arguments
// http://stackoverflow.com/questions/9034787/function-parameters-max-number
// 5.2.4.1 Translation Limits
//  127 parameters in one function definition
//  127 arguments in one function call
 void CDDETAILS (ref short, ref short, ref short, ref short, 
		ref float[MaxStageSerl], ref float[MaxStageSerl], ref float[MaxStageSerl], ref float[MaxStageSerl], 
		ref float[MaxStageSerl], ref float[MaxStageSerl], ref float[MaxStageSerl], ref float[MaxStageSerl], 
		ref float[MaxStageSerl], ref float[MaxStageSerl], ref float[MaxStageSerl], ref float[MaxStageSerl],
		ref float[maxCTstage][MaxStageSerl], ref float[maxCTstage][MaxStageSerl], ref float[maxCTstage][MaxStageSerl],
		ref float[maxCTstage][MaxStageSerl], ref float[maxCTstage][MaxStageSerl], 
		ref float[maxBTstage][MaxStageSerl],
		ref short[MaxStageSerl], ref short[MaxStageSerl], ref short[MaxStageSerl], 
		ref float, ref float, ref float, ref float, ref float, short,
		ref float, ref float, ref float, ref float, ref float, 
		ref float[MaxStageSerl], 
		HWND, HWND,
		short, short) nothrow;
 void PSPCD (ref short,
		ref float, ref float, float, float, 
		ref float, ref float, ref float, ref float, ref float, ref float, ref float, 
		ref double) nothrow;
}
       
void* (or void) is used for Pascal procedure calls, indicating the subprogram does not return a value.

Using anything other than extern (Pascal) {...} to declare the external Pascal procedures (which were originally
meant for the stdcall model) caused a variant of Error 42: Symbol Undefined.   extern (Pascal) {...}
causes the passed arguments to be Pushed/Popped to/from the stack in a different order, requiring the parameters
passed to the external Pascal procedures be listed in reverse order in the call statement.
Since NewNumEdtCtrl (...) is declared extern (C) {...}, its parameters are passed in normal order.



pragma (...)

pragma (...) statements can be used in both .d source files and .di D interface files.

One use for D's pragma statement is to specify a library to link in when compiling a D module, especially when
compiling a .dll.  Module aero010 is compiled as a .dll and calls four other .dlls - gdi32, missle13, aero020, and
hedtio.  All four appear in pragma (lib, ...) statements in aero010.d but only three appear in aero010.di - required
for clean compile.

As a general rule, use pragma (lib, ...) statements to link in non-D libraries not specified in an extern (...) {...} for
a main program; link in any library (even if a D library in an import statement) for a .dll.



Compiling and Linking :

Compile and link FORTRAN mathproc.for

Compile and link Pascal .dll's   (Command Prompt)
fpcdll hwndio
fpcdll missle02
fpcdll missle13
implib missle13.lib missle13.dll
fpcdll aero020
implib aero020.lib aero020.dll

Compile and link XBLite .dll
Run XBLite Scintilla Editor (XSED)
File, Open   XBCRANK.X
Run, Compile as Library (DLL)
in Command Prompt,
XBCRANK.bat
implib /system XBCRANK.lib XBCRANK.dll


Compile and link D .dll's
chedtio

dmd -c aero010.d -g
dmd aero010.obj aero010.def -g
implib /noi /system aero010.lib aero010.dll


Compile and link D main program
dmd aero030.d hedtio.lib aero010.lib aero020.lib XBCRANK.lib missle13.lib win.def




1. missle13.dll is the primary .dll for calculating CD, Mean Aerodynamic Chord, etc.  uses units fnameIO.pas
and missle06.pas.
See source code comments for various reference sources used.
2. When an import statement is encountered, the compiler first searches for a D interface (.di) file, which is simply a
declaration of module constants, variables, exported functions.  Also included is a list of most (but not necessarily all)
of the pragma (lib, ...) and imported modules listed in the module's source (.d) file.
3. This appears to be a Free Pascal error, as the Exception may occur in an all Pascal MS-DOS solution.  Possibly
related to a known Windows problem, have encountered similar problem in
Lazarus, Free Pascal, Silverfrost FTN95, and Numerical Recipes: The Art of Scientific Computing (BGEPCD (...) calls
several FORTRAN subprograms both directly & indirectly).  Using Free Pascal Compiler v2.6.4, later versions may not
have this problem.  Also, may be a simple issue of changing a default compiler directive.
4. aero030.d extern statement shown; aero010.d has it's own extern statement
See Variable Storage Compatibility and Equivalency for D / Pascal data type cross-reference.
Not shown are the extern (Windows) {...} statements for the Windows API calls.


Any and all © copyrights, ™ trademarks, or other intellectual property (IP) mentioned here are the property of their respective owners. No infringement is intended.

Feel free to use any of the above in your project; please give credit (same idea as Copyleft).  The source code files available for download on these pages are enhanced (including error fixes) and tested periodically - check often for revised versions (some portions of source code still in beta).

Page best viewed with Mozilla FireFox 3.6.13 (or higher), and Safari 5.1.7.  Internet Explorer / Microsoft Edge may not display properly.

Website is supported on DESKTOP platforms only.

Web hosting provided by  
FREE WEB HOSTING ,   Free Web Hosting. , & GigaRocket Web Hosting



>> Rodney Roberts IS & Education Professional Homepage   >> Model Rockets & Boost/Gliders Programming