Skip to content
Snippets Groups Projects
Commit 6381cf5c authored by Tobias Weckenmann's avatar Tobias Weckenmann
Browse files

Merge branch 'fix/librariesUpdate' into 'develop'

libraries: correct formating

See merge request !54
parents bd284a6a bb15b7f7
Branches
Tags
3 merge requests!76Draft: Updated Python code example,!73Initial open source version,!54libraries: correct formating
Pipeline #1621994 passed
...@@ -13,7 +13,7 @@ The library is completely *test driven* so you can find most functionality in th ...@@ -13,7 +13,7 @@ The library is completely *test driven* so you can find most functionality in th
The **CGAL** library is an external dependency we do not provide within the copy of **UNICADO**. So you need to make sure the library is installed and can be found by *CMake*. You can refer to the [→ Getting Started Guide](https://doc.cgal.org/latest/Manual/general_intro.html) of **CGAL** to find instructions for your machine. The **CGAL** library is an external dependency we do not provide within the copy of **UNICADO**. So you need to make sure the library is installed and can be found by *CMake*. You can refer to the [→ Getting Started Guide](https://doc.cgal.org/latest/Manual/general_intro.html) of **CGAL** to find instructions for your machine.
If you use the **MSYS2** environment as the **UNICADO** build setup requires, you can install **CGAL** with this command in your terminal: If you use the **MSYS2** environment as the **UNICADO** build setup requires, you can install **CGAL** with this command in your terminal:
```sh ```{ .sh .copy }
pacman -S mingw-w64-ucrt-x86_64-cgal pacman -S mingw-w64-ucrt-x86_64-cgal
``` ```
......
...@@ -13,7 +13,8 @@ It is used to determine the transformation in between the different coordinate s ...@@ -13,7 +13,8 @@ It is used to determine the transformation in between the different coordinate s
Before we dive into the coordinate systems however, let's get to know how the actual geometry and shapes are represented using **CGAL**. Before we dive into the coordinate systems however, let's get to know how the actual geometry and shapes are represented using **CGAL**.
@attention → This library does only support discrete shapes. Meaning the shapes are **always** polygons where the discrete vertices of the polygon are connected with lines which form the edges of the polygon. !!!
attention → This library does only support discrete shapes. Meaning the shapes are **always** polygons where the discrete vertices of the polygon are connected with lines which form the edges of the polygon.
!!! note !!! note
The Python binding of this library does __not__ include a complete implementation of **CGAL**! The Python binding of this library does __not__ include a complete implementation of **CGAL**!
...@@ -36,6 +37,7 @@ A concrete implementation of this described polygon concept which is used in the ...@@ -36,6 +37,7 @@ A concrete implementation of this described polygon concept which is used in the
The concept of the polygon shape is formalized with the *C++* concept [Shape](@ref geom2.Shape). The concept of the polygon shape is formalized with the *C++* concept [Shape](@ref geom2.Shape).
You can use any shape class which satisfies this concept to create the surfaces. You can use any shape class which satisfies this concept to create the surfaces.
This library currently implements two main types: This library currently implements two main types:
- [PolygonSection](@ref geom2.PolygonSection): For creating general "tube" based surfaces, i.e. fuselages or nacelles. - [PolygonSection](@ref geom2.PolygonSection): For creating general "tube" based surfaces, i.e. fuselages or nacelles.
- [AirfoilSection](@ref geom2.AirfoilSection): For creating aerodynamic surfaces which have an airfoil shape. - [AirfoilSection](@ref geom2.AirfoilSection): For creating aerodynamic surfaces which have an airfoil shape.
...@@ -73,6 +75,7 @@ Now, comes the part where we position the geometry within one space and actually ...@@ -73,6 +75,7 @@ Now, comes the part where we position the geometry within one space and actually
> Keep your right hand ready to always do the "three finger dance" to visualize the right hand coordinate space. Also be aware, **Euler angles** will be involved! :-) > Keep your right hand ready to always do the "three finger dance" to visualize the right hand coordinate space. Also be aware, **Euler angles** will be involved! :-)
The library currently differentiates three coordinate spaces: The library currently differentiates three coordinate spaces:
1. `2D` : The local coordinate system of a 2D section profile/shape. 1. `2D` : The local coordinate system of a 2D section profile/shape.
2. `3D` : The local coordinate system of a multi-section surface which can include multiple 2D sections. 2. `3D` : The local coordinate system of a multi-section surface which can include multiple 2D sections.
3. `3D` : The global body-fixed coordinate system of the aircraft where all the surfaces finally live and are positioned. 3. `3D` : The global body-fixed coordinate system of the aircraft where all the surfaces finally live and are positioned.
...@@ -90,9 +93,11 @@ The `child` entity is then contained within the 3D entity `parent`. The `child` ...@@ -90,9 +93,11 @@ The `child` entity is then contained within the 3D entity `parent`. The `child`
Within the scope of `child`, point `p` has the coordinates as they are shown in the figure. Within the scope of `child`, point `p` has the coordinates as they are shown in the figure.
In the scope of `parent`, you have to add the offset of the `child` origin `O` to the coordinates of point `p`. In the scope of `parent`, you have to add the offset of the `child` origin `O` to the coordinates of point `p`.
The resulting coordinates of `p` will then be: The resulting coordinates of `p` will then be:
\f{align*}{
p_{parent, 3d} &= \begin{bmatrix} 2.5 \\1.5 \\0.0 \end{bmatrix} $$
\f} {align*}{
p_{parent, 3d} &= \begin{bmatrix} 2.5 \\1.5 \\0.0 \end{bmatrix}}
$$
An additional offset of the `child` in `Z` direction is applied to the coordinate transform in the same manner. It just adds the offset to the resulting `Z` coordinate. An additional offset of the `child` in `Z` direction is applied to the coordinate transform in the same manner. It just adds the offset to the resulting `Z` coordinate.
...@@ -112,6 +117,7 @@ This angle applies a rotation around the local `Z` axis whenever the coordinates ...@@ -112,6 +117,7 @@ This angle applies a rotation around the local `Z` axis whenever the coordinates
The handling of the third Euler angle can still be subjected to change. The handling of the third Euler angle can still be subjected to change.
The usage of the Euler angles can lead to unintuitive results, but that is unfortunately the nature of those angles. Here are some results of Euler angles with different normal directions: The usage of the Euler angles can lead to unintuitive results, but that is unfortunately the nature of those angles. Here are some results of Euler angles with different normal directions:
|Normal Direction | Euler Angle $\alpha$ | Euler Angle $\beta$ | Euler Angle $\gamma$ | |Normal Direction | Euler Angle $\alpha$ | Euler Angle $\beta$ | Euler Angle $\gamma$ |
| --- | :---: | :---: | :---: | | --- | :---: | :---: | :---: |
|`[0, 0, 1]` | 0° | 0° | 0° | |`[0, 0, 1]` | 0° | 0° | 0° |
......
...@@ -6,19 +6,19 @@ There are just means to translate the geometry to other class concepts. ...@@ -6,19 +6,19 @@ There are just means to translate the geometry to other class concepts.
It is up to those concepts to provide the file access! It is up to those concepts to provide the file access!
The converters are implemented using the *visitor design pattern*. The converters are implemented using the *visitor design pattern*.
The converters inherit from a common base class geom2::io::Converter, for future polymorphic use. The converters inherit from a common base class geom2\:\:io\:\:Converter, for future polymorphic use.
You can "visit" a specific converter with a surface object and the object gets converted to the converter specific return type. You can "visit" a specific converter with a surface object and the object gets converted to the converter specific return type.
You have the specify how the converter "treats" this surface, since certain formats might treat the same surface geometry differently based on their function (for example wings or stabilizers are both airfoil surfaces, but might get treated differently in the export format). You have the specify how the converter "treats" this surface, since certain formats might treat the same surface geometry differently based on their function (for example wings or stabilizers are both airfoil surfaces, but might get treated differently in the export format).
You can select the surface function base on type by using the surface type variant geom2::io::SurfaceType. You can select the surface function base on type by using the surface type variant geom2\:\:io\:\:SurfaceType.
Depending on which type you select for the variant the converter will treat the surface accordingly. Depending on which type you select for the variant the converter will treat the surface accordingly.
!!! note !!! note
The python bindings do work differently. They use the same underlying functions, but the interface does not enable the polymorphic use (yet)! The python bindings do work differently. They use the same underlying functions, but the interface does not enable the polymorphic use (yet)!
## Convert to aixml::node Object ## Convert to aixml::node Object
The following tutorial will show you how you can convert a multi-section surface as a wing surface node to the aircraft XML using the geom2::io::AixmlConverter class. The following tutorial will show you how you can convert a multi-section surface as a wing surface node to the aircraft XML using the geom2\:\:io\:\:AixmlConverter class.
The *aixml* library will not be discussed in detail in this tutorial. The *aixml* library will not be discussed in detail in this tutorial.
Refer to its [documentation](https://www.google.de) if you need further information. Refer to its [documentation](../index.md) if you need further information.
!!! note !!! note
The Python examples assume that you imported the following modules: The Python examples assume that you imported the following modules:
...@@ -31,9 +31,10 @@ import pyaixml as aixml ...@@ -31,9 +31,10 @@ import pyaixml as aixml
The *aixml* converter can only insert nodes into an **existing** node! The *aixml* converter can only insert nodes into an **existing** node!
This is a precaution, so that the user has to take care of memory management and not the library. This is a precaution, so that the user has to take care of memory management and not the library.
The user can provide heap and/or stack allocated node objects. The user can provide heap and/or stack allocated node objects.
The library treats both the same and does not leak memory. ;) The library treats both the same and does not leak memory. :wink:
For this tutorial, we will show two use cases of inserting a node: For this tutorial, we will show two use cases of inserting a node:
- Create a completely new node. - Create a completely new node.
- Update an existing node which has additional, non geometry related nodes as children. - Update an existing node which has additional, non geometry related nodes as children.
...@@ -64,12 +65,14 @@ AcXML = aixml.openDocument("path/to/your/aircraft.xml") ...@@ -64,12 +65,14 @@ AcXML = aixml.openDocument("path/to/your/aircraft.xml")
</div> </div>
### Convert To Node ### Convert To Node
@attention The following steps assume that you have created a surface which contains valid geometry!
Refer to @ref tutorial_geometry to learn how to do that. !!!
attention The following steps assume that you have created a surface which contains valid geometry!
Refer to [tutorial_geometry](tutorial-geometry.md) to learn how to do that.
You can convert an existing surface by visiting the *aixml* converter. You can convert an existing surface by visiting the *aixml* converter.
- Convert surface to an *aerodynamic surface node*: Convert surface to an *aerodynamic surface node*:
<div class="tabbed"> <div class="tabbed">
...@@ -81,10 +84,10 @@ You can convert an existing surface by visiting the *aixml* converter. ...@@ -81,10 +84,10 @@ You can convert an existing surface by visiting the *aixml* converter.
geom2::MultisectionSurface<geom2::AirfoilSection> surface = <<some-geometry>>... geom2::MultisectionSurface<geom2::AirfoilSection> surface = <<some-geometry>>...
/* Treat the surface as an airfoil surface */ /* Treat the surface as an airfoil surface */
geom2::io::SurfaceType wing = geom2::io::AirfoilSurface{surface}; geom2\:\:io\:\:SurfaceType wing = geom2\:\:io\:\:AirfoilSurface{surface};
/* Convert using the aixml format */ /* Convert using the aixml format */
node& created_node = std::visit(geom2::io::AixmlConverter{new_node, {"aerodynamic_surface", "0", "description"}}, wing); node& created_node = std::visit(geom2\:\:io\:\:AixmlConverter{new_node, {"aerodynamic_surface", "0", "description"}}, wing);
``` ```
- <span class="tab-title">Python</span> - <span class="tab-title">Python</span>
```python ```python
...@@ -95,6 +98,7 @@ created_node = geom2.convert.aixml.to_aerodynamic_surface(new_node, ("aerodynami ...@@ -95,6 +98,7 @@ created_node = geom2.convert.aixml.to_aerodynamic_surface(new_node, ("aerodynami
</div> </div>
Now what is happening here: Now what is happening here:
- You tell the converter to create a node **inside** `new_node`. - You tell the converter to create a node **inside** `new_node`.
- The created node will have the **name** `"aerodynamic_surface"`. - The created node will have the **name** `"aerodynamic_surface"`.
- The created node will have the **id** `"0"`. - The created node will have the **id** `"0"`.
...@@ -109,14 +113,14 @@ Now you can save the node as an XML file or further use the node object. ...@@ -109,14 +113,14 @@ Now you can save the node as an XML file or further use the node object.
### Add Another Node ### Add Another Node
You can add different nodes by specifying different IDs. You can add different nodes by specifying different IDs.
- Add another node using the same surface: Add another node using the same surface:
<div class="tabbed"> <div class="tabbed">
- <span class="tab-title">C++</span> - <span class="tab-title">C++</span>
```cpp ```cpp
/* Add another node */ /* Add another node */
node& created_node = std::visit(geom2::io::AixmlConverter{new_node, {"aerodynamic_surface", "1", "main wing"}}, wing); node& created_node = std::visit(geom2\:\:io\:\:AixmlConverter{new_node, {"aerodynamic_surface", "1", "main wing"}}, wing);
``` ```
- <span class="tab-title">Python</span> - <span class="tab-title">Python</span>
```python ```python
...@@ -133,14 +137,14 @@ However, the `created_node` will just contain the second inserted node! ...@@ -133,14 +137,14 @@ However, the `created_node` will just contain the second inserted node!
Let's assume we imported the geometry from an existing aircraft XML file and modified the geometry. Let's assume we imported the geometry from an existing aircraft XML file and modified the geometry.
Now, we want to update the data inside the imported node tree. Now, we want to update the data inside the imported node tree.
- Update an existing node tree with the surface geometry: Update an existing node tree with the surface geometry:
<div class="tabbed"> <div class="tabbed">
- <span class="tab-title">C++</span> - <span class="tab-title">C++</span>
```cpp ```cpp
/* Update the existing node */ /* Update the existing node */
node& created_node = std::visit(geom2::io::AixmlConverter{AcXML->at("path/to/wing/geometry/"), {"aerodynamic_surface", "0", "main wing"}}, wing); node& created_node = std::visit(geom2\:\:io\:\:AixmlConverter{AcXML->at("path/to/wing/geometry/"), {"aerodynamic_surface", "0", "main wing"}}, wing);
``` ```
- <span class="tab-title">Python</span> - <span class="tab-title">Python</span>
```python ```python
......
# Using the Factory Classes {#tutorial_factory} # Using the Factory Classes {#tutorial_factory}
@remark You only need to use the factories when you quickly want to create geometry which **is already** existing in the aircraft XML file.
!!! remark
You only need to use the factories when you quickly want to create geometry which **is already** existing in the aircraft XML file.
If you start geometry from scratch you just need to use the geom2::MultisectionSurface and the geom2::SectionBuilder itself. If you start geometry from scratch you just need to use the geom2::MultisectionSurface and the geom2::SectionBuilder itself.
The surface provides all the necessary tools to build your geometry. The surface provides all the necessary tools to build your geometry.
...@@ -14,12 +17,13 @@ In our case, the build plan is the *aircraft XML file* and the items are the *re ...@@ -14,12 +17,13 @@ In our case, the build plan is the *aircraft XML file* and the items are the *re
Although, this might change in future release if the aircraft XML structure. Although, this might change in future release if the aircraft XML structure.
The library has factories for all major components of the aircraft geometry as they are currently defined in the aircraft XML file: The library has factories for all major components of the aircraft geometry as they are currently defined in the aircraft XML file:
- @ref hull_factory
- @ref fuselage_factory - [hull_factory](#hull-factory)
- @ref airfoil_surface_factory - [fuselage_factory](#fuselage-factory)
- @ref wing_factory - [airfoil_surface_factory](#airfoil-surface-factory)
- @ref spar_factory - [wing_factory](#wing-factory)
- @ref control_device_factory - [spar_factory](#spar-factory)
- [control_device_factory](#control-device-factory)
!!! note !!! note
The Python examples assume that you imported the following modules: The Python examples assume that you imported the following modules:
...@@ -34,7 +38,7 @@ import pyaixml as aixml ...@@ -34,7 +38,7 @@ import pyaixml as aixml
Before you can get started extracting the surfaces from the aircraft XML file, you need to have the file loaded as a `node` object/pointer. Before you can get started extracting the surfaces from the aircraft XML file, you need to have the file loaded as a `node` object/pointer.
It is best if you use the `std::filesystem::path` class to specify the file path. It is best if you use the `std::filesystem::path` class to specify the file path.
- Load the aircraft XML file: Load the aircraft XML file:
<div class="tabbed"> <div class="tabbed">
...@@ -57,22 +61,23 @@ AcXML = aixml.openDocument("path/to/your/aircraft.xml") ...@@ -57,22 +61,23 @@ AcXML = aixml.openDocument("path/to/your/aircraft.xml")
</div> </div>
@attention Please always use `/` as the separator! The `std::filesystem` library takes care of converting this separator to the OS appropriate one. !!! attention
However, it does not deal very well with strings where you use `\` or `\\` as the separator, since these are valid characters for file names on *UNIX* systems. Please always use `/` as the separator! The `std::filesystem` library takes care of converting this separator to the OS appropriate one. However, it does not deal very well with strings where you use `\` or `\\` as the separator, since these are valid characters for file names on *UNIX* systems.
**Please note:** **Please note:**
For the sake of maintainability of this documentation, the following examples do not provide the content of the aircraft XML file. Instead, each example lists the XML file which is used for *unit testing* the class, since those files directly set the requirements of the XML content and are always up to date. For the sake of maintainability of this documentation, the following examples do not provide the content of the aircraft XML file. Instead, each example lists the XML file which is used for *unit testing* the class, since those files directly set the requirements of the XML content and are always up to date.
Due to changes in the format of the aircraft exchange file, there are subtle differences when using the factories with the newer version. Due to changes in the format of the aircraft exchange file, there are subtle differences when using the factories with the newer version.
You can jump to @ref tutorial_aixml_v3 to directly get started with the newer version. You can jump to [tutorial_aixml_v3](#tutorial_aixml_v3) to directly get started with the newer version.
The factories support both versions and automatically deduce from the input data which version of the aircraft XML you are using. The factories support both versions and automatically deduce from the input data which version of the aircraft XML you are using.
--- ---
## Aircraft XML Version 2.0.0 {#tutorial_aixml_v2} ## Aircraft XML Version 2.0.0 {#tutorial_aixml_v2}
@attention The factories **always** assume a relative path to `"AcftExchangeFile/Geometry"` when specifying paths to geometry nodes! !!! attention
The factories **always** assume a relative path to `"AcftExchangeFile/Geometry"` when specifying paths to geometry nodes!
At least for now... At least for now...
Most of the surfaces defined in the aircraft XML **version 2.0.0** file use `*.dat` files to specify the shape of the surface sections. Most of the surfaces defined in the aircraft XML **version 2.0.0** file use `*.dat` files to specify the shape of the surface sections.
...@@ -97,7 +102,7 @@ It is then enough to specify the path, to i.e. the `n0012.dat` file, by adding t ...@@ -97,7 +102,7 @@ It is then enough to specify the path, to i.e. the `n0012.dat` file, by adding t
<SegmentPointData ToolLevel="1">geometryData/airfoilData/n0012.dat</SegmentPointData> <SegmentPointData ToolLevel="1">geometryData/airfoilData/n0012.dat</SegmentPointData>
``` ```
If the specified data file does not exist or the path is wrong, the library does **not** throw an error in the current implementation! When loading a `*.dat` file which does not exist, the library just returns a shape which contains a single point with the coordinates `[0.0, 0.0, 0.0]`. See @ref geom2.io.read_dat_file for more information. If the specified data file does not exist or the path is wrong, the library does **not** throw an error in the current implementation! When loading a `*.dat` file which does not exist, the library just returns a shape which contains a single point with the coordinates `[0.0, 0.0, 0.0]`. See geom2.io.read_dat_file for more information.
### Hull Factory {#hull_factory} ### Hull Factory {#hull_factory}
> **XML Example:** `aircraftGeometry2/test/stubs/aixml-v2/hull.xml` > **XML Example:** `aircraftGeometry2/test/stubs/aixml-v2/hull.xml`
...@@ -105,7 +110,7 @@ If the specified data file does not exist or the path is wrong, the library does ...@@ -105,7 +110,7 @@ If the specified data file does not exist or the path is wrong, the library does
The hull factory is the most basic factory of the library and can be used to create simple hulls or tube surfaces, for example **nacelles**. The hull factory is the most basic factory of the library and can be used to create simple hulls or tube surfaces, for example **nacelles**.
All described functionality of this factory does also apply to all other factories since they are all derived from the same base factory class. All described functionality of this factory does also apply to all other factories since they are all derived from the same base factory class.
- Create a hull factory: Create a hull factory:
<div class="tabbed"> <div class="tabbed">
...@@ -136,7 +141,7 @@ You can use the id notation as provided by the **aixml** library. ...@@ -136,7 +141,7 @@ You can use the id notation as provided by the **aixml** library.
You are not limited to just creating *nacelles* with this factory. You are not limited to just creating *nacelles* with this factory.
As long as the data structure of the custom surface follows the convention as defined in `aircraftGeometry2/test/stubs/acxml-v2/hull.xml` it can be created with this factory. As long as the data structure of the custom surface follows the convention as defined in `aircraftGeometry2/test/stubs/acxml-v2/hull.xml` it can be created with this factory.
- Get **nacelle** with the id `SimpleHull` from the factory: Get **nacelle** with the id `SimpleHull` from the factory:
<div class="tabbed"> <div class="tabbed">
...@@ -153,9 +158,8 @@ nacelle = factory.create("Nacelle@SimpleHull") ...@@ -153,9 +158,8 @@ nacelle = factory.create("Nacelle@SimpleHull")
</div> </div>
@attention The current aircraft XML does not define the orientation of those surfaces, yet. !!! attention
Therefore, the normal direction when retrieving the surface from the factory is always the default direction. The current aircraft XML does not define the orientation of those surfaces, yet.Therefore, the normal direction when retrieving the surface from the factory is always the default direction. The origin point, however, is extracted from the aircraft XML file.
The origin point, however, is extracted from the aircraft XML file.
The resulting multi-section surface is **moved** from the factory! The resulting multi-section surface is **moved** from the factory!
This means you can use the same factory multiple times and create different surfaces by passing different surface id's. This means you can use the same factory multiple times and create different surfaces by passing different surface id's.
...@@ -183,7 +187,7 @@ nacelle = geom2.factory.HullFactory(AcXML, "").create("Nacelle@SimpleHull") ...@@ -183,7 +187,7 @@ nacelle = geom2.factory.HullFactory(AcXML, "").create("Nacelle@SimpleHull")
The fuselage factory does basically the same thing as the hull factory. The fuselage factory does basically the same thing as the hull factory.
But since the aircraft XML currently defines the data structure for fuselages a bit differently than for nacelles, this specialized factory exists. But since the aircraft XML currently defines the data structure for fuselages a bit differently than for nacelles, this specialized factory exists.
- Create the fuselage surface: Create the fuselage surface:
<div class="tabbed"> <div class="tabbed">
...@@ -211,12 +215,13 @@ fuselage = factory.create("Fuselage@SimpleFuselage") ...@@ -211,12 +215,13 @@ fuselage = factory.create("Fuselage@SimpleFuselage")
> **XML Example:** `aircraftGeometry2/test/stubs/aixml-v2/pylon.xml` > **XML Example:** `aircraftGeometry2/test/stubs/aixml-v2/pylon.xml`
The airfoil surface factory can be used to create the following surfaces from the aircraft XML file: The airfoil surface factory can be used to create the following surfaces from the aircraft XML file:
- **Pylon** - **Pylon**
- **VerticalSurface** - **VerticalSurface**
The main difference of this factory is, that is uses geom2::AirfoilSection when creating the multi-section surface. The main difference of this factory is, that is uses geom2::AirfoilSection when creating the multi-section surface.
- Create a pylon surface: Create a pylon surface:
<div class="tabbed"> <div class="tabbed">
...@@ -240,7 +245,8 @@ pylon = factory.create("Pylon@SimplePylon") ...@@ -240,7 +245,8 @@ pylon = factory.create("Pylon@SimplePylon")
</div> </div>
@attention As recommended in @ref tutorial_airfoil_surface , the airfoil factories use the **negative** local `Z` direction as the extrusion or span direction! !!! attention
As recommended in [tutorial_airfoil_surface](#tutorial_airfoil_surface) , the airfoil factories use the **negative** local `Z` direction as the extrusion or span direction!
### Wing Factory {#wing_factory} ### Wing Factory {#wing_factory}
> **XML Example:** `aircraftGeometry2/test/stubs/aixml-v2/wing.xml` > **XML Example:** `aircraftGeometry2/test/stubs/aixml-v2/wing.xml`
...@@ -249,7 +255,7 @@ The wing factory specializes the airfoil surface factory. ...@@ -249,7 +255,7 @@ The wing factory specializes the airfoil surface factory.
Again, due to a slight different data structure in the aircraft XML file. Again, due to a slight different data structure in the aircraft XML file.
The functionality is otherwise the same. The functionality is otherwise the same.
- Create a wing surface: Create a wing surface:
<div class="tabbed"> <div class="tabbed">
...@@ -287,7 +293,7 @@ The **front** and the **rear** position in relative coordinates ranging from *0* ...@@ -287,7 +293,7 @@ The **front** and the **rear** position in relative coordinates ranging from *0*
The position is defined by the local `X` direction, the `Y` coordinate of the section points is **always** *0.0*! The position is defined by the local `X` direction, the `Y` coordinate of the section points is **always** *0.0*!
The `Z` offset of these sections corresponds to the relative span position and also ranges from *0* to *1*. The `Z` offset of these sections corresponds to the relative span position and also ranges from *0* to *1*.
- Create the spar of a wing: Create the spar of a wing:
<div class="tabbed"> <div class="tabbed">
...@@ -330,7 +336,7 @@ Since the control devices are modelled as "flat plates", they do **not** have a ...@@ -330,7 +336,7 @@ Since the control devices are modelled as "flat plates", they do **not** have a
You can use the control device factory to extract single devices from the aircraft XML file using geom2::ControlDeviceFactory::create. You can use the control device factory to extract single devices from the aircraft XML file using geom2::ControlDeviceFactory::create.
- Create the geometry of a control device of a wing: Create the geometry of a control device of a wing:
<div class="tabbed"> <div class="tabbed">
...@@ -358,7 +364,8 @@ flaps = factory.create("LiftingSurface@MainWing/SurfaceParameters/HalfSurfaceDes ...@@ -358,7 +364,8 @@ flaps = factory.create("LiftingSurface@MainWing/SurfaceParameters/HalfSurfaceDes
## Aircraft XML Version 3.0.0 {#tutorial_aixml_v3} ## Aircraft XML Version 3.0.0 {#tutorial_aixml_v3}
@attention The factories **always** assume a relative path to `"aircraft_exchange_file/component_design/"` when specifying paths to geometry nodes! !!! attention
The factories **always** assume a relative path to `"aircraft_exchange_file/component_design/"` when specifying paths to geometry nodes!
At least for now... At least for now...
The newer version of the aircraft XML file does not expect the geometry files at a certain location as a result of the modularization of the whole project. The newer version of the aircraft XML file does not expect the geometry files at a certain location as a result of the modularization of the whole project.
...@@ -371,7 +378,7 @@ The node defining the geometry file in the aircraft XML simply looks like this: ...@@ -371,7 +378,7 @@ The node defining the geometry file in the aircraft XML simply looks like this:
The library will then try to use a `n0012.dat` file from the `data_directory` you have given it. The library will then try to use a `n0012.dat` file from the `data_directory` you have given it.
!!! note !!! note
In the following examples it is assumed, that you have the same directory structure for the *version 3.0.0* XML files as for the *version 2.0.0* files in @ref tutorial_aixml_v2 ! In the following examples it is assumed, that you have the same directory structure for the *version 3.0.0* XML files as for the *version 2.0.0* files in [tutorial_aixml_v2](#tutorial_aixml_v2) !
### Hull Factory ### Hull Factory
> **XML Example:** `aircraftGeometry2/test/stubs/aixml-v3/hull.xml` > **XML Example:** `aircraftGeometry2/test/stubs/aixml-v3/hull.xml`
...@@ -379,7 +386,7 @@ The library will then try to use a `n0012.dat` file from the `data_directory` yo ...@@ -379,7 +386,7 @@ The library will then try to use a `n0012.dat` file from the `data_directory` yo
The hull factory is the most basic factory of the library and can be used to create simple hulls or tube surfaces, for example **nacelles**. The hull factory is the most basic factory of the library and can be used to create simple hulls or tube surfaces, for example **nacelles**.
All described functionality of this factory does also apply to all other factories since they are all derived from the same base factory class. All described functionality of this factory does also apply to all other factories since they are all derived from the same base factory class.
- Create a hull factory: Create a hull factory:
<div class="tabbed"> <div class="tabbed">
...@@ -400,7 +407,7 @@ factory = geom2.factory.HullFactory(AcXML, "./geometryData") ...@@ -400,7 +407,7 @@ factory = geom2.factory.HullFactory(AcXML, "./geometryData")
!!! note !!! note
You **cannot** omit the path `"./geometryData"` for the *version 3.0.0* aircraft exchange files! You **cannot** omit the path `"./geometryData"` for the *version 3.0.0* aircraft exchange files!
- Get **nacelle** with the id `0` from the factory: Get **nacelle** with the id `0` from the factory:
<div class="tabbed"> <div class="tabbed">
...@@ -417,7 +424,7 @@ nacelle = factory.create("propulsion/specific/geometry/nacelle@0") ...@@ -417,7 +424,7 @@ nacelle = factory.create("propulsion/specific/geometry/nacelle@0")
</div> </div>
Note that the path to the nacelle node needs more information than in @ref tutorial_aixml_v2 since the structure of the aircraft exchange file *version 3.0.0* allows for a more flexible arrangement for different components. Note that the path to the nacelle node needs more information than in [tutorial_aixml_v2](#tutorial_aixml_v2) since the structure of the aircraft exchange file *version 3.0.0* allows for a more flexible arrangement for different components.
Since those components still use the some geometry encoding throughout the file, the same factories can be used to create the geometry surfaces. Since those components still use the some geometry encoding throughout the file, the same factories can be used to create the geometry surfaces.
However, the factories cannot know where to find each individual component. However, the factories cannot know where to find each individual component.
That is why you have to give the more detailed node path when creating the surfaces, so that the factory knows where to find the specific nodes. That is why you have to give the more detailed node path when creating the surfaces, so that the factory knows where to find the specific nodes.
...@@ -429,9 +436,8 @@ This makes the factory more flexible, since you are not confined to certain loca ...@@ -429,9 +436,8 @@ This makes the factory more flexible, since you are not confined to certain loca
The fuselage factory does basically the same thing as the hull factory. The fuselage factory does basically the same thing as the hull factory.
But since the aircraft XML currently defines the data structure for fuselages a bit differently than for nacelles, this specialized factory exists. But since the aircraft XML currently defines the data structure for fuselages a bit differently than for nacelles, this specialized factory exists.
- Create the fuselage surface: Create the fuselage surface:
</div>
`tbd` `tbd`
### Airfoil Surface Factory ### Airfoil Surface Factory
...@@ -439,14 +445,15 @@ But since the aircraft XML currently defines the data structure for fuselages a ...@@ -439,14 +445,15 @@ But since the aircraft XML currently defines the data structure for fuselages a
`tbd` `tbd`
@attention As recommended in @ref tutorial_airfoil_surface , the airfoil factories use the **negative** local `Z` direction as the extrusion or span direction! !!! attention
As recommended in [tutorial_airfoil_surface](tutorial-geometry.md/#tutorial_airfoil_surface) , the airfoil factories use the **negative** local `Z` direction as the extrusion or span direction!
### Wing Factory ### Wing Factory
> **XML Example:** `aircraftGeometry2/test/stubs/aixml-v3/wing.xml` > **XML Example:** `aircraftGeometry2/test/stubs/aixml-v3/wing.xml`
The wing factory creates the aerodynamic surfaces of the wings. The wing factory creates the aerodynamic surfaces of the wings.
- Create a wing surface: Create a wing surface:
<div class="tabbed"> <div class="tabbed">
...@@ -480,7 +487,7 @@ The **front** and the **rear** position in relative coordinates ranging from *0* ...@@ -480,7 +487,7 @@ The **front** and the **rear** position in relative coordinates ranging from *0*
The position is defined by the local `X` direction, the `Y` coordinate of the section points is **always** *0.0*! The position is defined by the local `X` direction, the `Y` coordinate of the section points is **always** *0.0*!
The `Z` offset of these sections corresponds to the relative span position and also ranges from *0* to *1*. The `Z` offset of these sections corresponds to the relative span position and also ranges from *0* to *1*.
- Create the spar of a wing: Create the spar of a wing:
<div class="tabbed"> <div class="tabbed">
...@@ -523,7 +530,7 @@ Since the control devices are modelled as "flat plates", they do **not** have a ...@@ -523,7 +530,7 @@ Since the control devices are modelled as "flat plates", they do **not** have a
You can use the control device factory to extract single devices from the aircraft XML file using geom2::ControlDeviceFactory::create. You can use the control device factory to extract single devices from the aircraft XML file using geom2::ControlDeviceFactory::create.
- Create the geometry of a control device of a wing: Create the geometry of a control device of a wing:
<div class="tabbed"> <div class="tabbed">
......
...@@ -22,7 +22,7 @@ The simplest way to start with a shape for the sections is to load the 2D data f ...@@ -22,7 +22,7 @@ The simplest way to start with a shape for the sections is to load the 2D data f
An example file which defines the shape of a circle is provided as part of the unit tests. An example file which defines the shape of a circle is provided as part of the unit tests.
The file can be found here: `aircraftGeometry2/test/stubs/circle-tab.dat`. The file can be found here: `aircraftGeometry2/test/stubs/circle-tab.dat`.
- Load the geometry: Load the geometry:
<div class="tabbed"> <div class="tabbed">
...@@ -43,7 +43,7 @@ shape = geom2.io.read_dat_file("aircraftGeometry2/test/stubs/dat-files/circle-ta ...@@ -43,7 +43,7 @@ shape = geom2.io.read_dat_file("aircraftGeometry2/test/stubs/dat-files/circle-ta
This will give you the following 2D polygon: This will give you the following 2D polygon:
![Tutorial Step 1](Tutorial/step001.png){html: width=600} ![Tutorial Step 1](figures/Tutorial/step001.png){html: width=600}
The 2D polygon is **always** oriented in the `XY`-Plane. The 2D polygon is **always** oriented in the `XY`-Plane.
The 2D geometry gets oriented in the 3D space when you use it as the section of a surface. The 2D geometry gets oriented in the 3D space when you use it as the section of a surface.
...@@ -52,7 +52,7 @@ The 2D geometry gets oriented in the 3D space when you use it as the section of ...@@ -52,7 +52,7 @@ The 2D geometry gets oriented in the 3D space when you use it as the section of
The imported shape just contains the coordinates of the vertices of the polygon. The imported shape just contains the coordinates of the vertices of the polygon.
You have to create a `geom2::PolygonSection` from this shape to further create geometry. You have to create a `geom2::PolygonSection` from this shape to further create geometry.
- Create a section: Create a section:
<div class="tabbed"> <div class="tabbed">
...@@ -79,7 +79,7 @@ This library uses the *builder design pattern* to build a surface. ...@@ -79,7 +79,7 @@ This library uses the *builder design pattern* to build a surface.
This builder has some convenient methods to quickly create a surface. This builder has some convenient methods to quickly create a surface.
The key concept is, that you first create the builder, perform the build steps and then you can retrieve the result from the builder to further use the surface. The key concept is, that you first create the builder, perform the build steps and then you can retrieve the result from the builder to further use the surface.
- Create a surface with two sections: Create a surface with two sections:
<div class="tabbed"> <div class="tabbed">
...@@ -113,9 +113,11 @@ surface.sections = builder.get_result() ...@@ -113,9 +113,11 @@ surface.sections = builder.get_result()
</div> </div>
@remark There is also the geom2::SectionBuilder::arrange function which can be used to insert multiple equidistant sections of the same shape. !!! remark
There is also the geom2::SectionBuilder::arrange function which can be used to insert multiple equidistant sections of the same shape.
A few things to note about the builder: A few things to note about the builder:
1. The section gets copy-constructed within the builder. So you can use the same section multiple times and even change some parameters in between without affecting the already inserted sections. 1. The section gets copy-constructed within the builder. So you can use the same section multiple times and even change some parameters in between without affecting the already inserted sections.
2. The result of the builder gets **moved**! This means, after you retrieve the result, the builder is "empty" and does not contain a valid surface anymore. 2. The result of the builder gets **moved**! This means, after you retrieve the result, the builder is "empty" and does not contain a valid surface anymore.
3. Instead of providing a geom2::PolygonSection as the shape input, you can directly use a geom2::Polygon_2. The builder converts the polygon to a section automatically in this case. 3. Instead of providing a geom2::PolygonSection as the shape input, you can directly use a geom2::Polygon_2. The builder converts the polygon to a section automatically in this case.
...@@ -123,16 +125,14 @@ A few things to note about the builder: ...@@ -123,16 +125,14 @@ A few things to note about the builder:
The resulting surface has two circular sections and looks like a cylinder. The resulting surface has two circular sections and looks like a cylinder.
The length of the cylinder is 1 as the defined by the offset of the second section. The length of the cylinder is 1 as the defined by the offset of the second section.
![Tutorial Step 3](Tutorial/step003.png){html: width=600} ![Tutorial Step 3](figures/Tutorial/step003.png){html: width=600}
### Step 4 - Modify Section ### Step 4 - Modify Section
The builder is only intended to create the basic structure of the multi-section surface with the necessary section count. The builder is only intended to create the basic structure of the multi-section surface with the necessary section count.
It does not provide all the flexibility which is needed to form any surface. It does not provide all the flexibility which is needed to form any surface.
You can access and modify each section of the surface instead. You can access and modify each section of the surface instead.
- Set the width of the second section: Set the width of the second section:
<div class="tabbed">
- <span class="tab-title">C++</span> - <span class="tab-title">C++</span>
```cpp ```cpp
...@@ -143,11 +143,9 @@ surface.sections.back().set_width(0.5); ...@@ -143,11 +143,9 @@ surface.sections.back().set_width(0.5);
surface.sections[-1].set_width(0.5) surface.sections[-1].set_width(0.5)
``` ```
</div>
The top section looks like this now: The top section looks like this now:
![Tutorial Step 4](Tutorial/step004.png){html: width=600} ![Tutorial Step 4](figures/Tutorial/step004.png){html: width=600}
The **width** refers to the dimension in the local `X` direction of the section. The **width** refers to the dimension in the local `X` direction of the section.
Whereas the **height** refers to the `Y` direction. Whereas the **height** refers to the `Y` direction.
...@@ -158,9 +156,7 @@ The **scale** methods applies an **uniform** scaling with the origin point of th ...@@ -158,9 +156,7 @@ The **scale** methods applies an **uniform** scaling with the origin point of th
You also change the location of the section within the surface afterwards, but **not the order of the sections!** You also change the location of the section within the surface afterwards, but **not the order of the sections!**
The location of the section within the local coordinate system of the section is defined by the origin point of the section. The location of the section within the local coordinate system of the section is defined by the origin point of the section.
- Change the location of a section: Change the location of a section:
<div class="tabbed">
- <span class="tab-title">C++</span> - <span class="tab-title">C++</span>
```cpp ```cpp
...@@ -171,14 +167,12 @@ surface.sections[0].origin = geom2::Point_3(-0.5,0,0); ...@@ -171,14 +167,12 @@ surface.sections[0].origin = geom2::Point_3(-0.5,0,0);
surface.sections[0].origin = geom2.Point_3(-0.5,0,0); surface.sections[0].origin = geom2.Point_3(-0.5,0,0);
``` ```
</div>
!!! note !!! note
**CGAL** does not supply a mechanism to change single components of points or vectors. You always have to assign a complete new set of coordinates. However, you can read the value of single coordinate components. **CGAL** does not supply a mechanism to change single components of points or vectors. You always have to assign a complete new set of coordinates. However, you can read the value of single coordinate components.
As you can see, the bottom section moved in negative X direction: As you can see, the bottom section moved in negative X direction:
![Tutorial Step 5](Tutorial/step005.png){html: width=600} ![Tutorial Step 5](figures/Tutorial/step005.png){html: width=600}
### Step 6 - Orient Surface ### Step 6 - Orient Surface
So far, we only operated in the local coordinate system of the multi-section surface. So far, we only operated in the local coordinate system of the multi-section surface.
...@@ -187,9 +181,10 @@ The main extrusion axis within the **local coordinate** system of the surface is ...@@ -187,9 +181,10 @@ The main extrusion axis within the **local coordinate** system of the surface is
You can specify the orientation of the *local* `Z` axis within the *global* 3D space by defining the direction of the **normal**. You can specify the orientation of the *local* `Z` axis within the *global* 3D space by defining the direction of the **normal**.
The **normal** defacto represents the orientation of the `Z` axis. The **normal** defacto represents the orientation of the `Z` axis.
@attention It is not enough to just specify the `Z` direction to fully define the orientation of geometry within the 3D space. This only defines 2 of the 3 necessary Euler angles, the third is technically undefined! See @ref euler_angles for more details. The library assumes the third angle to be 0°, which leads most of the times to the expected result. !!! attention
It is not enough to just specify the `Z` direction to fully define the orientation of geometry within the 3D space. This only defines 2 of the 3 necessary Euler angles, the third is technically undefined! See [euler_angles](index.md/#euler_angles) for more details. The library assumes the third angle to be 0°, which leads most of the times to the expected result.
- Orient the surface along global X direction: Orient the surface along global X direction:
<div class="tabbed"> <div class="tabbed">
...@@ -206,11 +201,11 @@ surface.normal = geom2.Direction_3(1,0,0); ...@@ -206,11 +201,11 @@ surface.normal = geom2.Direction_3(1,0,0);
In this example the result is this: In this example the result is this:
![Tutorial Step 6](Tutorial/step006.png){html: width=600} ![Tutorial Step 6](figures/Tutorial/step006.png){html: width=600}
The highlighted coordinate system in the figure is now the **global** coordinate space and not the local any more. The highlighted coordinate system in the figure is now the **global** coordinate space and not the local any more.
The local coordinate system of the surface remains unchanged. The local coordinate system of the surface remains unchanged.
You can also see that the orientation introduced a rotation around the local `Z` axis in this case, again see @ref euler_angles why this is. You can also see that the orientation introduced a rotation around the local `Z` axis in this case, again see [euler_angles](index.md/#euler_angles) why this is.
For the expected result you need to set the parameter `rotate_z` of the surface. For the expected result you need to set the parameter `rotate_z` of the surface.
!!! note !!! note
...@@ -221,9 +216,7 @@ As for moving the location of a section, the same principle applies when moving ...@@ -221,9 +216,7 @@ As for moving the location of a section, the same principle applies when moving
The **origin** of the surface defines the global position. The **origin** of the surface defines the global position.
The **origin** is located at the origin of the first section. The **origin** is located at the origin of the first section.
- Move surface Move surface:
<div class="tabbed">
- <span class="tab-title">C++</span> - <span class="tab-title">C++</span>
```cpp ```cpp
...@@ -234,20 +227,16 @@ surface.origin = geom2::Point_3(0,-0.25,0); ...@@ -234,20 +227,16 @@ surface.origin = geom2::Point_3(0,-0.25,0);
surface.normal = geom2.Point_3(0,-0.25,0); surface.normal = geom2.Point_3(0,-0.25,0);
``` ```
</div>
This moves the surface *0.25* in negative `Y` direction: This moves the surface *0.25* in negative `Y` direction:
![Tutorial Step 7](Tutorial/step007.png){html: width=600} ![Tutorial Step 7](figures/Tutorial/step007.png){html: width=600}
### Step 8 - Measure Surface ### Step 8 - Measure Surface
After creating the geometry, you can use different measurement tools to extract dimensions. After creating the geometry, you can use different measurement tools to extract dimensions.
The measurement tools always reference the surface in its local coordinate system. The measurement tools always reference the surface in its local coordinate system.
So the results do not depend on the global orientation of the surface. So the results do not depend on the global orientation of the surface.
- Measure the width of the surface at local `Z` position 0.5: Measure the width of the surface at local `Z` position 0.5:
<div class="tabbed">
- <span class="tab-title">C++</span> - <span class="tab-title">C++</span>
```cpp ```cpp
...@@ -259,8 +248,6 @@ double width = geom2::measure::width(surface, 0.5); ...@@ -259,8 +248,6 @@ double width = geom2::measure::width(surface, 0.5);
width = geom2.measure.width(surface, 0.5) width = geom2.measure.width(surface, 0.5)
``` ```
</div>
This should result in `width = 0.75`. This should result in `width = 0.75`.
!!! note !!! note
...@@ -269,9 +256,7 @@ This should result in `width = 0.75`. ...@@ -269,9 +256,7 @@ This should result in `width = 0.75`.
### Step 9 - Export PLY (optional) ### Step 9 - Export PLY (optional)
As an optional step, you can export your surface as a triangulated surface mesh in the **PLY** format. As an optional step, you can export your surface as a triangulated surface mesh in the **PLY** format.
- Export mesh: Export mesh:
<div class="tabbed">
- <span class="tab-title">C++</span> - <span class="tab-title">C++</span>
```cpp ```cpp
...@@ -284,8 +269,6 @@ CGAL::IO::write_PLY("./mesh.ply", mesh); ...@@ -284,8 +269,6 @@ CGAL::IO::write_PLY("./mesh.ply", mesh);
geom2.io.export_ply(surface, "./mesh.ply") geom2.io.export_ply(surface, "./mesh.ply")
``` ```
</div>
!!! note !!! note
This function is rather a debugging tool than a fully tested tool for production use! This function is rather a debugging tool than a fully tested tool for production use!
...@@ -296,7 +279,7 @@ An airfoil surface works similar to the hull surface. ...@@ -296,7 +279,7 @@ An airfoil surface works similar to the hull surface.
Instead of using polygon sections, the airfoil surface expects geom2::AirfoilSection as inputs. Instead of using polygon sections, the airfoil surface expects geom2::AirfoilSection as inputs.
Those sections follow the same principle as the polygon sections, but offer different methods which are more suitable/intuitive for airfoil shapes. Those sections follow the same principle as the polygon sections, but offer different methods which are more suitable/intuitive for airfoil shapes.
- You can load an airfoil files with the corresponding function: You can load an airfoil files with the corresponding function:
<div class="tabbed"> <div class="tabbed">
...@@ -314,7 +297,7 @@ shape = geom2.io.read_airfoil("aircraftGeometry2/test/stubs/n0012-tab.dat") ...@@ -314,7 +297,7 @@ shape = geom2.io.read_airfoil("aircraftGeometry2/test/stubs/n0012-tab.dat")
This reads the dat file **and** additionally sorts the points that the resulting polygon does not intersect itself, because airfoil coordinate files specify first the upper coordinates and then the lower coordinates which would result in a discontinuity in between the upper and lower part. This reads the dat file **and** additionally sorts the points that the resulting polygon does not intersect itself, because airfoil coordinate files specify first the upper coordinates and then the lower coordinates which would result in a discontinuity in between the upper and lower part.
- Create an initial airfoil surface: Create an initial airfoil surface:
<div class="tabbed"> <div class="tabbed">
...@@ -348,6 +331,7 @@ surface.sections = builder.get_result() ...@@ -348,6 +331,7 @@ surface.sections = builder.get_result()
This gives a planar rectangular wing shape: This gives a planar rectangular wing shape:
![Tutorial Airfoil Surface](Tutorial/airfoil_surface.png){html: width=600} ![Tutorial Airfoil Surface](figures/Tutorial/airfoil_surface.png){html: width=600}
@attention You should always use the **negative** `Z` direction as the main span direction of an airfoil surface. Only then do the angles like twist or dihedral rotate in the direction you would expect. !!! attention
You should always use the **negative** `Z` direction as the main span direction of an airfoil surface. Only then do the angles like twist or dihedral rotate in the direction you would expect.
# Tutorial {#Tutorial} # Tutorial {#Tutorial}
There are tutorial available for the following topics: There are tutorial available for the following topics:
- @subpage tutorial_geometry
- @subpage tutorial_factory - [tutorial_geometry](tutorial-geometry.md)
- @subpage tutorial_convert - [tutorial_factory](tutorial-factory.md)
\ No newline at end of file - [tutorial_convert](tutorial-convert.md)
\ No newline at end of file
# The `engine` Library in UNICADO # The `engine` Library in UNICADO
The `_engine_` library serves as the core analysis tool for engine data within UNICADO. It provides access to all possible engine data for every tool in UNICADO. The data can be fixed for an engine or at a given operating point. The data output depends on various factors such as the scale factor and power and bleed offtakes from the engine. The primary objective is to establish a **single source of truth** for engine data retrieval. The `engine` library serves as the core analysis tool for engine data within UNICADO. It provides access to all possible engine data for every tool in UNICADO. The data can be fixed for an engine or at a given operating point. The data output depends on various factors such as the scale factor and power and bleed offtakes from the engine. The primary objective is to establish a **single source of truth** for engine data retrieval.
## Role in `propulsion_design` ## Role in `propulsion_design`
Within the `propulsion_design` module: Within the `propulsion_design` module:
- Engines for the aircraft are selected, and their respective files are copied to the engine directory. - Engines for the aircraft are selected, and their respective files are copied to the engine directory.
- The **scale factor** is calculated, determining how the engine's thrust is adjusted to meet aircraft requirements (refer to the `propulsion_design` documentation). - The **scale factor** is calculated, determining how the engine's thrust is adjusted to meet aircraft requirements (refer to the `propulsion_design` documentation).
...@@ -11,6 +12,7 @@ The `engine` library applies this scale factor, ensuring that aircraft parameter ...@@ -11,6 +12,7 @@ The `engine` library applies this scale factor, ensuring that aircraft parameter
## Engine Data Formats ## Engine Data Formats
The engine data is stored in: The engine data is stored in:
- `engine.xml` — Contains data **independent** of the operating point. - `engine.xml` — Contains data **independent** of the operating point.
- CSV files — Store values **dependent** on: - CSV files — Store values **dependent** on:
......
...@@ -17,7 +17,7 @@ As mentioned in the [build instructions](../get-involved/build/general.md), we h ...@@ -17,7 +17,7 @@ As mentioned in the [build instructions](../get-involved/build/general.md), we h
!!! note !!! note
Currently, only `aircraftGeometry2` is documented. Currently, only `aircraftGeometry2` and `engine` are documented.
## aerodynamics ## aerodynamics
![Icon](site:assets/images/documentation/aerodynamics.svg){.overview-img align=left} ![Icon](site:assets/images/documentation/aerodynamics.svg){.overview-img align=left}
...@@ -98,7 +98,7 @@ The engine decks can originate from different softwaretools as long as they prov ...@@ -98,7 +98,7 @@ The engine decks can originate from different softwaretools as long as they prov
|Module Version|Language|License|Documentation|Dependencies| |Module Version|Language|License|Documentation|Dependencies|
|:---:|:---:|:---:|---|---| |:---:|:---:|:---:|---|---|
|2.1.0|:simple-cplusplus: |GPLv3|-|-| |2.1.0|:simple-cplusplus: |GPLv3|[Link](engine/index.md)|-|
--- ---
......
...@@ -354,7 +354,11 @@ nav: # Customizes the main navigation struc ...@@ -354,7 +354,11 @@ nav: # Customizes the main navigation struc
- AircraftGeometry2: - AircraftGeometry2:
- Introduction: documentation/libraries/aircraftGeometry2/index.md - Introduction: documentation/libraries/aircraftGeometry2/index.md
- Getting Started: documentation/libraries/aircraftGeometry2/getting-started.md - Getting Started: documentation/libraries/aircraftGeometry2/getting-started.md
- Tutorial: documentation/libraries/aircraftGeometry2/tutorial.md - Tutorial:
- Overview: documentation/libraries/aircraftGeometry2/tutorial.md
- Geometry: documentation/libraries/aircraftGeometry2/tutorial-geometry.md
- Factory: documentation/libraries/aircraftGeometry2/tutorial-factory.md
- Convert: documentation/libraries/aircraftGeometry2/tutorial-convert.md
- API Reference: - API Reference:
- aircraftGeometry2/classes.md - aircraftGeometry2/classes.md
- aircraftGeometry2/namespaces.md - aircraftGeometry2/namespaces.md
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment