1 // =============================================================================
2 // PROJECT CHRONO - http://projectchrono.org
3 //
4 // Copyright (c) 2015 projectchrono.org
5 // All rights reserved.
6 //
7 // Use of this source code is governed by a BSD-style license that can be found
8 // in the LICENSE file at the top level of the distribution and at
9 // http://projectchrono.org/license-chrono.txt.
10 //
11 // =============================================================================
12 // Authors: Radu Serban, Michael Taylor, Rainer Gericke
13 // =============================================================================
14 //
15 // Template for Fiala tire model
16 //
17 // =============================================================================
18 
19 #ifndef CH_FIALATIRE_H
20 #define CH_FIALATIRE_H
21 
22 #include <vector>
23 
24 #include "chrono/physics/ChBody.h"
25 #include "chrono/assets/ChCylinderShape.h"
26 #include "chrono/assets/ChTexture.h"
27 
28 #include "chrono_vehicle/wheeled_vehicle/ChTire.h"
29 #include "chrono_vehicle/ChTerrain.h"
30 
31 namespace chrono {
32 namespace vehicle {
33 
34 /// @addtogroup vehicle_wheeled_tire
35 /// @{
36 
37 /// Fiala based tire model.
38 class CH_VEHICLE_API ChFialaTire : public ChTire {
39   public:
40     ChFialaTire(const std::string& name);
41 
~ChFialaTire()42     virtual ~ChFialaTire() {}
43 
44     /// Get the name of the vehicle subsystem template.
GetTemplateName()45     virtual std::string GetTemplateName() const override { return "FialaTire"; }
46 
47     /// Add visualization assets for the rigid tire subsystem.
48     virtual void AddVisualizationAssets(VisualizationType vis) override;
49 
50     /// Remove visualization assets for the rigid tire subsystem.
51     virtual void RemoveVisualizationAssets() override;
52 
53     /// Get the tire width.
54     /// For a Fiala tire, this is the unloaded tire radius.
GetRadius()55     virtual double GetRadius() const override { return m_unloaded_radius; }
56 
57     /// Report the tire force and moment.
ReportTireForce(ChTerrain * terrain)58     virtual TerrainForce ReportTireForce(ChTerrain* terrain) const override { return m_tireforce; }
59 
60     /// Get the width of the tire.
GetWidth()61     virtual double GetWidth() const override { return m_width; }
62 
63     /// Get visualization width.
GetVisualizationWidth()64     virtual double GetVisualizationWidth() const { return m_width; }
65 
66     /// Get the tire slip angle computed internally by the Fiala model (in radians).
67     /// The reported value will be similar to that reported by ChTire::GetSlipAngle.
GetSlipAngle_internal()68     double GetSlipAngle_internal() const { return m_states.alpha; }
69 
70     /// Get the tire longitudinal slip computed internally by the Fiala model.
71     /// The reported value will be different from that reported by ChTire::GetLongitudinalSlip
72     /// because ChFialaTire uses the loaded tire radius for its calculation.
GetLongitudinalSlip_internal()73     double GetLongitudinalSlip_internal() const { return m_states.kappa; }
74 
75     /// Get the camber angle for the Fiala tire model (in radians).
76     /// ChFialaTire does not calculate its own camber angle. This value is the same as that
77     /// reported by ChTire::GetCamberAngle.
GetCamberAngle_internal()78     double GetCamberAngle_internal() { return GetCamberAngle(); }
79 
80     /// Generate basic tire plots.
81     /// This function creates a Gnuplot script file with the specified name.
82     void WritePlots(const std::string& plFileName, const std::string& plTireFormat);
83 
84   protected:
85     /// Return the vertical tire stiffness contribution to the normal force.
86     virtual double GetNormalStiffnessForce(double depth) const = 0;
87 
88     /// Return the vertical tire damping contribution to the normal force.
89     virtual double GetNormalDampingForce(double depth, double velocity) const = 0;
90 
91     /// Set the parameters in the Fiala model.
92     virtual void SetFialaParams() = 0;
93 
94     /// Calculate Patch Forces
95     void FialaPatchForces(double& fx, double& fy, double& mz, double kappa, double alpha, double fz);
96 
97     /// Fiala tire model parameters
98 
99     double m_unloaded_radius;
100     double m_width;
101     double m_rolling_resistance;
102     double m_c_slip;
103     double m_c_alpha;
104     double m_u_min;
105     double m_u_max;
106     double m_relax_length_x;
107     double m_relax_length_y;
108 
109     // Fiala extensions from ADAMS/Car user source example and TMeasy
110     double m_mu;    ///< Actual friction coefficient of the road
111     double m_mu_0;  ///< Local friction coefficient of the road for given parameters
112 
113     /// Switch for dynamic mode (relaxation)
114     bool m_dynamic_mode;
115     double m_time;        // actual system time
116     double m_time_trans;  // end of start transient
117 
118   //private:
119     /// Get the tire force and moment.
120     /// This represents the output from this tire system that is passed to the
121     /// vehicle system.  Typically, the vehicle subsystem will pass the tire force
122     /// to the appropriate suspension subsystem which applies it as an external
123     /// force one the wheel body.
GetTireForce()124     virtual TerrainForce GetTireForce() const override { return m_tireforce; }
125 
126     /// Initialize this tire by associating it to the specified wheel.
127     virtual void Initialize(std::shared_ptr<ChWheel> wheel) override;
128 
129     /// Update the state of this tire system at the current time.
130     virtual void Synchronize(double time,              ///< [in] current time
131                              const ChTerrain& terrain  ///< [in] reference to the terrain system
132                              ) override;
133 
134     /// Advance the state of this tire by the specified time step.
135     virtual void Advance(double step) override;
136 
137     struct ContactData {
138         bool in_contact;      // true if disc in contact with terrain
139         ChCoordsys<> frame;   // contact frame (x: long, y: lat, z: normal)
140         ChVector<> vel;       // relative velocity expressed in contact frame
141         double normal_force;  // magnitude of normal contact force
142         double depth;         // penetration depth
143     };
144 
145     struct TireStates {
146         double kappa;   // Contact Path - Stationary Longitudinal Slip State (Kappa)
147         double alpha;   // Contact Path - Stationary Side Slip State (Alpha)
148         double abs_vx;  // Longitudinal speed
149         double abs_vt;  // Longitudinal transport speed
150         double vsx;     // Longitudinal slip velocity
151         double vsy;     // Lateral slip velocity = Lateral velocity
152         double omega;   // Wheel angular velocity about its spin axis (temporary for debug)
153         double Fx_l;
154         double Fy_l;
155         ChVector<> disc_normal;  // temporary for debug
156     };
157 
158     ChFunction_Recorder m_areaDep;  // lookup table for estimation of penetration depth from intersection area
159 
160     ContactData m_data;
161     TireStates m_states;
162 
163     TerrainForce m_tireforce;
164 
165     std::shared_ptr<ChCylinderShape> m_cyl_shape;  ///< visualization cylinder asset
166     std::shared_ptr<ChTexture> m_texture;          ///< visualization texture asset
167 };
168 
169 /// @} vehicle_wheeled_tire
170 
171 }  // end namespace vehicle
172 }  // end namespace chrono
173 
174 #endif
175