|
From: Julian S. <ju...@op...> - 2023-07-02 22:44:29
|
I think i've come across a problem with this commit.
Arguably it's not actually the commit that's wrong but, for me, with
bad scenery the commit introduces NaNs that did not previously happen.
If one starts Flightgear with:
--airport=bikf --runway=20
and then taxis along the ground with a heading near 95 deg, a short
distance after leaving the runway there appears to be a glitch in the
ground level, which suddenly seems to increase by 6e6 metres.
The YASim code tries to compress the gear by 6e6 metres in order to
place the wheel on the ground. This is obviously beyond the limit of
the gear, in which case the new "steep force increase" code sets the
force from gear compression to:
pow(frac_with_initial_load, 4) * clen * _spring
Here, frac_with_initial_load is basically `6e6 / gear_max_compression`.
So we end up with a force of `1e27 * clen * _spring`, which
unsurprisingly causes NaNs in the next iteration, freezing Flightgear.
The previous code would always clip `frac_with_initial_load` to a
maximum of 1, which avoids the problem, and i think will merely result
in a small jump as the aircraft crosses the bad scenery.
[I've tried this with --aircraft=Harrier-GR3, but i suspect the same
will happen with any other YASim aircraft.]
As i mentioned on
https://sourceforge.net/p/flightgear/codetickets/1509/, i'm not
convinced that the old behaviour is actually wrong - if gear is
compressed more than it can physically handle, it will break, and
making it generate more force than it could ever generate in real life,
doesn't really make sense. [And arguably it would be better to set
`/sim/crashed` to true.]
I think my preferred solution here would involve two things:
1. Make the new code be optional, and activated by a new flag in the
`<gear>...</grear>` XML described in
https://wiki.flightgear.org/YASim#Landing_gear, e.g. `steep` or similar.
2. Change the new code to avoid generating ridiculous forces when given
ridiculous ground level data.
I think 1 is easy enough to do. [Though perhaps there could be extra
decisions to make about whether to also allow control over how the
force steepens.]
I'm not sure how to do 2 in a non-hacky way. We'd have to decide what
constitutes a reasonable maximum force.
Thanks,
- Jules
On Tue, 13 Jun 2023 11:24:03 +0000
flightgear-commitlogs--- via Flightgear-commitlogs
<fli...@li...> wrote:
> jmturner pushed a commit to branch next
> in repository flightgear.
>
> SF URL:
> http://sourceforge.net/p/flightgear/flightgear/ci/6df2904f758f25fc0f034422dd32b48f787bf656/
>
> Commit: 6df2904f758f25fc0f034422dd32b48f787bf656
> Author: Jakub Kákona
> Committer: James Turner
> AuthorDate: Thu Jan 20 20:13:52 2022 +0100
>
> YASim gear: Clamping of _frac replaced
>
> Instead use a a steep force increase
>
> Implement Ticket
> https://sourceforge.net/p/flightgear/codetickets/1509/
>
>
>
> ---
> src/FDM/YASim/Gear.cpp | 47
> +++++++++++++++++++++-------------------------- 1 file changed, 21
> insertions(+), 26 deletions(-)
>
> diff --git a/src/FDM/YASim/Gear.cpp b/src/FDM/YASim/Gear.cpp
> index c4c855f5f..be39b8faa 100644
> --- a/src/FDM/YASim/Gear.cpp
> +++ b/src/FDM/YASim/Gear.cpp
> @@ -88,7 +88,7 @@ Gear::Gear()
>
> Math::zero3(_ground_trans);
> Math::identity33(_ground_rot);
> -
> +
> _wheelAxle.set(0, 1, 0);
> _wheelRadius = 0;
> _tyreRadius = 0;
> @@ -268,14 +268,14 @@ bool gearCompression(
> So:
> compression_distance = -a / (compression . G)
> */
> -
> +
> float ground_unit[3];
> magnitudeUnit( ground, ground_unit);
> -
> +
> /* Find S, the lowest point on wheel. */
> float S[3];
> Math::set3( wheel_pos, S);
> -
> +
> if (wheel_radius) {
> /* Find radial wheel vector pointing closest to ground using
> two cross-products: wheel_axle_unit x ground_unit x wheel_axle_unit */
> @@ -287,11 +287,11 @@ bool gearCompression(
> use it to find S. */
> Math::unit3( R, R);
> Math::mul3( wheel_radius, R, R);
> -
> +
> /* Add R to S to get lowest point on wheel. */
> Math::add3( S, R, S);
> }
> -
> +
> /* Calculate <a>, distance of S below ground. */
> float a = Math::dot3( ground, S) - ( ground[3] - tyre_radius);
> float bump_altitude = 0;
> @@ -299,15 +299,15 @@ bool gearCompression(
> bump_altitude = bump_fn();
> a -= bump_altitude;
> }
> -
> +
> if ( a < 0) {
> /* S is above ground so we are not on ground. */
> return false;
> }
> -
> +
> /* Lowest part of wheel is below ground. */
> o_compression_distance_vertical = a;
> -
> +
> /* Find compression_norm. First we need to find
> compression_distance, the distance to compress the gear so that S
> (which is below ground+tyre_radius) would move to just touch
> ground+tyre_radius. We need to move gear further @@ -325,10 +325,7 @@
> bool gearCompression( if ( compression.magnitude) {
> o_compression_norm = compression_distance /
> compression.magnitude; }
> - if (o_compression_norm > 1) {
> - o_compression_norm = 1;
> - }
> -
> +
> /* Contact point on ground-plus-tyre-radius is S plus compression
> vector. */
> float delta[3];
> @@ -359,7 +356,7 @@ bool gearCompression(
> Math::mul3( tyre_radius, ground_unit, delta);
> Math::add3( o_contact, delta, o_contact);
> }
> -
> +
> {
> /* Verify that <o_contact> is on ground; this can fail e.g.
> when resetting so for now we just output a diagnostic rather than
> assert fail. */ @@ -376,7 +373,7 @@ bool gearCompression(
> );
> }
> }
> -
> +
> return true;
> }
>
> @@ -399,7 +396,7 @@ bool gearCompressionOld(
> BumpAltitude = bump_fn();
> a+=BumpAltitude;
> }
> -
> +
> if(a > 0) {
> o_compression_distance_vertical = 0;
> o_compression_norm = 0;
> @@ -407,7 +404,7 @@ bool gearCompressionOld(
> }
>
> o_compression_distance_vertical = -a;
> -
> +
> // Now a is the distance from the tip to ground, so make b the
> // distance from the base to ground. We can get the fraction
> // (0-1) of compression from a/(a-b). Note the minus sign --
> stuff @@ -417,10 +414,7 @@ bool gearCompressionOld(
> float b = ground[3] - Math::dot3(tmp, ground)+BumpAltitude;
>
> // Calculate the point of ground _contact.
> - if(b < 0)
> - o_compression_norm = 1;
> - else
> - o_compression_norm = a/(a-b);
> + o_compression_norm = a/(a-b);
> for(int i=0; i<3; i++)
> o_contact[i] = pos[i] + o_compression_norm *
> compression.v[i]; return true;
> @@ -489,10 +483,7 @@ void Gear::calcForce(Ground *g_cb, RigidBody*
> body, State *s, float* v, float* r Math::add3(cv, v, cv);
> Math::sub3(cv, glvel, cv);
>
> - // Finally, we can start adding up the forces. First the spring
> - // compression. (note the clamping of _frac to 1):
> - _frac = (_frac > 1) ? 1 : _frac;
> -
> + // Finally, we can start adding up the forces. First the spring
> compression. // Add the initial load to frac, but with continous
> transistion around 0 float frac_with_initial_load;
> if (_frac>0.2 || _initialLoad==0.0)
> @@ -501,7 +492,12 @@ void Gear::calcForce(Ground *g_cb, RigidBody*
> body, State *s, float* v, float* r frac_with_initial_load =
> (_frac+_initialLoad) *_frac*_frac*3*25-_frac*_frac*_frac*2*125;
>
> + // in case of _frac >= 1 spring at bump stop has rapidly
> increasing rebound force float fmag =
> frac_with_initial_load*clen*_spring;
> + if (_frac > 1 ) {
> + fmag = pow(frac_with_initial_load, 4) * clen * _spring;
> + }
> +
> if (_speed_planing>0)
> {
> float v = Math::mag3(cv);
> @@ -919,4 +915,3 @@ void Gear::updateStuckPoint(State* s)
>
>
> }; // namespace yasim
> -
>
>
> _______________________________________________
> Flightgear-commitlogs mailing list
> Fli...@li...
> https://lists.sourceforge.net/lists/listinfo/flightgear-commitlogs
--
http://op59.net
|