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 CHLINKLOCK_H
16 #define CHLINKLOCK_H
17 
18 #include "chrono/physics/ChLimit.h"
19 #include "chrono/physics/ChLinkForce.h"
20 #include "chrono/physics/ChLinkMarkers.h"
21 #include "chrono/physics/ChLinkMask.h"
22 
23 namespace chrono {
24 
25 /// Base class for joints implemented using the "lock formulation".
26 /// Derived classes provide models for revolute, prismatic, spherical, etc.
27 /// Note that certain kinematic joints (e.g., Universal) cannot be modeled using the lock formulation.
28 /// Joints of this type can optionally specify 'limits' over upper-lower motions of their respective
29 /// degrees of freedom, using the ChLinkLimit objects.
30 class ChApi ChLinkLock : public ChLinkMarkers {
31   public:
32     using ChConstraintVectorX = Eigen::Matrix<double, Eigen::Dynamic, 1, Eigen::ColMajor, 7, 1>;
33     using ChConstraintMatrixX6 = Eigen::Matrix<double, Eigen::Dynamic, BODY_DOF, Eigen::RowMajor, 7, BODY_DOF>;
34     using ChConstraintMatrixX7 = Eigen::Matrix<double, Eigen::Dynamic, BODY_QDOF, Eigen::RowMajor, 7, BODY_QDOF>;
35 
36     /// Default constructor. Builds a ChLinkLockSpherical.
37     ChLinkLock();
38 
39     /// Copy constructor.
40     ChLinkLock(const ChLinkLock& other);
41 
42     virtual ~ChLinkLock();
43 
44     /// "Virtual" copy constructor (covariant return type).
Clone()45     virtual ChLinkLock* Clone() const override { return new ChLinkLock(*this); }
46 
47     /// If some constraint is redundant, return to normal state.
48     int RestoreRedundant() override;
49 
50     /// Enable/disable all constraints of the link.
51     virtual void SetDisabled(bool mdis) override;
52 
53     /// For example, a 3rd party software can set the 'broken' status via this method
54     virtual void SetBroken(bool mon) override;
55 
56     /// Get the link mask (a container for the ChConstraint items).
GetMask()57     ChLinkMask& GetMask() { return mask; }
58 
59     /// Set the two markers associated with this link.
60     virtual void SetUpMarkers(ChMarker* mark1, ChMarker* mark2) override;
61 
62     //@{
63     /// Accessors for internal forces on free degrees of freedom.
64     /// These functions provide access to initialize and set parameters for link
65     /// forces acting on different degrees of freedom of the joint.
66     /// Note that they use "lazy initialization"; an internal link force object is
67     /// created on the first invocation of the corresponding accessor function.
68     ChLinkForce& GetForce_D();
69     ChLinkForce& GetForce_R();
70     ChLinkForce& GetForce_X();
71     ChLinkForce& GetForce_Y();
72     ChLinkForce& GetForce_Z();
73     ChLinkForce& GetForce_Rx();
74     ChLinkForce& GetForce_Ry();
75     ChLinkForce& GetForce_Rz();
76     //@}
77 
78     //@{
79     /// Accessors for limits on free degrees of freedom.
80     /// These functions provide access to initialize and set parameters for link
81     /// limits on different free degrees of freedom of the joint.
82     /// Note that they use "lazy initialization"; an internal link limit object is
83     /// created on the first invocation of the corresponding accessor function.
84     ChLinkLimit& GetLimit_X();
85     ChLinkLimit& GetLimit_Y();
86     ChLinkLimit& GetLimit_Z();
87     ChLinkLimit& GetLimit_Rx();
88     ChLinkLimit& GetLimit_Ry();
89     ChLinkLimit& GetLimit_Rz();
90     ChLinkLimit& GetLimit_Rp();
91     ChLinkLimit& GetLimit_D();
92     //@}
93 
94     /// Get the number of scalar constraints for this link.
GetDOC()95     virtual int GetDOC() override { return GetDOC_c() + GetDOC_d(); }
96 
97     /// Get the number of bilateral constraints for this link.
GetDOC_c()98     virtual int GetDOC_c() override { return ndoc_c; }
99 
100     /// Get the number of unilateral constraints for this link.
101     virtual int GetDOC_d() override;
102 
103     // LINK VIOLATIONS
104 
105     /// Link violation (residuals of the link constraint equations).
GetConstraintViolation()106     virtual ChVectorDynamic<> GetConstraintViolation() const override { return C; }
107 
108     /// Time derivatives of link violation.
GetConstraintViolation_dt()109     const ChConstraintVectorX& GetConstraintViolation_dt() const { return C_dt; }
110     /// Second time derivatives of link violation.
GetConstraintViolation_dtdt()111     const ChConstraintVectorX& GetConstraintViolation_dtdt() const { return C_dtdt; }
112 
113     // LINK STATE MATRICES
114 
115     // Functions used by simulation engines to fetch the system state matrices
116     // (the jacobians, the Q vector, etc.) for building the state system matrices
117     // Note that these functions do not compute/update such matrices; this happens
118     // in the Update functions.
119 
120     /// The jacobian (body n.1 part, i.e. columns= 7 ,  rows= ndoc)
GetCq1()121     const ChConstraintMatrixX7& GetCq1() const { return Cq1; }
122     /// The jacobian (body n.2 part, i.e. columns= 7 ,  rows= ndoc)
GetCq2()123     const ChConstraintMatrixX7& GetCq2() const { return Cq2; }
124 
125     /// The jacobian for Wl (col 6, rows= ndoc), as [Cqw1_rot]=[Cq_rot]*[Gl_1]'
GetCqw1()126     const ChConstraintMatrixX6& GetCqw1() const { return Cqw1; }
127     /// The jacobian for Wl (col 6, rows= ndoc)	as [Cqw2_rot]=[Cq_rot]*[Gl_2]'
GetCqw2()128     const ChConstraintMatrixX6& GetCqw2() const { return Cqw2; }
129 
130     /// The gamma vector used in dynamics,  [Cq]x''=Qc
GetQc()131     const ChConstraintVectorX& GetQc() const { return Qc; }
132 
133     /// The Ct vector used in kinematics,  [Cq]x'=Ct
GetCt()134     const ChConstraintVectorX& GetCt() const { return Ct; }
135 
136     /// Access the reaction vector, after dynamics computations
GetReact()137     const ChConstraintVectorX& GetReact() const { return react; }
138 
139     // UPDATE FUNCTIONS
140 
141     /// Given current time and body state, computes the constraint differentiation to get the the state matrices Cq1,
142     /// Cq2,  Qc,  Ct , and also C, C_dt, C_dtd.
143     virtual void UpdateState();
144 
145     /// Updates the local F, M forces adding penalties from ChLinkLimit objects, if any.
146     virtual void UpdateForces(double mytime) override;
147 
148     /// Updates Cqw1 and Cqw2  given updated  Cq1 and Cq2, i.e. computes the jacobians with 'Wl' rotational coordinates
149     /// knowing the jacobians for body rotations in quaternion coordinates.
150     void UpdateCqw();
151 
152     /// Full update. Fills-in all the matrices of the link, and does all required calculations by calling specific
153     /// Update functions in sequence: <pre>
154     ///     UpdateTime;
155     ///     UpdateRelMarkerCoords;
156     ///     UpdateState;
157     ///     UpdateCqw
158     ///     UpdateForces;
159     /// </pre>
160     virtual void Update(double mytime, bool update_assets = true) override;
161 
162     /// Method to allow serialization of transient data to archives.
163     virtual void ArchiveOUT(ChArchiveOut& marchive) override;
164 
165     /// Method to allow deserialization of transient data from archives.
166     virtual void ArchiveIN(ChArchiveIn& marchive) override;
167 
168   protected:
169     /// Type of link-lock
170     enum class LinkType {
171         LOCK,
172         SPHERICAL,
173         POINTPLANE,
174         POINTLINE,
175         CYLINDRICAL,
176         PRISMATIC,
177         PLANEPLANE,
178         OLDHAM,
179         REVOLUTE,
180         FREE,
181         ALIGN,
182         PARALLEL,
183         PERPEND,
184         TRAJECTORY,
185         CLEARANCE,
186         REVOLUTEPRISMATIC
187     };
188 
189     LinkType type;  ///< type of link_lock joint
190 
191     // The mask of the locked coords, with the status of the scalar constraints.
192     // This object also encapsulates the jacobians and residuals for the solver.
193     ChLinkMaskLF mask;  ///< scalar constraints
194 
195     // Degrees of constraint (excluding constraints from joint limits)
196     int ndoc;    ///< number of degrees of constraint
197     int ndoc_c;  ///< number of degrees of constraint (bilateral constraintss)
198     int ndoc_d;  ///< number of degrees of constraint (unilateral constraints, excluding joint limits)
199 
200     std::unique_ptr<ChLinkForce> force_D;   ///< the force acting on the straight line m1-m2 (distance)
201     std::unique_ptr<ChLinkForce> force_R;   ///< the torque acting about rotation axis
202     std::unique_ptr<ChLinkForce> force_X;   ///< the force acting along X dof
203     std::unique_ptr<ChLinkForce> force_Y;   ///< the force acting along Y dof
204     std::unique_ptr<ChLinkForce> force_Z;   ///< the force acting along Z dof
205     std::unique_ptr<ChLinkForce> force_Rx;  ///< the torque acting about Rx dof
206     std::unique_ptr<ChLinkForce> force_Ry;  ///< the torque acting about Ry dof
207     std::unique_ptr<ChLinkForce> force_Rz;  ///< the torque acting about Rz dof
208     double d_restlength;                    ///< the rest length of the "d_spring" spring
209 
210     std::unique_ptr<ChLinkLimit> limit_X;   ///< the upper/lower limits for X dof
211     std::unique_ptr<ChLinkLimit> limit_Y;   ///< the upper/lower limits for Y dof
212     std::unique_ptr<ChLinkLimit> limit_Z;   ///< the upper/lower limits for Z dof
213     std::unique_ptr<ChLinkLimit> limit_Rx;  ///< the upper/lower limits for Rx dof
214     std::unique_ptr<ChLinkLimit> limit_Ry;  ///< the upper/lower limits for Ry dof
215     std::unique_ptr<ChLinkLimit> limit_Rz;  ///< the upper/lower limits for Rz dof
216     std::unique_ptr<ChLinkLimit> limit_Rp;  ///< the polar (conical) limit for "shoulder"rotation
217     std::unique_ptr<ChLinkLimit> limit_D;   ///< the polar (conical) limit for "shoulder"rotation
218 
219     ChConstraintVectorX C;       ///< C(q,q_dt,t), the constraint violations
220     ChConstraintVectorX C_dt;    ///< Speed constraint violations
221     ChConstraintVectorX C_dtdt;  ///< Acceleration constraint violations
222 
223     ChConstraintMatrixX7 Cq1;  ///< [Cq1], the jacobian of the constraint, for coords1, [ndoc,7]
224     ChConstraintMatrixX7 Cq2;  ///< [Cq2], the jacobian of the constraint, for coords2. [ndoc,7]
225 
226     ChConstraintMatrixX6 Cqw1;  ///< [Cqw1], the jacobian [ndoc,6] for 3 Wl rot.coordinates instead of quaternions
227     ChConstraintMatrixX6 Cqw2;  ///< [Cqw2], the jacobian [ndoc,6] for 3 Wl rot.coordinates instead of quaternions
228 
229     ChConstraintVectorX Qc;     ///< {Qc}, the known part, {Qc}=-{C_dtdt}-([Cq]{q_dt})q-2[Cq_dt]{q_dt}
230     ChConstraintVectorX Ct;     ///< partial derivative of the link kin. equation wrt to time
231     ChConstraintVectorX react;  ///< {l}, the lagrangians forces in the constraints
232 
233     // Only for intermediate calculus
234     ChMatrixNM<double, 7, BODY_QDOF> Cq1_temp;  //
235     ChMatrixNM<double, 7, BODY_QDOF> Cq2_temp;  //   the temporary "lock" jacobians,
236     ChVectorN<double, 7> Qc_temp;               //   i.e. the full x,y,z,r0,r1,r2,r3 joint
237     Coordsys Ct_temp;                           //
238 
239   public:
240     EIGEN_MAKE_ALIGNED_OPERATOR_NEW
241 
242   protected:
243     /// Resize matrices and initializes all mask-dependent quantities.
244     /// Sets number of DOF and number DOC based on current mask information.
245     void BuildLink();
246 
247     /// Set the mask and then resize matrices.
248     void BuildLinkType(LinkType link_type);
249     void BuildLink(bool x, bool y, bool z, bool e0, bool e1, bool e2, bool e3);
250 
251     void ChangeLinkType(LinkType new_link_type);
252 
253 
254     // Extend parent functions to account for any ChLinkLimit objects.
255     ////virtual void IntLoadResidual_F(const unsigned int off,	ChVectorDynamic<>& R, const double c );
256     virtual void IntStateScatterReactions(const unsigned int off_L, const ChVectorDynamic<>& L) override;
257 
258     virtual void IntStateGatherReactions(const unsigned int off_L, ChVectorDynamic<>& L) override;
259 
260     virtual void IntLoadResidual_CqL(const unsigned int off_L,
261                                      ChVectorDynamic<>& R,
262                                      const ChVectorDynamic<>& L,
263                                      const double c) override;
264     virtual void IntLoadConstraint_C(const unsigned int off,
265                                      ChVectorDynamic<>& Qc,
266                                      const double c,
267                                      bool do_clamp,
268                                      double recovery_clamp) override;
269     virtual void IntLoadConstraint_Ct(const unsigned int off, ChVectorDynamic<>& Qc, const double c) override;
270     virtual void IntToDescriptor(const unsigned int off_v,
271                                  const ChStateDelta& v,
272                                  const ChVectorDynamic<>& R,
273                                  const unsigned int off_L,
274                                  const ChVectorDynamic<>& L,
275                                  const ChVectorDynamic<>& Qc) override;
276     virtual void IntFromDescriptor(const unsigned int off_v,
277                                    ChStateDelta& v,
278                                    const unsigned int off_L,
279                                    ChVectorDynamic<>& L) override;
280 
281     // Extend parent constraint functions to consider constraints possibly induced by 'limits'.
282     virtual void InjectConstraints(ChSystemDescriptor& mdescriptor) override;
283     virtual void ConstraintsBiReset() override;
284     virtual void ConstraintsBiLoad_C(double factor = 1, double recovery_clamp = 0.1, bool do_clamp = false) override;
285     virtual void ConstraintsBiLoad_Ct(double factor = 1) override;
286     virtual void ConstraintsBiLoad_Qc(double factor = 1) override;
287     virtual void ConstraintsLoadJacobians() override;
288     virtual void ConstraintsFetch_react(double factor = 1) override;
289 
290     friend class ChConveyor;
291 };
292 
293 CH_CLASS_VERSION(ChLinkLock, 0)
294 
295 // ---------------------------------------------------------------------------------------
296 // Specialization of a "weld" joint, in the link-lock formulation
297 // ---------------------------------------------------------------------------------------
298 
299 /// 6-dof locked joint, with the link-lock formulation.
300 /// This specialization allows for specification of prescribed motion in the direction of
301 /// any of the 6 directions (3 translations and 3 rotations).
302 class ChApi ChLinkLockLock : public ChLinkLock {
303   public:
304     ChLinkLockLock();
305     ChLinkLockLock(const ChLinkLockLock& other);
306 
307     /// "Virtual" copy constructor (covariant return type).
Clone()308     virtual ChLinkLockLock* Clone() const override { return new ChLinkLockLock(*this); }
309 
310     // Imposed motion functions
311 
312     void SetMotion_X(std::shared_ptr<ChFunction> m_funct);
313     void SetMotion_Y(std::shared_ptr<ChFunction> m_funct);
314     void SetMotion_Z(std::shared_ptr<ChFunction> m_funct);
315     void SetMotion_ang(std::shared_ptr<ChFunction> m_funct);
316     void SetMotion_ang2(std::shared_ptr<ChFunction> m_funct);
317     void SetMotion_ang3(std::shared_ptr<ChFunction> m_funct);
318     void SetMotion_axis(Vector m_axis);
Set_angleset(AngleSet mset)319     void Set_angleset(AngleSet mset) { angleset = mset; }
320 
GetMotion_X()321     std::shared_ptr<ChFunction> GetMotion_X() const { return motion_X; }
GetMotion_Y()322     std::shared_ptr<ChFunction> GetMotion_Y() const { return motion_Y; }
GetMotion_Z()323     std::shared_ptr<ChFunction> GetMotion_Z() const { return motion_Z; }
GetMotion_ang()324     std::shared_ptr<ChFunction> GetMotion_ang() const { return motion_ang; }
GetMotion_ang2()325     std::shared_ptr<ChFunction> GetMotion_ang2() const { return motion_ang2; }
GetMotion_ang3()326     std::shared_ptr<ChFunction> GetMotion_ang3() const { return motion_ang3; }
GetMotion_axis()327     const ChVector<>& GetMotion_axis() const { return motion_axis; }
Get_angleset()328     AngleSet Get_angleset() const { return angleset; }
329 
330     /// Get constraint violations in pos/rot coordinates.
GetRelC()331     const Coordsys& GetRelC() const { return relC; }
332     /// Get first time derivative of constraint violations in pos/rot coordinates.
GetRelC_dt()333     const Coordsys& GetRelC_dt() const { return relC_dt; }
334     /// Get second time derivative of constraint violations in pos/rot coordinates.
GetRelC_dtdt()335     const Coordsys& GetRelC_dtdt() const { return relC_dtdt; }
336 
337     /// Method to allow serialization of transient data to archives.
338     virtual void ArchiveOUT(ChArchiveOut& marchive) override;
339 
340     /// Method to allow deserialization of transient data from archives.
341     virtual void ArchiveIN(ChArchiveIn& marchive) override;
342 
343   protected:
344     std::shared_ptr<ChFunction> motion_X;     ///< user imposed motion for X coord, marker relative
345     std::shared_ptr<ChFunction> motion_Y;     ///< user imposed motion for Y coord, marker relative
346     std::shared_ptr<ChFunction> motion_Z;     ///< user imposed motion for Z coord, marker relative
347     std::shared_ptr<ChFunction> motion_ang;   ///< user imposed angle rotation about axis
348     std::shared_ptr<ChFunction> motion_ang2;  ///< user imposed angle rotation if three-angles rot.
349     std::shared_ptr<ChFunction> motion_ang3;  ///< user imposed angle rotation if three-angles rot.
350     Vector motion_axis;                       ///< this is the axis for the user imposed rotation
351     AngleSet angleset;                        ///< type of rotation (3 Eul angles, angle/axis, etc.)
352 
353     Coordsys relC;       ///< relative constraint position: relC = (relM-deltaC)
354     Coordsys relC_dt;    ///< relative constraint speed
355     Coordsys relC_dtdt;  ///< relative constraint acceleration
356 
357     Coordsys deltaC;       ///< user-imposed rel. position
358     Coordsys deltaC_dt;    ///< user-imposed rel. speed
359     Coordsys deltaC_dtdt;  ///< user-imposed rel. acceleration
360 
361     /// Inherits, and also updates motion laws: deltaC, deltaC_dt, deltaC_dtdt
362     virtual void UpdateTime(double mytime) override;
363 
364     /// Given current time and body state, computes the constraint differentiation to get the
365     /// the state matrices Cq1,  Cq2,  Qc,  Ct , and also C, C_dt, C_dtd.
366     virtual void UpdateState() override;
367 };
368 
369 CH_CLASS_VERSION(ChLinkLockLock, 0)
370 
371 // ---------------------------------------------------------------------------------------
372 // Concrete joints using the link-lock formulation
373 // ---------------------------------------------------------------------------------------
374 
375 /// Revolute joint, with the 'ChLinkLock' formulation.
376 /// (allows a simpler creation of a link as a sub-type of ChLinkLock).
377 class ChApi ChLinkLockRevolute : public ChLinkLock {
378   public:
ChLinkLockRevolute()379     ChLinkLockRevolute() { ChangeLinkType(LinkType::REVOLUTE); }
380 
381     /// "Virtual" copy constructor (covariant return type).
Clone()382     virtual ChLinkLockRevolute* Clone() const override { return new ChLinkLockRevolute(*this); }
383 
384     /// Lock the joint.
385     /// If enabled (lock = true) this effectively converts this joint into a weld joint.
386     /// If lock = false, the joint reverts to its original degrees of freedom.
387     void Lock(bool lock);
388 };
389 
390 /// Spherical joint, with the 'ChLinkLock' formulation.
391 /// (allows a simpler creation of a link as a sub-type of ChLinkLock).
392 class ChApi ChLinkLockSpherical : public ChLinkLock {
393   public:
ChLinkLockSpherical()394     ChLinkLockSpherical() { ChangeLinkType(LinkType::SPHERICAL); }
395 
396     /// "Virtual" copy constructor (covariant return type).
Clone()397     virtual ChLinkLockSpherical* Clone() const override { return new ChLinkLockSpherical(*this); }
398 
399     /// Lock the joint.
400     /// If enabled (lock = true) this effectively converts this joint into a weld joint.
401     /// If lock = false, the joint reverts to its original degrees of freedom.
402     void Lock(bool lock);
403 };
404 
405 /// Cylindrical joint, with the 'ChLinkLock' formulation.
406 /// (allows a simpler creation of a link as a sub-type of ChLinkLock).
407 class ChApi ChLinkLockCylindrical : public ChLinkLock {
408   public:
ChLinkLockCylindrical()409     ChLinkLockCylindrical() { ChangeLinkType(LinkType::CYLINDRICAL); }
410 
411     /// "Virtual" copy constructor (covariant return type).
Clone()412     virtual ChLinkLockCylindrical* Clone() const override { return new ChLinkLockCylindrical(*this); }
413 
414     /// Lock the joint.
415     /// If enabled (lock = true) this effectively converts this joint into a weld joint.
416     /// If lock = false, the joint reverts to its original degrees of freedom.
417     void Lock(bool lock);
418 };
419 
420 /// Prismatic joint, with the 'ChLinkLock' formulation.
421 /// Default axis along +z
422 class ChApi ChLinkLockPrismatic : public ChLinkLock {
423   public:
ChLinkLockPrismatic()424     ChLinkLockPrismatic() { ChangeLinkType(LinkType::PRISMATIC); }
425 
426     /// "Virtual" copy constructor (covariant return type).
Clone()427     virtual ChLinkLockPrismatic* Clone() const override { return new ChLinkLockPrismatic(*this); }
428 
429     /// Lock the joint.
430     /// If enabled (lock = true) this effectively converts this joint into a weld joint.
431     /// If lock = false, the joint reverts to its original degrees of freedom.
432     void Lock(bool lock);
433 };
434 
435 /// Point-plane joint, with the 'ChLinkLock' formulation.
436 /// (allows a simpler creation of a link as a sub-type of ChLinkLock).
437 class ChApi ChLinkLockPointPlane : public ChLinkLock {
438   public:
ChLinkLockPointPlane()439     ChLinkLockPointPlane() { ChangeLinkType(LinkType::POINTPLANE); }
440 
441     /// "Virtual" copy constructor (covariant return type).
Clone()442     virtual ChLinkLockPointPlane* Clone() const override { return new ChLinkLockPointPlane(*this); }
443 
444     /// Lock the joint.
445     /// If enabled (lock = true) this effectively converts this joint into a weld joint.
446     /// If lock = false, the joint reverts to its original degrees of freedom.
447     void Lock(bool lock);
448 };
449 
450 /// Point-line joint, with the 'ChLinkLock' formulation.
451 /// (allows a simpler creation of a link as a sub-type of ChLinkLock).
452 class ChApi ChLinkLockPointLine : public ChLinkLock {
453   public:
ChLinkLockPointLine()454     ChLinkLockPointLine() { ChangeLinkType(LinkType::POINTLINE); }
455 
456     /// "Virtual" copy constructor (covariant return type).
Clone()457     virtual ChLinkLockPointLine* Clone() const override { return new ChLinkLockPointLine(*this); }
458 
459     /// Lock the joint.
460     /// If enabled (lock = true) this effectively converts this joint into a weld joint.
461     /// If lock = false, the joint reverts to its original degrees of freedom.
462     void Lock(bool lock);
463 };
464 
465 /// Plane-plane joint, with the 'ChLinkLock' formulation.
466 /// (allows a simpler creation of a link as a sub-type of ChLinkLock).
467 class ChApi ChLinkLockPlanePlane : public ChLinkLock {
468   public:
ChLinkLockPlanePlane()469     ChLinkLockPlanePlane() { ChangeLinkType(LinkType::PLANEPLANE); }
470 
471     /// "Virtual" copy constructor (covariant return type).
Clone()472     virtual ChLinkLockPlanePlane* Clone() const override { return new ChLinkLockPlanePlane(*this); }
473 
474     /// Lock the joint.
475     /// If enabled (lock = true) this effectively converts this joint into a weld joint.
476     /// If lock = false, the joint reverts to its original degrees of freedom.
477     void Lock(bool lock);
478 };
479 
480 /// Oldham joint, with the 'ChLinkLock' formulation.
481 /// (allows a simpler creation of a link as a sub-type of ChLinkLock).
482 class ChApi ChLinkLockOldham : public ChLinkLock {
483   public:
ChLinkLockOldham()484     ChLinkLockOldham() { ChangeLinkType(LinkType::OLDHAM); }
485 
486     /// "Virtual" copy constructor (covariant return type).
Clone()487     virtual ChLinkLockOldham* Clone() const override { return new ChLinkLockOldham(*this); }
488 
489     /// Lock the joint.
490     /// If enabled (lock = true) this effectively converts this joint into a weld joint.
491     /// If lock = false, the joint reverts to its original degrees of freedom.
492     void Lock(bool lock);
493 };
494 
495 /// Free joint, with the 'ChLinkLock' formulation.
496 /// (allows a simpler creation of a link as a sub-type of ChLinkLock).
497 class ChApi ChLinkLockFree : public ChLinkLock {
498   public:
ChLinkLockFree()499     ChLinkLockFree() { ChangeLinkType(LinkType::FREE); }
500 
501     /// "Virtual" copy constructor (covariant return type).
Clone()502     virtual ChLinkLockFree* Clone() const override { return new ChLinkLockFree(*this); }
503 
504     /// Lock the joint.
505     /// If enabled (lock = true) this effectively converts this joint into a weld joint.
506     /// If lock = false, the joint reverts to its original degrees of freedom.
507     void Lock(bool lock);
508 };
509 
510 /// Align joint, with the 'ChLinkLock' formulation.
511 /// (allows a simpler creation of a link as a sub-type of ChLinkLock).
512 class ChApi ChLinkLockAlign : public ChLinkLock {
513   public:
ChLinkLockAlign()514     ChLinkLockAlign() { ChangeLinkType(LinkType::ALIGN); }
515 
516     /// "Virtual" copy constructor (covariant return type).
Clone()517     virtual ChLinkLockAlign* Clone() const override { return new ChLinkLockAlign(*this); }
518 
519     /// Lock the joint.
520     /// If enabled (lock = true) this effectively converts this joint into a weld joint.
521     /// If lock = false, the joint reverts to its original degrees of freedom.
522     void Lock(bool lock);
523 };
524 
525 /// Parallel joint, with the 'ChLinkLock' formulation.
526 /// (allows a simpler creation of a link as a sub-type of ChLinkLock).
527 class ChApi ChLinkLockParallel : public ChLinkLock {
528   public:
ChLinkLockParallel()529     ChLinkLockParallel() { ChangeLinkType(LinkType::PARALLEL); }
530 
531     /// "Virtual" copy constructor (covariant return type).
Clone()532     virtual ChLinkLockParallel* Clone() const override { return new ChLinkLockParallel(*this); }
533 
534     /// Lock the joint.
535     /// If enabled (lock = true) this effectively converts this joint into a weld joint.
536     /// If lock = false, the joint reverts to its original degrees of freedom.
537     void Lock(bool lock);
538 };
539 
540 /// Perpendicularity joint, with the 'ChLinkLock' formulation.
541 /// (allows a simpler creation of a link as a sub-type of ChLinkLock).
542 class ChApi ChLinkLockPerpend : public ChLinkLock {
543   public:
ChLinkLockPerpend()544     ChLinkLockPerpend() { ChangeLinkType(LinkType::PERPEND); }
545 
546     /// "Virtual" copy constructor (covariant return type).
Clone()547     virtual ChLinkLockPerpend* Clone() const override { return new ChLinkLockPerpend(*this); }
548 
549     /// Lock the joint.
550     /// If enabled (lock = true) this effectively converts this joint into a weld joint.
551     /// If lock = false, the joint reverts to its original degrees of freedom.
552     void Lock(bool lock);
553 };
554 
555 /// RevolutePrismatic joint, with the 'ChLinkLock' formulation.
556 /// Translates along x-dir, rotates about z-axis
557 class ChApi ChLinkLockRevolutePrismatic : public ChLinkLock {
558   public:
ChLinkLockRevolutePrismatic()559     ChLinkLockRevolutePrismatic() { ChangeLinkType(LinkType::REVOLUTEPRISMATIC); }
560 
561     /// "Virtual" copy constructor (covariant return type).
Clone()562     virtual ChLinkLockRevolutePrismatic* Clone() const override { return new ChLinkLockRevolutePrismatic(*this); }
563 
564     /// Lock the joint.
565     /// If enabled (lock = true) this effectively converts this joint into a weld joint.
566     /// If lock = false, the joint reverts to its original degrees of freedom.
567     void Lock(bool lock);
568 };
569 
570 }  // end namespace chrono
571 
572 #endif
573