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: Alessandro Tasora, Radu Serban 13 // ============================================================================= 14 15 #ifndef CHSHAFT_H 16 #define CHSHAFT_H 17 18 #include "chrono/physics/ChPhysicsItem.h" 19 #include "chrono/physics/ChLoadable.h" 20 #include "chrono/solver/ChVariablesShaft.h" 21 22 23 namespace chrono { 24 25 // Forward references (for parent hierarchy pointer) 26 class ChSystem; 27 28 /// Class for one-degree-of-freedom mechanical parts with associated 29 /// inertia (mass, or J moment of inertial for rotating parts). 30 /// In most cases these represent shafts that can be used to build 1D models 31 /// of power trains. This is more efficient than simulating power trains 32 /// modeled with full 3D ChBody objects. 33 34 class ChApi ChShaft : public ChPhysicsItem, public ChLoadable { 35 36 private: 37 double torque; ///< The torque acting on shaft (force, if used as linear DOF) 38 39 double pos; //< shaft angle 40 double pos_dt; //< shaft angular velocity 41 double pos_dtdt; //< shaft angular acceleration 42 43 double inertia; ///< shaft J moment of inertia (or mass, if used as linear DOF) 44 45 ChVariablesShaft variables; ///< used as an interface to the solver 46 47 float max_speed; ///< limit on linear speed 48 49 float sleep_time; 50 float sleep_minspeed; 51 float sleep_minwvel; 52 float sleep_starttime; 53 54 bool fixed; 55 bool limitspeed; 56 bool sleeping; 57 bool use_sleeping; 58 59 unsigned int id; ///< shaft id used for internal indexing 60 61 public: 62 ChShaft(); 63 ChShaft(const ChShaft& other); ~ChShaft()64 ~ChShaft() {} 65 66 /// "Virtual" copy constructor (covariant return type). Clone()67 virtual ChShaft* Clone() const override { return new ChShaft(*this); } 68 69 // 70 // FLAGS 71 // 72 73 /// Sets the 'fixed' state of the shaft. If true, it does not rotate 74 /// despite constraints, forces, etc. SetShaftFixed(bool mev)75 void SetShaftFixed(bool mev) { 76 fixed = mev; 77 variables.SetDisabled(mev); 78 } GetShaftFixed()79 bool GetShaftFixed() const { return fixed; } 80 /// Trick. Set the maximum shaft velocity (beyond this limit it will 81 /// be clamped). This is useful in virtual reality and real-time 82 /// simulations. 83 /// The realism is limited, but the simulation is more stable. SetLimitSpeed(bool mlimit)84 void SetLimitSpeed(bool mlimit) { limitspeed = mlimit; } GetLimitSpeed()85 bool GetLimitSpeed() const { return limitspeed; } 86 87 /// Trick. If use sleeping= true, shafts which do not rotate 88 /// for too long time will be deactivated, for optimization. 89 /// The realism is limited, but the simulation is faster. SetUseSleeping(bool ms)90 void SetUseSleeping(bool ms) { use_sleeping = ms; } GetUseSleeping()91 bool GetUseSleeping() const { return use_sleeping; } 92 93 /// Force the shaft in sleeping mode or not (usually this state change is not 94 /// handled by users, anyway, because it is mostly automatic). SetSleeping(bool ms)95 void SetSleeping(bool ms) { sleeping = ms; } 96 /// Tell if the shaft is actually in sleeping state. GetSleeping()97 bool GetSleeping() const { return sleeping; } 98 99 /// Put the shaft in sleeping state if requirements are satisfied. 100 bool TrySleeping(); 101 102 /// Tell if the body is active, i.e. it is neither fixed to ground nor 103 /// it is in sleep mode. IsActive()104 bool IsActive() const { return !(sleeping || fixed); } 105 106 // 107 // FUNCTIONS 108 // 109 110 /// Set the shaft id for indexing (only used internally) SetId(unsigned int identifier)111 void SetId(unsigned int identifier) { id = identifier; } 112 113 /// Get the shaft id for indexing (only used internally) GetId()114 unsigned int GetId() const { return id; } 115 116 /// Number of coordinates of the shaft GetDOF()117 virtual int GetDOF() override { return 1; } 118 119 /// Returns reference to the encapsulated ChVariables, Variables()120 ChVariablesShaft& Variables() { return variables; } 121 122 // 123 // STATE FUNCTIONS 124 // 125 126 // (override/implement interfaces for global state vectors, see ChPhysicsItem for comments.) 127 virtual void IntStateGather(const unsigned int off_x, 128 ChState& x, 129 const unsigned int off_v, 130 ChStateDelta& v, 131 double& T) override; 132 virtual void IntStateScatter(const unsigned int off_x, 133 const ChState& x, 134 const unsigned int off_v, 135 const ChStateDelta& v, 136 const double T, 137 bool full_update) override; 138 virtual void IntStateGatherAcceleration(const unsigned int off_a, ChStateDelta& a) override; 139 virtual void IntStateScatterAcceleration(const unsigned int off_a, const ChStateDelta& a) override; 140 virtual void IntLoadResidual_F(const unsigned int off, ChVectorDynamic<>& R, const double c) override; 141 virtual void IntLoadResidual_Mv(const unsigned int off, 142 ChVectorDynamic<>& R, 143 const ChVectorDynamic<>& w, 144 const double c) override; 145 virtual void IntToDescriptor(const unsigned int off_v, 146 const ChStateDelta& v, 147 const ChVectorDynamic<>& R, 148 const unsigned int off_L, 149 const ChVectorDynamic<>& L, 150 const ChVectorDynamic<>& Qc) override; 151 virtual void IntFromDescriptor(const unsigned int off_v, 152 ChStateDelta& v, 153 const unsigned int off_L, 154 ChVectorDynamic<>& L) override; 155 156 // 157 // SOLVER FUNCTIONS 158 // 159 160 // Override/implement system functions of ChPhysicsItem 161 // (to assemble/manage data for system solver) 162 163 /// Sets the 'fb' part of the encapsulated ChVariables to zero. 164 virtual void VariablesFbReset() override; 165 166 /// Adds the current torques in the 'fb' part: qf+=torques*factor 167 virtual void VariablesFbLoadForces(double factor = 1) override; 168 169 /// Initialize the 'qb' part of the ChVariables with the 170 /// current value of shaft speed. Note: since 'qb' is the unknown , this 171 /// function seems unnecessary, unless used before VariablesFbIncrementMq() 172 virtual void VariablesQbLoadSpeed() override; 173 174 /// Adds M*q (masses multiplied current 'qb') to Fb, ex. if qb is initialized 175 /// with v_old using VariablesQbLoadSpeed, this method can be used in 176 /// timestepping schemes that do: M*v_new = M*v_old + forces*dt 177 virtual void VariablesFbIncrementMq() override; 178 179 /// Fetches the shaft speed from the 'qb' part of the ChVariables (does not 180 /// updates the full shaft state) and sets it as the current shaft speed. 181 /// If 'step' is not 0, also computes the approximate acceleration of 182 /// the shaft using backward differences, that is accel=(new_speed-old_speed)/step. 183 virtual void VariablesQbSetSpeed(double step = 0) override; 184 185 /// Increment shaft position by the 'qb' part of the ChVariables, 186 /// multiplied by a 'step' factor. 187 /// pos+=qb*step 188 virtual void VariablesQbIncrementPosition(double step) override; 189 190 /// Tell to a system descriptor that there are variables of type 191 /// ChVariables in this object (for further passing it to a solver) 192 virtual void InjectVariables(ChSystemDescriptor& mdescriptor) override; 193 194 // 195 // INTERFACE to ChLoadable 196 // LoadableGet_ndof_x()197 virtual int LoadableGet_ndof_x() override { return 1; } LoadableGet_ndof_w()198 virtual int LoadableGet_ndof_w() override { return 1; } LoadableGetStateBlock_x(int block_offset,ChState & mD)199 virtual void LoadableGetStateBlock_x(int block_offset, ChState& mD) override { mD(block_offset) = this->GetPos(); } LoadableGetStateBlock_w(int block_offset,ChStateDelta & mD)200 virtual void LoadableGetStateBlock_w(int block_offset, ChStateDelta& mD) override { mD(block_offset) = this->GetPos_dt(); } LoadableStateIncrement(const unsigned int off_x,ChState & x_new,const ChState & x,const unsigned int off_v,const ChStateDelta & Dv)201 virtual void LoadableStateIncrement(const unsigned int off_x, 202 ChState& x_new, 203 const ChState& x, 204 const unsigned int off_v, 205 const ChStateDelta& Dv) override { x_new(off_x) = x(off_x) + Dv(off_v); } Get_field_ncoords()206 virtual int Get_field_ncoords() override { return 1; } GetSubBlocks()207 virtual int GetSubBlocks() override { return 1; } GetSubBlockOffset(int nblock)208 virtual unsigned int GetSubBlockOffset(int nblock) override { return this->GetOffset_w(); } GetSubBlockSize(int nblock)209 virtual unsigned int GetSubBlockSize(int nblock) override { return 1; } IsSubBlockActive(int nblock)210 virtual bool IsSubBlockActive(int nblock) const override { return true; } LoadableGetVariables(std::vector<ChVariables * > & mvars)211 virtual void LoadableGetVariables(std::vector<ChVariables*>& mvars) override { mvars.push_back(&this->Variables()); }; 212 213 214 // Other functions 215 216 /// Set no speed and no accelerations (but does not change the position) 217 void SetNoSpeedNoAcceleration() override; 218 219 /// Set the torque applied to the shaft SetAppliedTorque(double mtorque)220 void SetAppliedTorque(double mtorque) { torque = mtorque; } 221 /// Get the torque applied to the shaft GetAppliedTorque()222 double GetAppliedTorque() const { return torque; } 223 224 /// Set the angular position SetPos(double mp)225 void SetPos(double mp) { pos = mp; } 226 /// Get the angular position GetPos()227 double GetPos() const { return pos; } 228 229 /// Set the angular velocity SetPos_dt(double mp)230 void SetPos_dt(double mp) { pos_dt = mp; } 231 /// Get the angular velocity GetPos_dt()232 double GetPos_dt() const { return pos_dt; } 233 234 /// Set the angular acceleration SetPos_dtdt(double mp)235 void SetPos_dtdt(double mp) { pos_dtdt = mp; } 236 /// Get the angular acceleration GetPos_dtdt()237 double GetPos_dtdt() const { return pos_dtdt; } 238 239 /// Inertia of the shaft. Must be positive. 240 /// Try not to mix bodies with too high/too low values of mass, for numerical stability. 241 void SetInertia(double newJ); GetInertia()242 double GetInertia() const { return inertia; } 243 244 /// Trick. Set the maximum velocity (beyond this limit it will 245 /// be clamped). This is useful in virtual reality and real-time 246 /// simulations, to increase robustness at the cost of realism. 247 /// This limit is active only if you set SetLimitSpeed(true); SetMaxSpeed(float m_max_speed)248 void SetMaxSpeed(float m_max_speed) { max_speed = m_max_speed; } GetMaxSpeed()249 float GetMaxSpeed() const { return max_speed; } 250 251 /// When this function is called, the speed of the shaft is clamped 252 /// into limits posed by max_speed and max_wvel - but remember to 253 /// put the shaft in the SetLimitSpeed(true) mode. 254 void ClampSpeed(); 255 256 /// Set the amount of time which must pass before going automatically in 257 /// sleep mode when the shaft has very small movements. SetSleepTime(float m_t)258 void SetSleepTime(float m_t) { sleep_time = m_t; } GetSleepTime()259 float GetSleepTime() const { return sleep_time; } 260 261 /// Set the max linear speed to be kept for 'sleep_time' before freezing. SetSleepMinSpeed(float m_t)262 void SetSleepMinSpeed(float m_t) { sleep_minspeed = m_t; } GetSleepMinSpeed()263 float GetSleepMinSpeed() const { return sleep_minspeed; } 264 265 /// Set the max linear speed to be kept for 'sleep_time' before freezing. SetSleepMinWvel(float m_t)266 void SetSleepMinWvel(float m_t) { sleep_minwvel = m_t; } GetSleepMinWvel()267 float GetSleepMinWvel() const { return sleep_minwvel; } 268 269 // 270 // UPDATE FUNCTIONS 271 // 272 273 /// Update all auxiliary data of the shaft at given time 274 virtual void Update(double mytime, bool update_assets = true) override; 275 276 // 277 // SERIALIZATION 278 // 279 280 /// Method to allow serialization of transient data to archives. 281 virtual void ArchiveOUT(ChArchiveOut& marchive) override; 282 283 /// Method to allow deserialization of transient data from archives. 284 virtual void ArchiveIN(ChArchiveIn& marchive) override; 285 }; 286 287 CH_CLASS_VERSION(ChShaft,0) 288 289 290 } // end namespace chrono 291 292 #endif 293