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 // Various utility classes for vehicle subsystems.
16 //
17 // =============================================================================
18 
19 #ifndef CH_SUBSYS_DEFS_H
20 #define CH_SUBSYS_DEFS_H
21 
22 #include <string>
23 #include <vector>
24 
25 #include "chrono/core/ChQuaternion.h"
26 #include "chrono/core/ChVector.h"
27 #include "chrono/physics/ChBodyAuxRef.h"
28 #include "chrono/physics/ChMaterialSurface.h"
29 #include "chrono/physics/ChLinkRotSpringCB.h"
30 #include "chrono/physics/ChLinkTSDA.h"
31 #include "chrono/assets/ChColor.h"
32 
33 #include "chrono_vehicle/ChApiVehicle.h"
34 
35 namespace chrono {
36 namespace vehicle {
37 
38 /// @addtogroup vehicle
39 /// @{
40 
41 // -----------------------------------------------------------------------------
42 // Utility classes and structures for data exchange
43 // -----------------------------------------------------------------------------
44 
45 /// Enum for the side (left/right) of a vehicle.
46 enum VehicleSide {
47     LEFT = 0,  ///< left side of vehicle is always 0
48     RIGHT = 1  ///< right side of vehicle is always 1
49 };
50 
51 /// Enum for wheel location on spindle.
52 enum WheelLocation {
53     SINGLE = 0,  ///< wheel on one side of a single-wheel axle
54     INNER = 1,   ///< inner wheel on one side of a double-wheel axle
55     OUTER = 2    ///< outer wheel on one side of a double-wheel axle
56 };
57 
58 /// Structure to communicate a full body state.
59 struct BodyState {
60     ChVector<> pos;      ///< global position
61     ChQuaternion<> rot;  ///< orientation with respect to global frame
62     ChVector<> lin_vel;  ///< linear velocity, expressed in the global frame
63     ChVector<> ang_vel;  ///< angular velocity, expressed in the global frame
64 };
65 
66 /// Vector of body state structures
67 typedef std::vector<BodyState> BodyStates;
68 
69 /// Structure to communicate a full wheel body state.
70 /// In addition to the quantities communicated for a generic body, the wheel
71 /// state also includes the wheel angular speed about its axis of rotation.
72 struct WheelState {
73     ChVector<> pos;      ///< global position
74     ChQuaternion<> rot;  ///< orientation with respect to global frame
75     ChVector<> lin_vel;  ///< linear velocity, expressed in the global frame
76     ChVector<> ang_vel;  ///< angular velocity, expressed in the global frame
77     double omega;        ///< wheel angular speed about its rotation axis
78 };
79 
80 /// Vector of wheel state structures
81 typedef std::vector<WheelState> WheelStates;
82 
83 /// Structure to communicate a set of generalized terrain contact forces (tire or track shoe).
84 struct TerrainForce {
85     ChVector<> force;   ///< force vector, epxressed in the global frame
86     ChVector<> point;   ///< global location of the force application point
87     ChVector<> moment;  ///< moment vector, expressed in the global frame
88 };
89 
90 /// Vector of terrain conatct force structures.
91 typedef std::vector<TerrainForce> TerrainForces;
92 
93 // -----------------------------------------------------------------------------
94 // Utility functor classes for force elements
95 // -----------------------------------------------------------------------------
96 
97 /// Utility class for specifying a linear translational spring force.
98 class LinearSpringForce : public ChLinkTSDA::ForceFunctor {
99   public:
LinearSpringForce(double k)100     LinearSpringForce(double k) : m_k(k) {}
operator()101     virtual double operator()(double time, double rest_length, double length, double vel, ChLinkTSDA* link) override {
102         return -m_k * (length - rest_length);
103     }
104 
105   private:
106     double m_k;
107 };
108 
109 /// Utility class for specifying a linear translational damper force.
110 class LinearDamperForce : public ChLinkTSDA::ForceFunctor {
111   public:
LinearDamperForce(double c)112     LinearDamperForce(double c) : m_c(c) {}
operator()113     virtual double operator()(double time, double rest_length, double length, double vel, ChLinkTSDA* link) override {
114         return -m_c * vel;
115     }
116 
117   private:
118     double m_c;
119 };
120 
121 /// Utility class for specifying a linear translational spring-damper force.
122 class LinearSpringDamperForce : public ChLinkTSDA::ForceFunctor {
123   public:
LinearSpringDamperForce(double k,double c)124     LinearSpringDamperForce(double k, double c) : m_k(k), m_c(c) {}
operator()125     virtual double operator()(double time, double rest_length, double length, double vel, ChLinkTSDA* link) override {
126         return -m_k * (length - rest_length) - m_c * vel;
127     }
128 
129   private:
130     double m_k;
131     double m_c;
132 };
133 
134 /// Utility class for specifying a linear translational spring-damper force with pre-tension.
135 class LinearSpringDamperActuatorForce : public ChLinkTSDA::ForceFunctor {
136   public:
LinearSpringDamperActuatorForce(double k,double c,double f)137     LinearSpringDamperActuatorForce(double k, double c, double f) : m_k(k), m_c(c), m_f(f) {}
operator()138     virtual double operator()(double time, double rest_length, double length, double vel, ChLinkTSDA* link) override {
139         return m_f - m_k * (length - rest_length) - m_c * vel;
140     }
141 
142   private:
143     double m_k;
144     double m_c;
145     double m_f;
146 };
147 
148 /// Utility class for specifying a map translational spring force.
149 class MapSpringForce : public ChLinkTSDA::ForceFunctor {
150   public:
MapSpringForce()151     MapSpringForce() {}
MapSpringForce(const std::vector<std::pair<double,double>> & data)152     MapSpringForce(const std::vector<std::pair<double, double>>& data) {
153         for (unsigned int i = 0; i < data.size(); ++i) {
154             m_map.AddPoint(data[i].first, data[i].second);
155         }
156     }
add_point(double x,double y)157     void add_point(double x, double y) { m_map.AddPoint(x, y); }
operator()158     virtual double operator()(double time, double rest_length, double length, double vel, ChLinkTSDA* link) override {
159         return -m_map.Get_y(length - rest_length);
160     }
161 
162   private:
163     ChFunction_Recorder m_map;
164 };
165 
166 /// Utility class for specifying a map translational spring force with bump and rebound stop.
167 class MapSpringBistopForce : public ChLinkTSDA::ForceFunctor {
168   public:
MapSpringBistopForce(double spring_min_length,double spring_max_length)169     MapSpringBistopForce(double spring_min_length, double spring_max_length)
170         : m_min_length(spring_min_length), m_max_length(spring_max_length) {
171         setup_stop_maps();
172     }
MapSpringBistopForce(const std::vector<std::pair<double,double>> & data,double spring_min_length,double spring_max_length)173     MapSpringBistopForce(const std::vector<std::pair<double, double>>& data,
174                          double spring_min_length,
175                          double spring_max_length)
176         : m_min_length(spring_min_length), m_max_length(spring_max_length) {
177         setup_stop_maps();
178         for (unsigned int i = 0; i < data.size(); ++i) {
179             m_map.AddPoint(data[i].first, data[i].second);
180         }
181     }
add_point(double x,double y)182     void add_point(double x, double y) { m_map.AddPoint(x, y); }
operator()183     virtual double operator()(double time, double rest_length, double length, double vel, ChLinkTSDA* link) override {
184         double defl_bump = 0.0;
185         double defl_rebound = 0.0;
186 
187         if (length < m_min_length) {
188             defl_bump = m_min_length - length;
189         }
190 
191         if (length > m_max_length) {
192             defl_rebound = length - m_max_length;
193         }
194 
195         return -m_map.Get_y(length - rest_length) + m_bump.Get_y(defl_bump) - m_rebound.Get_y(defl_rebound);
196     }
197 
198   private:
setup_stop_maps()199     void setup_stop_maps() {
200         m_bump.AddPoint(0.0, 0.0);
201         m_bump.AddPoint(2.0e-3, 200.0);
202         m_bump.AddPoint(4.0e-3, 400.0);
203         m_bump.AddPoint(6.0e-3, 600.0);
204         m_bump.AddPoint(8.0e-3, 800.0);
205         m_bump.AddPoint(10.0e-3, 1000.0);
206         m_bump.AddPoint(20.0e-3, 2500.0);
207         m_bump.AddPoint(30.0e-3, 4500.0);
208         m_bump.AddPoint(40.0e-3, 7500.0);
209         m_bump.AddPoint(50.0e-3, 12500.0);
210         m_bump.AddPoint(60.0e-3, 125000.0);
211 
212         m_rebound.AddPoint(0.0, 0.0);
213         m_rebound.AddPoint(2.0e-3, 200.0);
214         m_rebound.AddPoint(4.0e-3, 400.0);
215         m_rebound.AddPoint(6.0e-3, 600.0);
216         m_rebound.AddPoint(8.0e-3, 800.0);
217         m_rebound.AddPoint(10.0e-3, 1000.0);
218         m_rebound.AddPoint(20.0e-3, 2500.0);
219         m_rebound.AddPoint(30.0e-3, 4500.0);
220         m_rebound.AddPoint(40.0e-3, 7500.0);
221         m_rebound.AddPoint(50.0e-3, 12500.0);
222         m_rebound.AddPoint(60.0e-3, 125000.0);
223     }
224     ChFunction_Recorder m_map;
225     ChFunction_Recorder m_bump;
226     ChFunction_Recorder m_rebound;
227     double m_min_length;
228     double m_max_length;
229 };
230 
231 /// Utility class for specifying a linear translational spring force with bump and rebound stop.
232 class LinearSpringBistopForce : public ChLinkTSDA::ForceFunctor {
233   public:
234     /// Use default bump stop and rebound stop maps
LinearSpringBistopForce(double k,double min_length,double max_length)235     LinearSpringBistopForce(double k, double min_length, double max_length)
236         : m_k(k), m_min_length(min_length), m_max_length(max_length) {
237         // From ADAMS/Car example
238         m_bump.AddPoint(0.0, 0.0);
239         m_bump.AddPoint(2.0e-3, 200.0);
240         m_bump.AddPoint(4.0e-3, 400.0);
241         m_bump.AddPoint(6.0e-3, 600.0);
242         m_bump.AddPoint(8.0e-3, 800.0);
243         m_bump.AddPoint(10.0e-3, 1000.0);
244         m_bump.AddPoint(20.0e-3, 2500.0);
245         m_bump.AddPoint(30.0e-3, 4500.0);
246         m_bump.AddPoint(40.0e-3, 7500.0);
247         m_bump.AddPoint(50.0e-3, 12500.0);
248         m_bump.AddPoint(60.0e-3, 125000.0);
249 
250         m_rebound.AddPoint(0.0, 0.0);
251         m_rebound.AddPoint(2.0e-3, 200.0);
252         m_rebound.AddPoint(4.0e-3, 400.0);
253         m_rebound.AddPoint(6.0e-3, 600.0);
254         m_rebound.AddPoint(8.0e-3, 800.0);
255         m_rebound.AddPoint(10.0e-3, 1000.0);
256         m_rebound.AddPoint(20.0e-3, 2500.0);
257         m_rebound.AddPoint(30.0e-3, 4500.0);
258         m_rebound.AddPoint(40.0e-3, 7500.0);
259         m_rebound.AddPoint(50.0e-3, 12500.0);
260         m_rebound.AddPoint(60.0e-3, 125000.0);
261     }
262 
operator()263     virtual double operator()(double time, double rest_length, double length, double vel, ChLinkTSDA* link) override {
264         double force = 0;
265 
266         double defl_spring = rest_length - length;
267         double defl_bump = 0.0;
268         double defl_rebound = 0.0;
269 
270         if (length < m_min_length) {
271             defl_bump = m_min_length - length;
272         }
273 
274         if (length > m_max_length) {
275             defl_rebound = length - m_max_length;
276         }
277 
278         force = defl_spring * m_k + m_bump.Get_y(defl_bump) - m_rebound.Get_y(defl_rebound);
279 
280         return force;
281     }
282 
283   private:
284     double m_k;
285     double m_min_length;
286     double m_max_length;
287 
288     ChFunction_Recorder m_bump;
289     ChFunction_Recorder m_rebound;
290 };
291 
292 /// Utility class for specifying a degressive translational damper force.
293 class DegressiveDamperForce : public ChLinkTSDA::ForceFunctor {
294   public:
295     /// Fallback to LinearDamperForce
DegressiveDamperForce(double c_compression)296     DegressiveDamperForce(double c_compression)
297         : m_c_compression(c_compression), m_c_expansion(c_compression), m_degr_compression(0), m_degr_expansion(0) {}
298 
299     /// Fallback to LinearDamperForce with different compression and expansion bins
DegressiveDamperForce(double c_compression,double c_expansion)300     DegressiveDamperForce(double c_compression, double c_expansion)
301         : m_c_compression(c_compression), m_c_expansion(c_expansion), m_degr_compression(0), m_degr_expansion(0) {}
302 
303     /// Different compression and expansion degressivity, same damper coefficient at origin
DegressiveDamperForce(double c_compression,double degr_compression,double degr_expansion)304     DegressiveDamperForce(double c_compression, double degr_compression, double degr_expansion)
305         : m_c_compression(c_compression),
306           m_c_expansion(c_compression),
307           m_degr_compression(degr_compression),
308           m_degr_expansion(degr_expansion) {}
309 
310     /// Full parametrization
DegressiveDamperForce(double c_compression,double degr_compression,double c_expansion,double degr_expansion)311     DegressiveDamperForce(double c_compression, double degr_compression, double c_expansion, double degr_expansion)
312         : m_c_compression(c_compression),
313           m_c_expansion(c_expansion),
314           m_degr_compression(degr_compression),
315           m_degr_expansion(degr_expansion) {}
316 
operator()317     virtual double operator()(double time, double rest_length, double length, double vel, ChLinkTSDA* link) override {
318         if (vel >= 0) {
319             return -m_c_expansion * vel / (1.0 + m_degr_expansion * vel);
320         } else {
321             return -m_c_compression * vel / (1.0 - m_degr_compression * vel);
322         }
323     }
324 
325   private:
326     double m_c_compression;
327     double m_c_expansion;
328     double m_degr_compression;
329     double m_degr_expansion;
330 };
331 
332 /// Utility class for specifying a map translational damper force.
333 class MapDamperForce : public ChLinkTSDA::ForceFunctor {
334   public:
MapDamperForce()335     MapDamperForce() {}
MapDamperForce(const std::vector<std::pair<double,double>> & data)336     MapDamperForce(const std::vector<std::pair<double, double>>& data) {
337         for (unsigned int i = 0; i < data.size(); ++i) {
338             m_map.AddPoint(data[i].first, data[i].second);
339         }
340     }
add_point(double x,double y)341     void add_point(double x, double y) { m_map.AddPoint(x, y); }
operator()342     virtual double operator()(double time, double rest_length, double length, double vel, ChLinkTSDA* link) override {
343         return -m_map.Get_y(vel);
344     }
345 
346   private:
347     ChFunction_Recorder m_map;
348 };
349 
350 /// Utility class for specifying a map translational spring-damper force with pre-tension.
351 class MapSpringDamperActuatorForce : public ChLinkTSDA::ForceFunctor {
352   public:
MapSpringDamperActuatorForce()353     MapSpringDamperActuatorForce() {}
MapSpringDamperActuatorForce(const std::vector<std::pair<double,double>> & dataK,const std::vector<std::pair<double,double>> & dataC,double f)354     MapSpringDamperActuatorForce(const std::vector<std::pair<double, double>>& dataK,
355                                  const std::vector<std::pair<double, double>>& dataC,
356                                  double f) {
357         for (unsigned int i = 0; i < dataK.size(); ++i) {
358             m_mapK.AddPoint(dataK[i].first, dataK[i].second);
359         }
360         for (unsigned int i = 0; i < dataC.size(); ++i) {
361             m_mapC.AddPoint(dataC[i].first, dataC[i].second);
362         }
363     }
add_pointK(double x,double y)364     void add_pointK(double x, double y) { m_mapK.AddPoint(x, y); }
add_pointC(double x,double y)365     void add_pointC(double x, double y) { m_mapC.AddPoint(x, y); }
set_f(double f)366     void set_f(double f) { m_f = f; }
operator()367     virtual double operator()(double time, double rest_length, double length, double vel, ChLinkTSDA* link) override {
368         return m_f - m_mapK.Get_y(length - rest_length) - m_mapC.Get_y(vel);
369     }
370 
371   private:
372     ChFunction_Recorder m_mapK;
373     ChFunction_Recorder m_mapC;
374     double m_f;
375 };
376 
377 /// Utility class for specifying a linear rotational spring torque.
378 class LinearSpringTorque : public ChLinkRotSpringCB::TorqueFunctor {
379   public:
m_k(k)380     LinearSpringTorque(double k, double rest_angle = 0) : m_k(k), m_rest_angle(rest_angle) {}
operator()381     virtual double operator()(double time, double angle, double vel, ChLinkRotSpringCB* link) override {
382         return -m_k * (angle - m_rest_angle);
383     }
384 
385   private:
386     double m_k;
387     double m_rest_angle;
388 };
389 
390 /// Utility class for specifying a linear rotational damper torque.
391 class LinearDamperTorque : public ChLinkRotSpringCB::TorqueFunctor {
392   public:
LinearDamperTorque(double c)393     LinearDamperTorque(double c) : m_c(c) {}
operator()394     virtual double operator()(double time, double angle, double vel, ChLinkRotSpringCB* link) override {
395         return -m_c * vel;
396     }
397 
398   private:
399     double m_c;
400 };
401 
402 /// Utility class for specifying a linear rotational spring-damper torque.
403 class LinearSpringDamperTorque : public ChLinkRotSpringCB::TorqueFunctor {
404   public:
m_k(k)405     LinearSpringDamperTorque(double k, double c, double rest_angle = 0) : m_k(k), m_c(c), m_rest_angle(rest_angle) {}
operator()406     virtual double operator()(double time, double angle, double vel, ChLinkRotSpringCB* link) override {
407         return -m_k * (angle - m_rest_angle) - m_c * vel;
408     }
409 
410   private:
411     double m_k;
412     double m_c;
413     double m_rest_angle;
414 };
415 
416 /// Utility class for specifying a linear rotational spring-damper torque with pre-tension.
417 class LinearSpringDamperActuatorTorque : public ChLinkRotSpringCB::TorqueFunctor {
418   public:
419     LinearSpringDamperActuatorTorque(double k, double c, double t, double rest_angle = 0)
m_k(k)420         : m_k(k), m_c(c), m_t(t), m_rest_angle(rest_angle) {}
operator()421     virtual double operator()(double time, double angle, double vel, ChLinkRotSpringCB* link) override {
422         return m_t - m_k * (angle - m_rest_angle) - m_c * vel;
423     }
424 
425   private:
426     double m_k;
427     double m_c;
428     double m_t;
429     double m_rest_angle;
430 };
431 
432 /// Utility class for specifying a map rotational spring torque.
433 class MapSpringTorque : public ChLinkRotSpringCB::TorqueFunctor {
434   public:
MapSpringTorque()435     MapSpringTorque() {}
436     MapSpringTorque(const std::vector<std::pair<double, double>>& data, double rest_angle = 0)
m_rest_angle(rest_angle)437         : m_rest_angle(rest_angle) {
438         for (unsigned int i = 0; i < data.size(); ++i) {
439             m_map.AddPoint(data[i].first, data[i].second);
440         }
441     }
add_point(double x,double y)442     void add_point(double x, double y) { m_map.AddPoint(x, y); }
operator()443     virtual double operator()(double time, double angle, double vel, ChLinkRotSpringCB* link) override {
444         return -m_map.Get_y(angle - m_rest_angle);
445     }
446 
447   private:
448     ChFunction_Recorder m_map;
449     double m_rest_angle;
450 };
451 
452 /// Utility class for specifying a map rotational damper torque.
453 class MapDamperTorque : public ChLinkRotSpringCB::TorqueFunctor {
454   public:
MapDamperTorque()455     MapDamperTorque() {}
MapDamperTorque(const std::vector<std::pair<double,double>> & data)456     MapDamperTorque(const std::vector<std::pair<double, double>>& data) {
457         for (unsigned int i = 0; i < data.size(); ++i) {
458             m_map.AddPoint(data[i].first, data[i].second);
459         }
460     }
add_point(double x,double y)461     void add_point(double x, double y) { m_map.AddPoint(x, y); }
operator()462     virtual double operator()(double time, double angle, double vel, ChLinkRotSpringCB* link) override {
463         return -m_map.Get_y(vel);
464     }
465 
466   private:
467     ChFunction_Recorder m_map;
468 };
469 
470 // -----------------------------------------------------------------------------
471 // Enums and flags for wheeled and tracked vehicles
472 // -----------------------------------------------------------------------------
473 
474 /// Enum for visualization types.
475 enum class VisualizationType {
476     NONE,        ///< no visualization
477     PRIMITIVES,  ///< use primitve shapes
478     MESH         ///< use meshes
479 };
480 
481 /// Enum for available tire models.
482 enum class TireModelType {
483     RIGID,       ///< rigid tire (cylindrical)
484     RIGID_MESH,  ///< rigid tire (mesh)
485     PACEJKA,     ///< Pacejka (magic formula) tire
486     LUGRE,       ///< Lugre frition model tire
487     FIALA,       ///< Fiala tire
488     ANCF,        ///< ANCF shell element-based tire
489     REISSNER,    ///< Reissner 6-field shell element-based tire
490     FEA,         ///< FEA co-rotational tire
491     PAC89,       ///< Pacejka 89 (magic formula) tire
492     TMEASY,      ///< Tire Model Made Easy tire (G. Rill)
493     PAC02        ///< Pacejka 02 (magic formula) tire, redesign of PACEJKA
494 };
495 
496 /// Enum for available powertrain model templates.
497 enum class PowertrainModelType {
498     SHAFTS,      ///< powertrain based on ChShaft elements
499     SIMPLE_MAP,  ///< simple powertrain model (based on engine-map)
500     SIMPLE,      ///< simple powertrain model (similar to a DC motor)
501     SIMPLE_CVT   ///< simple cvt powertrain model (like a DC motor / CVT gearbox)
502 };
503 
504 /// Enum for available wheeled-vehicle suspension model templates.
505 enum class SuspensionTypeWV {
506     DOUBLE_WISHBONE,                  ///< double wishbone
507     DOUBLE_WISHBONE_REDUCED,          ///< simplified double wishbone (constraint-based)
508     HENDRICKSON_PRIMAXX,              ///< Hendrickson PRIMAXX (walking beam)
509     LEAF_SPRING_AXLE,                 ///< leaf-spring solid axle
510     SAE_LEAF_SPRING_AXLE,             ///< leaf-spring solid axle with kinematic leaf-spring model
511     MACPHERSON_STRUT,                 ///< MacPherson strut
512     MULTI_LINK,                       ///< multi-link
513     RIGID_PINNED,                     ///< pinned rigid beam
514     RIGID_SUSPENSION,                 ///< rigid suspension
515     SEMI_TRAILING_ARM,                ///< semi trailing arm
516     SOLID_AXLE,                       ///< solid axle
517     SOLID_THREE_LINK_AXLE,            ///< rigid suspension + 3 guiding links
518     SOLID_BELLCRANK_THREE_LINK_AXLE,  ///< rigid suspension + 3 guiding linls + bellcrank steering mechanism
519     THREE_LINK_IRS,                   ///< three-link independent rear suspension
520     TOE_BAR_LEAF_SPRING_AXLE,         ///< steerable leaf-spring solid axle
521     SAE_TOE_BAR_LEAF_SPRING_AXLE      ///< steerable leaf-spring solid axle with kinematic leaf-spring model
522 };
523 
524 /// Enum for available brake model templates.
525 enum class BrakeType {
526     SHAFTS,  ///< brake model using a clutch between two shafts
527     SIMPLE   ///< brake model using a simple speed-dependent torque
528 };
529 
530 /// Enum for available wheeled-vehicle steering model templates.
531 enum class SteeringTypeWV {
532     PITMAN_ARM,         ///< Pitman arm (input to revolute joint)
533     PITMAN_ARM_SHAFTS,  ///< Pitman arm with compliant column (input to steering wheel)
534     RACK_PINION         ///< rack-pinion (input to pinion)
535 };
536 
537 /// Enum for wheeled-vehicle driveline types.
538 enum class DrivelineTypeWV {
539     FWD,        ///< front-wheel drive
540     RWD,        ///< rear-wheel drive
541     AWD,        ///< all-wheel drive (4x4)
542     AWD6,       ///< all-wheel drive (6x4 / 6x6 locked)
543     AWD8,       ///< all-wheel drive (8x8)
544     SIMPLE,     ///< simple kinematic driveline
545     SIMPLE_XWD  ///< simple kinematic driveline for more than 2 axles
546 };
547 
548 /// Enum for tracked-vehicle driveline types.
549 enum class DrivelineTypeTV {
550     BDS,    ///< braked differential steering
551     SIMPLE  ///< simple kinematic driveline
552 };
553 
554 /// Enumerations for wheeled vehicle collision families.
555 namespace WheeledCollisionFamily {
556 // Note: we cannot use strongly typed enums, since these are passed as integers
557 enum Enum {
558     CHASSIS = 0,  ///< chassis collision family
559     TIRES = 1     ///< collision family for tire systems
560 };
561 }  // namespace WheeledCollisionFamily
562 
563 /// Enum for track shoe types.
564 enum class TrackShoeType {
565     SINGLE_PIN,    ///< single-pin track shoe and sprocket
566     DOUBLE_PIN,    ///< double-pin track shoe and sprocket
567     BAND_BUSHING,  ///< rigid tooth-rigid web continuous band track shoe and sprocket
568     BAND_ANCF      ///< rigid tooth-ANCF web continuous band track shoe and sprocket
569 };
570 
571 /// Enum for guide pin (track shoe/roadwheel/idler).
572 enum class GuidePinType {
573     CENTRAL_PIN,  ///< track shoes with central guiding pin and double wheels
574     LATERAL_PIN   ///< track shoes with lateral guiding pins and single wheels
575 };
576 
577 /// Enumerations for track collision flags.
578 namespace TrackedCollisionFlag {
579 // Note: we cannot use strongly typed enums since these are used as integers
580 enum Enum {
581     NONE = 0,
582     CHASSIS = 1 << 0,
583     SPROCKET_LEFT = 1 << 1,
584     SPROCKET_RIGHT = 1 << 2,
585     IDLER_LEFT = 1 << 3,
586     IDLER_RIGHT = 1 << 4,
587     WHEELS_LEFT = 1 << 5,
588     WHEELS_RIGHT = 1 << 6,
589     SHOES_LEFT = 1 << 7,
590     SHOES_RIGHT = 1 << 8,
591     ROLLERS_LEFT = 1 << 9,
592     ROLLERS_RIGHT = 1 << 10,
593     ALL = 0xFFFF
594 };
595 }  // namespace TrackedCollisionFlag
596 
597 /// Enumerations for tracked vehicle collision families.
598 namespace TrackedCollisionFamily {
599 // Note: we cannot use strongly typed enums, since these are passed as integers
600 enum Enum {
601     CHASSIS = 0,  ///< chassis collision family
602     IDLERS = 1,   ///< collision family for idler subsystems
603     WHEELS = 2,   ///< collision family for road-wheel assemblies
604     ROLLERS = 3,  ///< collision family for roller subsystems
605     SHOES = 4     ///< collision family for track shoe subsystems
606 };
607 }  // namespace TrackedCollisionFamily
608 
609 /// Flags for output (log/debug).
610 /// These flags can be bit-wise ORed and used as a mask.
611 enum OutputInformation {
612     OUT_SPRINGS = 1 << 0,      ///< suspension spring information
613     OUT_SHOCKS = 1 << 1,       ///< suspension shock information
614     OUT_CONSTRAINTS = 1 << 2,  ///< constraint violation information
615     OUT_TESTRIG = 1 << 3       ///< test-rig specific information
616 };
617 
618 /// Identifiers for specific component bodies.
619 enum BodyID {
620     CHASSIS_BODY = -99990,
621     SPROCKET_BODY = -99991,
622     IDLER_BODY = -99992,
623     WHEEL_BODY = -99993,
624     ROLER_BODY = -99994,
625     SHOE_BODY = -99995
626 };
627 
628 // -----------------------------------------------------------------------------
629 // Class defining geometry (visualization and collision) and contact materials.
630 // -----------------------------------------------------------------------------
631 
632 /// Utility class defining geometry (visualization and collision) and contact materials for a rigid vehicle body.
633 /// Holds vectors of primitive shapes (any one of which may be empty) and a list of contact materials.
634 /// Each shape defines its position and orientation relative to the parent body, geometric dimensions, and an index into
635 /// the list of contact materials.
636 class CH_VEHICLE_API ChVehicleGeometry {
637   public:
638     ChVehicleGeometry();
639 
640     /// Box shape for visualization and/or collision.
641     struct BoxShape {
642         BoxShape(const ChVector<>& pos, const ChQuaternion<>& rot, const ChVector<>& dims, int matID = -1)
m_posBoxShape643             : m_pos(pos), m_rot(rot), m_dims(dims), m_matID(matID) {}
644         ChVector<> m_pos;      ///< position relative to body
645         ChQuaternion<> m_rot;  ///< orientation relative to body
646         ChVector<> m_dims;     ///< box dimensions
647         int m_matID;           ///< index in contact material list
648     };
649 
650     /// Sphere shape for visualization and/or collision.
651     struct SphereShape {
652         SphereShape(const ChVector<>& pos, double radius, int matID = -1)
m_posSphereShape653             : m_pos(pos), m_radius(radius), m_matID(matID) {}
654         ChVector<> m_pos;  ///< position relative to body
655         double m_radius;   ///< sphere radius
656         int m_matID;       ///< index in contact material list
657     };
658 
659     /// Cylinder shape for visualization and/or collision.
660     struct CylinderShape {
661         CylinderShape(const ChVector<>& pos, const ChQuaternion<>& rot, double radius, double length, int matID = -1)
m_posCylinderShape662             : m_pos(pos), m_rot(rot), m_radius(radius), m_length(length), m_matID(matID) {}
663         ChVector<> m_pos;      ///< position relative to body
664         ChQuaternion<> m_rot;  ///< orientation relative to body
665         double m_radius;       ///< cylinder radius
666         double m_length;       ///< cylinder length
667         int m_matID;           ///< index in contact material list
668     };
669 
670     /// Convex hulls shape for collision.
671     struct ConvexHullsShape {
m_filenameConvexHullsShape672         ConvexHullsShape(const std::string& filename, int matID = -1) : m_filename(filename), m_matID(matID) {}
673         std::string m_filename;  ///< name of Wavefront OBJ file
674         int m_matID;             ///< index in contact material list
675     };
676 
677     /// Tri-mesh shape for collision.
678     struct TrimeshShape {
679         TrimeshShape(const ChVector<>& pos, const std::string& filename, double radius, int matID = -1)
m_filenameTrimeshShape680             : m_filename(filename), m_radius(radius), m_pos(pos), m_matID(matID) {}
681         std::string m_filename;  ///< name of Wavefront OBJ file
682         double m_radius;         ///< radius of sweeping sphere
683         ChVector<> m_pos;        ///< position relative to body
684         int m_matID;             ///< index in contact material list
685     };
686 
687     bool m_has_collision;                                         ///< true if body has a collision model
688     std::vector<std::shared_ptr<ChMaterialSurface>> m_materials;  ///< list of contact materials
689     std::vector<BoxShape> m_coll_boxes;                           ///< list of collision boxes
690     std::vector<SphereShape> m_coll_spheres;                      ///< list of collision spheres
691     std::vector<CylinderShape> m_coll_cylinders;                  ///< list of collision cylinders
692     std::vector<ConvexHullsShape> m_coll_hulls;                   ///< list of collision convex hulls
693     std::vector<TrimeshShape> m_coll_meshes;                      ///< list of collision trimeshes
694 
695     bool m_has_primitives;                       ///< true if the body uses visualization primitives
696     std::vector<BoxShape> m_vis_boxes;           ///< list of visualization boxes
697     std::vector<SphereShape> m_vis_spheres;      ///< list of visualization spheres
698     std::vector<CylinderShape> m_vis_cylinders;  ///< list of visualization cylinders
699 
700     bool m_has_colors;          ///< true if primitive colors were provided
701     ChColor m_color_boxes;      ///< visualization color
702     ChColor m_color_spheres;    ///< visualization color
703     ChColor m_color_cylinders;  ///< visualization color
704 
705     bool m_has_mesh;              ///< true if the body uses a visualization mesh
706     std::string m_vis_mesh_file;  ///< name of Wavefront OBJ file with visualizaiton mesh
707 
708     /// Create visualization assets for the specified body.
709     void AddVisualizationAssets(std::shared_ptr<ChBody> body, VisualizationType vis);
710 
711     /// Create collision shapes for the specified body.
712     void AddCollisionShapes(std::shared_ptr<ChBody> body, int collision_family);
713 };
714 
715 /// @} vehicle
716 
717 }  // end namespace vehicle
718 }  // end namespace chrono
719 
720 #endif
721