1 // =============================================================================
2 // PROJECT CHRONO - http://projectchrono.org
3 //
4 // Copyright (c) 2019 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: Asher Elmquist
13 // =============================================================================
14 //
15 // Chrono demonstration of a creating visual materials
16 //
17 // =============================================================================
18 
19 #include <cmath>
20 #include <cstdio>
21 #include <iomanip>
22 
23 #include "chrono/assets/ChTriangleMeshShape.h"
24 #include "chrono/assets/ChVisualMaterial.h"
25 #include "chrono/assets/ChVisualization.h"
26 #include "chrono/geometry/ChTriangleMeshConnected.h"
27 #include "chrono/physics/ChBodyEasy.h"
28 #include "chrono/physics/ChSystemNSC.h"
29 #include "chrono/utils/ChUtilsCreators.h"
30 #include "chrono_thirdparty/filesystem/path.h"
31 
32 #include "chrono_sensor/sensors/ChCameraSensor.h"
33 #include "chrono_sensor/ChSensorManager.h"
34 #include "chrono_sensor/filters/ChFilterAccess.h"
35 #include "chrono_sensor/filters/ChFilterGrayscale.h"
36 #include "chrono_sensor/filters/ChFilterSave.h"
37 #include "chrono_sensor/filters/ChFilterImageOps.h"
38 #include "chrono_sensor/filters/ChFilterVisualize.h"
39 
40 using namespace chrono;
41 using namespace chrono::geometry;
42 using namespace chrono::sensor;
43 
44 float end_time = 100.0f;
45 
main(int argc,char * argv[])46 int main(int argc, char* argv[]) {
47     GetLog() << "Copyright (c) 2019 projectchrono.org\nChrono version: " << CHRONO_VERSION << "\n\n";
48 
49     // -----------------
50     // Create the system
51     // -----------------
52     ChSystemNSC mphysicalSystem;
53 
54     int x_dim = 11;
55     int y_dim = 7;
56 
57     for (int i = 0; i <= x_dim; i++) {
58         for (int j = 0; j <= y_dim; j++) {
59             auto sphere1 = chrono_types::make_shared<ChBodyEasySphere>(.4, 1000, true, false);
60             sphere1->SetPos({0, i - (x_dim / 2.), j - (y_dim / 2.)});
61             sphere1->SetBodyFixed(true);
62             auto sphere_asset1 = sphere1->GetAssets()[0];
63             if (std::shared_ptr<ChVisualization> visual_asset =
64                     std::dynamic_pointer_cast<ChVisualization>(sphere_asset1)) {
65                 auto color = chrono_types::make_shared<ChVisualMaterial>();
66                 color->SetDiffuseColor({.8f, 0.f, 0.f});
67                 color->SetSpecularColor({(float)i / x_dim, (float)i / x_dim, (float)i / x_dim});
68                 color->SetMetallic((float)i / x_dim);
69                 color->SetRoughness(1 - (float)j / y_dim);
70                 color->SetUseSpecularWorkflow(false);
71                 visual_asset->material_list.push_back(color);
72             }
73             mphysicalSystem.Add(sphere1);
74         }
75     }
76 
77     auto sphere2 = chrono_types::make_shared<ChBodyEasySphere>(.001, 1000, false, false);
78     sphere2->SetPos({0, 0, 0});
79     sphere2->SetBodyFixed(true);
80     mphysicalSystem.Add(sphere2);
81 
82     // -----------------------
83     // Create a sensor manager
84     // -----------------------
85     auto manager = chrono_types::make_shared<ChSensorManager>(&mphysicalSystem);
86     manager->scene->AddPointLight({-100, 0, 100}, {1, 1, 1}, 500);
87     Background b;
88     b.mode = BackgroundMode::ENVIRONMENT_MAP;  // GRADIENT
89     b.color_zenith = {.5f, .6f, .7f};
90     b.color_horizon = {.9f, .8f, .7f};
91     b.env_tex = GetChronoDataFile("sensor/textures/sky_2_4k.hdr");
92     manager->scene->SetBackground(b);
93 
94     // ------------------------------------------------
95     // Create a camera and add it to the sensor manager
96     // ------------------------------------------------
97     auto cam = chrono_types::make_shared<ChCameraSensor>(
98         sphere2,                                                             // body camera is attached to
99         30.0f,                                                               // update rate in Hz
100         chrono::ChFrame<double>({-12, 0, 0}, Q_from_AngAxis(0, {0, 1, 0})),  // offset pose
101         1920,                                                                // image width
102         1080,                                                                // image height
103         (float)CH_C_PI / 3                                                   // FOV
104     );
105     cam->SetName("Camera Sensor");
106     cam->PushFilter(chrono_types::make_shared<ChFilterVisualize>(1280, 720, "For user display"));
107     manager->AddSensor(cam);
108 
109     auto cam_g = chrono_types::make_shared<ChCameraSensor>(
110         sphere2,                                                             // body camera is attached to
111         30.0f,                                                               // update rate in Hz
112         chrono::ChFrame<double>({-12, 0, 0}, Q_from_AngAxis(0, {0, 1, 0})),  // offset pose
113         1920,                                                                // image width
114         1080,                                                                // image height
115         (float)CH_C_PI / 3, 1, CameraLensModelType::PINHOLE, true            // FOV
116     );
117     cam_g->SetName("Camera Sensor");
118     cam_g->PushFilter(chrono_types::make_shared<ChFilterVisualize>(1280, 720, "For user display, GI"));
119     manager->AddSensor(cam_g);
120 
121     // ---------------
122     // Simulate system
123     // ---------------
124     float ch_time = 0.0;
125 
126     std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now();
127 
128     while (ch_time < end_time) {
129         manager->Update();
130         mphysicalSystem.DoStepDynamics(0.001);
131 
132         ch_time = (float)mphysicalSystem.GetChTime();
133     }
134     std::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now();
135     std::chrono::duration<double> wall_time = std::chrono::duration_cast<std::chrono::duration<double>>(t2 - t1);
136     std::cout << "Simulation time: " << ch_time << "s, wall time: " << wall_time.count() << "s.\n";
137 
138     return 0;
139 }
140