Skip to content

Improve NEU properties#1327

Merged
seanmcleod70 merged 4 commits intoJSBSim-Team:masterfrom
seanmcleod70:FixNEU
Sep 2, 2025
Merged

Improve NEU properties#1327
seanmcleod70 merged 4 commits intoJSBSim-Team:masterfrom
seanmcleod70:FixNEU

Conversation

@seanmcleod70
Copy link
Contributor

  • Fix the inadvertent removal of the ft to m conversion for the position/distance-from-start-lat/lon-mt properties in the original PR for NEU properties.
  • Improve the naming of the NEU properties, i.e. position/from-start-neu-n-ft
  • Initialize NEU starting position in a more JSBSim idiomatic way

@codecov
Copy link

codecov bot commented Aug 28, 2025

Codecov Report

❌ Patch coverage is 72.72727% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 24.91%. Comparing base (83e3df2) to head (a714722).
⚠️ Report is 2 commits behind head on master.

Files with missing lines Patch % Lines
src/models/FGAuxiliary.cpp 75.00% 5 Missing ⚠️
src/FGFDMExec.cpp 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1327      +/-   ##
==========================================
+ Coverage   24.89%   24.91%   +0.02%     
==========================================
  Files         169      169              
  Lines       19669    19675       +6     
==========================================
+ Hits         4896     4902       +6     
  Misses      14773    14773              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Member

@bcoconni bcoconni left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me 👍

Just some food for thought: we might want to compute the NEU position only when needed rather than forcing it being updated every time step.

@bcoconni bcoconni requested a review from Copilot August 29, 2025 18:28
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR improves the North East Up (NEU) properties implementation in JSBSim by fixing unit conversion issues and adopting better initialization practices. The changes restore proper feet-to-meters conversion for distance properties and rename NEU properties for better clarity.

Key changes:

  • Restored missing feet-to-meters conversion for position/distance properties
  • Renamed NEU properties to use more descriptive from-start-neu-* naming pattern
  • Replaced runtime initialization check with proper JSBSim initialization pattern

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
src/models/FGAuxiliary.h Added forward declaration and SetInitialState method, removed initialization flag
src/models/FGAuxiliary.cpp Implemented proper initialization, restored unit conversions, updated property names
src/FGFDMExec.cpp Added Auxiliary initialization call to main initialization sequence

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@seanmcleod70
Copy link
Contributor Author

Just some food for thought: we might want to compute the NEU position only when needed rather than forcing it being updated every time step.

Yep, I actually thought of it at the time I first implemented them. Especially given it's not something that other systems like the EOM etc. need on each time step, plus they're not going to be popular properties in general. So, adding some additional conditional logic will more than likely be better performance wise as opposed to calculating it on every time step.

However, I've run into an issue with our recent friend, FGPropertyManager::Tie 😉

So these are the changes I made, note the change in const.

-  double GetNEUPositionFromStart(int idx) const { return vNEUFromStart(idx); }
-  const FGColumnVector3& GetNEUPositionFromStart() const { return vNEUFromStart; }

+  double GetNEUPositionFromStart(int idx) { return (GetNEUPositionFromStart())(idx); }
+  const FGColumnVector3& GetNEUPositionFromStart();

const FGColumnVector3& FGAuxiliary::GetNEUPositionFromStart()
{ 
  if (!NEUValid) {
    // Position tracking in local frame with local frame origin at lat, lon of initial condition
    // and at 0 altitude relative to the reference ellipsoid. Position is NEU (North, East, UP) in feet.
    vNEUFromStart = NEUStartLocation.LocationToLocal(in.vLocation);
    vNEUFromStart(3) *= -1.0;  // Flip sign for Up, so + for altitude above reference ellipsoid
    NEUValid = true;
  }

  return vNEUFromStart; 
}

bool FGAuxiliary::Run(bool Holding)
{
............
  // New timestep so vNEUFromStart is no longer valid since we only calculate it on demand
  NEUValid = false;
...........  
}

Which results in this, doesn't appear we can currently have getters that aren't const for binding via FGPropertyManager::Tie?

1>FGAuxiliary.cpp
1>C:\source\jsbsim\src\models\FGAuxiliary.cpp(469,20): error C2672: 'JSBSim::FGPropertyManager::Tie': no matching overloaded function found
1>    C:\source\jsbsim\src\input_output\FGPropertyManager.h(437,7):

@seanmcleod70
Copy link
Contributor Author

One workaround for the const issue, make the methods const again and declare vNEUFromStart and NEUValid as mutable.

+  double GetNEUPositionFromStart(int idx) const { return (GetNEUPositionFromStart())(idx); }
+  const FGColumnVector3& GetNEUPositionFromStart() const;

  FGLocation NEUStartLocation;
  mutable FGColumnVector3 vNEUFromStart;
  mutable bool NEUValid;

@bcoconni
Copy link
Member

bcoconni commented Sep 1, 2025

One workaround for the const issue, make the methods const again and declare vNEUFromStart and NEUValid as mutable.

+  double GetNEUPositionFromStart(int idx) const { return (GetNEUPositionFromStart())(idx); }
+  const FGColumnVector3& GetNEUPositionFromStart() const;

  FGLocation NEUStartLocation;
  mutable FGColumnVector3 vNEUFromStart;
  mutable bool NEUValid;

Yep ! Seems reasonable to me. Especially since the mutable members are "byproducts" of the class. The method GetNEUPositionFromStart is not actually changing the class state so we can still claim it is const during the call to the getter.

@seanmcleod70
Copy link
Contributor Author

Yep, I came across the following when I was looking into the options available.

https://isocpp.org/wiki/faq/const-correctness

What do I do if I want a const member function to make an “invisible” change to a data member?

Use mutable (or, as a last resort, use const_cast).

A small percentage of inspectors need to make changes to an object’s physical state that cannot be observed by external users — changes to the physical but not logical state.

For example, the collection-object discussed earlier cached its last lookup in hopes of improving the performance of its next lookup. Since the cache, in this example, cannot be directly observed by any part of the collection-object’s public interface (other than timing), its existence and state is not part of the object’s logical state, so changes to it are invisible to external users. The lookup method is an inspector since it never changes the object’s logical state, irrespective of the fact that, at least for the present implementation, it changes the object’s physical state.

When methods change the physical but not logical state, the method should generally be marked as const since it really is an inspector-method. That creates a problem: when the compiler sees your const method changing the physical state of the this object, it will complain — it will give your code an error message.

The C++ compiler language uses the mutable keyword to help you embrace this logical const notion. In this case, you would mark the cache with the mutable keyword, that way the compiler knows it is allowed to change inside a const method or via any other const pointer or reference. In our lingo, the mutable keyword marks those portions of the object’s physical state which are not part of the logical state.

@bcoconni
Copy link
Member

bcoconni commented Sep 2, 2025

Looks good to me 👍

@seanmcleod70 seanmcleod70 merged commit a55604b into JSBSim-Team:master Sep 2, 2025
50 of 51 checks passed
bcoconni pushed a commit to bcoconni/jsbsim that referenced this pull request Feb 6, 2026
Co-authored-by: Sean McLeod <sean@seanmcleod.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants