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
13 // =============================================================================
14
15 #include "chrono/physics/ChLinkMotorLinearSpeed.h"
16
17 namespace chrono {
18
19 // Register into the object factory, to enable run-time dynamic creation and persistence
CH_FACTORY_REGISTER(ChLinkMotorLinearSpeed)20 CH_FACTORY_REGISTER(ChLinkMotorLinearSpeed)
21
22 ChLinkMotorLinearSpeed::ChLinkMotorLinearSpeed() {
23 variable.GetMass()(0, 0) = 1.0;
24 variable.GetInvMass()(0, 0) = 1.0;
25
26 m_func = chrono_types::make_shared<ChFunction_Const>(1.0);
27
28 pos_offset = 0;
29
30 aux_dt = 0; // used for integrating speed, = pos
31 aux_dtdt = 0;
32
33 avoid_position_drift = true;
34 }
35
ChLinkMotorLinearSpeed(const ChLinkMotorLinearSpeed & other)36 ChLinkMotorLinearSpeed::ChLinkMotorLinearSpeed(const ChLinkMotorLinearSpeed& other) : ChLinkMotorLinear(other) {
37 variable = other.variable;
38 pos_offset = other.pos_offset;
39 aux_dt = other.aux_dt;
40 aux_dtdt = other.aux_dtdt;
41 avoid_position_drift = other.avoid_position_drift;
42 }
43
~ChLinkMotorLinearSpeed()44 ChLinkMotorLinearSpeed::~ChLinkMotorLinearSpeed() {}
45
Update(double mytime,bool update_assets)46 void ChLinkMotorLinearSpeed::Update(double mytime, bool update_assets) {
47 // Inherit parent class:
48 ChLinkMotorLinear::Update(mytime, update_assets);
49
50 // Add the time-dependent term in residual C as
51 // C = d_error - d_setpoint - d_offset
52 // with d_error = x_pos_A- x_pos_B, and d_setpoint = x(t)
53 if (this->avoid_position_drift)
54 C(0) = this->mpos - aux_dt - this->pos_offset;
55 else
56 C(0) = 0.0;
57 }
58
IntLoadConstraint_Ct(const unsigned int off_L,ChVectorDynamic<> & Qc,const double c)59 void ChLinkMotorLinearSpeed::IntLoadConstraint_Ct(const unsigned int off_L, ChVectorDynamic<>& Qc, const double c) {
60 double mCt = -m_func->Get_y(this->GetChTime());
61 if (mask.Constr_N(0).IsActive()) {
62 Qc(off_L + 0) += c * mCt;
63 }
64 }
65
ConstraintsBiLoad_Ct(double factor)66 void ChLinkMotorLinearSpeed::ConstraintsBiLoad_Ct(double factor) {
67 if (!this->IsActive())
68 return;
69
70 double mCt = -m_func->Get_y(this->GetChTime());
71 if (mask.Constr_N(0).IsActive()) {
72 mask.Constr_N(0).Set_b_i(mask.Constr_N(0).Get_b_i() + factor * mCt);
73 }
74 }
75
76 //// STATE BOOKKEEPING FUNCTIONS
77
IntStateGather(const unsigned int off_x,ChState & x,const unsigned int off_v,ChStateDelta & v,double & T)78 void ChLinkMotorLinearSpeed::IntStateGather(const unsigned int off_x, // offset in x state vector
79 ChState& x, // state vector, position part
80 const unsigned int off_v, // offset in v state vector
81 ChStateDelta& v, // state vector, speed part
82 double& T // time
83 ) {
84 x(off_x) = 0; // aux;
85 v(off_v) = aux_dt;
86 T = GetChTime();
87 }
88
IntStateScatter(const unsigned int off_x,const ChState & x,const unsigned int off_v,const ChStateDelta & v,const double T,bool full_update)89 void ChLinkMotorLinearSpeed::IntStateScatter(const unsigned int off_x, // offset in x state vector
90 const ChState& x, // state vector, position part
91 const unsigned int off_v, // offset in v state vector
92 const ChStateDelta& v, // state vector, speed part
93 const double T, // time
94 bool full_update // perform complete update
95 ) {
96 // aux = x(off_x);
97 aux_dt = v(off_v);
98
99 Update(T, full_update);
100 }
101
IntStateGatherAcceleration(const unsigned int off_a,ChStateDelta & a)102 void ChLinkMotorLinearSpeed::IntStateGatherAcceleration(const unsigned int off_a, ChStateDelta& a) {
103 a(off_a) = aux_dtdt;
104 }
105
IntStateScatterAcceleration(const unsigned int off_a,const ChStateDelta & a)106 void ChLinkMotorLinearSpeed::IntStateScatterAcceleration(const unsigned int off_a, const ChStateDelta& a) {
107 aux_dtdt = a(off_a);
108 }
109
IntLoadResidual_F(const unsigned int off,ChVectorDynamic<> & R,const double c)110 void ChLinkMotorLinearSpeed::IntLoadResidual_F(const unsigned int off, // offset in R residual
111 ChVectorDynamic<>& R, // result: the R residual, R += c*F
112 const double c // a scaling factor
113 ) {
114 double imposed_speed = m_func->Get_y(this->GetChTime());
115 R(off) += imposed_speed * c;
116 }
117
IntLoadResidual_Mv(const unsigned int off,ChVectorDynamic<> & R,const ChVectorDynamic<> & w,const double c)118 void ChLinkMotorLinearSpeed::IntLoadResidual_Mv(const unsigned int off, // offset in R residual
119 ChVectorDynamic<>& R, // result: the R residual, R += c*M*v
120 const ChVectorDynamic<>& w, // the w vector
121 const double c // a scaling factor
122 ) {
123 R(off) += c * 1.0 * w(off);
124 }
125
IntToDescriptor(const unsigned int off_v,const ChStateDelta & v,const ChVectorDynamic<> & R,const unsigned int off_L,const ChVectorDynamic<> & L,const ChVectorDynamic<> & Qc)126 void ChLinkMotorLinearSpeed::IntToDescriptor(const unsigned int off_v, // offset in v, R
127 const ChStateDelta& v,
128 const ChVectorDynamic<>& R,
129 const unsigned int off_L, // offset in L, Qc
130 const ChVectorDynamic<>& L,
131 const ChVectorDynamic<>& Qc) {
132 // inherit parent
133 ChLinkMotorLinear::IntToDescriptor(off_v, v, R, off_L, L, Qc);
134
135 this->variable.Get_qb()(0, 0) = v(off_v);
136 this->variable.Get_fb()(0, 0) = R(off_v);
137 }
138
IntFromDescriptor(const unsigned int off_v,ChStateDelta & v,const unsigned int off_L,ChVectorDynamic<> & L)139 void ChLinkMotorLinearSpeed::IntFromDescriptor(const unsigned int off_v, // offset in v
140 ChStateDelta& v,
141 const unsigned int off_L, // offset in L
142 ChVectorDynamic<>& L) {
143 // inherit parent
144 ChLinkMotorLinear::IntFromDescriptor(off_v, v, off_L, L);
145
146 v(off_v) = this->variable.Get_qb()(0, 0);
147 }
148
149 ////
InjectVariables(ChSystemDescriptor & mdescriptor)150 void ChLinkMotorLinearSpeed::InjectVariables(ChSystemDescriptor& mdescriptor) {
151 variable.SetDisabled(!IsActive());
152
153 mdescriptor.InsertVariables(&variable);
154 }
155
VariablesFbReset()156 void ChLinkMotorLinearSpeed::VariablesFbReset() {
157 variable.Get_fb().setZero();
158 }
159
VariablesFbLoadForces(double factor)160 void ChLinkMotorLinearSpeed::VariablesFbLoadForces(double factor) {
161 double imposed_speed = m_func->Get_y(this->GetChTime());
162 variable.Get_fb()(0) += imposed_speed * factor;
163 }
164
VariablesFbIncrementMq()165 void ChLinkMotorLinearSpeed::VariablesFbIncrementMq() {
166 variable.Compute_inc_Mb_v(variable.Get_fb(), variable.Get_qb());
167 }
168
VariablesQbLoadSpeed()169 void ChLinkMotorLinearSpeed::VariablesQbLoadSpeed() {
170 // set current speed in 'qb', it can be used by the solver when working in incremental mode
171 variable.Get_qb()(0) = aux_dt;
172 }
173
VariablesQbSetSpeed(double step)174 void ChLinkMotorLinearSpeed::VariablesQbSetSpeed(double step) {
175 // from 'qb' vector, sets body speed, and updates auxiliary data
176 aux_dt = variable.Get_qb()(0);
177
178 // Compute accel. by BDF (approximate by differentiation); not needed
179 }
180
ArchiveOUT(ChArchiveOut & marchive)181 void ChLinkMotorLinearSpeed::ArchiveOUT(ChArchiveOut& marchive) {
182 // version number
183 marchive.VersionWrite<ChLinkMotorLinearSpeed>();
184
185 // serialize parent class
186 ChLinkMotorLinear::ArchiveOUT(marchive);
187
188 // serialize all member data:
189 marchive << CHNVP(pos_offset);
190 marchive << CHNVP(avoid_position_drift);
191 }
192
193 /// Method to allow de serialization of transient data from archives.
ArchiveIN(ChArchiveIn & marchive)194 void ChLinkMotorLinearSpeed::ArchiveIN(ChArchiveIn& marchive) {
195 // version number
196 /*int version =*/ marchive.VersionRead<ChLinkMotorLinearSpeed>();
197
198 // deserialize parent class
199 ChLinkMotorLinear::ArchiveIN(marchive);
200
201 // deserialize all member data:
202 marchive >> CHNVP(pos_offset);
203 marchive >> CHNVP(avoid_position_drift);
204 }
205
206 } // end namespace chrono
207