diff --git a/.gitignore b/.gitignore index 6dfb10b..104a558 100644 --- a/.gitignore +++ b/.gitignore @@ -11,9 +11,6 @@ compile_commands.json # Generated MAVLink headers /include/mavlink -# Packaged application -/project/export - # Ignore addons files (copied from submodules), except uid created on import /project/addons/godot-xr-tools/** !/project/addons/godot-xr-tools/**/*.uid diff --git a/.godot-version b/.godot-version index 515be8f..80ef135 100644 --- a/.godot-version +++ b/.godot-version @@ -1 +1 @@ -4.4 +4.4-beta3 diff --git a/LICENSE-CC-BY.txt b/LICENSE-CC-BY.txt deleted file mode 100644 index 4ea99c2..0000000 --- a/LICENSE-CC-BY.txt +++ /dev/null @@ -1,395 +0,0 @@ -Attribution 4.0 International - -======================================================================= - -Creative Commons Corporation ("Creative Commons") is not a law firm and -does not provide legal services or legal advice. Distribution of -Creative Commons public licenses does not create a lawyer-client or -other relationship. Creative Commons makes its licenses and related -information available on an "as-is" basis. Creative Commons gives no -warranties regarding its licenses, any material licensed under their -terms and conditions, or any related information. Creative Commons -disclaims all liability for damages resulting from their use to the -fullest extent possible. - -Using Creative Commons Public Licenses - -Creative Commons public licenses provide a standard set of terms and -conditions that creators and other rights holders may use to share -original works of authorship and other material subject to copyright -and certain other rights specified in the public license below. The -following considerations are for informational purposes only, are not -exhaustive, and do not form part of our licenses. - - Considerations for licensors: Our public licenses are - intended for use by those authorized to give the public - permission to use material in ways otherwise restricted by - copyright and certain other rights. Our licenses are - irrevocable. Licensors should read and understand the terms - and conditions of the license they choose before applying it. - Licensors should also secure all rights necessary before - applying our licenses so that the public can reuse the - material as expected. Licensors should clearly mark any - material not subject to the license. This includes other CC- - licensed material, or material used under an exception or - limitation to copyright. More considerations for licensors: - wiki.creativecommons.org/Considerations_for_licensors - - Considerations for the public: By using one of our public - licenses, a licensor grants the public permission to use the - licensed material under specified terms and conditions. If - the licensor's permission is not necessary for any reason--for - example, because of any applicable exception or limitation to - copyright--then that use is not regulated by the license. Our - licenses grant only permissions under copyright and certain - other rights that a licensor has authority to grant. Use of - the licensed material may still be restricted for other - reasons, including because others have copyright or other - rights in the material. A licensor may make special requests, - such as asking that all changes be marked or described. - Although not required by our licenses, you are encouraged to - respect those requests where reasonable. More considerations - for the public: - wiki.creativecommons.org/Considerations_for_licensees - -======================================================================= - -Creative Commons Attribution 4.0 International Public License - -By exercising the Licensed Rights (defined below), You accept and agree -to be bound by the terms and conditions of this Creative Commons -Attribution 4.0 International Public License ("Public License"). To the -extent this Public License may be interpreted as a contract, You are -granted the Licensed Rights in consideration of Your acceptance of -these terms and conditions, and the Licensor grants You such rights in -consideration of benefits the Licensor receives from making the -Licensed Material available under these terms and conditions. - - -Section 1 -- Definitions. - - a. Adapted Material means material subject to Copyright and Similar - Rights that is derived from or based upon the Licensed Material - and in which the Licensed Material is translated, altered, - arranged, transformed, or otherwise modified in a manner requiring - permission under the Copyright and Similar Rights held by the - Licensor. For purposes of this Public License, where the Licensed - Material is a musical work, performance, or sound recording, - Adapted Material is always produced where the Licensed Material is - synched in timed relation with a moving image. - - b. Adapter's License means the license You apply to Your Copyright - and Similar Rights in Your contributions to Adapted Material in - accordance with the terms and conditions of this Public License. - - c. Copyright and Similar Rights means copyright and/or similar rights - closely related to copyright including, without limitation, - performance, broadcast, sound recording, and Sui Generis Database - Rights, without regard to how the rights are labeled or - categorized. For purposes of this Public License, the rights - specified in Section 2(b)(1)-(2) are not Copyright and Similar - Rights. - - d. Effective Technological Measures means those measures that, in the - absence of proper authority, may not be circumvented under laws - fulfilling obligations under Article 11 of the WIPO Copyright - Treaty adopted on December 20, 1996, and/or similar international - agreements. - - e. Exceptions and Limitations means fair use, fair dealing, and/or - any other exception or limitation to Copyright and Similar Rights - that applies to Your use of the Licensed Material. - - f. Licensed Material means the artistic or literary work, database, - or other material to which the Licensor applied this Public - License. - - g. Licensed Rights means the rights granted to You subject to the - terms and conditions of this Public License, which are limited to - all Copyright and Similar Rights that apply to Your use of the - Licensed Material and that the Licensor has authority to license. - - h. Licensor means the individual(s) or entity(ies) granting rights - under this Public License. - - i. Share means to provide material to the public by any means or - process that requires permission under the Licensed Rights, such - as reproduction, public display, public performance, distribution, - dissemination, communication, or importation, and to make material - available to the public including in ways that members of the - public may access the material from a place and at a time - individually chosen by them. - - j. Sui Generis Database Rights means rights other than copyright - resulting from Directive 96/9/EC of the European Parliament and of - the Council of 11 March 1996 on the legal protection of databases, - as amended and/or succeeded, as well as other essentially - equivalent rights anywhere in the world. - - k. You means the individual or entity exercising the Licensed Rights - under this Public License. Your has a corresponding meaning. - - -Section 2 -- Scope. - - a. License grant. - - 1. Subject to the terms and conditions of this Public License, - the Licensor hereby grants You a worldwide, royalty-free, - non-sublicensable, non-exclusive, irrevocable license to - exercise the Licensed Rights in the Licensed Material to: - - a. reproduce and Share the Licensed Material, in whole or - in part; and - - b. produce, reproduce, and Share Adapted Material. - - 2. Exceptions and Limitations. For the avoidance of doubt, where - Exceptions and Limitations apply to Your use, this Public - License does not apply, and You do not need to comply with - its terms and conditions. - - 3. Term. The term of this Public License is specified in Section - 6(a). - - 4. Media and formats; technical modifications allowed. The - Licensor authorizes You to exercise the Licensed Rights in - all media and formats whether now known or hereafter created, - and to make technical modifications necessary to do so. The - Licensor waives and/or agrees not to assert any right or - authority to forbid You from making technical modifications - necessary to exercise the Licensed Rights, including - technical modifications necessary to circumvent Effective - Technological Measures. For purposes of this Public License, - simply making modifications authorized by this Section 2(a) - (4) never produces Adapted Material. - - 5. Downstream recipients. - - a. Offer from the Licensor -- Licensed Material. Every - recipient of the Licensed Material automatically - receives an offer from the Licensor to exercise the - Licensed Rights under the terms and conditions of this - Public License. - - b. No downstream restrictions. You may not offer or impose - any additional or different terms or conditions on, or - apply any Effective Technological Measures to, the - Licensed Material if doing so restricts exercise of the - Licensed Rights by any recipient of the Licensed - Material. - - 6. No endorsement. Nothing in this Public License constitutes or - may be construed as permission to assert or imply that You - are, or that Your use of the Licensed Material is, connected - with, or sponsored, endorsed, or granted official status by, - the Licensor or others designated to receive attribution as - provided in Section 3(a)(1)(A)(i). - - b. Other rights. - - 1. Moral rights, such as the right of integrity, are not - licensed under this Public License, nor are publicity, - privacy, and/or other similar personality rights; however, to - the extent possible, the Licensor waives and/or agrees not to - assert any such rights held by the Licensor to the limited - extent necessary to allow You to exercise the Licensed - Rights, but not otherwise. - - 2. Patent and trademark rights are not licensed under this - Public License. - - 3. To the extent possible, the Licensor waives any right to - collect royalties from You for the exercise of the Licensed - Rights, whether directly or through a collecting society - under any voluntary or waivable statutory or compulsory - licensing scheme. In all other cases the Licensor expressly - reserves any right to collect such royalties. - - -Section 3 -- License Conditions. - -Your exercise of the Licensed Rights is expressly made subject to the -following conditions. - - a. Attribution. - - 1. If You Share the Licensed Material (including in modified - form), You must: - - a. retain the following if it is supplied by the Licensor - with the Licensed Material: - - i. identification of the creator(s) of the Licensed - Material and any others designated to receive - attribution, in any reasonable manner requested by - the Licensor (including by pseudonym if - designated); - - ii. a copyright notice; - - iii. a notice that refers to this Public License; - - iv. a notice that refers to the disclaimer of - warranties; - - v. a URI or hyperlink to the Licensed Material to the - extent reasonably practicable; - - b. indicate if You modified the Licensed Material and - retain an indication of any previous modifications; and - - c. indicate the Licensed Material is licensed under this - Public License, and include the text of, or the URI or - hyperlink to, this Public License. - - 2. You may satisfy the conditions in Section 3(a)(1) in any - reasonable manner based on the medium, means, and context in - which You Share the Licensed Material. For example, it may be - reasonable to satisfy the conditions by providing a URI or - hyperlink to a resource that includes the required - information. - - 3. If requested by the Licensor, You must remove any of the - information required by Section 3(a)(1)(A) to the extent - reasonably practicable. - - 4. If You Share Adapted Material You produce, the Adapter's - License You apply must not prevent recipients of the Adapted - Material from complying with this Public License. - - -Section 4 -- Sui Generis Database Rights. - -Where the Licensed Rights include Sui Generis Database Rights that -apply to Your use of the Licensed Material: - - a. for the avoidance of doubt, Section 2(a)(1) grants You the right - to extract, reuse, reproduce, and Share all or a substantial - portion of the contents of the database; - - b. if You include all or a substantial portion of the database - contents in a database in which You have Sui Generis Database - Rights, then the database in which You have Sui Generis Database - Rights (but not its individual contents) is Adapted Material; and - - c. You must comply with the conditions in Section 3(a) if You Share - all or a substantial portion of the contents of the database. - -For the avoidance of doubt, this Section 4 supplements and does not -replace Your obligations under this Public License where the Licensed -Rights include other Copyright and Similar Rights. - - -Section 5 -- Disclaimer of Warranties and Limitation of Liability. - - a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE - EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS - AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF - ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, - IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, - WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR - PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, - ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT - KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT - ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. - - b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE - TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, - NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, - INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, - COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR - USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN - ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR - DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR - IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. - - c. The disclaimer of warranties and limitation of liability provided - above shall be interpreted in a manner that, to the extent - possible, most closely approximates an absolute disclaimer and - waiver of all liability. - - -Section 6 -- Term and Termination. - - a. This Public License applies for the term of the Copyright and - Similar Rights licensed here. However, if You fail to comply with - this Public License, then Your rights under this Public License - terminate automatically. - - b. Where Your right to use the Licensed Material has terminated under - Section 6(a), it reinstates: - - 1. automatically as of the date the violation is cured, provided - it is cured within 30 days of Your discovery of the - violation; or - - 2. upon express reinstatement by the Licensor. - - For the avoidance of doubt, this Section 6(b) does not affect any - right the Licensor may have to seek remedies for Your violations - of this Public License. - - c. For the avoidance of doubt, the Licensor may also offer the - Licensed Material under separate terms or conditions or stop - distributing the Licensed Material at any time; however, doing so - will not terminate this Public License. - - d. Sections 1, 5, 6, 7, and 8 survive termination of this Public - License. - - -Section 7 -- Other Terms and Conditions. - - a. The Licensor shall not be bound by any additional or different - terms or conditions communicated by You unless expressly agreed. - - b. Any arrangements, understandings, or agreements regarding the - Licensed Material not stated herein are separate from and - independent of the terms and conditions of this Public License. - - -Section 8 -- Interpretation. - - a. For the avoidance of doubt, this Public License does not, and - shall not be interpreted to, reduce, limit, restrict, or impose - conditions on any use of the Licensed Material that could lawfully - be made without permission under this Public License. - - b. To the extent possible, if any provision of this Public License is - deemed unenforceable, it shall be automatically reformed to the - minimum extent necessary to make it enforceable. If the provision - cannot be reformed, it shall be severed from this Public License - without affecting the enforceability of the remaining terms and - conditions. - - c. No term or condition of this Public License will be waived and no - failure to comply consented to unless expressly agreed to by the - Licensor. - - d. Nothing in this Public License constitutes or may be interpreted - as a limitation upon, or waiver of, any privileges and immunities - that apply to the Licensor or You, including from the legal - processes of any jurisdiction or authority. - - -======================================================================= - -Creative Commons is not a party to its public -licenses. Notwithstanding, Creative Commons may elect to apply one of -its public licenses to material it publishes and in those instances -will be considered the “Licensor.” The text of the Creative Commons -public licenses is dedicated to the public domain under the CC0 Public -Domain Dedication. Except for the limited purpose of indicating that -material is shared under a Creative Commons public license or as -otherwise permitted by the Creative Commons policies published at -creativecommons.org/policies, Creative Commons does not authorize the -use of the trademark "Creative Commons" or any other trademark or logo -of Creative Commons without its prior written consent including, -without limitation, in connection with any unauthorized modifications -to any of its public licenses or any other arrangements, -understandings, or agreements concerning use of licensed material. For -the avoidance of doubt, this paragraph does not form part of the -public licenses. - -Creative Commons may be contacted at creativecommons.org. diff --git a/LICENSE-MIT.txt b/LICENSE-MIT.txt deleted file mode 100644 index 61ddf28..0000000 --- a/LICENSE-MIT.txt +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2025 Marek S. Lukasiewicz, Margaux Touzard - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/README.md b/README.md index 23d4d29..66075cf 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,70 @@ # Visualisation for MARSH -This is a visualisation module for [Modular Architecture for Reconfigurable Simulation of Helicopters](https://marsh-sim.github.io/). -For documentation, see [MARSH Documentation - Visualisation](https://marsh-sim.github.io/nodes/visualisation/) +Named in this order so not everything starts with the same word -## License +## Development -Source code available under the terms of [The MIT License](https://opensource.org/license/mit). -Other assets available under [Creative Commons Attribution 4.0 (CC-BY)](https://creativecommons.org/licenses/by/4.0/). +This repository uses [Git Submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules), to get all the code you need to run either: + +```sh +git clone --recurse-submodules
+# Or at any later point +git submodule update --init --recursive +``` + +Using Godot v4.4 beta3 (expect it to change often until 4.4 is released) +Install SCons with `pipx install scons`. +You will need a C++ compiler, you might have one already on Linux, see below for Windows, otherwise in [Godot documentation](https://docs.godotengine.org/en/stable/contributing/development/compiling/index.html). + +For updating MAVLink generator, you additionally `pip install future`. +It is recommended to install any packages in a [virtual environment](https://docs.python.org/3/library/venv.html), for example: + +```sh +python3 -m venv venv +source venv/bin/activate +pip install future +``` + +Some files are generated, run the following commands on first setup and when dependencies change: + +```sh +godot --dump-extension-api # after updating Godot +python update_mavlink.py # after updating MAVLink dialect +python update_addons.py # after changing any addon submodules +scons compile_commands # after modifying SConstruct +cd project/addons/gdcef; python build.py +``` + +### Windows setup + +The most convenient way of getting a C++ compiler is via the LLVM-MinGW project (by the way, it optimizes the binary more). +Download the `llvm-mingw-...-msvcrt-x86_64.zip` from the [Releases page](https://github.com/mstorsjo/llvm-mingw/releases). +Unzip the archive to some location you like, and add its `bin` folder to `Path` using the "Edit environment variables for your account" program. + +### Build + +To build the GDExtension binary run SCons in the repository root, the default arguments have been added to the file. + +```sh +scons +``` + +When building for Windows with MinGW-LLVM, you need to [select this compiler](https://docs.godotengine.org/en/stable/contributing/development/compiling/compiling_for_windows.html#selecting-a-compiler): + +```powershell +scons platform=windows use_mingw=yes use_llvm=yes +``` + +## Roadmap + +- When having a short tracker interruption, maintain it in the same position until it times out to minimize the viewport jumps +- Try to have some acceptable setup for Varjo even without the tracker +- Rework the fly area + - Make it bigger + - Keep it square to avoid assymetric geometry + - Don't use the flat plane, just flatten the terrain + - Make the terrain mostly green, but add some small patches of different color +- Fix z-figthing when looking at the runway from afar +- Reduce pixel artifacts + - Adjust antialiasing + - Ensure there are mipmaps and they're used diff --git a/mise.toml b/mise.toml deleted file mode 100644 index 8f8d3d7..0000000 --- a/mise.toml +++ /dev/null @@ -1,3 +0,0 @@ -[tools] -clangd = "latest" -"pipx:scons" = "latest" diff --git a/modules/mavlink b/modules/mavlink index 7d3a041..153d474 160000 --- a/modules/mavlink +++ b/modules/mavlink @@ -1 +1 @@ -Subproject commit 7d3a04174105c00eb712b6a6ab16452a372e4a93 +Subproject commit 153d474873a461f1554c2c34aaa864f818509eef diff --git a/project/ads33-terrain/Cones_scene_terrain.tscn b/project/ads33-terrain/Cones_scene_terrain.tscn index d55a8ce..50d8a52 100644 --- a/project/ads33-terrain/Cones_scene_terrain.tscn +++ b/project/ads33-terrain/Cones_scene_terrain.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=205 format=3 uid="uid://bchcr54i3piaw"] +[gd_scene load_steps=204 format=3 uid="uid://bchcr54i3piaw"] [ext_resource type="Texture2D" uid="uid://41mr2bbcbjpo" path="res://ads33-terrain/concrete_moss_diff_4k.jpg" id="1_ong3a"] [ext_resource type="PackedScene" uid="uid://7tddcx4u26w4" path="res://assets/cone/cone.tscn" id="2_hj5f7"] @@ -79,7 +79,7 @@ size = Vector3(2.5, 0.244, 0.012) [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ohwyq"] shading_mode = 0 -albedo_color = Color(0.537255, 0.756863, 0.278431, 1) +albedo_color = Color(0.537255, 0.529412, 0.278431, 1) [sub_resource type="BoxMesh" id="BoxMesh_rnkd2"] size = Vector3(6, 0.3, 6) @@ -91,15 +91,12 @@ uv1_scale = Vector3(3, 3, 3) [sub_resource type="CylinderMesh" id="CylinderMesh_ri5lb"] top_radius = 0.3 bottom_radius = 0.3 -height = 24.5 +height = 15.04 [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ugwq3"] albedo_texture = ExtResource("4_poywc") uv1_scale = Vector3(3, 36, 3) -[sub_resource type="BoxMesh" id="BoxMesh_tgb06"] -size = Vector3(6, 4.572, 6) - [sub_resource type="CylinderMesh" id="CylinderMesh_j01qt"] height = 0.001 @@ -708,7 +705,7 @@ shader_params/u_globalmap_blend_start = 0.0 shader_params/u_globalmap_blend_distance = 0.0 shader_params/u_colormap_opacity_per_texture = Vector4(1, 1, 1, 1) shader_params/u_specular = 0.5 -metadata/_custom_type_script = "uid://bov8uure5wkmf" +metadata/_custom_type_script = ExtResource("6_1xj3b") metadata/MaterialOverride = false [node name="Flat_herbe" type="MeshInstance3D" parent="."] @@ -720,7 +717,7 @@ surface_material_override/0 = SubResource("StandardMaterial3D_omy3l") transform = Transform3D(0.305, 0, 0, 0, 0.305, 0, 0, 0, 0.305, 0, 0, 15) [node name="TargetHeightFeet" type="Node3D" parent="Table"] -transform = Transform3D(3.281, 0, 0, 0, 3.281, 0, 0, 0, 3.281, 0, 40, 0) +transform = Transform3D(3.281, 0, 0, 0, 3.281, 0, 0, 0, 3.281, 0, 25, 0) [node name="boule" type="MeshInstance3D" parent="Table/TargetHeightFeet"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.678, -1) @@ -758,47 +755,8 @@ mesh = SubResource("BoxMesh_u22o6") skeleton = NodePath("") surface_material_override/0 = SubResource("StandardMaterial3D_ohwyq") -[node name="TargetHeightFeetLow" type="Node3D" parent="Table"] -transform = Transform3D(3.281, 0, 0, 0, 3.281, 0, 0, 0, 3.281, 0, 15, 0) - -[node name="boule" type="MeshInstance3D" parent="Table/TargetHeightFeetLow"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.678, -1) -material_override = SubResource("StandardMaterial3D_io3gc") -mesh = SubResource("SphereMesh_x847j") -skeleton = NodePath("") -surface_material_override/0 = SubResource("StandardMaterial3D_sdjw4") - -[node name="pied" type="MeshInstance3D" parent="Table/TargetHeightFeetLow/boule"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.851962, 0) -mesh = SubResource("CylinderMesh_x847j") -skeleton = NodePath("") -surface_material_override/0 = SubResource("StandardMaterial3D_6b770") - -[node name="panneau1" type="MeshInstance3D" parent="Table/TargetHeightFeetLow"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.678, 2) -mesh = SubResource("BoxMesh_aqqlo") -skeleton = NodePath("") -surface_material_override/0 = SubResource("StandardMaterial3D_araq8") - -[node name="Support" type="MeshInstance3D" parent="Table/TargetHeightFeetLow/panneau1"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.15, -1.25077, 0) -mesh = SubResource("BoxMesh_oo0l3") -skeleton = NodePath("") -surface_material_override/0 = SubResource("StandardMaterial3D_yo10o") - -[node name="Support2" type="MeshInstance3D" parent="Table/TargetHeightFeetLow/panneau1"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.15, -1.25141, 0) -mesh = SubResource("BoxMesh_oo0l3") -skeleton = NodePath("") -surface_material_override/0 = SubResource("StandardMaterial3D_7icp3") - -[node name="centrage" type="MeshInstance3D" parent="Table/TargetHeightFeetLow/panneau1"] -mesh = SubResource("BoxMesh_u22o6") -skeleton = NodePath("") -surface_material_override/0 = SubResource("StandardMaterial3D_ohwyq") - [node name="Top" type="MeshInstance3D" parent="Table"] -transform = Transform3D(3.281, 0, 0, 0, 3.281, 0, 0, 0, 3.281, 0, 40, 0) +transform = Transform3D(3.281, 0, 0, 0, 3.281, 0, 0, 0, 3.281, 0, 24.5079, 0) mesh = SubResource("BoxMesh_rnkd2") surface_material_override/0 = SubResource("StandardMaterial3D_jm3fw") @@ -822,12 +780,6 @@ transform = Transform3D(3.281, 0, 0, 0, 3.281, 0, 0, 0, 3.281, -7.05415, -0.0012 mesh = SubResource("CylinderMesh_ri5lb") surface_material_override/0 = SubResource("StandardMaterial3D_ugwq3") -[node name="Top2" type="MeshInstance3D" parent="Table"] -transform = Transform3D(3.28, 0, 0, 0, 3.28, 0, 0, 0, 3.28, 0, 7.60068, 0) -mesh = SubResource("BoxMesh_tgb06") -skeleton = NodePath("../Top") -surface_material_override/0 = SubResource("StandardMaterial3D_jm3fw") - [node name="Cercle" type="Node3D" parent="."] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 100, 0, 100) @@ -1264,11 +1216,9 @@ surface_material_override/0 = SubResource("StandardMaterial3D_073i7") [node name="Cone80cm" parent="Sidestep/Marques_0ft" instance=ExtResource("2_hj5f7")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -2.438) -visible = false [node name="Cone80cm3" parent="Sidestep/Marques_0ft" instance=ExtResource("2_hj5f7")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 2.438) -visible = false [node name="Carre_ext_400ft" type="Node3D" parent="Sidestep"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 121.92, 0, 0) diff --git a/project/aircraft/aircraft.gd b/project/aircraft/aircraft.gd index 5e01092..fec7cca 100644 --- a/project/aircraft/aircraft.gd +++ b/project/aircraft/aircraft.gd @@ -1,18 +1,15 @@ extends Node3D signal use_fallback(active: bool) -signal fog_density_changed(new_density: float) ## Rotation of cyclic stick model for full control deflection, in degrees @export var range_cyclic: float = 30 ## Main rotor speed, in revolutions per minute @export var rotor_rpm: float = 500 @export var track_platform: bool = false -@export var fog_values: Array[float] = [0.0, -1.0, -2.0, -3.0, -4.0] ## Current angle of rotor rotation var _rotor_azimuth: float = 0 -var fog_index: int = 0 @onready var connector: MarshConnector = $MarshConnector @onready var skeleton: Skeleton3D = $"Mi-2/Armature/Skeleton3D" @@ -22,75 +19,44 @@ var fog_index: int = 0 @onready var xr_origin: XROrigin3D = $AttitudeRoot/PilotEyes/PilotFloor/XROrigin3D @onready var tracker: XRController3D = $AttitudeRoot/PilotEyes/PilotFloor/XROrigin3D/ViveTracker @onready var xr_camera: XRCamera3D = $AttitudeRoot/PilotEyes/PilotFloor/XROrigin3D/XRCamera3D -@onready var recent_tracking: Timer = $AttitudeRoot/PilotEyes/PilotFloor/XROrigin3D/RecentTracking @onready var bone_cg: int = skeleton.find_bone("BodyCG") @onready var bone_cyclic: int = skeleton.find_bone("Cyclic") @onready var bone_rotor: int = skeleton.find_bone("Rotor") -@onready var instruments: Node = $AttitudeRoot/Instruments - func _process(delta: float) -> void: - var target: Transform3D = connector.get_aircraft() + var target := connector.get_aircraft() position = target.origin # Add the rotation to the correct bone for rotation around CG - var rest: Quaternion = skeleton.get_bone_rest(bone_cg).basis.get_rotation_quaternion() - var attitude: Quaternion = target.basis.get_rotation_quaternion() + var rest := skeleton.get_bone_rest(bone_cg).basis.get_rotation_quaternion() + var attitude := target.basis.get_rotation_quaternion() skeleton.set_bone_pose_rotation(bone_cg, attitude * rest) # Rotate other children (not using BoneAttachment3D due to jitter) attitude_root.rotation = target.basis.get_euler() # Rotate the cyclic stick bone - var cyclic: Vector2 = connector.get_cyclic() - var cyc_rest: Quaternion= skeleton.get_bone_rest(bone_cyclic).basis.get_rotation_quaternion() - var cyc_angles_rad: Vector2 = cyclic * deg_to_rad(range_cyclic) + var cyclic := connector.get_cyclic() + var cyc_rest := skeleton.get_bone_rest(bone_cyclic).basis.get_rotation_quaternion() + var cyc_angles_rad := cyclic * deg_to_rad(range_cyclic) var cyc_att := Quaternion.from_euler(Vector3(cyc_angles_rad.y, cyc_angles_rad.x, 0)) skeleton.set_bone_pose_rotation(bone_cyclic, cyc_att * cyc_rest) - - # Update the instruments - instruments.call("set_controls", connector.get_controls()) - instruments.call("set_trim", connector.get_trim()) - instruments.call("update_pfd", connector.get_aircraft(), connector.get_velocity()) # Spin the rotor only when receiving flight data if connector.get_model_connected(): _rotor_azimuth += rotor_rpm * 2 * PI / 60 * delta - var rotor_rest: Quaternion = skeleton.get_bone_rest(bone_rotor).basis.get_rotation_quaternion() + var rotor_rest := skeleton.get_bone_rest(bone_rotor).basis.get_rotation_quaternion() var rotor_att := Quaternion.from_euler(Vector3(0, _rotor_azimuth, 0)) # Note that this is reverse order, to rotate in local bone axes skeleton.set_bone_pose_rotation(bone_rotor, rotor_rest * rotor_att) - # Move the XR origin in such way that the tracker is in reference position if tracker.get_has_tracking_data(): - var tracker_mount: Node3D = tracker_mount_platform if track_platform else tracker_mount_chair + var tracker_mount = tracker_mount_platform if track_platform else tracker_mount_chair xr_origin.transform = tracker_mount.transform * tracker.transform.affine_inverse() - recent_tracking.start() - -func _input(event): - if event.is_action_pressed("fog_cycle"): - var step = 1 - if event is InputEventWithModifiers and event.shift_pressed: - step = -1 - # The index is updated in the signal callback to handle parameter changes - connector.fog_density = fog_values[(fog_index + step) % len(fog_values)] - -# Only reset the position when tracking is lost for some time -func _on_recent_tracking_timeout() -> void: - xr_origin.transform = Transform3D.IDENTITY + else: + xr_origin.transform = Transform3D.IDENTITY func _on_vr_setup_failed() -> void: xr_camera.current = false use_fallback.emit(true) - -func _on_marsh_connector_fog_density_changed(new_density: float) -> void: - # Forward to parent - fog_density_changed.emit(new_density) - - # Round down to nearest defined value or assign the last one (so it will disable on next cycle) - # Example: -1.5 should select -2 and on next cycle it will be -3 - var new_index = fog_values.find_custom(func (d): return d <= new_density) - if new_index == -1: - new_index = len(fog_values) - 1 - fog_index = new_index diff --git a/project/aircraft/aircraft.tscn b/project/aircraft/aircraft.tscn index edd497e..0a9a2fc 100644 --- a/project/aircraft/aircraft.tscn +++ b/project/aircraft/aircraft.tscn @@ -3,7 +3,7 @@ [ext_resource type="Script" uid="uid://cx30pr7kn4c74" path="res://aircraft/aircraft.gd" id="1_l4uib"] [ext_resource type="PackedScene" uid="uid://cux4tju0ovvly" path="res://assets/mi2/Mi-2.glb" id="1_mrxe8"] [ext_resource type="PackedScene" uid="uid://fmygcraoturj" path="res://reference_axes.tscn" id="3_2bi7g"] -[ext_resource type="PackedScene" uid="uid://cis4s43ubuynp" path="res://instruments/instruments.tscn" id="3_5w717"] +[ext_resource type="PackedScene" uid="uid://cis4s43ubuynp" path="res://instruments.tscn" id="3_5w717"] [ext_resource type="Script" uid="uid://bt32fse84itrp" path="res://aircraft/fallback_input.gd" id="3_gf6ud"] [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_mrxe8"] @@ -55,14 +55,8 @@ tracker = &"/user/vive_tracker_htcx/role/camera" transform = Transform3D(0.25, 0, 0, 0, 0.25, 0, 0, 0, 0.25, 0, 0, 0) visible = false -[node name="RecentTracking" type="Timer" parent="AttitudeRoot/PilotEyes/PilotFloor/XROrigin3D"] -wait_time = 5.0 -one_shot = true -ignore_time_scale = true - [node name="FallbackCamera" type="Camera3D" parent="AttitudeRoot/PilotEyes"] transform = Transform3D(1, 0, 0, 0, 0.980955, 0.194234, 0, -0.194234, 0.980955, 0, 0, 0) -fov = 60.0 [node name="Instruments" parent="AttitudeRoot" instance=ExtResource("3_5w717")] transform = Transform3D(-0.5, -1.27582e-08, 7.43353e-08, 4.33325e-10, 0.4923, 0.0874084, -7.5421e-08, 0.0874084, -0.4923, 0.00724897, -1.1581, 2.40391) @@ -70,7 +64,5 @@ transform = Transform3D(-0.5, -1.27582e-08, 7.43353e-08, 4.33325e-10, 0.4923, 0. [node name="MarshConnector" type="MarshConnector" parent="."] [connection signal="use_fallback" from="." to="AttitudeRoot/PilotEyes" method="_on_aircraft_use_fallback"] -[connection signal="timeout" from="AttitudeRoot/PilotEyes/PilotFloor/XROrigin3D/RecentTracking" to="." method="_on_recent_tracking_timeout"] -[connection signal="fog_density_changed" from="MarshConnector" to="." method="_on_marsh_connector_fog_density_changed"] [editable path="Mi-2"] diff --git a/project/aircraft/fallback_input.gd b/project/aircraft/fallback_input.gd index ecbaade..a48e11d 100644 --- a/project/aircraft/fallback_input.gd +++ b/project/aircraft/fallback_input.gd @@ -8,12 +8,8 @@ const CAMERA_MOUSE_ROTATION_SPEED := 0.001 const CAMERA_X_ROT_MIN := deg_to_rad(-85) const CAMERA_X_ROT_MAX := deg_to_rad(70) -@export var use_mouse: bool = true -@export var pov_move_speed = 0.05 - var active: bool = false var initial_rotation: Vector3 -var initial_pov_position: Vector3 @onready var camera_base = $"." @onready var camera = $FallbackCamera @@ -22,7 +18,6 @@ func _ready() -> void: set_process(false) set_process_input(false) initial_rotation = camera.rotation - initial_pov_position = position func _on_aircraft_use_fallback(active_in: bool) -> void: if active_in: @@ -51,18 +46,10 @@ func _input(event): (float(get_viewport().size.y) / get_viewport().get_visible_rect().size.y) ) - if use_mouse and event is InputEventMouseMotion: + if event is InputEventMouseMotion: var camera_speed_this_frame = CAMERA_MOUSE_ROTATION_SPEED rotate_camera(event.relative * camera_speed_this_frame * scale_factor) - - if event.is_action_pressed("pov_reset"): - position = initial_pov_position -func _process(delta: float): - var horizontal = Input.get_vector("pov_left", "pov_right", "pov_forward", "pov_back") - var vertical = Input.get_axis("pov_down", "pov_up") - # Currently PilotEyes has Yaw 180, so horizontal axes need to be inverted - position += delta * pov_move_speed * Vector3(-horizontal.x, vertical, -horizontal.y) func rotate_camera(move): camera_base.rotate_y(-move.x) diff --git a/project/fog_controller.gd b/project/fog_controller.gd deleted file mode 100644 index 248abf7..0000000 --- a/project/fog_controller.gd +++ /dev/null @@ -1,8 +0,0 @@ -extends WorldEnvironment - -func _on_fog_density_changed(new_density: float) -> void: - if new_density == 0.0 or not is_finite(new_density): - environment.fog_enabled = false - else: - environment.fog_enabled = true - environment.fog_density = 10 ** new_density diff --git a/project/fog_controller.gd.uid b/project/fog_controller.gd.uid deleted file mode 100644 index 285eeb8..0000000 --- a/project/fog_controller.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://6g3b2ohwbkyv diff --git a/project/instruments.gd b/project/instruments.gd index de11eba..28a25e6 100644 --- a/project/instruments.gd +++ b/project/instruments.gd @@ -1,12 +1,33 @@ extends Node -@onready var controls: Node = $SubViewport2/Controls -@onready var pfd: Node = $SubViewport/PFD +const PFD_PATH: String = "pfd#adi,vsi,alt,ias,rht,rpm,hsi" +const CONTROLS_PATH: String = "controls#collective,cyclic,rudder" -# Propagate the calls to child -func set_controls(current: Vector4): - controls.set("controls", current) -func set_trim(trim: Vector4): - controls.set("trim", trim) -func update_pfd(aircraft: Transform3D, velocity: Vector3): - pfd.call("update", aircraft, velocity) +@export var lidia_hostname: String = "localhost" +@export var lidia_port: int = 5555 + +func _ready(): + if !$CEF.initialize({"incognito":true, "locale":"en-US"}): + push_error($CEF.get_error()) + get_tree().quit() + return + print("CEF version: " + $CEF.get_full_version()) + + # Wait one frame for the texture rect to get its size + await get_tree().process_frame + + var browser_pfd = $CEF.create_browser( + "http://{}:{}/{}".format([lidia_hostname, lidia_port, PFD_PATH], "{}"), + $SubViewport/TextureRect, + { "frame_rate": 90, "javascript": true }, + ) + browser_pfd.name = "pfd" + browser_pfd.enable_ad_block(false) # Required for lidia static assets + + var browser_ctrl = $CEF.create_browser( + "http://{}:{}/{}".format([lidia_hostname, lidia_port, CONTROLS_PATH], "{}"), + $SubViewport2/TextureRect, + { "frame_rate": 90, "javascript": true }, + ) + browser_ctrl.name = "controls" + browser_ctrl.enable_ad_block(false) # Required for lidia static assets diff --git a/project/instruments/instruments.tscn b/project/instruments.tscn similarity index 71% rename from project/instruments/instruments.tscn rename to project/instruments.tscn index dcd9dc1..584584a 100644 --- a/project/instruments/instruments.tscn +++ b/project/instruments.tscn @@ -1,8 +1,6 @@ -[gd_scene load_steps=9 format=3 uid="uid://cis4s43ubuynp"] +[gd_scene load_steps=7 format=3 uid="uid://cis4s43ubuynp"] -[ext_resource type="Script" uid="uid://01bmfj4wthwg" path="res://instruments.gd" id="1_wlkep"] -[ext_resource type="PackedScene" uid="uid://bgkpwebqksth5" path="res://instruments/controls.tscn" id="2_372d7"] -[ext_resource type="PackedScene" uid="uid://b26tu6wb2h3ce" path="res://instruments/pfd.tscn" id="2_uhiu3"] +[ext_resource type="Script" uid="uid://01bmfj4wthwg" path="res://instruments.gd" id="1_h5at3"] [sub_resource type="QuadMesh" id="QuadMesh_nowl7"] @@ -21,12 +19,14 @@ resource_local_to_scene = true albedo_texture = SubResource("ViewportTexture_h5at3") [node name="Instruments" type="Node3D"] -script = ExtResource("1_wlkep") +script = ExtResource("1_h5at3") [node name="SubViewport" type="SubViewport" parent="."] -size = Vector2i(1024, 1024) -[node name="PFD" parent="SubViewport" instance=ExtResource("2_uhiu3")] +[node name="TextureRect" type="TextureRect" parent="SubViewport"] +offset_right = 512.0 +offset_bottom = 512.0 +expand_mode = 5 [node name="Quad" type="MeshInstance3D" parent="."] transform = Transform3D(0.8, 0, 0, 0, 0.8, 0, 0, 0, 0.8, -0.35, 0, 0) @@ -35,7 +35,10 @@ surface_material_override/0 = SubResource("StandardMaterial3D_h5at3") [node name="SubViewport2" type="SubViewport" parent="."] -[node name="Controls" parent="SubViewport2" instance=ExtResource("2_372d7")] +[node name="TextureRect" type="TextureRect" parent="SubViewport2"] +offset_right = 512.0 +offset_bottom = 512.0 +expand_mode = 5 [node name="Quad2" type="MeshInstance3D" parent="."] transform = Transform3D(0.6, 0, 0, 0, 0.6, 0, 0, 0, 0.6, 0.425, 0, 0) diff --git a/project/instruments/RobotoMono-LICENSE.txt b/project/instruments/RobotoMono-LICENSE.txt deleted file mode 100644 index f08da9b..0000000 --- a/project/instruments/RobotoMono-LICENSE.txt +++ /dev/null @@ -1,41 +0,0 @@ -Roboto Mono - -Copyright 2015 Google - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -===================================================================== - -Socket.IO - -MIT License - -Copyright (c) 2014-2022 Guillermo Rauch - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/project/instruments/RobotoMono-Regular.ttf b/project/instruments/RobotoMono-Regular.ttf deleted file mode 100644 index d9371a1..0000000 Binary files a/project/instruments/RobotoMono-Regular.ttf and /dev/null differ diff --git a/project/instruments/RobotoMono-Regular.ttf.import b/project/instruments/RobotoMono-Regular.ttf.import deleted file mode 100644 index 5f58fa5..0000000 --- a/project/instruments/RobotoMono-Regular.ttf.import +++ /dev/null @@ -1,35 +0,0 @@ -[remap] - -importer="font_data_dynamic" -type="FontFile" -uid="uid://chqgmpsthpbgt" -path="res://.godot/imported/RobotoMono-Regular.ttf-48a8b9dfd581c05f54f90e11c9fc9d5f.fontdata" - -[deps] - -source_file="res://instruments/RobotoMono-Regular.ttf" -dest_files=["res://.godot/imported/RobotoMono-Regular.ttf-48a8b9dfd581c05f54f90e11c9fc9d5f.fontdata"] - -[params] - -Rendering=null -antialiasing=1 -generate_mipmaps=false -disable_embedded_bitmaps=true -multichannel_signed_distance_field=false -msdf_pixel_range=8 -msdf_size=48 -allow_system_fallback=true -force_autohinter=false -hinting=1 -subpixel_positioning=4 -keep_rounding_remainders=true -oversampling=0.0 -Fallbacks=null -fallbacks=[] -Compress=null -compress=true -preload=[] -language_support={} -script_support={} -opentype_features={} diff --git a/project/instruments/controls-background.png b/project/instruments/controls-background.png deleted file mode 100644 index 01648dd..0000000 --- a/project/instruments/controls-background.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:94045c4fc08b5d93d3a2436de2c8399341246ec157f8ac3dbf0a89806a9e0e91 -size 2842 diff --git a/project/instruments/controls-background.png.import b/project/instruments/controls-background.png.import deleted file mode 100644 index b6fb2d4..0000000 --- a/project/instruments/controls-background.png.import +++ /dev/null @@ -1,34 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://b0oeokas7mq4q" -path="res://.godot/imported/controls-background.png-626db610a70b7b467da1123d55529d5c.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://instruments/controls-background.png" -dest_files=["res://.godot/imported/controls-background.png-626db610a70b7b467da1123d55529d5c.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 diff --git a/project/instruments/controls-ref.png b/project/instruments/controls-ref.png deleted file mode 100644 index f4f3726..0000000 --- a/project/instruments/controls-ref.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4eef65cc3a825494e9d405ea68c480de3da6fe2e62f202e5d387771331d2904f -size 15488 diff --git a/project/instruments/controls-ref.png.import b/project/instruments/controls-ref.png.import deleted file mode 100644 index f623b6a..0000000 --- a/project/instruments/controls-ref.png.import +++ /dev/null @@ -1,34 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c5bcvbphgg1nk" -path="res://.godot/imported/controls-ref.png-ed1b9d803223424fa895ad19151b7e9f.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://instruments/controls-ref.png" -dest_files=["res://.godot/imported/controls-ref.png-ed1b9d803223424fa895ad19151b7e9f.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 diff --git a/project/instruments/controls.gd b/project/instruments/controls.gd deleted file mode 100644 index 5211b83..0000000 --- a/project/instruments/controls.gd +++ /dev/null @@ -1,30 +0,0 @@ -@tool -class_name Controls -extends Node2D -## Recreate the controls page from lidia Python package - -const AXIS_SIZE: float = 326 - -@export var controls: Vector4: - set(value): - controls = value - current_cyclic.position.x = AXIS_SIZE / 2.0 * controls.x - current_cyclic.position.y = AXIS_SIZE / 2.0 * controls.y - current_pedals.position.x = AXIS_SIZE / 2.0 * controls.z - current_collective.position.y = -AXIS_SIZE * controls.w - -@export var trim: Vector4: - set(value): - trim = value - trim_lateral.position.x = AXIS_SIZE / 2.0 * trim.x - trim_longitudinal.position.y = AXIS_SIZE / 2.0 * trim.y - trim_pedals.position.x = AXIS_SIZE / 2.0 * trim.z - trim_collective.position.y = -AXIS_SIZE * trim.w - -@onready var trim_longitudinal: Node2D = $CyclicOrigin/TrimLongitudinal -@onready var trim_lateral: Node2D = $CyclicOrigin/TrimLateral -@onready var current_cyclic: Node2D = $CyclicOrigin/CurrentCyclic -@onready var trim_collective: Node2D = $CollectiveOrigin/TrimCollective -@onready var current_collective: Node2D = $CollectiveOrigin/CurrentCollective -@onready var trim_pedals: Node2D = $PedalsOrigin/TrimPedals -@onready var current_pedals: Node2D = $PedalsOrigin/CurrentPedals diff --git a/project/instruments/controls.gd.uid b/project/instruments/controls.gd.uid deleted file mode 100644 index 0a62356..0000000 --- a/project/instruments/controls.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://ds6f8cur05ka0 diff --git a/project/instruments/controls.tscn b/project/instruments/controls.tscn deleted file mode 100644 index be77aeb..0000000 --- a/project/instruments/controls.tscn +++ /dev/null @@ -1,54 +0,0 @@ -[gd_scene load_steps=7 format=3 uid="uid://bgkpwebqksth5"] - -[ext_resource type="Script" uid="uid://ds6f8cur05ka0" path="res://instruments/controls.gd" id="1_g7kvs"] -[ext_resource type="Texture2D" uid="uid://b0oeokas7mq4q" path="res://instruments/controls-background.png" id="2_wbvwt"] -[ext_resource type="Texture2D" uid="uid://c561m3pvc0kop" path="res://instruments/trim-long.png" id="3_37ekc"] -[ext_resource type="Texture2D" uid="uid://wdqnlguxmi2a" path="res://instruments/current-dot.png" id="4_4updv"] -[ext_resource type="Texture2D" uid="uid://dytpn8rcdimr" path="res://instruments/trim-short.png" id="5_ni3tk"] -[ext_resource type="Texture2D" uid="uid://dkda6ju5daocf" path="res://instruments/current-arrow.png" id="6_mfntf"] - -[node name="Controls" type="Node2D"] -script = ExtResource("1_g7kvs") - -[node name="Background" type="Sprite2D" parent="."] -position = Vector2(256, 256) -texture = ExtResource("2_wbvwt") - -[node name="CyclicOrigin" type="Node2D" parent="."] -position = Vector2(309, 189) - -[node name="TrimLongitudinal" type="Sprite2D" parent="CyclicOrigin"] -position = Vector2(10, 0) -texture = ExtResource("3_37ekc") - -[node name="TrimLateral" type="Sprite2D" parent="CyclicOrigin"] -position = Vector2(0, 10) -rotation = 1.5708 -texture = ExtResource("3_37ekc") - -[node name="CurrentCyclic" type="Sprite2D" parent="CyclicOrigin"] -texture = ExtResource("4_4updv") - -[node name="CollectiveOrigin" type="Node2D" parent="."] -position = Vector2(72.5, 352) - -[node name="TrimCollective" type="Sprite2D" parent="CollectiveOrigin"] -position = Vector2(-10.5, 0) -texture = ExtResource("5_ni3tk") - -[node name="CurrentCollective" type="Sprite2D" parent="CollectiveOrigin"] -position = Vector2(20.5, 0) -texture = ExtResource("6_mfntf") - -[node name="PedalsOrigin" type="Node2D" parent="."] -position = Vector2(309, 425.5) - -[node name="TrimPedals" type="Sprite2D" parent="PedalsOrigin"] -position = Vector2(0, 10.5) -rotation = -1.5708 -texture = ExtResource("5_ni3tk") - -[node name="CurrentPedals" type="Sprite2D" parent="PedalsOrigin"] -position = Vector2(0, -21.5) -rotation = -1.5708 -texture = ExtResource("6_mfntf") diff --git a/project/instruments/current-arrow.png b/project/instruments/current-arrow.png deleted file mode 100644 index e4aa8e4..0000000 --- a/project/instruments/current-arrow.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e9f32544518014aa8fbb852c82b5a9a32e78cc96724a095e261f3bb870602e4a -size 1228 diff --git a/project/instruments/current-arrow.png.import b/project/instruments/current-arrow.png.import deleted file mode 100644 index 430c1a0..0000000 --- a/project/instruments/current-arrow.png.import +++ /dev/null @@ -1,34 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dkda6ju5daocf" -path="res://.godot/imported/current-arrow.png-8e092288abc9ec8d31cbc8f708a9c800.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://instruments/current-arrow.png" -dest_files=["res://.godot/imported/current-arrow.png-8e092288abc9ec8d31cbc8f708a9c800.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 diff --git a/project/instruments/current-dot.png b/project/instruments/current-dot.png deleted file mode 100644 index c7eea25..0000000 --- a/project/instruments/current-dot.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ac4ea7768fdae5a5f8e6f2ab7d48d332a6ab09f78d520c4fe0404c414aaf1b69 -size 1047 diff --git a/project/instruments/current-dot.png.import b/project/instruments/current-dot.png.import deleted file mode 100644 index ce845b9..0000000 --- a/project/instruments/current-dot.png.import +++ /dev/null @@ -1,34 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://wdqnlguxmi2a" -path="res://.godot/imported/current-dot.png-789da8759af9526ce5f8705121a1077d.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://instruments/current-dot.png" -dest_files=["res://.godot/imported/current-dot.png-789da8759af9526ce5f8705121a1077d.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 diff --git a/project/instruments/heading-ticks.png b/project/instruments/heading-ticks.png deleted file mode 100644 index ab34048..0000000 --- a/project/instruments/heading-ticks.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fb45a774c6a9381a172996207b5b2b3c23e902990b22f8e4888d282dadc3ac0c -size 21042 diff --git a/project/instruments/heading-ticks.png.import b/project/instruments/heading-ticks.png.import deleted file mode 100644 index 19e6c58..0000000 --- a/project/instruments/heading-ticks.png.import +++ /dev/null @@ -1,34 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c36kaqyfalb2v" -path="res://.godot/imported/heading-ticks.png-8d0b08e5e3af463192c04d5a2068a1e0.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://instruments/heading-ticks.png" -dest_files=["res://.godot/imported/heading-ticks.png-8d0b08e5e3af463192c04d5a2068a1e0.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 diff --git a/project/instruments/horizon-mask.png b/project/instruments/horizon-mask.png deleted file mode 100644 index 24cd07a..0000000 --- a/project/instruments/horizon-mask.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0b5aa4314b575de2f8a680150f96f3f6510984356293977c28201e637e4e7229 -size 5964 diff --git a/project/instruments/horizon-mask.png.import b/project/instruments/horizon-mask.png.import deleted file mode 100644 index d6e70d0..0000000 --- a/project/instruments/horizon-mask.png.import +++ /dev/null @@ -1,34 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c5nbrnus8pcyd" -path="res://.godot/imported/horizon-mask.png-03d2bafdd84b9816ae1fe68fc4baf43d.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://instruments/horizon-mask.png" -dest_files=["res://.godot/imported/horizon-mask.png-03d2bafdd84b9816ae1fe68fc4baf43d.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 diff --git a/project/instruments/horizon-overlay.png b/project/instruments/horizon-overlay.png deleted file mode 100644 index 100f1e8..0000000 --- a/project/instruments/horizon-overlay.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:496d869e45085d3547edeab73e93711320bd7f2dc7f314f28db47750348f6dce -size 4334 diff --git a/project/instruments/horizon-overlay.png.import b/project/instruments/horizon-overlay.png.import deleted file mode 100644 index cae3ce4..0000000 --- a/project/instruments/horizon-overlay.png.import +++ /dev/null @@ -1,34 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://b703lu8yhaoav" -path="res://.godot/imported/horizon-overlay.png-7e128e1a0dd8183251d6119879899864.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://instruments/horizon-overlay.png" -dest_files=["res://.godot/imported/horizon-overlay.png-7e128e1a0dd8183251d6119879899864.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 diff --git a/project/instruments/horizon.png b/project/instruments/horizon.png deleted file mode 100644 index 19ecd6f..0000000 --- a/project/instruments/horizon.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:20b2cd5de91fbc589e3a0c33b67b8837b535a2c41a0f256940c779bfb4339f98 -size 16585 diff --git a/project/instruments/horizon.png.import b/project/instruments/horizon.png.import deleted file mode 100644 index 9196986..0000000 --- a/project/instruments/horizon.png.import +++ /dev/null @@ -1,34 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bxdfrv8bovdai" -path="res://.godot/imported/horizon.png-9384af1095d9251c4f8861113a545ccf.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://instruments/horizon.png" -dest_files=["res://.godot/imported/horizon.png-9384af1095d9251c4f8861113a545ccf.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 diff --git a/project/instruments/pfd-background.png b/project/instruments/pfd-background.png deleted file mode 100644 index d160558..0000000 --- a/project/instruments/pfd-background.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:24e12f54cb40f58eb2e51247e6f90bc9daf9d46017ac7f531364d099b435889d -size 60304 diff --git a/project/instruments/pfd-background.png.import b/project/instruments/pfd-background.png.import deleted file mode 100644 index 4efb713..0000000 --- a/project/instruments/pfd-background.png.import +++ /dev/null @@ -1,34 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://colp4xsovikmv" -path="res://.godot/imported/pfd-background.png-99626101f4d3a30d7dd189ac71adf1c0.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://instruments/pfd-background.png" -dest_files=["res://.godot/imported/pfd-background.png-99626101f4d3a30d7dd189ac71adf1c0.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 diff --git a/project/instruments/pfd-ref.png b/project/instruments/pfd-ref.png deleted file mode 100644 index b765e28..0000000 --- a/project/instruments/pfd-ref.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:44f6cebabe3ae23e9993b7485ee2fb3904a3312dd1ba388d6e76306e856ceccc -size 133172 diff --git a/project/instruments/pfd-ref.png.import b/project/instruments/pfd-ref.png.import deleted file mode 100644 index 3f31bfa..0000000 --- a/project/instruments/pfd-ref.png.import +++ /dev/null @@ -1,34 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://toojp8r3424r" -path="res://.godot/imported/pfd-ref.png-18e0fc5274406321f68279cb4defcf25.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://instruments/pfd-ref.png" -dest_files=["res://.godot/imported/pfd-ref.png-18e0fc5274406321f68279cb4defcf25.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 diff --git a/project/instruments/pfd.gd b/project/instruments/pfd.gd deleted file mode 100644 index 43790a0..0000000 --- a/project/instruments/pfd.gd +++ /dev/null @@ -1,58 +0,0 @@ -@tool -class_name PFD -extends Node2D - -@export var euler_attitude_deg: Vector3: - set(value): - euler_attitude_deg = value - horizon_pivot.rotation = deg_to_rad(-value.x) - const px_per_deg: float = 6.56 - horizon_background.position.y = px_per_deg * clamp(value.y, -30, 30) - heading_ticks.rotation = deg_to_rad(-value.z) - heading_label.text = "%03d" % (int(round(value.z) + 360) % 360) - -@export var airspeed: float: - set(value): - airspeed = value - airspeed_label.text = str(int(round(value))) - -@export var groundspeed: float: - set(value): - groundspeed = value - groundspeed_label.text = str(int(round(value))) - -@export var altitude: float: - set(value): - altitude = value - var step = 1 - altitude_label.text = str(int(step * round(value / step))) - -@export var climbrate: float = 1000: - set(value): - climbrate = value - climbrate_arrow.scale.y = clamp(value / 1000.0, -1, 1) - -@onready var horizon_pivot: Node2D = $HorizonMask/HorizonOrigin/Pivot -@onready var horizon_background: Node2D = $HorizonMask/HorizonOrigin/Pivot/Background -@onready var heading_ticks: Node2D = $HeadingOrigin/Ticks -@onready var climbrate_arrow: Node2D = $ClimbrateOrigin/Polygon2D -@onready var airspeed_label: Label = $Airspeed -@onready var groundspeed_label: Label = $Groundspeed -@onready var altitude_label: Label = $Altitude -@onready var heading_label: Label = $Heading - -func update(aircraft: Transform3D, velocity: Vector3): - var godot_euler = aircraft.basis.get_euler() - euler_attitude_deg = Vector3(godot_euler.z, -godot_euler.x, -godot_euler.y) * rad_to_deg(1) - - const mps_to_kt = 1.94384 - var v_local = aircraft.basis.inverse() * velocity - airspeed = max(0, v_local.z) * mps_to_kt - var v_horizontal = Vector3(velocity.x, 0, velocity.z) - groundspeed = v_horizontal.length() * mps_to_kt - - const mps_to_fpm = 196.848 - climbrate = velocity.y * mps_to_fpm - - const m_to_ft = 3.2808 - altitude = aircraft.origin.y * m_to_ft diff --git a/project/instruments/pfd.gd.uid b/project/instruments/pfd.gd.uid deleted file mode 100644 index fbc3cd3..0000000 --- a/project/instruments/pfd.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://368tfiyen071 diff --git a/project/instruments/pfd.tscn b/project/instruments/pfd.tscn deleted file mode 100644 index 306ed2a..0000000 --- a/project/instruments/pfd.tscn +++ /dev/null @@ -1,103 +0,0 @@ -[gd_scene load_steps=9 format=3 uid="uid://b26tu6wb2h3ce"] - -[ext_resource type="Texture2D" uid="uid://colp4xsovikmv" path="res://instruments/pfd-background.png" id="1_inkqg"] -[ext_resource type="Script" uid="uid://368tfiyen071" path="res://instruments/pfd.gd" id="1_t02it"] -[ext_resource type="Texture2D" uid="uid://c5nbrnus8pcyd" path="res://instruments/horizon-mask.png" id="2_t02it"] -[ext_resource type="Texture2D" uid="uid://bxdfrv8bovdai" path="res://instruments/horizon.png" id="3_kwqn1"] -[ext_resource type="Texture2D" uid="uid://b703lu8yhaoav" path="res://instruments/horizon-overlay.png" id="4_1vq1p"] -[ext_resource type="Texture2D" uid="uid://c36kaqyfalb2v" path="res://instruments/heading-ticks.png" id="5_3w2cf"] -[ext_resource type="FontFile" uid="uid://chqgmpsthpbgt" path="res://instruments/RobotoMono-Regular.ttf" id="6_wtx4e"] -[ext_resource type="Texture2D" uid="uid://toojp8r3424r" path="res://instruments/pfd-ref.png" id="7_86xjv"] - -[node name="PFD" type="Node2D"] -script = ExtResource("1_t02it") - -[node name="Background" type="Sprite2D" parent="."] -position = Vector2(512, 512) -texture = ExtResource("1_inkqg") - -[node name="HorizonMask" type="Sprite2D" parent="."] -clip_children = 1 -position = Vector2(512, 512) -texture = ExtResource("2_t02it") - -[node name="HorizonOrigin" type="Node2D" parent="HorizonMask"] -position = Vector2(-82, -244) - -[node name="Pivot" type="Node2D" parent="HorizonMask/HorizonOrigin"] - -[node name="Background" type="Sprite2D" parent="HorizonMask/HorizonOrigin/Pivot"] -texture = ExtResource("3_kwqn1") - -[node name="RollArrowContour" type="Polygon2D" parent="HorizonMask/HorizonOrigin/Pivot"] -position = Vector2(-430, -267) -color = Color(0, 0, 0, 1) -polygon = PackedVector2Array(430, 70, 416, 92, 444, 92) - -[node name="RollArrowFill" type="Polygon2D" parent="HorizonMask/HorizonOrigin/Pivot"] -position = Vector2(-430, -267) -polygon = PackedVector2Array(430, 74, 420, 90, 440, 90) - -[node name="Overlay" type="Sprite2D" parent="HorizonMask/HorizonOrigin"] -texture = ExtResource("4_1vq1p") - -[node name="HeadingOrigin" type="Node2D" parent="."] -position = Vector2(430, 794) - -[node name="Ticks" type="Sprite2D" parent="HeadingOrigin"] -texture = ExtResource("5_3w2cf") - -[node name="ClimbrateOrigin" type="Node2D" parent="."] -position = Vector2(711, 268) - -[node name="Polygon2D" type="Polygon2D" parent="ClimbrateOrigin"] -polygon = PackedVector2Array(12, 0, -12, 0, -12, -121, 0, -133, 12, -121) - -[node name="Airspeed" type="Label" parent="."] -offset_left = 35.0 -offset_top = 233.0 -offset_right = 154.0 -offset_bottom = 298.0 -theme_override_fonts/font = ExtResource("6_wtx4e") -theme_override_font_sizes/font_size = 48 -text = "0" -horizontal_alignment = 2 -vertical_alignment = 1 - -[node name="Groundspeed" type="Label" parent="."] -offset_left = 59.0 -offset_top = 477.0 -offset_right = 178.0 -offset_bottom = 542.0 -theme_override_fonts/font = ExtResource("6_wtx4e") -theme_override_font_sizes/font_size = 33 -text = "0" -horizontal_alignment = 2 -vertical_alignment = 1 - -[node name="Altitude" type="Label" parent="."] -offset_left = 859.0 -offset_top = 233.0 -offset_right = 978.0 -offset_bottom = 298.0 -theme_override_fonts/font = ExtResource("6_wtx4e") -theme_override_font_sizes/font_size = 48 -text = "0" -horizontal_alignment = 2 -vertical_alignment = 1 - -[node name="Heading" type="Label" parent="."] -offset_left = 370.0 -offset_top = 498.0 -offset_right = 489.0 -offset_bottom = 563.0 -theme_override_fonts/font = ExtResource("6_wtx4e") -theme_override_font_sizes/font_size = 33 -text = "000" -horizontal_alignment = 1 -vertical_alignment = 1 - -[node name="Reference" type="Sprite2D" parent="."] -visible = false -position = Vector2(512, 512) -texture = ExtResource("7_86xjv") diff --git a/project/instruments/trim-long.png b/project/instruments/trim-long.png deleted file mode 100644 index 0a52de6..0000000 --- a/project/instruments/trim-long.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6f57cf6e93c3c68e48afdc3ee078c28c9f3292d4303a7fcc0ec51e1651d33e3a -size 2108 diff --git a/project/instruments/trim-long.png.import b/project/instruments/trim-long.png.import deleted file mode 100644 index fbfafb1..0000000 --- a/project/instruments/trim-long.png.import +++ /dev/null @@ -1,34 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://c561m3pvc0kop" -path="res://.godot/imported/trim-long.png-0b9b67642209f6a2ae4b2165f3b33d5d.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://instruments/trim-long.png" -dest_files=["res://.godot/imported/trim-long.png-0b9b67642209f6a2ae4b2165f3b33d5d.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 diff --git a/project/instruments/trim-short.png b/project/instruments/trim-short.png deleted file mode 100644 index f54ccfb..0000000 --- a/project/instruments/trim-short.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fa70ce3b0fa0c5716ba0e771877eb8499cdd33d8b0c7478bea1c91b79b32e6b1 -size 1265 diff --git a/project/instruments/trim-short.png.import b/project/instruments/trim-short.png.import deleted file mode 100644 index 9777f63..0000000 --- a/project/instruments/trim-short.png.import +++ /dev/null @@ -1,34 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dytpn8rcdimr" -path="res://.godot/imported/trim-short.png-707c75166ad2d77e18c02dc4882968b1.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://instruments/trim-short.png" -dest_files=["res://.godot/imported/trim-short.png-707c75166ad2d77e18c02dc4882968b1.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 diff --git a/project/main.tscn b/project/main.tscn index 364a3b0..1f92149 100644 --- a/project/main.tscn +++ b/project/main.tscn @@ -1,8 +1,7 @@ -[gd_scene load_steps=8 format=3 uid="uid://crq3o0eu4y8ya"] +[gd_scene load_steps=7 format=3 uid="uid://crq3o0eu4y8ya"] [ext_resource type="Script" uid="uid://dfcjdxesyn3l0" path="res://start_vr.gd" id="1_ig7tw"] [ext_resource type="PackedScene" uid="uid://bj1s0g7ixjw71" path="res://aircraft/aircraft.tscn" id="2_0xm2m"] -[ext_resource type="Script" uid="uid://6g3b2ohwbkyv" path="res://fog_controller.gd" id="3_1bvp3"] [ext_resource type="PackedScene" uid="uid://bchcr54i3piaw" path="res://ads33-terrain/Cones_scene_terrain.tscn" id="3_h2yge"] [sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_7dm0k"] @@ -13,10 +12,6 @@ sky_material = SubResource("ProceduralSkyMaterial_7dm0k") [sub_resource type="Environment" id="Environment_0xm2m"] background_mode = 2 sky = SubResource("Sky_ig7tw") -fog_enabled = true -fog_sun_scatter = 0.5 -fog_density = 0.0 -fog_depth_end = 80.0 [node name="Main" type="Node3D"] @@ -26,7 +21,6 @@ fog_depth_end = 80.0 [node name="WorldEnvironment" type="WorldEnvironment" parent="."] environment = SubResource("Environment_0xm2m") -script = ExtResource("3_1bvp3") [node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] transform = Transform3D(0.866025, 0.433013, 0.25, 0, -0.5, 0.866025, 0.5, -0.75, -0.433013, -5, 5, -5) @@ -35,5 +29,4 @@ shadow_enabled = true [node name="StartVR" type="Node3D" parent="."] script = ExtResource("1_ig7tw") -[connection signal="fog_density_changed" from="Aircraft" to="WorldEnvironment" method="_on_fog_density_changed"] [connection signal="setup_failed" from="StartVR" to="Aircraft" method="_on_vr_setup_failed"] diff --git a/project/project.godot b/project/project.godot index 5f7adb8..949b555 100644 --- a/project/project.godot +++ b/project/project.godot @@ -17,72 +17,22 @@ config/icon="res://icon.svg" [display] -window/size/viewport_width=1600 -window/size/viewport_height=900 window/stretch/mode="viewport" [editor_plugins] enabled=PackedStringArray() -[input] - -pov_up={ -"deadzone": 0.2, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":69,"key_label":0,"unicode":101,"location":0,"echo":false,"script":null) -] -} -pov_down={ -"deadzone": 0.2, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":67,"key_label":0,"unicode":99,"location":0,"echo":false,"script":null) -] -} -pov_forward={ -"deadzone": 0.2, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null) -] -} -pov_back={ -"deadzone": 0.2, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"location":0,"echo":false,"script":null) -] -} -pov_right={ -"deadzone": 0.2, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null) -] -} -pov_left={ -"deadzone": 0.2, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null) -] -} -pov_reset={ -"deadzone": 0.2, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":81,"key_label":0,"unicode":113,"location":0,"echo":false,"script":null) -] -} -fog_cycle={ -"deadzone": 0.2, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":70,"key_label":0,"unicode":102,"location":0,"echo":false,"script":null) -] -} - [physics] common/enable_object_picking=false [rendering] -textures/canvas_textures/default_texture_filter=2 renderer/rendering_method="gl_compatibility" renderer/rendering_method.mobile="gl_compatibility" -lights_and_shadows/directional_shadow/size=8192 -lights_and_shadows/directional_shadow/soft_shadow_filter_quality=3 -lights_and_shadows/positional_shadow/soft_shadow_filter_quality=3 anti_aliasing/quality/msaa_2d=1 anti_aliasing/quality/msaa_3d=1 -lights_and_shadows/positional_shadow/atlas_size=8192 [xr] diff --git a/src/marshconnector.cpp b/src/marshconnector.cpp index 00edf56..cdd5aca 100644 --- a/src/marshconnector.cpp +++ b/src/marshconnector.cpp @@ -18,29 +18,19 @@ #include "mavlink/all/mavlink.h" // IWYU pragma: keep; always include the mavlink.h file for selected dialect #include "mavlink/common/mavlink_msg_command_long.h" #include "mavlink/common/mavlink_msg_manual_control.h" -#include "mavlink/common/mavlink_msg_manual_setpoint.h" -#include "mavlink/common/mavlink_msg_param_request_list.h" -#include "mavlink/common/mavlink_msg_param_set.h" -#include "mavlink/common/mavlink_msg_param_value.h" #include "mavlink/common/mavlink_msg_sim_state.h" #include "mavlink/mavlink_helpers.h" #include "mavlink/mavlink_types.h" -#include -#include -#include using namespace godot; void MarshConnector::_bind_methods() { // Data access ClassDB::bind_method(D_METHOD("get_aircraft"), &MarshConnector::get_aircraft); - ClassDB::bind_method(D_METHOD("get_velocity"), &MarshConnector::get_velocity); ClassDB::bind_method(D_METHOD("get_cyclic"), &MarshConnector::get_cyclic); ClassDB::bind_method(D_METHOD("get_collective"), &MarshConnector::get_collective); ClassDB::bind_method(D_METHOD("get_pedals"), &MarshConnector::get_pedals); - ClassDB::bind_method(D_METHOD("get_controls"), &MarshConnector::get_controls); - ClassDB::bind_method(D_METHOD("get_trim"), &MarshConnector::get_trim); ClassDB::bind_method(D_METHOD("get_model_connected"), &MarshConnector::get_model_connected); ClassDB::bind_method(D_METHOD("get_manager_connected"), @@ -53,15 +43,6 @@ void MarshConnector::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::STRING, "hostname"), "set_hostname", "get_hostname"); - ClassDB::bind_method(D_METHOD("get_fog_density"), - &MarshConnector::get_fog_density); - ClassDB::bind_method(D_METHOD("set_fog_density", "p_fog_density"), - &MarshConnector::set_fog_density); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_density"), "set_fog_density", - "get_fog_density"); - ADD_SIGNAL(MethodInfo("fog_density_changed", - PropertyInfo(Variant::FLOAT, "new_density"))); - // Timer callbacks ClassDB::bind_method(D_METHOD("send_heartbeat"), &MarshConnector::send_heartbeat); @@ -75,10 +56,6 @@ MarshConnector::MarshConnector() { // Initialize member variables time_passed = 0.0; - system_id = 1; - component_id = - MAV_COMP_ID_USER1 + (MARSH_TYPE_VISUALISATION - MARSH_TYPE_MANAGER); - heartbeat_timer = memnew(Timer); add_child(heartbeat_timer); heartbeat_timer->set_wait_time(1.0); @@ -144,15 +121,15 @@ Error MarshConnector::send_heartbeat() { // print_line("Sending HEARTBEAT at ", time_passed, " seconds"); mavlink_heartbeat_t heartbeat; - heartbeat.type = MARSH_TYPE_VISUALISATION; + heartbeat.type = MAV_TYPE_HELICOPTER; heartbeat.autopilot = MAV_AUTOPILOT_INVALID; heartbeat.base_mode = 0; // none of the flags applicable heartbeat.custom_mode = 0; // not used so far heartbeat.system_status = MAV_STATE_ACTIVE; mavlink_message_t message; - mavlink_msg_heartbeat_encode_chan(system_id, component_id, MAVLINK_COMM_0, - &message, &heartbeat); + mavlink_msg_heartbeat_encode_chan(1, MARSH_COMP_ID_VISUALISATION, + MAVLINK_COMM_0, &message, &heartbeat); return send_message(message); } @@ -195,9 +172,6 @@ void MarshConnector::receive_data(const PackedByteArray &data) { case MAVLINK_MSG_ID_MANUAL_CONTROL: handle_manual_control(message); break; - case MAVLINK_MSG_ID_MANUAL_SETPOINT: - handle_manual_setpoint(message); - break; case MAVLINK_MSG_ID_HEARTBEAT: handle_heartbeat(message); break; @@ -243,20 +217,7 @@ float MarshConnector::get_parameter(const String &id) { } Transform3D MarshConnector::get_aircraft() { - float heading_rad = parameters[NAV_OFS_HDG] * Math_PI / 180.0; - // To rotate clockwise looking from above, that's negative Y in Godot - Quaternion heading_offset = Quaternion(Vector3(0, 1, 0), -heading_rad); - Transform3D offset{Basis{heading_offset}, Vector3{-parameters[NAV_OFS_Y], 0.0, - parameters[NAV_OFS_X]}}; - Transform3D marsh{Basis{last_rotation}, last_location}; - return offset * marsh; -} - -Vector3 MarshConnector::get_velocity() { - float heading_rad = parameters[NAV_OFS_HDG] * Math_PI / 180.0; - // To rotate clockwise looking from above, that's negative Y in Godot - Quaternion heading_offset = Quaternion(Vector3(0, 1, 0), -heading_rad); - return heading_offset.xform(last_velocity); + return Transform3D{Basis{last_rotation}, last_location}; } Vector2 MarshConnector::get_cyclic() { @@ -267,21 +228,6 @@ float MarshConnector::get_collective() { return last_controls.w; } float MarshConnector::get_pedals() { return last_controls.z; } -Vector4 MarshConnector::get_controls() { return last_controls; } - -Vector4 MarshConnector::get_trim() { return last_trim; } - -float MarshConnector::get_fog_density() { return parameters[FOG_DENSITY]; } - -void MarshConnector::set_fog_density(float density) { - if (density == parameters[FOG_DENSITY]) - return; - - parameters[FOG_DENSITY] = density; - emit_signal("fog_density_changed", density); - send_param(FOG_DENSITY); -} - bool MarshConnector::get_manager_connected() { return manager_connected; } bool MarshConnector::get_model_connected() { return model_connected; } @@ -302,10 +248,6 @@ Vector2 MarshConnector::local_meters_from_global_degrees(double latitude, // Y East is just length along the circle of latitude double y = (lon - lon0) * (EARTH_RADIUS * cos(lat0)); - const double map_size = 3000.0; - x = (Math::fract(x / map_size + 0.5) - 0.5) * map_size; - y = (Math::fract(y / map_size + 0.5) - 0.5) * map_size; - return Vector2(x, y); } void MarshConnector::handle_sim_state(mavlink_message_t message) { @@ -325,8 +267,6 @@ void MarshConnector::handle_sim_state(mavlink_message_t message) { local_position.x, local_position.y, sim_state.alt)); receive_rotation(godot_rotation_from_mavlink(sim_state.roll, sim_state.pitch, sim_state.yaw)); - - last_velocity = Vector3{-sim_state.ve, -sim_state.vd, sim_state.vn}; } Vector3 MarshConnector::godot_location_from_mavlink(float north_meters, float east_meters, @@ -372,100 +312,7 @@ void MarshConnector::handle_attitude(mavlink_message_t message) { } void MarshConnector::handle_param(mavlink_message_t message) { - uint8_t target_system = 0; - uint8_t target_component = 0; - String param_id; - int16_t param_index = -1; - std::optional param_value; - - if (message.msgid == MAVLINK_MSG_ID_PARAM_REQUEST_LIST) { - mavlink_param_request_list_t param_request_list; - mavlink_msg_param_request_list_decode(&message, ¶m_request_list); - target_system = param_request_list.target_system; - target_component = param_request_list.target_component; - param_index = -2; // Not used by MAVLink, don't search for name - } else if (message.msgid == MAVLINK_MSG_ID_PARAM_REQUEST_READ) { - mavlink_param_request_read_t param_request_read; - mavlink_msg_param_request_read_decode(&message, ¶m_request_read); - target_system = param_request_read.target_system; - target_component = param_request_read.target_component; - param_index = param_request_read.param_index; - if (param_index == -1) { - param_id = String{param_request_read.param_id}; - } - } else if (message.msgid == MAVLINK_MSG_ID_PARAM_SET) { - mavlink_param_set_t param_set; - mavlink_msg_param_set_decode(&message, ¶m_set); - target_system = param_set.target_system; - target_component = param_set.target_component; - param_id = String{param_set.param_id}; - if (param_set.param_type == MAV_PARAM_EXT_TYPE_REAL32) { - // Only support float parameters, like MARSH Manager and ArduPilot - param_value = param_set.param_value; - } - } - - if (target_system != system_id && target_system != 0) { - return; // Not for us and not broadcast - } - if (target_component != component_id && target_component != 0) { - return; // Not for us and not broadcast - } - if (param_index == -1) { - for (uint16_t i = 0; i < PARAM_COUNT; i++) { - if (parameter_names[i] == param_id) { - param_index = i; - break; - } - } - if (param_index == -1) { - return; // Didn't find parameter - } - } - - if (message.msgid == MAVLINK_MSG_ID_PARAM_REQUEST_LIST) { - for (uint16_t i = 0; i < PARAM_COUNT; i++) { - send_param(Parameter{i}); - } - return; // Done everything for this message - } - - if (param_index < 0 || param_index >= PARAM_COUNT) { - return; // Invalid param_index - } - uint16_t i = param_index; - - if (param_value.has_value()) { - // TODO: Verify the value before updating - if (i == FOG_DENSITY) { - set_fog_density(*param_value); - } else { - parameters[i] = *param_value; - } - } - send_param(Parameter{i}); -} - -Error MarshConnector::send_param(Parameter index) { - if (index >= PARAM_COUNT) { - return ERR_PARAMETER_RANGE_ERROR; // "parameter" here as function argument - } - - mavlink_param_value_t param_value; - CharString nameBuffer = parameter_names[index].ascii(); - const char *name = nameBuffer.get_data(); - - // strncpy will write nulls after data until reaching target count - strncpy(param_value.param_id, name, sizeof(param_value.param_id)); - param_value.param_value = parameters[index]; - param_value.param_type = MAV_PARAM_TYPE_REAL32; - param_value.param_count = PARAM_COUNT; - param_value.param_index = index; - - mavlink_message_t message_sent; - mavlink_msg_param_value_encode_chan(system_id, component_id, MAVLINK_COMM_0, - &message_sent, ¶m_value); - return send_message(message_sent); + print_line("Implement handle_param"); } void MarshConnector::handle_manual_control(mavlink_message_t message) { @@ -485,42 +332,37 @@ void MarshConnector::handle_manual_control(mavlink_message_t message) { last_controls.w = manual_control.z / 1000.0f; } -void MarshConnector::handle_manual_setpoint(mavlink_message_t message) { - if (message.msgid != MAVLINK_MSG_ID_MANUAL_SETPOINT) - return; - - mavlink_manual_setpoint_t manual_setpoint; - mavlink_msg_manual_setpoint_decode(&message, &manual_setpoint); - if (manual_setpoint.mode_switch == MARSH_MANUAL_SETPOINT_MODE_TRIM) { - last_trim = Vector4{ - manual_setpoint.roll, - manual_setpoint.pitch, - manual_setpoint.yaw, - manual_setpoint.thrust, - }; - } -} - void MarshConnector::handle_heartbeat(mavlink_message_t message) { if (message.msgid != MAVLINK_MSG_ID_HEARTBEAT) return; - mavlink_heartbeat_t heartbeat; - mavlink_msg_heartbeat_decode(&message, &heartbeat); - if (heartbeat.type == MARSH_TYPE_MANAGER) { + // mavlink_heartbeat_t heartbeat; + // mavlink_msg_heartbeat_decode(&message, &heartbeat); + if (message.compid == MARSH_COMP_ID_MANAGER) { if (!manager_connected) { print_line("Connected to MARSH Manager"); - Error result = subscribe_message(message.sysid, message.compid, - MAVLINK_MSG_ID_MANUAL_CONTROL); - if (result != OK) { - print_line("Subscribe control send result ", result); - } + // subscribe to messages not sent to visualisation node by default + mavlink_command_long_t command; + command.target_system = 1; + command.target_component = MARSH_COMP_ID_MANAGER; + command.command = MAV_CMD_SET_MESSAGE_INTERVAL; + command.confirmation = 0; + command.param1 = static_cast(MAVLINK_MSG_ID_MANUAL_CONTROL); + command.param2 = 0; // Default rate + command.param3 = 0; // Not used + command.param4 = 0; + command.param5 = 0; + command.param6 = 0; + command.param7 = 1; // Address of requestor - result = subscribe_message(message.sysid, message.compid, - MAVLINK_MSG_ID_MANUAL_SETPOINT); + mavlink_message_t message_sent; + mavlink_msg_command_long_encode_chan(1, MARSH_COMP_ID_VISUALISATION, + MAVLINK_COMM_0, &message_sent, + &command); + Error result = send_message(message_sent); if (result != OK) { - print_line("Subscribe setpoint send result ", result); + print_line("Subscribe send result ", result); } } @@ -529,29 +371,6 @@ void MarshConnector::handle_heartbeat(mavlink_message_t message) { } } -Error MarshConnector::subscribe_message(uint8_t manager_system, - uint8_t manager_component, - uint32_t msgid) { - // subscribe to messages not sent to visualisation node by default - mavlink_command_long_t command; - command.target_system = manager_system; - command.target_component = manager_component; - command.command = MAV_CMD_SET_MESSAGE_INTERVAL; - command.confirmation = 0; - command.param1 = static_cast(msgid); - command.param2 = 0; // Default rate - command.param3 = 0; // Not used - command.param4 = 0; - command.param5 = 0; - command.param6 = 0; - command.param7 = 1; // Address of requester - - mavlink_message_t message_sent; - mavlink_msg_command_long_encode_chan(system_id, component_id, MAVLINK_COMM_0, - &message_sent, &command); - return send_message(message_sent); -} - void MarshConnector::manager_timeout() { print_line("Lost connection to MARSH Manager"); manager_connected = false; diff --git a/src/marshconnector.h b/src/marshconnector.h index 2de3a7d..e1a3e78 100644 --- a/src/marshconnector.h +++ b/src/marshconnector.h @@ -39,21 +39,12 @@ public: // Get current state of the aircraft Transform3D get_aircraft(); - Vector3 get_velocity(); // Get normalized (-1 to 1) cyclic position, where X is right, Y is pitch up Vector2 get_cyclic(); // Get normalized (0 to 1) collective position, positive to climb float get_collective(); // Get normalized (-1 to 1) pedals position, positive turn right float get_pedals(); - // Get normalized position for all controls - Vector4 get_controls(); - // Get normalized trim position - Vector4 get_trim(); - - // Get current fog density as set in the parameter - float get_fog_density(); - void set_fog_density(float value); // Is there a connection to MARSH Manager bool get_manager_connected(); @@ -85,7 +76,6 @@ private: void handle_attitude(mavlink_message_t message); void handle_param(mavlink_message_t message); void handle_manual_control(mavlink_message_t message); - void handle_manual_setpoint(mavlink_message_t message); void handle_heartbeat(mavlink_message_t message); void receive_model_data(); @@ -97,8 +87,8 @@ private: // Do not specify specific values, to ensure PARAM_COUNT is correct // Not an enum class on purpose, to make use more convenient, it's scoped // inside the class namespace anyway - enum Parameter : uint16_t { - FOG_DENSITY, + enum Parameter { + // FOG_DENSITY, NAV_OFS_HDG, NAV_OFS_X, NAV_OFS_Y, @@ -106,25 +96,17 @@ private: LOCAL_FRAME_LON, PARAM_COUNT, }; - float parameters[PARAM_COUNT] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + float parameters[PARAM_COUNT] = {0.0, 0.0, 0.0, 0.0, 0.0}; const String parameter_names[PARAM_COUNT] = { - "FOG_DENSITY", "NAV_OFS_HDG", "NAV_OFS_X", - "NAV_OFS_Y", "LOCAL_FRAME_LAT", "LOCAL_FRAME_LON", + // "FOG_DENSITY", + "NAV_OFS_HDG", "NAV_OFS_X", "NAV_OFS_Y", + "LOCAL_FRAME_LAT", "LOCAL_FRAME_LON", }; - Error send_param(Parameter index); - Error subscribe_message(uint8_t manager_system, uint8_t manager_component, - uint32_t msgid); - - uint8_t system_id; - uint8_t component_id; // TODO: Interpolate with some delay - // Or not, in practice the simple solution works nicely Vector3 last_location; Quaternion last_rotation; - Vector3 last_velocity; Vector4 last_controls; - Vector4 last_trim; double time_passed; Timer *heartbeat_timer;