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 #include <cstdlib>
16 #include <algorithm>
17
18 #include "chrono/core/ChTransform.h"
19 #include "chrono/physics/ChConveyor.h"
20 #include "chrono/physics/ChSystem.h"
21
22 namespace chrono {
23
24 using namespace collision;
25 using namespace geometry;
26
27 // Register into the object factory, to enable run-time dynamic creation and persistence
CH_FACTORY_REGISTER(ChConveyor)28 CH_FACTORY_REGISTER(ChConveyor)
29
30 ChConveyor::ChConveyor(double xlength, double ythick, double zwidth) : conveyor_speed(1) {
31 conveyor_truss = new ChBody;
32 conveyor_plate = new ChBody;
33
34 conveyor_mat = chrono_types::make_shared<ChMaterialSurfaceNSC>();
35
36 conveyor_plate->GetCollisionModel()->ClearModel();
37 conveyor_plate->GetCollisionModel()->AddBox(conveyor_mat, xlength * 0.5, ythick * 0.5, zwidth * 0.5);
38 conveyor_plate->GetCollisionModel()->BuildModel();
39 conveyor_plate->SetCollide(true);
40
41 internal_link = new ChLinkLockLock;
42 internal_link->SetMotion_X(chrono_types::make_shared<ChFunction_Ramp>());
43
44 std::shared_ptr<ChMarker> mmark1(new ChMarker);
45 std::shared_ptr<ChMarker> mmark2(new ChMarker);
46 conveyor_truss->AddMarker(mmark1);
47 conveyor_plate->AddMarker(mmark2);
48
49 internal_link->ReferenceMarkers(mmark1.get(), mmark2.get());
50 }
51
ChConveyor(const ChConveyor & other)52 ChConveyor::ChConveyor(const ChConveyor& other) : ChPhysicsItem(other) {
53 conveyor_speed = other.conveyor_speed;
54 internal_link = other.internal_link->Clone();
55 conveyor_plate = other.conveyor_plate->Clone();
56 conveyor_truss = other.conveyor_truss->Clone();
57
58 //// RADU: more to do here
59 }
60
~ChConveyor()61 ChConveyor::~ChConveyor() {
62 if (internal_link)
63 delete internal_link;
64 if (conveyor_plate)
65 delete conveyor_plate;
66 if (conveyor_truss)
67 delete conveyor_truss;
68 }
69
70 //// STATE BOOKKEEPING FUNCTIONS
71
IntStateGather(const unsigned int off_x,ChState & x,const unsigned int off_v,ChStateDelta & v,double & T)72 void ChConveyor::IntStateGather(const unsigned int off_x, // offset in x state vector
73 ChState& x, // state vector, position part
74 const unsigned int off_v, // offset in v state vector
75 ChStateDelta& v, // state vector, speed part
76 double& T // time
77 ) {
78 conveyor_truss->IntStateGather(off_x, x, off_v, v, T);
79 conveyor_plate->IntStateGather(off_x + 7, x, off_v + 6, v, T);
80 }
81
IntStateScatter(const unsigned int off_x,const ChState & x,const unsigned int off_v,const ChStateDelta & v,const double T,bool full_update)82 void ChConveyor::IntStateScatter(const unsigned int off_x, // offset in x state vector
83 const ChState& x, // state vector, position part
84 const unsigned int off_v, // offset in v state vector
85 const ChStateDelta& v, // state vector, speed part
86 const double T, // time
87 bool full_update // perform complete update
88 ) {
89 conveyor_truss->IntStateScatter(off_x, x, off_v, v, T, full_update);
90 conveyor_plate->IntStateScatter(off_x + 7, x, off_v + 6, v, T, full_update);
91 this->Update(T, full_update);
92 }
93
IntStateGatherAcceleration(const unsigned int off_a,ChStateDelta & a)94 void ChConveyor::IntStateGatherAcceleration(const unsigned int off_a, ChStateDelta& a) {
95 conveyor_truss->IntStateGatherAcceleration(off_a, a);
96 conveyor_plate->IntStateGatherAcceleration(off_a + 6, a);
97 }
98
IntStateScatterAcceleration(const unsigned int off_a,const ChStateDelta & a)99 void ChConveyor::IntStateScatterAcceleration(const unsigned int off_a, const ChStateDelta& a) {
100 conveyor_truss->IntStateScatterAcceleration(off_a, a);
101 conveyor_plate->IntStateScatterAcceleration(off_a + 6, a);
102 }
103
IntStateGatherReactions(const unsigned int off_L,ChVectorDynamic<> & L)104 void ChConveyor::IntStateGatherReactions(const unsigned int off_L, ChVectorDynamic<>& L) {
105 internal_link->IntStateGatherReactions(off_L, L);
106 }
107
IntStateScatterReactions(const unsigned int off_L,const ChVectorDynamic<> & L)108 void ChConveyor::IntStateScatterReactions(const unsigned int off_L, const ChVectorDynamic<>& L) {
109 internal_link->IntStateScatterReactions(off_L, L);
110 }
111
IntStateIncrement(const unsigned int off_x,ChState & x_new,const ChState & x,const unsigned int off_v,const ChStateDelta & Dv)112 void ChConveyor::IntStateIncrement(const unsigned int off_x, // offset in x state vector
113 ChState& x_new, // state vector, position part, incremented result
114 const ChState& x, // state vector, initial position part
115 const unsigned int off_v, // offset in v state vector
116 const ChStateDelta& Dv // state vector, increment
117 ) {
118 conveyor_truss->IntStateIncrement(off_x, x_new, x, off_v, Dv);
119 conveyor_plate->IntStateIncrement(off_x + 7, x_new, x, off_v + 6, Dv);
120 }
121
IntLoadResidual_F(const unsigned int off,ChVectorDynamic<> & R,const double c)122 void ChConveyor::IntLoadResidual_F(const unsigned int off, // offset in R residual
123 ChVectorDynamic<>& R, // result: the R residual, R += c*F
124 const double c // a scaling factor
125 ) {
126 conveyor_truss->IntLoadResidual_F(off, R, c);
127 conveyor_plate->IntLoadResidual_F(off + 6, R, c);
128 }
129
IntLoadResidual_Mv(const unsigned int off,ChVectorDynamic<> & R,const ChVectorDynamic<> & w,const double c)130 void ChConveyor::IntLoadResidual_Mv(const unsigned int off, // offset in R residual
131 ChVectorDynamic<>& R, // result: the R residual, R += c*M*v
132 const ChVectorDynamic<>& w, // the w vector
133 const double c // a scaling factor
134 ) {
135 conveyor_truss->IntLoadResidual_Mv(off, R, w, c);
136 conveyor_plate->IntLoadResidual_Mv(off + 6, R, w, c);
137 }
138
IntToDescriptor(const unsigned int off_v,const ChStateDelta & v,const ChVectorDynamic<> & R,const unsigned int off_L,const ChVectorDynamic<> & L,const ChVectorDynamic<> & Qc)139 void ChConveyor::IntToDescriptor(const unsigned int off_v,
140 const ChStateDelta& v,
141 const ChVectorDynamic<>& R,
142 const unsigned int off_L,
143 const ChVectorDynamic<>& L,
144 const ChVectorDynamic<>& Qc) {
145 conveyor_truss->IntToDescriptor(off_v, v, R, off_L, L, Qc);
146 conveyor_plate->IntToDescriptor(off_v + 6, v, R, off_L, L, Qc);
147 internal_link->IntToDescriptor(off_v, v, R, off_L, L, Qc);
148 }
149
IntFromDescriptor(const unsigned int off_v,ChStateDelta & v,const unsigned int off_L,ChVectorDynamic<> & L)150 void ChConveyor::IntFromDescriptor(const unsigned int off_v, // offset in v
151 ChStateDelta& v,
152 const unsigned int off_L, // offset in L
153 ChVectorDynamic<>& L) {
154 conveyor_truss->IntFromDescriptor(off_v, v, off_L, L);
155 conveyor_plate->IntFromDescriptor(off_v + 6, v, off_L, L);
156 internal_link->IntFromDescriptor(off_v, v, off_L, L);
157 }
158
IntLoadResidual_CqL(const unsigned int off_L,ChVectorDynamic<> & R,const ChVectorDynamic<> & L,const double c)159 void ChConveyor::IntLoadResidual_CqL(const unsigned int off_L,
160 ChVectorDynamic<>& R,
161 const ChVectorDynamic<>& L,
162 const double c) {
163 internal_link->IntLoadResidual_CqL(off_L, R, L, c);
164 }
165
IntLoadConstraint_C(const unsigned int off,ChVectorDynamic<> & Qc,const double c,bool do_clamp,double recovery_clamp)166 void ChConveyor::IntLoadConstraint_C(const unsigned int off,
167 ChVectorDynamic<>& Qc,
168 const double c,
169 bool do_clamp,
170 double recovery_clamp) {
171 internal_link->IntLoadConstraint_C(off, Qc, c, do_clamp, recovery_clamp);
172 }
173
IntLoadConstraint_Ct(const unsigned int off,ChVectorDynamic<> & Qc,const double c)174 void ChConveyor::IntLoadConstraint_Ct(const unsigned int off, ChVectorDynamic<>& Qc, const double c) {
175 internal_link->IntLoadConstraint_Ct(off, Qc, c);
176 }
177
178 // SOLVER INTERFACE
179
InjectVariables(ChSystemDescriptor & mdescriptor)180 void ChConveyor::InjectVariables(ChSystemDescriptor& mdescriptor) {
181 conveyor_truss->InjectVariables(mdescriptor);
182 conveyor_plate->InjectVariables(mdescriptor);
183 }
184
VariablesFbReset()185 void ChConveyor::VariablesFbReset() {
186 conveyor_truss->VariablesFbReset();
187 conveyor_plate->VariablesFbReset();
188 }
189
VariablesFbLoadForces(double factor)190 void ChConveyor::VariablesFbLoadForces(double factor) {
191 conveyor_truss->VariablesFbLoadForces(factor);
192 conveyor_plate->VariablesFbLoadForces(factor);
193 }
194
VariablesFbIncrementMq()195 void ChConveyor::VariablesFbIncrementMq() {
196 conveyor_truss->VariablesFbIncrementMq();
197 conveyor_plate->VariablesFbIncrementMq();
198 }
199
VariablesQbLoadSpeed()200 void ChConveyor::VariablesQbLoadSpeed() {
201 conveyor_truss->VariablesFbIncrementMq();
202 conveyor_plate->VariablesQbLoadSpeed();
203 }
204
VariablesQbSetSpeed(double step)205 void ChConveyor::VariablesQbSetSpeed(double step) {
206 conveyor_truss->VariablesQbSetSpeed(step);
207 conveyor_plate->VariablesQbSetSpeed(step);
208 }
209
VariablesQbIncrementPosition(double dt_step)210 void ChConveyor::VariablesQbIncrementPosition(double dt_step) {
211 conveyor_truss->VariablesQbIncrementPosition(dt_step);
212 conveyor_plate->VariablesQbIncrementPosition(dt_step);
213 }
214
InjectConstraints(ChSystemDescriptor & mdescriptor)215 void ChConveyor::InjectConstraints(ChSystemDescriptor& mdescriptor) {
216 internal_link->InjectConstraints(mdescriptor);
217 }
218
ConstraintsBiReset()219 void ChConveyor::ConstraintsBiReset() {
220 internal_link->ConstraintsBiReset();
221 }
222
ConstraintsBiLoad_C(double factor,double recovery_clamp,bool do_clamp)223 void ChConveyor::ConstraintsBiLoad_C(double factor, double recovery_clamp, bool do_clamp) {
224 internal_link->ConstraintsBiLoad_C(factor, recovery_clamp, do_clamp);
225 }
226
ConstraintsBiLoad_Ct(double factor)227 void ChConveyor::ConstraintsBiLoad_Ct(double factor) {
228 internal_link->ConstraintsBiLoad_Ct(factor);
229 }
230
ConstraintsBiLoad_Qc(double factor)231 void ChConveyor::ConstraintsBiLoad_Qc(double factor) {
232 internal_link->ConstraintsBiLoad_Qc(factor);
233 }
234
ConstraintsLoadJacobians()235 void ChConveyor::ConstraintsLoadJacobians() {
236 internal_link->ConstraintsLoadJacobians();
237 }
238
ConstraintsFetch_react(double factor)239 void ChConveyor::ConstraintsFetch_react(double factor) {
240 internal_link->ConstraintsFetch_react(factor);
241 }
242
SetSystem(ChSystem * m_system)243 void ChConveyor::SetSystem(ChSystem* m_system) {
244 system = m_system;
245 conveyor_truss->SetSystem(m_system);
246 conveyor_plate->SetSystem(m_system);
247 internal_link->SetSystem(m_system);
248 }
249
Update(double mytime,bool update_assets)250 void ChConveyor::Update(double mytime, bool update_assets) {
251 // inherit parent class function
252 ChPhysicsItem::Update(mytime, update_assets);
253
254 conveyor_truss->Update(mytime, update_assets);
255
256 if (conveyor_truss->GetBodyFixed()) {
257 double largemass = 100000;
258 conveyor_plate->SetMass(largemass);
259 conveyor_plate->SetInertiaXX(ChVector<>(largemass, largemass, largemass));
260 conveyor_plate->SetInertiaXY(ChVector<>(0, 0, 0));
261 } else {
262 conveyor_plate->SetMass(conveyor_truss->GetMass());
263 conveyor_plate->SetInertiaXX(conveyor_truss->GetInertiaXX());
264 conveyor_plate->SetInertiaXY(conveyor_truss->GetInertiaXY());
265 }
266
267 // keep the plate always at the same position of the main reference
268 conveyor_plate->SetCoord(conveyor_truss->GetCoord());
269 conveyor_plate->SetCoord_dt(conveyor_truss->GetCoord_dt());
270 // keep the plate always at the same speed of the main reference, plus the conveyor speed on X local axis
271 conveyor_plate->SetPos_dt(conveyor_truss->GetPos_dt() + (ChVector<>(conveyor_speed, 0, 0) >> (*conveyor_truss)));
272
273 conveyor_plate->Update(mytime, update_assets);
274
275 std::static_pointer_cast<ChFunction_Ramp>(internal_link->GetMotion_X())->Set_ang(-conveyor_speed);
276 // always zero pos. offset (trick):
277 std::static_pointer_cast<ChFunction_Ramp>(internal_link->GetMotion_X())->Set_y0(+conveyor_speed * GetChTime());
278
279 internal_link->Update(mytime, update_assets);
280 }
281
SyncCollisionModels()282 void ChConveyor::SyncCollisionModels() {
283 // inherit parent class
284 ChPhysicsItem::SyncCollisionModels();
285
286 conveyor_truss->SyncCollisionModels();
287 conveyor_plate->SyncCollisionModels();
288 }
289
AddCollisionModelsToSystem()290 void ChConveyor::AddCollisionModelsToSystem() {
291 // inherit parent class
292 ChPhysicsItem::AddCollisionModelsToSystem();
293 // conveyor_truss->AddCollisionModelsToSystem();
294 // conveyor_plate->AddCollisionModelsToSystem();
295 }
296
RemoveCollisionModelsFromSystem()297 void ChConveyor::RemoveCollisionModelsFromSystem() {
298 // inherit parent class
299 ChPhysicsItem::RemoveCollisionModelsFromSystem();
300 // conveyor_plate->RemoveCollisionModelsFromSystem();
301 // conveyor_truss->RemoveCollisionModelsFromSystem();
302 }
303
304 // FILE I/O
305
ArchiveOUT(ChArchiveOut & marchive)306 void ChConveyor::ArchiveOUT(ChArchiveOut& marchive) {
307 // version number
308 marchive.VersionWrite<ChConveyor>();
309
310 // serialize parent class
311 ChPhysicsItem::ArchiveOUT(marchive);
312
313 // serialize all member data:
314 marchive << CHNVP(conveyor_speed);
315 marchive << CHNVP(conveyor_truss);
316 marchive << CHNVP(conveyor_plate);
317 marchive << CHNVP(internal_link);
318 }
319
320 /// Method to allow de serialization of transient data from archives.
ArchiveIN(ChArchiveIn & marchive)321 void ChConveyor::ArchiveIN(ChArchiveIn& marchive) {
322 // version number
323 /*int version =*/ marchive.VersionRead<ChConveyor>();
324
325 // deserialize parent class
326 ChPhysicsItem::ArchiveIN(marchive);
327
328 // stream in all member data:
329 marchive >> CHNVP(conveyor_speed);
330 marchive >> CHNVP(conveyor_truss);
331 marchive >> CHNVP(conveyor_plate);
332 marchive >> CHNVP(internal_link);
333 }
334
335 } // end namespace chrono
336