1 // =============================================================================
2 // PROJECT CHRONO - http://projectchrono.org
3 //
4 // Copyright (c) 2014 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
13 // =============================================================================
14 //
15 // Base class for a deformable tire (i.e. modeled with an FEA mesh)
16 //
17 // =============================================================================
18 
19 #ifndef CH_DEFORMABLETIRE_H
20 #define CH_DEFORMABLETIRE_H
21 
22 #include "chrono/physics/ChBody.h"
23 #include "chrono/physics/ChLoadContainer.h"
24 #include "chrono/physics/ChSystemSMC.h"
25 #include "chrono/physics/ChLinkMate.h"
26 
27 #include "chrono/fea/ChContactSurfaceMesh.h"
28 #include "chrono/fea/ChContactSurfaceNodeCloud.h"
29 #include "chrono/fea/ChLinkDirFrame.h"
30 #include "chrono/fea/ChLinkPointFrame.h"
31 #include "chrono/fea/ChMesh.h"
32 #include "chrono/fea/ChNodeFEAbase.h"
33 #include "chrono/fea/ChVisualizationFEAmesh.h"
34 
35 #include "chrono_vehicle/wheeled_vehicle/ChTire.h"
36 
37 namespace chrono {
38 namespace vehicle {
39 
40 /// @addtogroup vehicle_wheeled_tire
41 /// @{
42 
43 /// Base class for a deformable tire model.
44 class CH_VEHICLE_API ChDeformableTire : public ChTire {
45   public:
46     /// Type of the mesh contact surface.
47     enum class ContactSurfaceType { NODE_CLOUD, TRIANGLE_MESH };
48 
49     /// Construct a deformable tire with the specified name.
50     ChDeformableTire(const std::string& name);
51 
52     virtual ~ChDeformableTire();
53 
54     /// Set the type of contact surface.
SetContactSurfaceType(ContactSurfaceType type)55     void SetContactSurfaceType(ContactSurfaceType type) { m_contact_type = type; }
GetContactSurfaceType()56     ContactSurfaceType GetContactSurfaceType() const { return m_contact_type; }
57 
58     /// Set radius of contact nodes.
59     /// This value is relevant only for NODE_CLOUD contact surface type.
SetContactNodeRadius(double radius)60     void SetContactNodeRadius(double radius) { m_contact_node_radius = radius; }
GetContactNodeRadius()61     double GetContactNodeRadius() const { return m_contact_node_radius; }
62 
63     /// Set thickness of contact faces (radius of swept sphere).
64     /// This value is relevant only for TRIANGLE_MESH contact surface type.
SetContactFaceThickness(double thickness)65     void SetContactFaceThickness(double thickness) { m_contact_face_thickness = thickness; }
GetContactFaceThickness()66     double GetContactFaceThickness() const { return m_contact_face_thickness; }
67 
68     /// Get the tire contact material.
69     /// Note that this is not set until after tire initialization.
GetContactMaterial()70     std::shared_ptr<ChMaterialSurfaceSMC> GetContactMaterial() const { return m_contact_mat; }
71 
72     /// Enable/disable tire pressure (default: true).
EnablePressure(bool val)73     void EnablePressure(bool val) { m_pressure_enabled = val; }
IsPressureEnabled()74     bool IsPressureEnabled() const { return m_pressure_enabled; }
75 
76     /// Enable/disable tire contact (default: true).
EnableContact(bool val)77     void EnableContact(bool val) { m_contact_enabled = val; }
IsContactEnabled()78     bool IsContactEnabled() const { return m_contact_enabled; }
79 
80     /// Enable/disable tire-rim connection (default: true).
EnableRimConnection(bool val)81     void EnableRimConnection(bool val) { m_connection_enabled = val; }
IsRimConnectionEnabled()82     bool IsRimConnectionEnabled() const { return m_connection_enabled; }
83 
84     /// Get a handle to the mesh visualization.
GetMeshVisualization()85     fea::ChVisualizationFEAmesh* GetMeshVisualization() const { return m_visualization.get(); }
86 
87     /// Get the underlying FEA mesh.
GetMesh()88     std::shared_ptr<fea::ChMesh> GetMesh() const { return m_mesh; }
89 
90     /// Get the mesh contact surface.
91     /// If contact is not enabled, an empty shared pointer is returned.
92     std::shared_ptr<fea::ChContactSurface> GetContactSurface() const;
93 
94     /// Get the load container associated with this tire.
GetLoadContainer()95     std::shared_ptr<ChLoadContainer> GetLoadContainer() const { return m_load_container; }
96 
97     /// Set the tire pressure.
SetPressure(double pressure)98     void SetPressure(double pressure) {
99         assert(m_pressure > 0);
100         m_pressure = pressure;
101     }
102 
103     /// Get the rim radius (inner tire radius).
104     virtual double GetRimRadius() const = 0;
105 
106     /// Calculate and return the tire mass.
107     /// The return value is the mass of the underlying FEA mesh.
108     double GetTireMass() const;
109 
110     /// Report the tire mass.
ReportMass()111     virtual double ReportMass() const override { return GetTireMass(); }
112 
113     /// Report the tire force and moment.
114     /// This generalized force encapsulates the tire-terrain forces, as well as the weight
115     /// of the tire itself and is calculated as the resultant of all reaction forces and
116     /// torques in the tire-wheel connections, as applied at the wheel body center of mass.
117     /// The force and moment are expressed in the global frame.
118     virtual TerrainForce ReportTireForce(ChTerrain* terrain) const override;
119 
120     /// Add visualization assets for the rigid tire subsystem.
121     virtual void AddVisualizationAssets(VisualizationType vis) override final;
122 
123     /// Remove visualization assets for the rigid tire subsystem.
124     virtual void RemoveVisualizationAssets() override final;
125 
126   protected:
127     /// Return the default tire pressure.
128     virtual double GetDefaultPressure() const = 0;
129 
130     /// Return list of nodes connected to the rim.
131     virtual std::vector<std::shared_ptr<fea::ChNodeFEAbase>> GetConnectedNodes() const = 0;
132 
133     /// Create the FEA nodes and elements.
134     /// The wheel rotational axis is assumed to be the Y axis.
135     virtual void CreateMesh(const ChFrameMoving<>& wheel_frame,  ///< [in] frame of associated wheel
136                             VehicleSide side                     ///< [in] left/right vehicle side
137                             ) = 0;
138 
139     /// Create the ChLoad for applying pressure to the tire.
140     /// A derived class must create a load and add it to the underlying load container.
141     virtual void CreatePressureLoad() = 0;
142 
143     /// Create the contact surface for the tire mesh.
144     /// A derived class must create a contact surface and add it to the underlying mesh.
145     virtual void CreateContactSurface() = 0;
146 
147     /// Create the tire-rim connections.
148     /// A derived class must create the various constraints between the tire and the
149     /// provided wheel body and add them to the underlying system.
150     virtual void CreateRimConnections(std::shared_ptr<ChBody> wheel  ///< [in] associated wheel body
151                                       ) = 0;
152 
153     /// Create the SMC contact material.
154     virtual void CreateContactMaterial() = 0;
155 
156     std::shared_ptr<fea::ChMesh> m_mesh;                                ///< tire mesh
157     std::shared_ptr<ChLoadContainer> m_load_container;                  ///< load container (for pressure load)
158     std::vector<std::shared_ptr<fea::ChLinkPointFrame>> m_connections;  ///< tire-wheel point connections
159     std::vector<std::shared_ptr<fea::ChLinkDirFrame>> m_connectionsD;   ///< tire-wheel direction connections
160     std::vector<std::shared_ptr<ChLinkMateFix>> m_connectionsF;         ///< tire-wheel fix connection (point+rotation)
161 
162     bool m_connection_enabled;  ///< enable tire connections to rim
163     bool m_pressure_enabled;    ///< enable internal tire pressure
164     bool m_contact_enabled;     ///< enable tire-terrain contact
165 
166     double m_pressure;  ///< internal tire pressure
167 
168     ContactSurfaceType m_contact_type;  ///< type of contact surface model (node cloud or mesh)
169     double m_contact_node_radius;       ///< node radius (for node cloud contact surface)
170     double m_contact_face_thickness;    ///< face thickness (for mesh contact surface)
171 
172     std::shared_ptr<ChMaterialSurfaceSMC> m_contact_mat;           ///< tire contact material
173     std::shared_ptr<fea::ChVisualizationFEAmesh> m_visualization;  ///< tire mesh visualization
174 
175   //private:
176     // The following two functions are marked as final.
177     // The mass properties of a deformable tire are implicitly included through
178     // the FEA mesh.  To prevent double counting the mass and inertia of a
179     // deformable tire, these functions must always return 0.
GetMass()180     virtual double GetMass() const final { return 0; }
GetInertia()181     virtual ChVector<> GetInertia() const final { return ChVector<>(0, 0, 0); }
182 
183     /// Initialize this tire by associating it to the specified wheel.
184     virtual void Initialize(std::shared_ptr<ChWheel> wheel) override;
185 
186     /// Get the tire force and moment.
187     /// A ChDeformableTire always returns zero forces and moments since tire forces
188     /// are implicitly applied to the associated wheel through the tire-wheel connections.
189     virtual TerrainForce GetTireForce() const override;
190 };
191 
192 /// @} vehicle_wheeled_tire
193 
194 }  // end namespace vehicle
195 }  // end namespace chrono
196 
197 #endif
198