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: Radu Serban
13 // =============================================================================
14 //
15 // Demonstration of actuating a translational joint with a ChLinkForce.
16 // The model is built with gravity acting in the negative Y direction.
17 //
18 // Recall that Irrlicht uses a left-hand frame, so everything is rendered with
19 // left and right flipped.
20 //
21 // =============================================================================
22 
23 #include <cmath>
24 
25 #include "chrono/physics/ChSystemNSC.h"
26 #include "chrono/physics/ChBody.h"
27 #include "chrono/assets/ChPointPointDrawing.h"
28 
29 #include "chrono_irrlicht/ChIrrApp.h"
30 
31 using namespace chrono;
32 using namespace chrono::irrlicht;
33 
main(int argc,char * argv[])34 int main(int argc, char* argv[]) {
35     GetLog() << "Copyright (c) 2017 projectchrono.org\nChrono version: " << CHRONO_VERSION << "\n\n";
36 
37     ChSystemNSC system;
38     system.Set_G_acc(ChVector<>(0, 0, 0));
39 
40     // Create the ground body
41     auto ground = chrono_types::make_shared<ChBody>();
42     system.AddBody(ground);
43     ground->SetIdentifier(-1);
44     ground->SetBodyFixed(true);
45     ground->SetCollide(false);
46 
47     auto rail1 = chrono_types::make_shared<ChBoxShape>();
48     rail1->GetBoxGeometry().SetLengths(ChVector<>(8, 0.1, 0.1));
49     rail1->GetBoxGeometry().Pos = ChVector<>(0, 0, -1);
50     ground->AddAsset(rail1);
51 
52     auto rail2 = chrono_types::make_shared<ChBoxShape>();
53     rail2->GetBoxGeometry().SetLengths(ChVector<>(8, 0.1, 0.1));
54     rail2->GetBoxGeometry().Pos = ChVector<>(0, 0, +1);
55     ground->AddAsset(rail2);
56 
57     auto col = chrono_types::make_shared<ChColorAsset>();
58     col->SetColor(ChColor(0.6f, 0.6f, 0.6f));
59     ground->AddAsset(col);
60 
61     // Create the slider bodies
62     auto slider1 = chrono_types::make_shared<ChBody>();
63     system.AddBody(slider1);
64     slider1->SetIdentifier(1);
65     slider1->SetBodyFixed(false);
66     slider1->SetCollide(false);
67     slider1->SetMass(1);
68     slider1->SetInertiaXX(ChVector<>(0.1, 0.1, 0.1));
69     slider1->SetPos(ChVector<>(-4, 0, -1));
70 
71     auto cyl1 = chrono_types::make_shared<ChCylinderShape>();
72     cyl1->GetCylinderGeometry().p1 = ChVector<>(-0.2, 0, 0);
73     cyl1->GetCylinderGeometry().p2 = ChVector<>(+0.2, 0, 0);
74     cyl1->GetCylinderGeometry().rad = 0.2;
75     slider1->AddAsset(cyl1);
76 
77     auto col1 = chrono_types::make_shared<ChColorAsset>();
78     col1->SetColor(ChColor(0.6f, 0, 0));
79     slider1->AddAsset(col1);
80 
81     auto slider2 = chrono_types::make_shared<ChBody>();
82     system.AddBody(slider2);
83     slider2->SetIdentifier(1);
84     slider2->SetBodyFixed(false);
85     slider2->SetCollide(false);
86     slider2->SetMass(1);
87     slider2->SetInertiaXX(ChVector<>(0.1, 0.1, 01));
88     slider2->SetPos(ChVector<>(-4, 0, +1));
89 
90     auto cyl2 = chrono_types::make_shared<ChCylinderShape>();
91     cyl2->GetCylinderGeometry().p1 = ChVector<>(-0.2, 0, 0);
92     cyl2->GetCylinderGeometry().p2 = ChVector<>(+0.2, 0, 0);
93     cyl2->GetCylinderGeometry().rad = 0.2;
94     slider2->AddAsset(cyl2);
95 
96     auto col2 = chrono_types::make_shared<ChColorAsset>();
97     col2->SetColor(ChColor(0, 0, 0.6f));
98     slider2->AddAsset(col2);
99 
100     // Create prismatic joints between ground and sliders
101     auto prismatic1 = chrono_types::make_shared<ChLinkLockPrismatic>();
102     prismatic1->Initialize(slider1, ground, ChCoordsys<>(ChVector<>(0, 0, -1), Q_from_AngY(CH_C_PI_2)));
103     system.AddLink(prismatic1);
104 
105     auto prismatic2 = chrono_types::make_shared<ChLinkLockPrismatic>();
106     prismatic2->Initialize(slider2, ground, ChCoordsys<>(ChVector<>(0, 0, +1), Q_from_AngY(CH_C_PI_2)));
107     system.AddLink(prismatic2);
108 
109     // Sine function
110     double freq = 1;
111     double ampl = 4;
112     ////double omg = 2 * CH_C_PI * freq;
113     auto mod = chrono_types::make_shared<ChFunction_Sine>(0.0, freq, ampl);
114 
115     // Actuate first slider using a link force
116     prismatic1->GetForce_Z().SetActive(true);
117     prismatic1->GetForce_Z().SetF(1);
118     prismatic1->GetForce_Z().SetModulationF(mod);
119 
120     // Actuate second slider using a body force
121     auto frc2 = chrono_types::make_shared<ChForce>();
122     frc2->SetF_x(mod);
123     slider2->AddForce(frc2);
124 
125     // Create the Irrlicht application
126     ChIrrApp application(&system, L"Actuated prismatic joint", irr::core::dimension2d<irr::u32>(800, 600));
127     application.AddTypicalLogo();
128     application.AddTypicalSky();
129     application.AddTypicalLights();
130     application.AddTypicalCamera(irr::core::vector3df(-1, 1.5, -6));
131 
132     application.AssetBindAll();
133     application.AssetUpdateAll();
134 
135     application.SetTimestep(1e-3);
136 
137     // Simulation loop
138     ////double x0 = slider1->GetPos().x();
139     while (application.GetDevice()->run()) {
140         ////double time = system.GetChTime();
141 
142         // Output slider x position/velocity and analytical solution
143         ////double x = slider1->GetPos().x();
144         ////double x_d = slider1->GetPos_dt().x();
145         ////double xa = x0 + (ampl / omg) * (time - std::sin(omg * time) / omg);
146         ////double xa_d = (ampl / omg) * (1 - std::cos(omg * time));
147         ////std::cout << time << "   " << x << " " << x_d << "   " << xa << " " << xa_d << std::endl;
148 
149         application.BeginScene();
150         application.DrawAll();
151         tools::drawAllLinkframes(system, application.GetVideoDriver(), 1.0);
152         application.DoStep();
153         application.EndScene();
154     }
155 
156     return 0;
157 }
158