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 semi-trailing arm suspension (non-steerable). 16 // Derived from ChSuspension, but still an abstract base class. 17 // 18 // The suspension subsystem is modeled with respect to a right-handed frame, 19 // with X pointing towards the front, Y to the left, and Z up (ISO standard). 20 // The suspension reference frame is assumed to be always aligned with that of 21 // the vehicle. When attached to a chassis, only an offset is provided. 22 // 23 // All point locations are assumed to be given for the left half of the 24 // suspension and will be mirrored (reflecting the y coordinates) to construct 25 // the right side. 26 // 27 // ============================================================================= 28 29 #ifndef CH_SEMITRAILINGARM_H 30 #define CH_SEMITRAILINGARM_H 31 32 #include <vector> 33 34 #include "chrono_vehicle/ChApiVehicle.h" 35 #include "chrono_vehicle/wheeled_vehicle/ChSuspension.h" 36 37 namespace chrono { 38 namespace vehicle { 39 40 /// @addtogroup vehicle_wheeled_suspension 41 /// @{ 42 43 /// Base class for a semi-trailing arm suspension (non-steerable). 44 /// Derived from ChSuspension, but still an abstract base class. 45 /// 46 /// The suspension subsystem is modeled with respect to a right-handed frame, 47 /// with X pointing towards the front, Y to the left, and Z up (ISO standard). 48 /// The suspension reference frame is assumed to be always aligned with that of 49 /// the vehicle. When attached to a chassis, only an offset is provided. 50 /// 51 /// All point locations are assumed to be given for the left half of the 52 /// suspension and will be mirrored (reflecting the y coordinates) to construct 53 /// the right side. 54 class CH_VEHICLE_API ChSemiTrailingArm : public ChSuspension { 55 public: 56 ChSemiTrailingArm(const std::string& name ///< [in] name of the subsystem 57 ); 58 59 virtual ~ChSemiTrailingArm(); 60 61 /// Get the name of the vehicle subsystem template. GetTemplateName()62 virtual std::string GetTemplateName() const override { return "SemiTrailingArm"; } 63 64 /// Specify whether or not this suspension can be steered. IsSteerable()65 virtual bool IsSteerable() const final override { return false; } 66 67 /// Specify whether or not this is an independent suspension. IsIndependent()68 virtual bool IsIndependent() const final override { return true; } 69 70 /// Initialize this suspension subsystem. 71 /// The suspension subsystem is initialized by attaching it to the specified chassis and (if provided) to the 72 /// specified subchassis, at the specified location (with respect to and expressed in the reference frame of the 73 /// chassis). It is assumed that the suspension reference frame is always aligned with the chassis reference frame. 74 /// Since this suspension is non-steerable, the steering subsystem is always ignored. 75 virtual void Initialize( 76 std::shared_ptr<ChChassis> chassis, ///< [in] associated chassis subsystem 77 std::shared_ptr<ChSubchassis> subchassis, ///< [in] associated subchassis subsystem (may be null) 78 std::shared_ptr<ChSteering> steering, ///< [in] associated steering subsystem (may be null) 79 const ChVector<>& location, ///< [in] location relative to the chassis frame 80 double left_ang_vel = 0, ///< [in] initial angular velocity of left wheel 81 double right_ang_vel = 0 ///< [in] initial angular velocity of right wheel 82 ) override; 83 84 /// Add visualization assets for the suspension subsystem. 85 /// This default implementation uses primitives. 86 virtual void AddVisualizationAssets(VisualizationType vis) override; 87 88 /// Remove visualization assets for the suspension subsystem. 89 virtual void RemoveVisualizationAssets() override; 90 91 /// Get the total mass of the suspension subsystem. 92 virtual double GetMass() const override; 93 94 /// Get the current global COM location of the suspension subsystem. 95 virtual ChVector<> GetCOMPos() const override; 96 97 /// Get the wheel track for the suspension subsystem. 98 virtual double GetTrack() override; 99 100 /// Get a handle to the specified spring element. GetSpring(VehicleSide side)101 std::shared_ptr<ChLinkTSDA> GetSpring(VehicleSide side) const { return m_spring[side]; } 102 103 /// Get a handle to the specified shock (damper) element. GetShock(VehicleSide side)104 std::shared_ptr<ChLinkTSDA> GetShock(VehicleSide side) const { return m_shock[side]; } 105 106 /// Return current suspension forces (spring and shock) on the specified side. 107 virtual ChSuspension::Force ReportSuspensionForce(VehicleSide side) const override; 108 109 /// Get the force in the spring element. GetSpringForce(VehicleSide side)110 double GetSpringForce(VehicleSide side) const { return m_spring[side]->GetForce(); } 111 112 /// Get the current length of the spring element GetSpringLength(VehicleSide side)113 double GetSpringLength(VehicleSide side) const { return m_spring[side]->GetLength(); } 114 115 /// Get the current deformation of the spring element. GetSpringDeformation(VehicleSide side)116 double GetSpringDeformation(VehicleSide side) const { return m_spring[side]->GetDeformation(); } 117 118 /// Get the force in the shock (damper) element. GetShockForce(VehicleSide side)119 double GetShockForce(VehicleSide side) const { return m_shock[side]->GetForce(); } 120 121 /// Get the current length of the shock (damper) element. GetShockLength(VehicleSide side)122 double GetShockLength(VehicleSide side) const { return m_shock[side]->GetLength(); } 123 124 /// Get the current deformation velocity of the shock (damper) element. GetShockVelocity(VehicleSide side)125 double GetShockVelocity(VehicleSide side) const { return m_shock[side]->GetVelocity(); } 126 127 /// Log current constraint violations. 128 virtual void LogConstraintViolations(VehicleSide side) override; 129 130 /// Specify the suspension body on the specified side to attach a possible antirollbar subsystem. 131 /// Return the corresponding trailing arm. GetAntirollBody(VehicleSide side)132 virtual std::shared_ptr<ChBody> GetAntirollBody(VehicleSide side) const override { return m_arm[side]; } 133 134 /// Log the locations of all hardpoints. 135 /// The reported locations are expressed in the suspension reference frame. 136 /// By default, these values are reported in SI units (meters), but can be 137 /// optionally reported in inches. 138 void LogHardpointLocations(const ChVector<>& ref, bool inches = false); 139 140 protected: 141 /// Identifiers for the various hardpoints. 142 enum PointId { 143 SPINDLE, ///< spindle location (center of mass) 144 TA_CM, ///< trailing arm, center of mass 145 TA_O, ///< trailing arm, chassis connection outter 146 TA_I, ///< trailing arm, chassis connection inner 147 TA_S, ///< trailing arm, connection to spindle 148 SHOCK_C, ///< shock, chassis 149 SHOCK_A, ///< shock, lower control arm 150 SPRING_C, ///< spring, chassis 151 SPRING_A, ///< spring, lower control arm 152 NUM_POINTS 153 }; 154 155 /// Return the location of the specified hardpoint. 156 /// The returned location must be expressed in the suspension reference frame. 157 virtual const ChVector<> getLocation(PointId which) = 0; 158 159 /// Return the mass of the spindle body. 160 virtual double getSpindleMass() const = 0; 161 /// Return the mass of the trailing arm body. 162 virtual double getArmMass() const = 0; 163 164 /// Return the moments of inertia of the spindle body. 165 virtual const ChVector<>& getSpindleInertia() const = 0; 166 /// Return the moments of inertia of the trailing arm body. 167 virtual const ChVector<>& getArmInertia() const = 0; 168 169 /// Return the inertia of the axle shaft. 170 virtual double getAxleInertia() const = 0; 171 172 /// Return the radius of the trailing arm body (visualization only). 173 virtual double getArmRadius() const = 0; 174 175 /// Return the free (rest) length of the spring element. 176 virtual double getSpringRestLength() const = 0; 177 /// Return the functor object for spring force. 178 virtual std::shared_ptr<ChLinkTSDA::ForceFunctor> getSpringForceFunctor() const = 0; 179 /// Return the functor object for shock force. 180 virtual std::shared_ptr<ChLinkTSDA::ForceFunctor> getShockForceFunctor() const = 0; 181 182 /// Return stiffness and damping data for the arm bushing. 183 /// Returning nullptr (default) results in using a kinematic revolute joint. getCABushingData()184 virtual std::shared_ptr<ChVehicleBushingData> getCABushingData() const { return nullptr; } 185 186 std::shared_ptr<ChBody> m_arm[2]; ///< trailing arm bodies (left/right) 187 188 std::shared_ptr<ChVehicleJoint> m_revoluteArm[2]; ///< chassis-arm revolute joints (left/right) 189 190 std::shared_ptr<ChLinkTSDA> m_shock[2]; ///< spring links (left/right) 191 std::shared_ptr<ChLinkTSDA> m_spring[2]; ///< shock links (left/right) 192 193 private: 194 // Hardpoint absolute locations 195 std::vector<ChVector<>> m_pointsL; 196 std::vector<ChVector<>> m_pointsR; 197 198 void InitializeSide(VehicleSide side, 199 std::shared_ptr<ChChassis> chassis, 200 const std::vector<ChVector<>>& points, 201 double ang_vel); 202 203 static void AddVisualizationArm(std::shared_ptr<ChBody> arm, 204 const ChVector<> pt_AC_O, 205 const ChVector<> pt_AC_I, 206 const ChVector<> pt_AS, 207 const ChVector<> pt_S, 208 double radius); 209 210 virtual void ExportComponentList(rapidjson::Document& jsonDocument) const override; 211 212 virtual void Output(ChVehicleOutput& database) const override; 213 214 static const std::string m_pointNames[NUM_POINTS]; 215 }; 216 217 /// @} vehicle_wheeled_suspension 218 219 } // end namespace vehicle 220 } // end namespace chrono 221 222 #endif 223