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, Justin Madsen 13 // ============================================================================= 14 // 15 // Base class for all suspension subsystems 16 // 17 // ============================================================================= 18 19 #ifndef CH_SUSPENSION_H 20 #define CH_SUSPENSION_H 21 22 #include <string> 23 #include <vector> 24 25 #include "chrono/physics/ChSystem.h" 26 #include "chrono/physics/ChShaft.h" 27 #include "chrono/physics/ChShaftsBody.h" 28 #include "chrono/assets/ChCylinderShape.h" 29 30 #include "chrono_vehicle/ChApiVehicle.h" 31 #include "chrono_vehicle/ChChassis.h" 32 #include "chrono_vehicle/wheeled_vehicle/ChSubchassis.h" 33 #include "chrono_vehicle/wheeled_vehicle/ChSteering.h" 34 35 namespace chrono { 36 namespace vehicle { 37 38 /// @addtogroup vehicle_wheeled_suspension 39 /// @{ 40 41 /// Base class for a suspension subsystem. 42 class CH_VEHICLE_API ChSuspension : public ChPart { 43 public: 44 struct Force { 45 double spring_force; 46 double shock_force; 47 double spring_length; 48 double spring_velocity; 49 double shock_length; 50 double shock_velocity; 51 }; 52 53 ChSuspension(const std::string& name); 54 55 virtual ~ChSuspension(); 56 57 /// Specify whether or not this suspension can be steered. 58 virtual bool IsSteerable() const = 0; 59 60 /// Specify whether or not this is an independent suspension. 61 virtual bool IsIndependent() const = 0; 62 63 /// Get the location of the suspension subsystem relative to the chassis reference frame. 64 /// The suspension reference frame is always aligned with the chassis reference frame. GetLocation()65 const ChVector<>& GetLocation() const { return m_location; } 66 67 /// Get a handle to the spindle body on the specified side. GetSpindle(VehicleSide side)68 std::shared_ptr<ChBody> GetSpindle(VehicleSide side) const { return m_spindle[side]; } 69 70 /// Get a handle to the axle shaft on the specified side. GetAxle(VehicleSide side)71 std::shared_ptr<ChShaft> GetAxle(VehicleSide side) const { return m_axle[side]; } 72 73 /// Get a handle to the revolute joint on the specified side. GetRevolute(VehicleSide side)74 std::shared_ptr<ChLinkLockRevolute> GetRevolute(VehicleSide side) const { return m_revolute[side]; } 75 76 /// Get the global location of the spindle on the specified side. GetSpindlePos(VehicleSide side)77 const ChVector<>& GetSpindlePos(VehicleSide side) const { return m_spindle[side]->GetPos(); } 78 79 /// Get the orientation of the spindle body on the specified side. 80 /// The spindle body orientation is returned as a quaternion representing a 81 /// rotation with respect to the global reference frame. 82 ChQuaternion<> GetSpindleRot(VehicleSide side) const; 83 84 /// Get the linear velocity of the spindle body on the specified side. 85 /// Return the linear velocity of the spindle center, expressed in the global 86 /// reference frame. GetSpindleLinVel(VehicleSide side)87 const ChVector<>& GetSpindleLinVel(VehicleSide side) const { return m_spindle[side]->GetPos_dt(); } 88 89 /// Get the angular velocity of the spindle body on the specified side. 90 /// Return the angular velocity of the spindle frame, expressed in the global 91 /// reference frame. GetSpindleAngVel(VehicleSide side)92 ChVector<> GetSpindleAngVel(VehicleSide side) const { return m_spindle[side]->GetWvel_par(); } 93 94 /// Get the angular speed of the axle on the specified side. GetAxleSpeed(VehicleSide side)95 double GetAxleSpeed(VehicleSide side) const { return m_axle[side]->GetPos_dt(); } 96 97 /// Synchronize this suspension subsystem. 98 /// This function must be called before synchronizing any wheels associated with this suspension. 99 void Synchronize(); 100 101 /// Apply the provided motor torque. 102 /// The given torque is applied to the specified (left or right) axle. This 103 /// function provides the interface to the drivetrain subsystem (intermediated 104 /// by the vehicle system). 105 void ApplyAxleTorque(VehicleSide side, ///< indicates the axle (left or right) where the torque should be applied 106 double torque ///< value of applied torque 107 ); 108 109 /// Initialize this suspension subsystem. 110 /// The suspension subsystem is initialized by attaching it to the specified chassis and (if provided) to the 111 /// specified subchassis, at the specified location (with respect to and expressed in the reference frame of the 112 /// chassis). It is assumed that the suspension reference frame is always aligned with the chassis reference frame. 113 /// If a steering subsystem is provided, the suspension tierods are to be attached to the steering's central link 114 /// body (steered suspension); otherwise they are to be attached to the chassis (non-steered suspension). 115 virtual void Initialize( 116 std::shared_ptr<ChChassis> chassis, ///< [in] associated chassis subsystem 117 std::shared_ptr<ChSubchassis> subchassis, ///< [in] associated subchassis subsystem (may be null) 118 std::shared_ptr<ChSteering> steering, ///< [in] associated steering subsystem (may be null) 119 const ChVector<>& location, ///< [in] location relative to the chassis frame 120 double left_ang_vel = 0, ///< [in] initial angular velocity of left wheel 121 double right_ang_vel = 0 ///< [in] initial angular velocity of right wheel 122 ) = 0; 123 124 /// Return the radius of the spindle body (visualization only). 125 virtual double getSpindleRadius() const = 0; 126 127 /// Return the width of the spindle body (visualization only). 128 virtual double getSpindleWidth() const = 0; 129 130 /// Add visualization assets for the suspension subsystem. 131 /// This default implementation uses primitives for spindle visualization. 132 virtual void AddVisualizationAssets(VisualizationType vis) override; 133 134 /// Remove visualization assets for the suspension subsystem. 135 virtual void RemoveVisualizationAssets() override; 136 137 /// Specify the suspension body on the specified side to attach a possible antirollbar subsystem. 138 /// The default implementation returns a NULL pointer. GetAntirollBody(VehicleSide side)139 virtual std::shared_ptr<ChBody> GetAntirollBody(VehicleSide side) const { return nullptr; } 140 141 /// Specify the body on the specified side for a possible connection to brake subsystem. 142 /// The default implementation returns a NULL pointer (indicating that a brake should connect to the chassis). GetBrakeBody(VehicleSide side)143 virtual std::shared_ptr<ChBody> GetBrakeBody(VehicleSide side) const { return nullptr; } 144 145 /// Get the total mass of the suspension subsystem. 146 virtual double GetMass() const = 0; 147 148 /// Get the current global COM location of the suspension subsystem. 149 virtual ChVector<> GetCOMPos() const = 0; 150 151 /// Get the wheel track for the suspension subsystem. 152 virtual double GetTrack() = 0; 153 154 /// Return current suspension forces (spring and shock) on the specified side. 155 /// Different derived types (suspension templates) may load different quantities in the output struct. 156 virtual Force ReportSuspensionForce(VehicleSide side) const = 0; 157 158 /// Log current constraint violations. LogConstraintViolations(VehicleSide side)159 virtual void LogConstraintViolations(VehicleSide side) {} 160 161 /// Simple model of a parking brake. 162 void ApplyParkingBrake(bool brake); 163 164 protected: 165 ChVector<> m_location; ///< location relative to chassis 166 std::shared_ptr<ChBody> m_spindle[2]; ///< handles to spindle bodies 167 std::shared_ptr<ChShaft> m_axle[2]; ///< handles to axle shafts 168 std::shared_ptr<ChShaftsBody> m_axle_to_spindle[2]; ///< handles to spindle-shaft connectors 169 std::shared_ptr<ChLinkLockRevolute> m_revolute[2]; ///< handles to spindle revolute joints 170 171 private: 172 std::shared_ptr<ChCylinderShape> m_spindle_shapes[2]; 173 174 void AddVisualizationSpindle(VehicleSide side, double radius, double width); 175 }; 176 177 /// Vector of handles to suspension subsystems. 178 typedef std::vector<std::shared_ptr<ChSuspension> > ChSuspensionList; 179 180 /// @} vehicle_wheeled_suspension 181 182 } // end namespace vehicle 183 } // end namespace chrono 184 185 #endif 186