From 3c912e6674cf410e8934b7b74c40b64a3bb3e4df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CKatrinBistreck=E2=80=9D?= <“katrin.bistreck@tuhh.de”> Date: Thu, 20 Feb 2025 16:28:03 +0100 Subject: [PATCH] correct formating --- .../aircraftGeometry2/getting-started.md | 2 +- .../libraries/aircraftGeometry2/index.md | 24 ++- .../aircraftGeometry2/tutorial-convert.md | 60 +++---- .../aircraftGeometry2/tutorial-factory.md | 155 +++++++++--------- .../aircraftGeometry2/tutorial-geometry.md | 94 +++++------ .../libraries/aircraftGeometry2/tutorial.md | 7 +- docs/documentation/libraries/engine/index.md | 6 +- docs/documentation/libraries/index.md | 4 +- mkdocs.yml | 10 +- 9 files changed, 185 insertions(+), 177 deletions(-) diff --git a/docs/documentation/libraries/aircraftGeometry2/getting-started.md b/docs/documentation/libraries/aircraftGeometry2/getting-started.md index 96b0bdc..83f617b 100644 --- a/docs/documentation/libraries/aircraftGeometry2/getting-started.md +++ b/docs/documentation/libraries/aircraftGeometry2/getting-started.md @@ -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. 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 ``` diff --git a/docs/documentation/libraries/aircraftGeometry2/index.md b/docs/documentation/libraries/aircraftGeometry2/index.md index 2d692b3..a73c0f8 100644 --- a/docs/documentation/libraries/aircraftGeometry2/index.md +++ b/docs/documentation/libraries/aircraftGeometry2/index.md @@ -13,15 +13,16 @@ 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**. -@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**! If you want to use the full flexibility of **CGAL** you need to implement your tool in C++. --- -## 2D Geometry +## 2D Geometry The base of every geometry are 2D sections. The base properties of such a shape are shown here: {html: width=30%} @@ -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). You can use any shape class which satisfies this concept to create the surfaces. This library currently implements two main types: + - [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. @@ -56,7 +58,7 @@ Note, that the library rather uses sections and not segments and therefore does The main extrusion direction of the surface is along the local `Z` axis. The origin points of each section are 3D coordinates and define the location of the section within the surface coordinate space. By moving the origin point, the complete section gets moved as well. -!!! note +!!! note The order how you insert the sections in the surface **does** matter as it defines how the sections are connected. The surfaces themselves have an origin point which defines their location in the 3D space of some parent entity. @@ -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! :-) The library currently differentiates three coordinate spaces: + 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. 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` 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`. 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. @@ -108,10 +113,11 @@ The direction is defined using the [Direction_3](@ref geom2.Direction_3) class o The definition of this normal direction is not enough to unambiguously define the three Euler angles which are needed for the coordinate transform. The normal direction can only define **two** of the three angles. As a consequence, the third Euler angle $\gamma$ has to be set manually using the `rotation_z` property of the geom2::Entity3D class. This angle applies a rotation around the local `Z` axis whenever the coordinates of the geometry are transformed to another coordinate system. -!!! note +!!! note 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: + |Normal Direction | Euler Angle $\alpha$ | Euler Angle $\beta$ | Euler Angle $\gamma$ | | --- | :---: | :---: | :---: | |`[0, 0, 1]` | 0° | 0° | 0° | @@ -128,5 +134,5 @@ Here is an overview how the library is structured: {html: width=1000} -!!! note +!!! note This is still work in progress and can change! diff --git a/docs/documentation/libraries/aircraftGeometry2/tutorial-convert.md b/docs/documentation/libraries/aircraftGeometry2/tutorial-convert.md index 7747cc7..d94d0d7 100644 --- a/docs/documentation/libraries/aircraftGeometry2/tutorial-convert.md +++ b/docs/documentation/libraries/aircraftGeometry2/tutorial-convert.md @@ -6,42 +6,43 @@ There are just means to translate the geometry to other class concepts. It is up to those concepts to provide the file access! 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 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. -!!! note +!!! note 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 -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. -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: -```python -import pyaircraftGeometry2 as geom2 -import pyaixml as aixml -``` + ```python + import pyaircraftGeometry2 as geom2 + import pyaixml as aixml + ``` ### Create 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. 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: + - Create a completely new node. - Update an existing node which has additional, non geometry related nodes as children. To create the node objects: <div class="tabbed"> - -- <span class="tab-title">C++</span> + +- <span class="tab-title">C++</span> ```cpp #include <filesystem> #include <aixml/node.h> @@ -64,16 +65,18 @@ AcXML = aixml.openDocument("path/to/your/aircraft.xml") </div> ### 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. -- Convert surface to an *aerodynamic surface node*: +Convert surface to an *aerodynamic surface node*: <div class="tabbed"> - -- <span class="tab-title">C++</span> + +- <span class="tab-title">C++</span> ```cpp #include <aircraftGeometry2/io/convert.h> @@ -81,10 +84,10 @@ You can convert an existing surface by visiting the *aixml* converter. geom2::MultisectionSurface<geom2::AirfoilSection> surface = <<some-geometry>>... /* 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 */ -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> ```python @@ -95,6 +98,7 @@ created_node = geom2.convert.aixml.to_aerodynamic_surface(new_node, ("aerodynami </div> Now what is happening here: + - 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 **id** `"0"`. @@ -109,14 +113,14 @@ Now you can save the node as an XML file or further use the node object. ### Add Another Node 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"> - -- <span class="tab-title">C++</span> + +- <span class="tab-title">C++</span> ```cpp /* 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> ```python @@ -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. 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"> - -- <span class="tab-title">C++</span> + +- <span class="tab-title">C++</span> ```cpp /* 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> ```python diff --git a/docs/documentation/libraries/aircraftGeometry2/tutorial-factory.md b/docs/documentation/libraries/aircraftGeometry2/tutorial-factory.md index 1ba48f5..96ae98f 100644 --- a/docs/documentation/libraries/aircraftGeometry2/tutorial-factory.md +++ b/docs/documentation/libraries/aircraftGeometry2/tutorial-factory.md @@ -1,5 +1,8 @@ # 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. The surface provides all the necessary tools to build your geometry. @@ -7,26 +10,27 @@ The factory classes follow the *factory design pattern*, hence the name. The idea is, that you give this "factory" a **build plan** of what you want and the factory produces or creates the **item** for you. In our case, the build plan is the *aircraft XML file* and the items are the *resulting surfaces*. -!!! note +!!! note The concept how the geometry is encoded in den aircraft XML file **differs** from the concept used in this library! The main difference is, that the library uses sections rather than segments! The factories translate the data of the aircraft XML to the surface concept of this library. 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: -- @ref hull_factory -- @ref fuselage_factory -- @ref airfoil_surface_factory -- @ref wing_factory -- @ref spar_factory -- @ref control_device_factory - -!!! note + +- [hull_factory](#hull-factory) +- [fuselage_factory](#fuselage-factory) +- [airfoil_surface_factory](#airfoil-surface-factory) +- [wing_factory](#wing-factory) +- [spar_factory](#spar-factory) +- [control_device_factory](#control-device-factory) + +!!! note The Python examples assume that you imported the following modules: -```python -import pyaircraftGeometry2 as geom2 -import pyaixml as aixml -``` + ```python + import pyaircraftGeometry2 as geom2 + import pyaixml as aixml + ``` --- @@ -34,11 +38,11 @@ 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. 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"> - -- <span class="tab-title">C++</span> + +- <span class="tab-title">C++</span> ```cpp #include <filesystem> #include <aixml/node.h> @@ -57,23 +61,24 @@ AcXML = aixml.openDocument("path/to/your/aircraft.xml") </div> -@attention 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. +!!! attention + 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:** 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. -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. --- ## 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! -At least for now... +!!! attention + The factories **always** assume a relative path to `"AcftExchangeFile/Geometry"` when specifying paths to geometry nodes! + 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. The paths to those files are denoted as *relative* paths. @@ -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> ``` -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} > **XML Example:** `aircraftGeometry2/test/stubs/aixml-v2/hull.xml` @@ -105,11 +110,11 @@ 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**. 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"> -- <span class="tab-title">C++</span> +- <span class="tab-title">C++</span> ```cpp /* Create the hull factory */ #include <aircraftGeometry2/hull_surface.h> @@ -123,7 +128,7 @@ factory = geom2.factory.HullFactory(AcXML, "./geometryData") </div> -!!! note +!!! note You can omit the path `"./geometryData"` for the *version 2.0.0* aircraft exchange files and just give an empty string. The factories then will search for the directory as explained before. After creating the factory with the existing aircraft XML data, the factory knows what to do and you can ask it to create the complete surface for you. @@ -136,11 +141,11 @@ You can use the id notation as provided by the **aixml** library. 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. -- Get **nacelle** with the id `SimpleHull` from the factory: +Get **nacelle** with the id `SimpleHull` from the factory: <div class="tabbed"> - -- <span class="tab-title">C++</span> + +- <span class="tab-title">C++</span> ```cpp /* Create the nacelle surface */ geom2::MultisectionSurface<geom2::PolygonSection> nacelle = factory.create("Nacelle@SimpleHull"); @@ -153,9 +158,8 @@ nacelle = factory.create("Nacelle@SimpleHull") </div> -@attention 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. +!!! attention + 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 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. @@ -163,8 +167,8 @@ This means you can use the same factory multiple times and create different surf If you only need the factory **once**, you can abbreviate the process as follows: <div class="tabbed"> - -- <span class="tab-title">C++</span> + +- <span class="tab-title">C++</span> ```cpp /* Create the nacelle surface */ geom2::MultisectionSurface<geom2::PolygonSection> nacelle = geom2::HullFactory{AcXML, ""}.create("Nacelle@SimpleHull"); @@ -183,11 +187,11 @@ nacelle = geom2.factory.HullFactory(AcXML, "").create("Nacelle@SimpleHull") 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. -- Create the fuselage surface: +Create the fuselage surface: <div class="tabbed"> -- <span class="tab-title">C++</span> +- <span class="tab-title">C++</span> ```cpp /* Create the factory */ #include <aircraftGeometry2/fuselage.h> @@ -211,16 +215,17 @@ fuselage = factory.create("Fuselage@SimpleFuselage") > **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: + - **Pylon** - **VerticalSurface** 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"> -- <span class="tab-title">C++</span> +- <span class="tab-title">C++</span> ```cpp /* Create the factory */ #include <aircraftGeometry2/airfoil_surface.h> @@ -240,7 +245,8 @@ pylon = factory.create("Pylon@SimplePylon") </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} > **XML Example:** `aircraftGeometry2/test/stubs/aixml-v2/wing.xml` @@ -249,11 +255,11 @@ The wing factory specializes the airfoil surface factory. Again, due to a slight different data structure in the aircraft XML file. The functionality is otherwise the same. -- Create a wing surface: +Create a wing surface: <div class="tabbed"> -- <span class="tab-title">C++</span> +- <span class="tab-title">C++</span> ```cpp /* Create the factory */ #include <aircraftGeometry2/airfoil_surface.h> @@ -273,7 +279,7 @@ wing = factory.create("LiftingSurface@MainWing") </div> -!!! note +!!! note The wing factory does **not** produces discontinuous sections! It takes the inner length of the first segment as the length for the first section and then continuous by using the outer length of the following segments from the aircraft XML file! @@ -287,11 +293,11 @@ 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 `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"> -- <span class="tab-title">C++</span> +- <span class="tab-title">C++</span> ```cpp /* Create the factory */ #include <aircraftGeometry2/airfoil_surface.h> @@ -311,7 +317,7 @@ spar = factory.create("LiftingSurface@MainWing") </div> -!!! note +!!! note This factory returns a multi-section surface which contains geom2::PolygonSection as the section type. Be aware, that the spar geometry is **not** considered an airfoil shape in the context of this library. The extrusion direction, however, is the **negative** local `Z` direction as for the airfoil surfaces, so that the spar geometry is at the same location as the wing geometry. @@ -330,11 +336,11 @@ 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. -- Create the geometry of a control device of a wing: +Create the geometry of a control device of a wing: <div class="tabbed"> -- <span class="tab-title">C++</span> +- <span class="tab-title">C++</span> ```cpp /* Create the factory */ #include <aircraftGeometry2/airfoil_surface.h> @@ -358,8 +364,9 @@ flaps = factory.create("LiftingSurface@MainWing/SurfaceParameters/HalfSurfaceDes ## 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! -At least for now... +!!! attention + The factories **always** assume a relative path to `"aircraft_exchange_file/component_design/"` when specifying paths to geometry nodes! + 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. Instead, each surface factory of this library expects a path where to find the geometry files. @@ -370,20 +377,20 @@ 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. -!!! 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 ! +!!! 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 [tutorial_aixml_v2](#tutorial_aixml_v2) ! -### Hull Factory +### Hull Factory > **XML Example:** `aircraftGeometry2/test/stubs/aixml-v3/hull.xml` 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. -- Create a hull factory: +Create a hull factory: <div class="tabbed"> -- <span class="tab-title">C++</span> +- <span class="tab-title">C++</span> ```cpp /* Create the hull factory */ #include <aircraftGeometry2/hull_surface.h> @@ -397,14 +404,14 @@ factory = geom2.factory.HullFactory(AcXML, "./geometryData") </div> -!!! note +!!! note 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"> - -- <span class="tab-title">C++</span> + +- <span class="tab-title">C++</span> ```cpp /* Create the nacelle surface */ geom2::MultisectionSurface<geom2::PolygonSection> nacelle = factory.create("propulsion/specific/geometry/nacelle@0"); @@ -417,40 +424,40 @@ nacelle = factory.create("propulsion/specific/geometry/nacelle@0") </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. 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. This makes the factory more flexible, since you are not confined to certain locations within the exchange file to extract geometry from, but you can use any node from the exchange file as long as its content structure satisfies the requirements of the surface. (Remember: The requirements are documented in the given XML example files.) -### Fuselage Factory +### Fuselage Factory > **XML Example:** `aircraftGeometry2/test/stubs/aixml-v3/fuselage.xml` 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. -- Create the fuselage surface: +Create the fuselage surface: -</div> `tbd` -### Airfoil Surface Factory +### Airfoil Surface Factory > **XML Example:** `aircraftGeometry2/test/stubs/aixml-v3/pylon.xml` `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` The wing factory creates the aerodynamic surfaces of the wings. -- Create a wing surface: +Create a wing surface: <div class="tabbed"> -- <span class="tab-title">C++</span> +- <span class="tab-title">C++</span> ```cpp /* Create the factory */ #include <aircraftGeometry2/airfoil_surface.h> @@ -470,7 +477,7 @@ wing = factory.create("wing/specific/geometry/aerodynamic_surface@0") </div> -### Spar Factory +### Spar Factory > **XML Example:** `aircraftGeometry2/test/stubs/aixml-v3/wing.xml` The aircraft XML file provides the relative positions of the front and rear spar location of the lifting surfaces. @@ -480,11 +487,11 @@ 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 `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"> -- <span class="tab-title">C++</span> +- <span class="tab-title">C++</span> ```cpp /* Create the factory */ #include <aircraftGeometry2/airfoil_surface.h> @@ -504,7 +511,7 @@ spar = factory.create("wing/specific/geometry/aerodynamic_surface@0/spars/spar@0 </div> -!!! note +!!! note This factory returns a multi-section surface which contains geom2::PolygonSection as the section type. Be aware, that the spar geometry is **not** considered an airfoil shape in the context of this library. The extrusion direction, however, is the **negative** local `Z` direction as for the airfoil surfaces, so that the spar geometry is at the same location as the wing geometry. @@ -513,7 +520,7 @@ spar = factory.create("wing/specific/geometry/aerodynamic_surface@0/spars/spar@0 The spar factory just returns the spar surface and **not** the wing surface. You have to use the wing factory separately to create the wing surface. -### Control Device Factory +### Control Device Factory > **XML Example:** `aircraftGeometry2/test/stubs/aixml-v3/wing.xml` As for the spar geometry, the control device geometry is coupled to the wing geometry it belongs to. @@ -523,11 +530,11 @@ 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. -- Create the geometry of a control device of a wing: +Create the geometry of a control device of a wing: <div class="tabbed"> -- <span class="tab-title">C++</span> +- <span class="tab-title">C++</span> ```cpp /* Create the factory */ #include <aircraftGeometry2/airfoil_surface.h> diff --git a/docs/documentation/libraries/aircraftGeometry2/tutorial-geometry.md b/docs/documentation/libraries/aircraftGeometry2/tutorial-geometry.md index 4424658..e666778 100644 --- a/docs/documentation/libraries/aircraftGeometry2/tutorial-geometry.md +++ b/docs/documentation/libraries/aircraftGeometry2/tutorial-geometry.md @@ -5,11 +5,11 @@ The resulting images of each step are not part of the library, though. Those images are rendered with a 3D animation software after the geometry is exported as a `*.ply` file after each step. The tutorial will show as a last step, how this is done. -!!! note +!!! note The Python examples assume that you imported the module with: -```python -import pyaircraftGeometry2 as geom2 -``` + ```python + import pyaircraftGeometry2 as geom2 + ``` --- @@ -22,11 +22,11 @@ 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. The file can be found here: `aircraftGeometry2/test/stubs/circle-tab.dat`. -- Load the geometry: +Load the geometry: <div class="tabbed"> - -- <span class="tab-title">C++</span> + +- <span class="tab-title">C++</span> ```cpp #include <aircraftGeometry2/io/dat.h> geom2::Polygon_2 shape = geom2::io::read_dat_file("aircraftGeometry2/test/stubs/dat-files/circle-tab.dat"); @@ -38,12 +38,12 @@ shape = geom2.io.read_dat_file("aircraftGeometry2/test/stubs/dat-files/circle-ta </div> -!!! note +!!! note Make sure the path to the file is correct according to your current working directory! This will give you the following 2D polygon: -{html: width=600} +{html: width=600} 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. @@ -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. You have to create a `geom2::PolygonSection` from this shape to further create geometry. -- Create a section: +Create a section: <div class="tabbed"> @@ -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. 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"> @@ -113,9 +113,11 @@ surface.sections = builder.get_result() </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: + 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. 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: 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. -{html: width=600} +{html: width=600} ### Step 4 - Modify Section 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. You can access and modify each section of the surface instead. -- Set the width of the second section: - -<div class="tabbed"> +Set the width of the second section: - <span class="tab-title">C++</span> ```cpp @@ -143,11 +143,9 @@ surface.sections.back().set_width(0.5); surface.sections[-1].set_width(0.5) ``` -</div> - The top section looks like this now: -{html: width=600} +{html: width=600} The **width** refers to the dimension in the local `X` direction of the section. 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 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. -- Change the location of a section: - -<div class="tabbed"> +Change the location of a section: - <span class="tab-title">C++</span> ```cpp @@ -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); ``` -</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. As you can see, the bottom section moved in negative X direction: -{html: width=600} +{html: width=600} ### Step 6 - Orient 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 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. -@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"> @@ -206,14 +201,14 @@ surface.normal = geom2.Direction_3(1,0,0); In this example the result is this: -{html: width=600} +{html: width=600} 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. -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. -!!! note +!!! note This behavior is admittedly not the most intuitive result. In further release this might get fixed. In a practical point of view, you are most often interested in properties within the local coordinate system of the surface rather then global properties in between multiple surfaces. ### Step 7 - Move Surface @@ -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** is located at the origin of the first section. -- Move surface - -<div class="tabbed"> +Move surface: - <span class="tab-title">C++</span> ```cpp @@ -234,20 +227,16 @@ surface.origin = 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: -{html: width=600} +{html: width=600} ### Step 8 - Measure Surface 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. 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: - -<div class="tabbed"> +Measure the width of the surface at local `Z` position 0.5: - <span class="tab-title">C++</span> ```cpp @@ -259,19 +248,15 @@ double width = geom2::measure::width(surface, 0.5); width = geom2.measure.width(surface, 0.5) ``` -</div> - This should result in `width = 0.75`. -!!! note +!!! note There are measurement functions which use additional properties of the geom2::MultisectionSurface as their input, because their result depends on more information than contained in the *sections* vector. See the documentation of each measurement for more information. ### Step 9 - Export PLY (optional) As an optional step, you can export your surface as a triangulated surface mesh in the **PLY** format. -- Export mesh: - -<div class="tabbed"> +Export mesh: - <span class="tab-title">C++</span> ```cpp @@ -284,9 +269,7 @@ CGAL::IO::write_PLY("./mesh.ply", mesh); 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! --- @@ -296,11 +279,11 @@ An airfoil surface works similar to the hull surface. 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. -- You can load an airfoil files with the corresponding function: +You can load an airfoil files with the corresponding function: <div class="tabbed"> - -- <span class="tab-title">C++</span> + +- <span class="tab-title">C++</span> ```cpp #include <aircraftGeometry2/io/dat.h> geom2::Polygon_2 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. -- Create an initial airfoil surface: +Create an initial airfoil surface: <div class="tabbed"> @@ -348,6 +331,7 @@ surface.sections = builder.get_result() This gives a planar rectangular wing shape: -{html: width=600} +{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. diff --git a/docs/documentation/libraries/aircraftGeometry2/tutorial.md b/docs/documentation/libraries/aircraftGeometry2/tutorial.md index cb11ba0..0d840be 100644 --- a/docs/documentation/libraries/aircraftGeometry2/tutorial.md +++ b/docs/documentation/libraries/aircraftGeometry2/tutorial.md @@ -1,5 +1,6 @@ # Tutorial {#Tutorial} There are tutorial available for the following topics: -- @subpage tutorial_geometry -- @subpage tutorial_factory -- @subpage tutorial_convert \ No newline at end of file + +- [tutorial_geometry](tutorial-geometry.md) +- [tutorial_factory](tutorial-factory.md) +- [tutorial_convert](tutorial-convert.md) \ No newline at end of file diff --git a/docs/documentation/libraries/engine/index.md b/docs/documentation/libraries/engine/index.md index c694d61..fd5c6ed 100644 --- a/docs/documentation/libraries/engine/index.md +++ b/docs/documentation/libraries/engine/index.md @@ -1,9 +1,10 @@ # 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` Within the `propulsion_design` module: + - 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). @@ -11,12 +12,13 @@ The `engine` library applies this scale factor, ensuring that aircraft parameter ## Engine Data Formats The engine data is stored in: + - `engine.xml` — Contains data **independent** of the operating point. - CSV files — Store values **dependent** on: - **Mach number** - **Altitude** - - **Engine power setting** + - **Engine power setting** > **Note:** The data in these files is **raw and unscaled**. The only modification made in `propulsion_design` is to the fuel flow CSV file, reflecting user-defined efficiency improvements. diff --git a/docs/documentation/libraries/index.md b/docs/documentation/libraries/index.md index 2713069..c1e750a 100644 --- a/docs/documentation/libraries/index.md +++ b/docs/documentation/libraries/index.md @@ -17,7 +17,7 @@ As mentioned in the [build instructions](../get-involved/build/general.md), we h !!! note - Currently, only `aircraftGeometry2` is documented. + Currently, only `aircraftGeometry2` and `engine` are documented. ## aerodynamics {.overview-img align=left} @@ -98,7 +98,7 @@ The engine decks can originate from different softwaretools as long as they prov |Module Version|Language|License|Documentation|Dependencies| |:---:|:---:|:---:|---|---| -|2.1.0|:simple-cplusplus: |GPLv3|-|-| +|2.1.0|:simple-cplusplus: |GPLv3|[Link](engine/index.md)|-| --- diff --git a/mkdocs.yml b/mkdocs.yml index ab1042e..7bb1617 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -307,7 +307,7 @@ nav: # Customizes the main navigation struc - systems_design/namespaces.md - systems_design/files.md - systems_design/functions.md - - Analysis: + - Analysis: - Modules: documentation/analysis.md # Link to analysis module page. - Mission Analysis: - Introduction: documentation/analysis/mission_analysis/index.md @@ -354,14 +354,18 @@ nav: # Customizes the main navigation struc - AircraftGeometry2: - Introduction: documentation/libraries/aircraftGeometry2/index.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: - aircraftGeometry2/classes.md - aircraftGeometry2/namespaces.md - aircraftGeometry2/files.md - aircraftGeometry2/functions.md - engine: - - Introduction: documentation/libraries/engine/index.md + - Introduction: documentation/libraries/engine/index.md - Utilities: documentation/additional_software.md - Workflow: 'workflow.md' # Link to the workflow page. - Get Involved: -- GitLab