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