1 // =============================================================================
2 // PROJECT CHRONO - http://projectchrono.org
3 //
4 // Copyright (c) 2021 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 // Wrapper for a vehicle joint (kinematic or bushing)
16 //
17 // =============================================================================
18 
19 #ifndef CH_VEHICLE_JOINT_H
20 #define CH_VEHICLE_JOINT_H
21 
22 #include "chrono_vehicle/ChApiVehicle.h"
23 #include "chrono/physics/ChBody.h"
24 #include "chrono/physics/ChLink.h"
25 #include "chrono/physics/ChLoadsBody.h"
26 
27 #include "chrono_thirdparty/variant/variant.hpp"
28 
29 namespace chrono {
30 namespace vehicle {
31 
32 /// @addtogroup vehicle
33 /// @{
34 
35 /// Stiffness and damping data for a vehicle bushing specification.
36 /// Attention! The Chrono bushing formulation is valid only for small relative rotations. As such, define a non-zero
37 /// rotational stiffness in a "DOF" direction only if the kinematics of the modeled mechanism prevent any large relative
38 /// rotations. For rotational stiffness in the presence of large rotations, use a ChLinkRSDA element.
39 struct ChVehicleBushingData {
ChVehicleBushingDataChVehicleBushingData40     ChVehicleBushingData()
41         : K_lin(0), K_rot(0), D_lin(0), D_rot(0), K_lin_dof(0), K_rot_dof(0), D_lin_dof(0), D_rot_dof(0) {}
42 
43     double K_lin;  ///< translational stiffness in "constrained" directions
44     double K_rot;  ///< rotational stiffness in "constrained" directions
45     double D_lin;  ///< translational damping in "constrained" directions
46     double D_rot;  ///< rotational damping in "constraint" directions
47 
48     double K_lin_dof;  ///< translational stiffness in "DOF" directions
49     double K_rot_dof;  ///< rotational stiffness in "DOF" directions
50     double D_lin_dof;  ///< translational damping in "DOF" directions
51     double D_rot_dof;  ///< rotational damping in "DOF" directions
52 };
53 
54 /// Wrapper class for a joint in a vehicle system which can be either a kinematic joint or a bushing.
55 class CH_VEHICLE_API ChVehicleJoint {
56   public:
57     /// Supported types of vehicle joint.
58     /// For a kinematic joint, the wrapped element will be a ChLink of the appropriate type. For a bushing, the
59     /// stiffness and damping in the appropriate directions (as defined by the DOFs of the joint type) are set to a
60     /// different value (typically 0).
61     enum class Type { LOCK, SPHERICAL, REVOLUTE, UNIVERSAL, POINTLINE, POINTPLANE };
62 
63     typedef std::shared_ptr<ChLink> Link;
64     typedef std::shared_ptr<ChLoadBodyBodyBushingGeneric> Bushing;
65 
66     /// Construct a vehicle joint wrapper of the specified type, with the given name, connecting the specified bodies at
67     /// the given position (expressed in the absolute reference frame).  If no bushing data is provided (default), a
68     /// kinematic joint is created; otherwise, this function creates a bushing. Note that the constructed element is not
69     /// included in the simulation; for that, pass the joint to the ChChassis::AddJoint function which adds the joint to
70     /// its appropriate container (the containing Chrono system for a kinematic joint or a load container managed by the
71     /// chassis subsystem for a bushing).
72     ChVehicleJoint(Type type,
73                    const std::string& name,
74                    std::shared_ptr<ChBody> body1,
75                    std::shared_ptr<ChBody> body2,
76                    ChCoordsys<> pos,
77                    std::shared_ptr<ChVehicleBushingData> bushing_data = nullptr);
78 
79     ~ChVehicleJoint();
80 
81     /// Get the current absolute position of the joint. This is the current absolute location of the underling marker on
82     /// the 2nd connected body.
83     ChVector<> GetPos() const;
84 
85     /// Get the current constraint violation. This will return an empty vector for a bushing element.
86     ChVectorDynamic<> GetConstraintViolation() const;
87 
88     /// Return true if wrapping a kinematic joint and false if wrapping a bushing.
89     bool IsKinematic() const;
90 
91     /// Get the underlying kinematic joint.
92     /// A null pointer is returned if the vehicle joint is in fact a bushing.
93     Link GetAsLink() const;
94 
95     /// Get the underlying bushing.
96     /// A null pointer is returned if the vehicle joint is in fact a kinematic joint.
97     Bushing GetAsBushing() const;
98 
99   private:
100     void CreateLink(Type type, std::shared_ptr<ChBody> body1, std::shared_ptr<ChBody> body2, ChCoordsys<> pos);
101     void CreateBushing(Type type,
102                        std::shared_ptr<ChBody> body1,
103                        std::shared_ptr<ChBody> body2,
104                        ChCoordsys<> pos,
105                        std::shared_ptr<ChVehicleBushingData> bd);
106 
107     mpark::variant<Link, Bushing> m_joint;
108 
109     friend class ChChassis;
110 };
111 
112 /// @} vehicle
113 
114 }  // namespace vehicle
115 }  // namespace chrono
116 
117 #endif
118