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 // Track assembly (double-pin) model constructed from a JSON specification file
16 //
17 // =============================================================================
18
19 #include "chrono_vehicle/tracked_vehicle/track_assembly/TrackAssemblyDoublePin.h"
20
21 #include "chrono_vehicle/tracked_vehicle/sprocket/SprocketDoublePin.h"
22 #include "chrono_vehicle/tracked_vehicle/track_shoe/TrackShoeDoublePin.h"
23
24 #include "chrono_vehicle/tracked_vehicle/brake/TrackBrakeSimple.h"
25
26 #include "chrono_vehicle/tracked_vehicle/idler/SingleIdler.h"
27 #include "chrono_vehicle/tracked_vehicle/idler/DoubleIdler.h"
28
29 #include "chrono_vehicle/tracked_vehicle/suspension/LinearDamperRWAssembly.h"
30
31 #include "chrono_vehicle/tracked_vehicle/roller/DoubleRoller.h"
32
33 #include "chrono_vehicle/ChVehicleModelData.h"
34 #include "chrono_vehicle/utils/ChUtilsJSON.h"
35
36 using namespace rapidjson;
37
38 namespace chrono {
39 namespace vehicle {
40
41 // -----------------------------------------------------------------------------
42 // -----------------------------------------------------------------------------
ReadSprocket(const std::string & filename,int output)43 void TrackAssemblyDoublePin::ReadSprocket(const std::string& filename, int output) {
44 Document d; ReadFileJSON(filename, d);
45 if (d.IsNull())
46 return;
47
48 // Check that the given file is a sprocket specification file.
49 assert(d.HasMember("Type"));
50 std::string type = d["Type"].GetString();
51 assert(type.compare("Sprocket") == 0);
52
53 // Check sprocket type.
54 assert(d.HasMember("Template"));
55 std::string subtype = d["Template"].GetString();
56 assert(subtype.compare("SprocketDoublePin") == 0);
57
58 // Create the sprocket using the appropriate template.
59 m_sprocket = chrono_types::make_shared<SprocketDoublePin>(d);
60
61 // A non-zero value of 'output' indicates overwriting the subsystem's flag
62 if (output != 0) {
63 m_sprocket->SetOutput(output == +1);
64 }
65
66 GetLog() << " Loaded JSON: " << filename.c_str() << "\n";
67 }
68
69 // -----------------------------------------------------------------------------
70 // -----------------------------------------------------------------------------
ReadTrackShoes(const std::string & filename,int num_shoes,int output)71 void TrackAssemblyDoublePin::ReadTrackShoes(const std::string& filename, int num_shoes, int output) {
72 Document d; ReadFileJSON(filename, d);
73 if (d.IsNull())
74 return;
75
76 // Check that the given file is a track shoe specification file.
77 assert(d.HasMember("Type"));
78 std::string type = d["Type"].GetString();
79 assert(type.compare("TrackShoe") == 0);
80
81 // Check track shoe type.
82 assert(d.HasMember("Template"));
83 std::string subtype = d["Template"].GetString();
84 assert(subtype.compare("TrackShoeDoublePin") == 0);
85
86 // Create the track shoes using the appropriate template.
87 for (size_t it = 0; it < num_shoes; it++) {
88 m_shoes.push_back(chrono_types::make_shared<TrackShoeDoublePin>(d));
89 }
90
91 // A non-zero value of 'output' indicates overwriting the subsystem's flag
92 if (output != 0) {
93 m_shoes[0]->SetOutput(output == +1);
94 }
95
96 GetLog() << " Loaded JSON: " << filename.c_str() << "\n";
97 }
98
99 // -----------------------------------------------------------------------------
100 // -----------------------------------------------------------------------------
TrackAssemblyDoublePin(const std::string & filename)101 TrackAssemblyDoublePin::TrackAssemblyDoublePin(const std::string& filename) : ChTrackAssemblyDoublePin("", LEFT) {
102 Document d; ReadFileJSON(filename, d);
103 if (d.IsNull())
104 return;
105
106 Create(d);
107
108 GetLog() << "Loaded JSON: " << filename.c_str() << "\n";
109 }
110
TrackAssemblyDoublePin(const rapidjson::Document & d)111 TrackAssemblyDoublePin::TrackAssemblyDoublePin(const rapidjson::Document& d) : ChTrackAssemblyDoublePin("", LEFT) {
112 Create(d);
113 }
114
Create(const rapidjson::Document & d)115 void TrackAssemblyDoublePin::Create(const rapidjson::Document& d) {
116 // Invoke base class method.
117 ChPart::Create(d);
118
119 // Create the sprocket
120 {
121 assert(d.HasMember("Sprocket"));
122 std::string file_name = d["Sprocket"]["Input File"].GetString();
123 int output = 0;
124 if (d["Sprocket"].HasMember("Output")) {
125 output = d["Sprocket"]["Output"].GetBool() ? +1 : -1;
126 }
127 ReadSprocket(vehicle::GetDataFile(file_name), output);
128 m_sprocket_loc = ReadVectorJSON(d["Sprocket"]["Location"]);
129 }
130
131 // Create the brake
132 {
133 assert(d.HasMember("Brake"));
134 std::string file_name = d["Brake"]["Input File"].GetString();
135 m_brake = ReadTrackBrakeJSON(vehicle::GetDataFile(file_name));
136 if (d["Brake"].HasMember("Output")) {
137 m_brake->SetOutput(d["Brake"]["Output"].GetBool());
138 }
139 }
140
141 // Create the idler
142 {
143 assert(d.HasMember("Idler"));
144 std::string file_name = d["Idler"]["Input File"].GetString();
145 m_idler = ReadIdlerJSON(vehicle::GetDataFile(file_name));
146 if (d["Idler"].HasMember("Output")) {
147 m_idler->SetOutput(d["Idler"]["Output"].GetBool());
148 }
149 m_idler_loc = ReadVectorJSON(d["Idler"]["Location"]);
150 }
151
152 // Create the suspensions
153 assert(d.HasMember("Suspension Subsystems"));
154 assert(d["Suspension Subsystems"].IsArray());
155 m_num_susp = d["Suspension Subsystems"].Size();
156 m_suspensions.resize(m_num_susp);
157 m_susp_locs.resize(m_num_susp);
158 for (int i = 0; i < m_num_susp; i++) {
159 std::string file_name = d["Suspension Subsystems"][i]["Input File"].GetString();
160 bool has_shock = d["Suspension Subsystems"][i]["Has Shock"].GetBool();
161 m_suspensions[i] = ReadRoadWheelAssemblyJSON(vehicle::GetDataFile(file_name), has_shock);
162 if (d["Suspension Subsystems"][i].HasMember("Output")) {
163 m_suspensions[i]->SetOutput(d["Suspension Subsystems"][i]["Output"].GetBool());
164 }
165 m_susp_locs[i] = ReadVectorJSON(d["Suspension Subsystems"][i]["Location"]);
166 }
167
168 // Create the rollers
169 m_num_rollers = 0;
170 if (d.HasMember("Rollers")) {
171 assert(d["Rollers"].IsArray());
172 m_num_rollers = d["Rollers"].Size();
173 m_rollers.resize(m_num_rollers);
174 m_roller_locs.resize(m_num_rollers);
175 for (int i = 0; i < m_num_rollers; i++) {
176 std::string file_name = d["Rollers"][i]["Input File"].GetString();
177 m_rollers[i] = ReadRollerJSON(vehicle::GetDataFile(file_name));
178 if (d["Rollers"][i].HasMember("Output")) {
179 m_rollers[i]->SetOutput(d["Rollers"][i]["Output"].GetBool());
180 }
181 m_roller_locs[i] = ReadVectorJSON(d["Rollers"][i]["Location"]);
182 }
183 }
184
185 // Create the track shoes
186 {
187 assert(d.HasMember("Track Shoes"));
188 std::string file_name = d["Track Shoes"]["Input File"].GetString();
189 int output = 0;
190 if (d["Track Shoes"].HasMember("Output")) {
191 output = d["Track Shoes"]["Output"].GetBool() ? +1 : -1;
192 }
193 m_num_track_shoes = d["Track Shoes"]["Number Shoes"].GetInt();
194 ReadTrackShoes(vehicle::GetDataFile(file_name), m_num_track_shoes, output);
195
196 if (d["Track Shoes"].HasMember("RSDA Data")) {
197 double k = d["Track Shoes"]["RSDA Data"]["Stiffness Rotational"].GetDouble();
198 double c = d["Track Shoes"]["RSDA Data"]["Damping Rotational"].GetDouble();
199 m_torque_funct = chrono_types::make_shared<ChTrackAssemblySegmented::TrackBendingFunctor>(k, c);
200 }
201
202 if (d["Track Shoes"].HasMember("Bushing Data")) {
203 m_bushing_data = ReadBushingDataJSON(d["Track Shoes"]["Bushing Data"]);
204 }
205 }
206 }
207
208 } // end namespace vehicle
209 } // end namespace chrono
210