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 // This file contains a number of ready-to-use loads (ChLoad inherited classes and 16 // their embedded ChLoader classes) that can be applied to objects of ChBody (and 17 // inherited classes) type. 18 // These are 'simplified' tools, that save you from inheriting your custom loads. 19 // Or just look at these classes and learn how to implement some special type of load. 20 // 21 // Example: 22 // std::shared_ptr<ChBodyEasyBox> body_test(new ChBodyEasyBox(8,4,4,1000)); 23 // mphysicalSystem.Add(body_test); 24 // 25 // std::shared_ptr<ChLoadContainer> mforcecontainer (new ChLoadContainer); 26 // mphysicalSystem.Add(mforcecontainer); 27 // 28 // std::shared_ptr<ChLoadBodyForce> mforce (new ChLoadBodyForce(body_test, ChVector<>(0,80000,0), false, 29 // ChVector<>(8,0,0),true)); mforcecontainer->Add(mforce); 30 // 31 // std::shared_ptr<ChLoadBodyTorque> mtorque (new ChLoadBodyTorque(body_test, ChVector<>(0,0,-80000*8), true)); 32 // mforcecontainer->Add(mtorque); 33 // 34 // ============================================================================= 35 36 #ifndef CHLOADSBODY_H 37 #define CHLOADSBODY_H 38 39 #include "chrono/motion_functions/ChFunction.h" 40 #include "chrono/physics/ChBody.h" 41 #include "chrono/physics/ChLoad.h" 42 43 namespace chrono { 44 45 /// Load representing a concentrated force acting on a rigid body. 46 /// The force can rotate together with the body (if in body local coordinates) or not. 47 /// The application point can follow the body (if in body local coordinates) or not. 48 /// The magnitude of the applied force can be optionally modulated by a function of time. 49 /// The default modulation is the constant function with value 1. 50 class ChApi ChLoadBodyForce : public ChLoadCustom { 51 public: 52 ChLoadBodyForce(std::shared_ptr<ChBody> body, ///< object to apply load to 53 const ChVector<>& force, ///< force to apply 54 bool local_force, ///< force is in body local coords 55 const ChVector<>& point, ///< application point for the force 56 bool local_point = true ///< application point is in body local coords 57 ); 58 59 /// "Virtual" copy constructor (covariant return type). Clone()60 virtual ChLoadBodyForce* Clone() const override { return new ChLoadBodyForce(*this); } 61 62 /// Set the constant force vector. 63 /// It can be expressed in absolute coordinates or body local coordinates. 64 /// This value is optionally modulated by a function of time. 65 void SetForce(const ChVector<>& force, bool is_local); 66 67 /// Return the current force vector (scaled by the current modulation value). 68 ChVector<> GetForce() const; 69 70 /// Set the application point of force, assumed to be constant. 71 /// It can be expressed in absolute coordinates or body local coordinates 72 void SetApplicationPoint(const ChVector<>& point, const bool is_local); 73 74 /// Return the location of the application point. GetApplicationPoint()75 ChVector<> GetApplicationPoint() const { return m_point; } 76 77 /// Set modulation function. 78 /// This is a function of time which (optionally) modulates the specified applied force. 79 /// By default the modulation is a constant function, always returning a value of 1. SetModulationFunction(std::shared_ptr<ChFunction> modulation)80 void SetModulationFunction(std::shared_ptr<ChFunction> modulation) { m_modulation = modulation; } 81 82 /// Compute Q, the generalized load. 83 /// Called automatically at each Update(). 84 virtual void ComputeQ(ChState* state_x, ///< state position to evaluate Q 85 ChStateDelta* state_w ///< state speed to evaluate Q 86 ) override; 87 88 private: 89 ChVector<> m_force; ///< base force value 90 ChVector<> m_point; ///< application point 91 bool m_local_force; ///< is force expressed in local frame? 92 bool m_local_point; ///< is application expressed in local frame? 93 94 std::shared_ptr<ChFunction> m_modulation; ///< modulation function of time 95 double m_scale; ///< scaling factor (current modulation value) 96 IsStiff()97 virtual bool IsStiff() override { return false; } 98 99 virtual void Update(double time) override; 100 }; 101 102 //------------------------------------------------------------------------------------------------ 103 104 /// Load representing a torque applied to a rigid body. 105 /// Torque direction does not rotate with the body. 106 /// The magnitude of the applied torque can be optionally modulated by a function of time. 107 /// The default modulation is the constant function with value 1. 108 class ChApi ChLoadBodyTorque : public ChLoadCustom { 109 public: 110 ChLoadBodyTorque(std::shared_ptr<ChBody> body, ///< object to apply load to 111 const ChVector<>& torque, ///< torque to apply 112 bool local_torque ///< torque is in body local coords 113 ); 114 115 /// "Virtual" copy constructor (covariant return type). Clone()116 virtual ChLoadBodyTorque* Clone() const override { return new ChLoadBodyTorque(*this); } 117 118 /// Set the constant torque vector. 119 /// This value is optionally modulated by a function of time. 120 void SetTorque(const ChVector<>& torque, bool is_local); 121 122 /// Return the current torque vector (scaled by the current modulation value). 123 ChVector<> GetTorque() const; 124 125 /// Set modulation function. 126 /// This is a function of time which (optionally) modulates the specified applied force. 127 /// By default the modulation is a constant function, always returning a value of 1. SetModulationFunction(std::shared_ptr<ChFunction> modulation)128 void SetModulationFunction(std::shared_ptr<ChFunction> modulation) { m_modulation = modulation; } 129 130 /// Compute Q, the generalized load. 131 /// Called automatically at each Update(). 132 virtual void ComputeQ(ChState* state_x, ///< state position to evaluate Q 133 ChStateDelta* state_w ///< state speed to evaluate Q 134 ) override; 135 136 private: 137 ChVector<> m_torque; ///< base torque value 138 bool m_local_torque; ///< is torque expressed in local frame? 139 140 std::shared_ptr<ChFunction> m_modulation; ///< modulation function of time 141 double m_scale; ///< scaling factor (current modulation value) 142 IsStiff()143 virtual bool IsStiff() override { return false; } 144 145 virtual void Update(double time) override; 146 }; 147 148 //------------------------------------------------------------------------------------------------ 149 150 /// Base class for wrench loads (a force + a torque) acting between two bodies. 151 /// See children classes for concrete implementations. 152 class ChApi ChLoadBodyBody : public ChLoadCustomMultiple { 153 public: 154 ChLoadBodyBody(std::shared_ptr<ChBody> bodyA, ///< body A 155 std::shared_ptr<ChBody> bodyB, ///< body B 156 const ChFrame<>& abs_application ///< location of load element (in abs. coordinates) 157 ); 158 159 /// Compute the force between the two bodies, in local reference loc_application_B, 160 /// given rel_AB, i.e. the position and speed of loc_application_A respect to loc_application_B. 161 /// Force is assumed applied to loc_application_B of body B, and its opposite reaction to A. 162 /// Inherited classes MUST IMPLEMENT THIS. 163 virtual void ComputeBodyBodyForceTorque(const ChFrameMoving<>& rel_AB, 164 ChVector<>& loc_force, 165 ChVector<>& loc_torque) = 0; 166 167 // Optional: inherited classes could implement this to avoid the 168 // default numerical computation of jacobians: 169 // virtual void ComputeJacobian(...) // see ChLoad 170 171 /// For diagnosis purposes, this can return the actual last computed value of 172 /// the applied force, expressed in coordinate system of loc_application_B, assumed applied to body B GetForce()173 ChVector<> GetForce() const { return locB_force; } 174 175 /// For diagnosis purposes, this can return the actual last computed value of 176 /// the applied torque, expressed in coordinate system of loc_application_B, assumed applied to body B GetTorque()177 ChVector<> GetTorque() const { return locB_torque; } 178 179 /// Set the application frame of bushing on bodyA SetApplicationFrameA(const ChFrame<> & mpA)180 void SetApplicationFrameA(const ChFrame<>& mpA) { loc_application_A = mpA; } GetApplicationFrameA()181 ChFrame<> GetApplicationFrameA() const { return loc_application_A; } 182 183 /// Set the application frame of bushing on bodyB SetApplicationFrameB(const ChFrame<> & mpB)184 void SetApplicationFrameB(const ChFrame<>& mpB) { loc_application_B = mpB; } GetApplicationFrameB()185 ChFrame<> GetApplicationFrameB() const { return loc_application_B; } 186 187 /// Get absolute coordinate of frame A (last computed) GetAbsoluteFrameA()188 ChFrameMoving<> GetAbsoluteFrameA() const { return frame_Aw; } 189 190 /// Get absolute coordinate of frame B (last computed) GetAbsoluteFrameB()191 ChFrameMoving<> GetAbsoluteFrameB() const { return frame_Bw; } 192 193 std::shared_ptr<ChBody> GetBodyA() const; 194 std::shared_ptr<ChBody> GetBodyB() const; 195 196 protected: 197 ChFrame<> loc_application_A; ///< application point on body A (local) 198 ChFrame<> loc_application_B; ///< application point on body B (local) 199 ChVector<> locB_force; ///< store computed values here 200 ChVector<> locB_torque; ///< store computed values here 201 ChFrameMoving<> frame_Aw; ///< for results 202 ChFrameMoving<> frame_Bw; ///< for results 203 204 /// Compute Q, the generalized load. It calls ComputeBodyBodyForceTorque, so in 205 /// children classes you do not need to implement it. 206 /// Called automatically at each Update(). 207 virtual void ComputeQ(ChState* state_x, ///< state position to evaluate Q 208 ChStateDelta* state_w ///< state speed to evaluate Q 209 ) override; 210 }; 211 212 //------------------------------------------------------------------------------------------------ 213 214 /// Load representing a torque applied between two bodies. 215 /// The magnitude of the applied torque can be optionally modulated by a function of time. 216 /// The default modulation is the constant function with value 1. 217 class ChApi ChLoadBodyBodyTorque : public ChLoadBodyBody { 218 public: 219 ChLoadBodyBodyTorque(std::shared_ptr<ChBody> bodyA, ///< first body 220 std::shared_ptr<ChBody> bodyB, ///< second body 221 const ChVector<> torque, ///< applied torque 222 bool local_torque ///< torque is in bodyB local coords 223 ); 224 225 /// "Virtual" copy constructor (covariant return type). Clone()226 virtual ChLoadBodyBodyTorque* Clone() const override { return new ChLoadBodyBodyTorque(*this); } 227 228 /// Set modulation function. 229 /// This is a function of time which (optionally) modulates the specified applied torque. 230 /// By default the modulation is a constant function, always returning a value of 1. SetModulationFunction(std::shared_ptr<ChFunction> modulation)231 void SetModulationFunction(std::shared_ptr<ChFunction> modulation) { m_modulation = modulation; } 232 233 private: 234 ChVector<> m_torque; ///< base torque value 235 bool m_local_torque; ///< is torque expressed in local frame (bodyB)? 236 237 std::shared_ptr<ChFunction> m_modulation; ///< modulation function of time 238 double m_scale; ///< scaling factor (current modulation value) 239 IsStiff()240 virtual bool IsStiff() override { return false; } 241 242 virtual void Update(double time) override; 243 244 /// Implement the computation of the body-body force, in local 245 /// coordinates of the loc_application_B. 246 /// Force is assumed applied to loc_application_B of body B, and its opposite reaction to A. 247 virtual void ComputeBodyBodyForceTorque(const ChFrameMoving<>& rel_AB, 248 ChVector<>& loc_force, 249 ChVector<>& loc_torque) override; 250 }; 251 252 //------------------------------------------------------------------------------------------------ 253 254 /// Load for a visco-elastic bushing acting between two bodies. 255 /// It uses three values for stiffness along the X Y Z axes of a coordinate system attached 256 /// to the second body. This is equivalent to having a bushing with 3x3 diagonal local stiffness matrix. 257 class ChApi ChLoadBodyBodyBushingSpherical : public ChLoadBodyBody { 258 public: 259 ChLoadBodyBodyBushingSpherical( 260 std::shared_ptr<ChBody> mbodyA, ///< body A 261 std::shared_ptr<ChBody> mbodyB, ///< body B 262 const ChFrame<>& abs_application, ///< bushing location, in abs. coordinates. 263 const ChVector<>& mstiffness, ///< stiffness, along x y z axes of the abs_application 264 const ChVector<>& mdamping ///< damping, along x y z axes of the abs_application 265 ); 266 267 /// "Virtual" copy constructor (covariant return type). Clone()268 virtual ChLoadBodyBodyBushingSpherical* Clone() const override { return new ChLoadBodyBodyBushingSpherical(*this); } 269 270 /// Set stiffness, along the x y z axes of loc_application_B, es [N/m] SetStiffness(const ChVector<> mstiffness)271 void SetStiffness(const ChVector<> mstiffness) { stiffness = mstiffness; } GetStiffness()272 ChVector<> GetStiffness() const { return stiffness; } 273 274 /// Set damping, along the x y z axes of loc_application_B, es [Ns/m] SetDamping(const ChVector<> mdamping)275 void SetDamping(const ChVector<> mdamping) { damping = mdamping; } GetDamping()276 ChVector<> GetDamping() const { return damping; } 277 278 protected: 279 ChVector<> stiffness; 280 ChVector<> damping; 281 IsStiff()282 virtual bool IsStiff() override { return true; } 283 284 /// Implement the computation of the bushing force, in local 285 /// coordinates of the loc_application_B. 286 /// Force is assumed applied to loc_application_B of body B, and its opposite reaction to A. 287 virtual void ComputeBodyBodyForceTorque(const ChFrameMoving<>& rel_AB, 288 ChVector<>& loc_force, 289 ChVector<>& loc_torque) override; 290 }; 291 292 //------------------------------------------------------------------------------------------------ 293 294 /// Load for a visco-elasto-plastic bushing acting between two bodies. 295 /// It uses three values for stiffness along the X Y Z axes of a coordinate system attached 296 /// to the second body. This is equivalent to having a bushing with 3x3 diagonal local stiffness matrix. 297 /// Also, it allows a very simple plasticity model, to cap the plastic force on x,y,z given three yelds. 298 class ChApi ChLoadBodyBodyBushingPlastic : public ChLoadBodyBodyBushingSpherical { 299 public: 300 ChLoadBodyBodyBushingPlastic( 301 std::shared_ptr<ChBody> mbodyA, ///< body A 302 std::shared_ptr<ChBody> mbodyB, ///< body B 303 const ChFrame<>& abs_application, ///< create the bushing here, in abs. coordinates. 304 const ChVector<>& mstiffness, ///< stiffness, along the x y z axes of the abs_application 305 const ChVector<>& mdamping, ///< damping, along the x y z axes of the abs_application 306 const ChVector<>& myield ///< plastic yield, along the x y z axes of the abs_application 307 ); 308 309 /// Set plastic yield, forces beyond this limit will be capped. 310 /// Expressed along the x y z axes of loc_application_B. SetYeld(const ChVector<> myeld)311 void SetYeld(const ChVector<> myeld) { yield = myeld; } GetYeld()312 ChVector<> GetYeld() const { return yield; } 313 314 /// Get the current accumulated plastic deformation. 315 /// This could become nonzero if forces went beyond the plastic yield. GetPlasticDeformation()316 ChVector<> GetPlasticDeformation() const { return plastic_def; } 317 318 protected: 319 ChVector<> yield; 320 ChVector<> plastic_def; 321 322 /// Implement the computation of the bushing force, in local 323 /// coordinates of the loc_application_B. 324 /// Force is assumed applied to loc_application_B of body B, and its opposite reaction to A. 325 virtual void ComputeBodyBodyForceTorque(const ChFrameMoving<>& rel_AB, 326 ChVector<>& loc_force, 327 ChVector<>& loc_torque) override; 328 }; 329 330 //------------------------------------------------------------------------------------------------ 331 332 /// Load for a visco-elastic translational/rotational bushing acting between two bodies. 333 /// It uses three values for stiffness along the X Y Z axes of a coordinate system attached 334 /// to the second body , and three rotational stiffness values for (small) rotations about X Y Z of the 335 /// same coordinate system. 336 /// This is equivalent to having a bushing with 6x6 diagonal local stiffness matrix. 337 class ChApi ChLoadBodyBodyBushingMate : public ChLoadBodyBodyBushingSpherical { 338 public: 339 ChLoadBodyBodyBushingMate( 340 std::shared_ptr<ChBody> mbodyA, ///< body A 341 std::shared_ptr<ChBody> mbodyB, ///< body B 342 const ChFrame<>& abs_application, ///< create the bushing here, in abs. coordinates. 343 const ChVector<>& mstiffness, ///< stiffness, along x y z axes of the abs_application 344 const ChVector<>& mdamping, ///< damping, along x y z axes of the abs_application 345 const ChVector<>& mrotstiffness, ///< rotational stiffness, about x y z axes of the abs_application 346 const ChVector<>& mrotdamping ///< rotational damping, about x y z axes of the abs_application 347 ); 348 349 /// Set radial stiffness, along the x y z axes of loc_application_B, es [N/m] SetRotationalStiffness(const ChVector<> mstiffness)350 void SetRotationalStiffness(const ChVector<> mstiffness) { rot_stiffness = mstiffness; } GetRotationalStiffness()351 ChVector<> GetRotationalStiffness() const { return rot_stiffness; } 352 353 /// Set radial damping, along the x y z axes of loc_application_B, es [Ns/m] SetRotationalDamping(const ChVector<> mdamping)354 void SetRotationalDamping(const ChVector<> mdamping) { rot_damping = mdamping; } GetRotationalDamping()355 ChVector<> GetRotationalDamping() const { return rot_damping; } 356 357 protected: 358 ChVector<> rot_stiffness; 359 ChVector<> rot_damping; 360 361 /// Implement the computation of the bushing force, in local 362 /// coordinates of the loc_application_B. 363 /// Force is assumed applied to loc_application_B of body B, and its opposite reaction to A. 364 virtual void ComputeBodyBodyForceTorque(const ChFrameMoving<>& rel_AB, 365 ChVector<>& loc_force, 366 ChVector<>& loc_torque) override; 367 }; 368 369 //------------------------------------------------------------------------------------------------ 370 371 /// Load for a visco-elastic translational/rotational bushing acting between two bodies. 372 /// It uses a full user-defined 6x6 matrix [K] to express the local stiffness of the 373 /// bushing, assumed expressed in the bushing coordinate system attached 374 /// to the second body. A user-defined 6x6 matrix [D] can be defined for damping, as well. 375 /// Note that this assumes small rotations. 376 /// Differently from the simpler ChLoadBodyBodyBushingMate and ChLoadBodyBodyBushingSpherical 377 /// this can represent coupled effects, by using extra-diagonal terms in [K] and/or [D]. 378 class ChApi ChLoadBodyBodyBushingGeneric : public ChLoadBodyBody { 379 public: 380 ChLoadBodyBodyBushingGeneric( 381 std::shared_ptr<ChBody> mbodyA, ///< body A 382 std::shared_ptr<ChBody> mbodyB, ///< body B 383 const ChFrame<>& abs_application, ///< create the bushing here, in abs. coordinates. 384 ChMatrixConstRef mstiffness, ///< stiffness as a 6x6 matrix, local in the abs_application frame 385 ChMatrixConstRef mdamping ///< damping as a 6x6 matrix, local in the abs_application frame 386 ); 387 388 /// "Virtual" copy constructor (covariant return type). Clone()389 virtual ChLoadBodyBodyBushingGeneric* Clone() const override { return new ChLoadBodyBodyBushingGeneric(*this); } 390 391 /// Set a generic 6x6 stiffness matrix, expressed in local 392 /// coordinate system of loc_application_B. SetStiffnessMatrix(ChMatrixConstRef mstiffness)393 void SetStiffnessMatrix(ChMatrixConstRef mstiffness) { stiffness = mstiffness; } GetStiffnessMatrix()394 const ChMatrixNM<double, 6, 6>& GetStiffnessMatrix() const { return stiffness; } 395 396 /// Set a generic 6x6 damping matrix, expressed in local 397 /// coordinate system of loc_application_B. SetDampingMatrix(ChMatrixConstRef mdamping)398 void SetDampingMatrix(ChMatrixConstRef mdamping) { damping = mdamping; } GetDampingMatrix()399 const ChMatrixNM<double, 6, 6>& GetDampingMatrix() const { return damping; } 400 401 /// Set the initial pre-load of the bushing, applied to loc_application_A, 402 /// expressed in local coordinate system of loc_application_B. 403 /// By default it is zero. SetNeutralForce(const ChVector<> mf)404 void SetNeutralForce(const ChVector<> mf) { neutral_force = mf; } GetNeutralForce()405 ChVector<> GetNeutralForce() const { return neutral_force; } 406 407 /// Set the initial pre-load torque of the bushing, applied to loc_application_A, 408 /// expressed in local coordinate system of loc_application_B. 409 /// By default it is zero. SetNeutralTorque(const ChVector<> mt)410 void SetNeutralTorque(const ChVector<> mt) { neutral_torque = mt; } GetNeutralTorque()411 ChVector<> GetNeutralTorque() const { return neutral_torque; } 412 413 /// Set/get the initial pre-displacement of the bushing, as the pre-displacement 414 /// of A, expressed in local coordinate system of loc_application_B. 415 /// Default behavior is no initial pre-displacement. NeutralDisplacement()416 ChFrame<>& NeutralDisplacement() { return neutral_displacement; } 417 418 protected: 419 ChMatrixNM<double, 6, 6> stiffness; 420 ChMatrixNM<double, 6, 6> damping; 421 422 ChVector<> neutral_force; 423 ChVector<> neutral_torque; 424 ChFrame<> neutral_displacement; 425 IsStiff()426 virtual bool IsStiff() override { return true; } 427 428 /// Implement the computation of the bushing force, in local 429 /// coordinates of the loc_application_B. 430 /// Force is assumed applied to loc_application_B of body B, and its opposite reaction to A. 431 virtual void ComputeBodyBodyForceTorque(const ChFrameMoving<>& rel_AB, 432 ChVector<>& loc_force, 433 ChVector<>& loc_torque) override; 434 435 public: 436 EIGEN_MAKE_ALIGNED_OPERATOR_NEW 437 }; 438 439 } // end namespace chrono 440 441 #endif 442