<commit_before>/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

 Module:       FGLGear.cpp
 Author:       <NAME>
               <NAME>
               <NAME>
 Date started: 11/18/99
 Purpose:      Encapsulates the landing gear elements
 Called by:    FGAircraft

 ------------- Copyright (C) 1999  <NAME> (<EMAIL>) -------------

 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU Lesser General Public License as published by the Free Software
 Foundation; either version 2 of the License, or (at your option) any later
 version.

 This program is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
 details.

 You should have received a copy of the GNU Lesser General Public License along with
 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 Place - Suite 330, Boston, MA  02111-1307, USA.

 Further information about the GNU Lesser General Public License can also be found on
 the world wide web at http://www.gnu.org.

FUNCTIONAL DESCRIPTION
--------------------------------------------------------------------------------

HISTORY
--------------------------------------------------------------------------------
11/18/99   JSB   Created
01/30/01   NHP   Extended gear model to properly simulate steering and braking
07/08/09   BC    Modified gear model to support large angles between aircraft and ground

/%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

#include <cstdlib>
#include <cstring>

#include "math/FGFunction.h"
#include "FGLGear.h"
#include "models/FGGroundReactions.h"
#include "math/FGTable.h"
#include "input_output/FGXMLElement.h"

using namespace std;

namespace JSBSim {

/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
GLOBAL DATA
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

IDENT(IdSrc,"$Id: FGLGear.cpp,v 1.120 2015/08/16 16:13:31 bcoconni Exp $");
IDENT(IdHdr,ID_LGEAR);

// Body To Structural (body frame is rotated 180 deg about Y and lengths are given in
// ft instead of inches)
const FGMatrix33 FGLGear::Tb2s(-1./inchtoft, 0., 0., 0., 1./inchtoft, 0., 0., 0., -1./inchtoft);
const FGMatrix33 FGLGear::Ts2b(-inchtoft, 0., 0., 0., inchtoft, 0., 0., 0., -inchtoft);

/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

FGLGear::FGLGear(Element* el, FGFDMExec* fdmex, int number, const struct Inputs& inputs) :
  FGSurface(fdmex, number),
  FGForce(fdmex),
  in(inputs),
  GearNumber(number),
  SteerAngle(0.0),
  Castered(false),
  StaticFriction(false)
{
  kSpring = bDamp = bDampRebound = dynamicFCoeff = staticFCoeff = rollingFCoeff = maxSteerAngle = 0;
  isRetractable = false;
  eDampType = dtLinear;
  eDampTypeRebound = dtLinear;

  name = el->GetAttributeValue("name");
  string sContactType = el->GetAttributeValue("type");
  if (sContactType == "BOGEY") {
    eContactType = ctBOGEY;
  } else if (sContactType == "STRUCTURE") {
    eContactType = ctSTRUCTURE;
  } else {
    // Unknown contact point types will be treated as STRUCTURE.
    eContactType = ctSTRUCTURE;
  }

  // Default values for structural contact points
  if (eContactType == ctSTRUCTURE) {
    kSpring = in.EmptyWeight;
    bDamp = kSpring;
    bDampRebound = kSpring * 10;
    staticFCoeff = 1.0;
    dynamicFCoeff = 1.0;
  }

  PropertyManager = fdmex->GetPropertyManager();

  fStrutForce = 0;
  Element* strutForce = el->FindElement("strut_force");
  if (strutForce) {
    Element* springFunc = strutForce->FindElement("function");
    fStrutForce = new FGFunction(PropertyManager, springFunc);
  }
  else {
    if (el->FindElement("spring_coeff"))
      kSpring = el->FindElementValueAsNumberConvertTo("spring_coeff", "LBS/FT");
    if (el->FindElement("damping_coeff")) {
      Element* dampCoeff = el->FindElement("damping_coeff");
      if (dampCoeff->GetAttributeValue("type") == "SQUARE") {
        eDampType = dtSquare;
        bDamp   = el->FindElementValueAsNumberConvertTo("damping_coeff", "LBS/FT2/SEC2");
      } else {
        bDamp   = el->FindElementValueAsNumberConvertTo("damping_coeff", "LBS/FT/SEC");
      }
    }

    if (el->FindElement("damping_coeff_rebound")) {
      Element* dampCoeffRebound = el->FindElement("damping_coeff_rebound");
      if (dampCoeffRebound->GetAttributeValue("type") == "SQUARE") {
        eDampTypeRebound = dtSquare;
        bDampRebound   = el->FindElementValueAsNumberConvertTo("damping_coeff_rebound", "LBS/FT2/SEC2");
      } else {
        bDampRebound   = el->FindElementValueAsNumberConvertTo("damping_coeff_rebound", "LBS/FT/SEC");
      }
    } else {
      bDampRebound   = bDamp;
      eDampTypeRebound = eDampType;
    }
  }

  if (el->FindElement("dynamic_friction"))
    dynamicFCoeff = el->FindElementValueAsNumber("dynamic_friction");
  if (el->FindElement("static_friction"))
    staticFCoeff = el->FindElementValueAsNumber("static_friction");
  if (el->FindElement("rolling_friction"))
    rollingFCoeff = el->FindElementValueAsNumber("rolling_friction");
  if (el->FindElement("retractable"))
    isRetractable = ((unsigned int)el->FindElementValueAsNumber("retractable"))>0.0?true:false;

  if (el->FindElement("max_steer"))
    maxSteerAngle = el->FindElementValueAsNumberConvertTo("max_steer", "DEG");

  if (maxSteerAngle == 360) {
    eSteerType = stCaster;
    Castered = true;
  }
  else if (maxSteerAngle == 0.0) {
    eSteerType = stFixed;
  }
  else
    eSteerType = stSteer;
<commit_msg>Explicitly allow wheel castering even with a max_steer value below 360, as a bosnus also allow non castered wheel with max_steer == 360<commit_after>/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

 Module:       FGLGear.cpp
 Author:       <NAME>
               <NAME>
               <NAME>
 Date started: 11/18/99
 Purpose:      Encapsulates the landing gear elements
 Called by:    FGAircraft

 ------------- Copyright (C) 1999  <NAME> (<EMAIL>) -------------

 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU Lesser General Public License as published by the Free Software
 Foundation; either version 2 of the License, or (at your option) any later
 version.

 This program is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
 details.

 You should have received a copy of the GNU Lesser General Public License along with
 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 Place - Suite 330, Boston, MA  02111-1307, USA.

 Further information about the GNU Lesser General Public License can also be found on
 the world wide web at http://www.gnu.org.

FUNCTIONAL DESCRIPTION
--------------------------------------------------------------------------------

HISTORY
--------------------------------------------------------------------------------
11/18/99   JSB   Created
01/30/01   NHP   Extended gear model to properly simulate steering and braking
07/08/09   BC    Modified gear model to support large angles between aircraft and ground

/%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

#include <cstdlib>
#include <cstring>

#include "math/FGFunction.h"
#include "FGLGear.h"
#include "models/FGGroundReactions.h"
#include "math/FGTable.h"
#include "input_output/FGXMLElement.h"

using namespace std;

namespace JSBSim {

/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
GLOBAL DATA
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

IDENT(IdSrc,"$Id: FGLGear.cpp,v 1.121 2015/09/29 13:22:47 ehofman Exp $");
IDENT(IdHdr,ID_LGEAR);

// Body To Structural (body frame is rotated 180 deg about Y and lengths are given in
// ft instead of inches)
const FGMatrix33 FGLGear::Tb2s(-1./inchtoft, 0., 0., 0., 1./inchtoft, 0., 0., 0., -1./inchtoft);
const FGMatrix33 FGLGear::Ts2b(-inchtoft, 0., 0., 0., inchtoft, 0., 0., 0., -inchtoft);

/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

FGLGear::FGLGear(Element* el, FGFDMExec* fdmex, int number, const struct Inputs& inputs) :
  FGSurface(fdmex, number),
  FGForce(fdmex),
  in(inputs),
  GearNumber(number),
  SteerAngle(0.0),
  Castered(false),
  StaticFriction(false)
{
  kSpring = bDamp = bDampRebound = dynamicFCoeff = staticFCoeff = rollingFCoeff = maxSteerAngle = 0;
  isRetractable = false;
  eDampType = dtLinear;
  eDampTypeRebound = dtLinear;

  name = el->GetAttributeValue("name");
  string sContactType = el->GetAttributeValue("type");
  if (sContactType == "BOGEY") {
    eContactType = ctBOGEY;
  } else if (sContactType == "STRUCTURE") {
    eContactType = ctSTRUCTURE;
  } else {
    // Unknown contact point types will be treated as STRUCTURE.
    eContactType = ctSTRUCTURE;
  }

  // Default values for structural contact points
  if (eContactType == ctSTRUCTURE) {
    kSpring = in.EmptyWeight;
    bDamp = kSpring;
    bDampRebound = kSpring * 10;
    staticFCoeff = 1.0;
    dynamicFCoeff = 1.0;
  }

  PropertyManager = fdmex->GetPropertyManager();

  fStrutForce = 0;
  Element* strutForce = el->FindElement("strut_force");
  if (strutForce) {
    Element* springFunc = strutForce->FindElement("function");
    fStrutForce = new FGFunction(PropertyManager, springFunc);
  }
  else {
    if (el->FindElement("spring_coeff"))
      kSpring = el->FindElementValueAsNumberConvertTo("spring_coeff", "LBS/FT");
    if (el->FindElement("damping_coeff")) {
      Element* dampCoeff = el->FindElement("damping_coeff");
      if (dampCoeff->GetAttributeValue("type") == "SQUARE") {
        eDampType = dtSquare;
        bDamp   = el->FindElementValueAsNumberConvertTo("damping_coeff", "LBS/FT2/SEC2");
      } else {
        bDamp   = el->FindElementValueAsNumberConvertTo("damping_coeff", "LBS/FT/SEC");
      }
    }

    if (el->FindElement("damping_coeff_rebound")) {
      Element* dampCoeffRebound = el->FindElement("damping_coeff_rebound");
      if (dampCoeffRebound->GetAttributeValue("type") == "SQUARE") {
        eDampTypeRebound = dtSquare;
        bDampRebound   = el->FindElementValueAsNumberConvertTo("damping_coeff_rebound", "LBS/FT2/SEC2");
      } else {
        bDampRebound   = el->FindElementValueAsNumberConvertTo("damping_coeff_rebound", "LBS/FT/SEC");
      }
    } else {
      bDampRebound   = bDamp;
      eDampTypeRebound = eDampType;
    }
  }

  if (el->FindElement("dynamic_friction"))
    dynamicFCoeff = el->FindElementValueAsNumber("dynamic_friction");
  if (el->FindElement("static_friction"))
    staticFCoeff = el->FindElementValueAsNumber("static_friction");
  if (el->FindElement("rolling_friction"))
    rollingFCoeff = el->FindElementValueAsNumber("rolling_friction");
  if (el->FindElement("retractable"))
    isRetractable = ((unsigned int)el->FindElementValueAsNumber("retractable"))>0.0?true:false;

  if (el->FindElement("max_steer"))
    maxSteerAngle = el->FindElementValueAsNumberConvertTo("max_steer", "DEG");

  if (maxSteerAngle == 360) {
    eSteerType = stCaster;
    Castered = true;
  }
  else if (maxSteerAngle == 0.0) {
    eSteerType = stFixed;
  }
  else
    eSteerType = stSteer;

  Element* castering = el->FindElement("castered");
  if (castering) {
    if (castering->GetDataAsNumber() != 0.0) {
      eSteerType = stCaster;
      Castered = true;
    }
    else {
      if (maxSteerAngle == 0.0) {
        eSteerType = stFixed;
      }
      else {
        eSteerType = stSteer;
      }
      Castered = false;
    }
  }

{'fraction_non_alphanumeric': 0.23979672860092108, 'fraction_numerical': 0.017627441638875654, 'mean_word_length': 3.7013811123553566, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 75, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3706088', 'n_tokens_mistral': 4043, 'n_tokens_neox': 3715, 'n_words': 932}