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 // Benchmark for testing changes to rendering algorimths
16 //
17 // =============================================================================
18 
19 #include "chrono/assets/ChTriangleMeshShape.h"
20 #include "chrono/assets/ChVisualMaterial.h"
21 #include "chrono/assets/ChVisualization.h"
22 #include "chrono/geometry/ChTriangleMeshConnected.h"
23 #include "chrono/physics/ChBodyEasy.h"
24 #include "chrono/physics/ChSystemNSC.h"
25 #include "chrono/utils/ChUtilsCreators.h"
26 #include "chrono_thirdparty/filesystem/path.h"
27 
28 #include "chrono_sensor/sensors/ChCameraSensor.h"
29 #include "chrono_sensor/ChSensorManager.h"
30 #include "chrono_sensor/filters/ChFilterAccess.h"
31 #include "chrono_sensor/filters/ChFilterGrayscale.h"
32 #include "chrono_sensor/filters/ChFilterSave.h"
33 #include "chrono_sensor/filters/ChFilterVisualize.h"
34 
35 using namespace chrono;
36 using namespace chrono::geometry;
37 using namespace chrono::sensor;
38 
39 float time_interval = 5.0f;
40 
41 float x_bound = 10;
42 float y_bound = 10;
43 float z_bound = 2;
44 
45 int start_exp = 17;
46 int stop_exp = 21;
47 
48 int obj_type = 0;  // 0=box, 1=sphere, 2=cylinder
49 
50 bool vis = true;
51 
randf()52 float randf() {
53     return static_cast<float>(rand()) / static_cast<float>(RAND_MAX);
54 }
55 
main(int argc,char * argv[])56 int main(int argc, char* argv[]) {
57     srand(0);
58     GetLog() << "Copyright (c) 2019 projectchrono.org\nChrono version: " << CHRONO_VERSION << "\n\n";
59 
60     // -----------------
61     // Create the system
62     // -----------------
63     ChSystemNSC mphysicalSystem;
64 
65     auto manager = std::make_shared<ChSensorManager>(&mphysicalSystem);
66     manager->scene->AddPointLight({100, 100, 100}, {1, 1, 1}, 5000);
67     manager->scene->AddPointLight({-100, 100, 100}, {1, 1, 1}, 5000);
68     manager->scene->AddPointLight({100, -100, 100}, {1, 1, 1}, 5000);
69     manager->scene->AddPointLight({-100, -100, 100}, {1, 1, 1}, 5000);
70 
71     auto cam_body = chrono_types::make_shared<ChBodyEasyBox>(.01, .01, .01, 1000, false, false);
72     cam_body->SetBodyFixed(true);
73     mphysicalSystem.Add(cam_body);
74     auto cam = std::make_shared<ChCameraSensor>(
75         cam_body,                                                           // body camera is attached to
76         10.0f,                                                              // update rate in Hz
77         chrono::ChFrame<double>({-8, 0, 1}, Q_from_AngAxis(0, {0, 1, 0})),  // offset pose
78         1280,                                                               // image width
79         720,                                                                // image height
80         (float)CH_C_PI / 3                                                  // FOV
81     );
82     cam->SetName("Camera Sensor");
83     if (vis)
84         cam->PushFilter(std::make_shared<ChFilterVisualize>(1280, 720));
85     manager->AddSensor(cam);
86 
87     int curr_item_cnt = 0;
88 
89     // ChBox box_asset = ChBox({0, 0, 0}, ChMatrix33<>(1), {1, 1, 1});
90     //
91     // auto box_shape = chrono_types::make_shared<ChBoxShape>(box_asset);
92     // box_shape->SetStatic(true);
93 
94     for (int q = start_exp; q <= stop_exp; q++) {
95         int target_item_cnt = pow(2, q);
96         std::cout << "Box Count: " << target_item_cnt << std::endl;
97         while (curr_item_cnt < target_item_cnt) {
98             if (obj_type == 2) {  // cylinder
99                 auto cyl = std::make_shared<ChBodyEasyCylinder>(randf() + .05, 2 * randf() + .1, 1000, true, false);
100                 cyl->SetBodyFixed(true);
101                 cyl->SetPos({2 * x_bound * (randf() - .5), 2 * y_bound * (randf() - .5), 2 * z_bound * (randf() - .5)});
102                 auto asset = cyl->GetAssets()[0];
103                 if (std::shared_ptr<ChVisualization> visual_asset = std::dynamic_pointer_cast<ChVisualization>(asset)) {
104                     auto vis_mat = std::make_shared<ChVisualMaterial>();
105                     vis_mat->SetAmbientColor({0.f, 0.f, 0.f});
106                     vis_mat->SetDiffuseColor({(float)ChRandom(), (float)ChRandom(), (float)ChRandom()});
107                     vis_mat->SetSpecularColor({.2f, .2f, .2f});
108 
109                     visual_asset->material_list.push_back(vis_mat);
110                 }
111                 mphysicalSystem.Add(cyl);
112                 curr_item_cnt++;
113             } else if (obj_type == 1) {  // sphere
114                 auto sphere = std::make_shared<ChBodyEasySphere>(randf() + .05, 1000, true, false);
115                 sphere->SetBodyFixed(true);
116                 sphere->SetPos(
117                     {2 * x_bound * (randf() - .5), 2 * y_bound * (randf() - .5), 2 * z_bound * (randf() - .5)});
118                 auto asset = sphere->GetAssets()[0];
119                 if (std::shared_ptr<ChVisualization> visual_asset = std::dynamic_pointer_cast<ChVisualization>(asset)) {
120                     auto vis_mat = std::make_shared<ChVisualMaterial>();
121                     vis_mat->SetAmbientColor({0.f, 0.f, 0.f});
122                     vis_mat->SetDiffuseColor({(float)ChRandom(), (float)ChRandom(), (float)ChRandom()});
123                     vis_mat->SetSpecularColor({.2f, .2f, .2f});
124 
125                     visual_asset->material_list.push_back(vis_mat);
126                 }
127                 mphysicalSystem.Add(sphere);
128                 curr_item_cnt++;
129             } else {  // box
130                 auto box = std::make_shared<ChBodyEasyBox>(2 * randf() + .1, 2 * randf() + .1, 2 * randf() + .1, 1000,
131                                                            true, false);
132                 box->SetBodyFixed(true);
133                 box->SetPos({2 * x_bound * (randf() - .5), 2 * y_bound * (randf() - .5), 2 * z_bound * (randf() - .5)});
134                 auto asset = box->GetAssets()[0];
135                 if (std::shared_ptr<ChVisualization> visual_asset = std::dynamic_pointer_cast<ChVisualization>(asset)) {
136                     auto vis_mat = std::make_shared<ChVisualMaterial>();
137                     vis_mat->SetAmbientColor({0.f, 0.f, 0.f});
138                     vis_mat->SetDiffuseColor({(float)ChRandom(), (float)ChRandom(), (float)ChRandom()});
139                     vis_mat->SetSpecularColor({.2f, .2f, .2f});
140 
141                     visual_asset->material_list.push_back(vis_mat);
142                 }
143                 mphysicalSystem.Add(box);
144                 curr_item_cnt++;
145             }
146         }
147 
148         manager->ReconstructScenes();
149         // ---------------
150         // Simulate system
151         // ---------------
152         float orbit_radius = 2 * sqrt(x_bound * x_bound + y_bound * y_bound);
153         float orbit_rate = 0.5;
154         float ch_time = 0.0;
155 
156         std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now();
157         float start_time = (float)mphysicalSystem.GetChTime();
158         while (ch_time < start_time + time_interval) {
159             cam->SetOffsetPose(chrono::ChFrame<double>(
160                 {-orbit_radius * cos(ch_time * orbit_rate), -orbit_radius * sin(ch_time * orbit_rate),
161                  .2 * orbit_radius},
162                 Q_from_AngAxis(ch_time * orbit_rate, {0, 0, 1}) * Q_from_AngAxis(.3, {0, 1, 0})));
163 
164             manager->Update();
165             mphysicalSystem.DoStepDynamics(0.1);
166 
167             ch_time = (float)mphysicalSystem.GetChTime();
168         }
169         std::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now();
170         std::chrono::duration<double> wall_time = std::chrono::duration_cast<std::chrono::duration<double>>(t2 - t1);
171         std::cout << "Num instances: " << curr_item_cnt << ", Simulation time: " << time_interval
172                   << ", wall time: " << wall_time.count() << ", RTF: " << time_interval / wall_time.count() << "\n";
173     }
174     return 0;
175 }
176