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 // Utility functions for parsing JSON files.
16 //
17 // =============================================================================
18 
19 #include <fstream>
20 
21 #include "chrono_vehicle/utils/ChUtilsJSON.h"
22 
23 #include "chrono_vehicle/chassis/RigidChassis.h"
24 #include "chrono_vehicle/chassis/ChassisConnectorHitch.h"
25 #include "chrono_vehicle/chassis/ChassisConnectorArticulated.h"
26 #include "chrono_vehicle/chassis/ChassisConnectorTorsion.h"
27 
28 #include "chrono_vehicle/powertrain/ShaftsPowertrain.h"
29 #include "chrono_vehicle/powertrain/SimpleCVTPowertrain.h"
30 #include "chrono_vehicle/powertrain/SimpleMapPowertrain.h"
31 #include "chrono_vehicle/powertrain/SimplePowertrain.h"
32 
33 #include "chrono_vehicle/wheeled_vehicle/antirollbar/AntirollBarRSD.h"
34 #include "chrono_vehicle/wheeled_vehicle/brake/BrakeSimple.h"
35 #include "chrono_vehicle/wheeled_vehicle/brake/BrakeShafts.h"
36 #include "chrono_vehicle/wheeled_vehicle/driveline/ShaftsDriveline2WD.h"
37 #include "chrono_vehicle/wheeled_vehicle/driveline/ShaftsDriveline4WD.h"
38 #include "chrono_vehicle/wheeled_vehicle/driveline/SimpleDriveline.h"
39 #include "chrono_vehicle/wheeled_vehicle/driveline/SimpleDrivelineXWD.h"
40 #include "chrono_vehicle/wheeled_vehicle/steering/PitmanArm.h"
41 #include "chrono_vehicle/wheeled_vehicle/steering/RackPinion.h"
42 #include "chrono_vehicle/wheeled_vehicle/steering/RotaryArm.h"
43 #include "chrono_vehicle/wheeled_vehicle/suspension/DoubleWishbone.h"
44 #include "chrono_vehicle/wheeled_vehicle/suspension/DoubleWishboneReduced.h"
45 #include "chrono_vehicle/wheeled_vehicle/suspension/HendricksonPRIMAXX.h"
46 #include "chrono_vehicle/wheeled_vehicle/suspension/LeafspringAxle.h"
47 #include "chrono_vehicle/wheeled_vehicle/suspension/SAELeafspringAxle.h"
48 #include "chrono_vehicle/wheeled_vehicle/suspension/MacPhersonStrut.h"
49 #include "chrono_vehicle/wheeled_vehicle/suspension/MultiLink.h"
50 #include "chrono_vehicle/wheeled_vehicle/suspension/RigidSuspension.h"
51 #include "chrono_vehicle/wheeled_vehicle/suspension/RigidPinnedAxle.h"
52 #include "chrono_vehicle/wheeled_vehicle/suspension/SemiTrailingArm.h"
53 #include "chrono_vehicle/wheeled_vehicle/suspension/SolidAxle.h"
54 #include "chrono_vehicle/wheeled_vehicle/suspension/SolidBellcrankThreeLinkAxle.h"
55 #include "chrono_vehicle/wheeled_vehicle/suspension/SolidThreeLinkAxle.h"
56 #include "chrono_vehicle/wheeled_vehicle/suspension/ThreeLinkIRS.h"
57 #include "chrono_vehicle/wheeled_vehicle/suspension/ToeBarLeafspringAxle.h"
58 #include "chrono_vehicle/wheeled_vehicle/suspension/SAEToeBarLeafspringAxle.h"
59 #include "chrono_vehicle/wheeled_vehicle/subchassis/Balancer.h"
60 #include "chrono_vehicle/wheeled_vehicle/tire/ANCFTire.h"
61 #include "chrono_vehicle/wheeled_vehicle/tire/FEATire.h"
62 #include "chrono_vehicle/wheeled_vehicle/tire/FialaTire.h"
63 #include "chrono_vehicle/wheeled_vehicle/tire/LugreTire.h"
64 #include "chrono_vehicle/wheeled_vehicle/tire/PacejkaTire.h"
65 #include "chrono_vehicle/wheeled_vehicle/tire/ReissnerTire.h"
66 #include "chrono_vehicle/wheeled_vehicle/tire/RigidTire.h"
67 #include "chrono_vehicle/wheeled_vehicle/tire/TMeasyTire.h"
68 #include "chrono_vehicle/wheeled_vehicle/tire/Pac89Tire.h"
69 #include "chrono_vehicle/wheeled_vehicle/tire/Pac02Tire.h"
70 #include "chrono_vehicle/wheeled_vehicle/wheel/Wheel.h"
71 
72 #include "chrono_vehicle/tracked_vehicle/brake/TrackBrakeSimple.h"
73 #include "chrono_vehicle/tracked_vehicle/brake/TrackBrakeShafts.h"
74 #include "chrono_vehicle/tracked_vehicle/driveline/SimpleTrackDriveline.h"
75 #include "chrono_vehicle/tracked_vehicle/driveline/TrackDrivelineBDS.h"
76 #include "chrono_vehicle/tracked_vehicle/idler/DoubleIdler.h"
77 #include "chrono_vehicle/tracked_vehicle/idler/SingleIdler.h"
78 #include "chrono_vehicle/tracked_vehicle/road_wheel/DoubleRoadWheel.h"
79 #include "chrono_vehicle/tracked_vehicle/road_wheel/SingleRoadWheel.h"
80 #include "chrono_vehicle/tracked_vehicle/roller/DoubleRoller.h"
81 #include "chrono_vehicle/tracked_vehicle/suspension/LinearDamperRWAssembly.h"
82 #include "chrono_vehicle/tracked_vehicle/suspension/RotationalDamperRWAssembly.h"
83 #include "chrono_vehicle/tracked_vehicle/track_assembly/TrackAssemblyBandANCF.h"
84 #include "chrono_vehicle/tracked_vehicle/track_assembly/TrackAssemblyBandBushing.h"
85 #include "chrono_vehicle/tracked_vehicle/track_assembly/TrackAssemblyDoublePin.h"
86 #include "chrono_vehicle/tracked_vehicle/track_assembly/TrackAssemblySinglePin.h"
87 
88 #include "chrono_thirdparty/rapidjson/filereadstream.h"
89 #include "chrono_thirdparty/rapidjson/istreamwrapper.h"
90 
91 using namespace rapidjson;
92 
93 namespace chrono {
94 namespace vehicle {
95 
96 // -----------------------------------------------------------------------------
97 
ReadFileJSON(const std::string & filename,Document & d)98 void ReadFileJSON(const std::string& filename, Document& d) {
99     std::ifstream ifs(filename);
100     if (!ifs.good()) {
101         GetLog() << "ERROR: Could not open JSON file: " << filename << "\n";
102     } else {
103         IStreamWrapper isw(ifs);
104         d.ParseStream<ParseFlag::kParseCommentsFlag>(isw);
105         if (d.IsNull()) {
106             GetLog() << "ERROR: Invalid JSON file: " << filename << "\n";
107         }
108     }
109 }
110 
111 // -----------------------------------------------------------------------------
112 
ReadVectorJSON(const Value & a)113 ChVector<> ReadVectorJSON(const Value& a) {
114     assert(a.IsArray());
115     assert(a.Size() == 3);
116     return ChVector<>(a[0u].GetDouble(), a[1u].GetDouble(), a[2u].GetDouble());
117 }
118 
ReadQuaternionJSON(const Value & a)119 ChQuaternion<> ReadQuaternionJSON(const Value& a) {
120     assert(a.IsArray());
121     assert(a.Size() == 4);
122     return ChQuaternion<>(a[0u].GetDouble(), a[1u].GetDouble(), a[2u].GetDouble(), a[3u].GetDouble());
123 }
124 
ReadColorJSON(const Value & a)125 ChColor ReadColorJSON(const Value& a) {
126     assert(a.IsArray());
127     assert(a.Size() == 3);
128     return ChColor(a[0u].GetFloat(), a[1u].GetFloat(), a[2u].GetFloat());
129 }
130 
131 // -----------------------------------------------------------------------------
132 
ReadMaterialInfoJSON(const rapidjson::Value & mat)133 MaterialInfo ReadMaterialInfoJSON(const rapidjson::Value& mat) {
134     MaterialInfo minfo;
135 
136     minfo.mu = mat["Coefficient of Friction"].GetFloat();
137     minfo.cr = mat["Coefficient of Restitution"].GetFloat();
138     if (mat.HasMember("Properties")) {
139         minfo.Y = mat["Properties"]["Young Modulus"].GetFloat();
140         minfo.nu = mat["Properties"]["Poisson Ratio"].GetFloat();
141     }
142     if (mat.HasMember("Coefficients")) {
143         minfo.kn = mat["Coefficients"]["Normal Stiffness"].GetFloat();
144         minfo.gn = mat["Coefficients"]["Normal Damping"].GetFloat();
145         minfo.kt = mat["Coefficients"]["Tangential Stiffness"].GetFloat();
146         minfo.gt = mat["Coefficients"]["Tangential Damping"].GetFloat();
147     }
148 
149     return minfo;
150 }
151 
ReadBushingDataJSON(const rapidjson::Value & bd)152 std::shared_ptr<ChVehicleBushingData> ReadBushingDataJSON(const rapidjson::Value& bd) {
153     auto bushing_data = chrono_types::make_shared<ChVehicleBushingData>();
154 
155     bushing_data->K_lin = bd["Stiffness Linear"].GetDouble();
156     bushing_data->D_lin = bd["Damping Linear"].GetDouble();
157     bushing_data->K_rot = bd["Stiffness Rotational"].GetDouble();
158     bushing_data->D_rot = bd["Damping Rotational"].GetDouble();
159 
160     if (bd.HasMember("DOF")) {
161         bushing_data->K_lin_dof = bd["DOF"]["Stiffness Linear"].GetDouble();
162         bushing_data->D_lin_dof = bd["DOF"]["Damping Linear"].GetDouble();
163         bushing_data->K_rot_dof = bd["DOF"]["Stiffness Rotational"].GetDouble();
164         bushing_data->D_rot_dof = bd["DOF"]["Damping Rotational"].GetDouble();
165     }
166 
167     return bushing_data;
168 }
169 
170 
171 // -----------------------------------------------------------------------------
172 
ReadChassisJSON(const std::string & filename)173 std::shared_ptr<ChChassis> ReadChassisJSON(const std::string& filename) {
174     std::shared_ptr<ChChassis> chassis;
175 
176     Document d;ReadFileJSON(filename, d);
177     if (d.IsNull())
178         return nullptr;
179 
180     // Check that the given file is a chassis specification file.
181     assert(d.HasMember("Type"));
182     std::string type = d["Type"].GetString();
183     assert(type.compare("Chassis") == 0);
184 
185     // Extract the chassis type.
186     assert(d.HasMember("Template"));
187     std::string subtype = d["Template"].GetString();
188 
189     // Create the chassis using the appropriate template.
190     if (subtype.compare("RigidChassis") == 0) {
191         chassis = chrono_types::make_shared<RigidChassis>(d);
192     } else {
193         throw ChException("Chassis type not supported in ReadChassisJSON.");
194     }
195 
196     return chassis;
197 }
198 
ReadChassisRearJSON(const std::string & filename)199 std::shared_ptr<ChChassisRear> ReadChassisRearJSON(const std::string& filename) {
200     std::shared_ptr<ChChassisRear> chassis;
201 
202     Document d;ReadFileJSON(filename, d);
203     if (d.IsNull())
204         return nullptr;
205 
206     // Check that the given file is a rear chassis specification file.
207     assert(d.HasMember("Type"));
208     std::string type = d["Type"].GetString();
209     assert(type.compare("ChassisRear") == 0);
210 
211     // Extract the chassis type.
212     assert(d.HasMember("Template"));
213     std::string subtype = d["Template"].GetString();
214 
215     // Create the chassis using the appropriate template.
216     if (subtype.compare("RigidChassisRear") == 0) {
217         chassis = chrono_types::make_shared<RigidChassisRear>(d);
218     } else {
219         throw ChException("Chassis type not supported in ReadChassisRearJSON.");
220     }
221 
222     return chassis;
223 }
224 
ReadChassisConnectorJSON(const std::string & filename)225 std::shared_ptr<ChChassisConnector> ReadChassisConnectorJSON(const std::string& filename) {
226     std::shared_ptr<ChChassisConnector> connector;
227 
228     Document d;ReadFileJSON(filename, d);
229     if (d.IsNull())
230         return nullptr;
231 
232     // Check that the given file is a chassis connector specification file.
233     assert(d.HasMember("Type"));
234     std::string type = d["Type"].GetString();
235     assert(type.compare("ChassisConnector") == 0);
236 
237     // Extract the connector type.
238     assert(d.HasMember("Template"));
239     std::string subtype = d["Template"].GetString();
240 
241     // Create the connector using the appropriate template.
242     if (subtype.compare("ChassisConnectorHitch") == 0) {
243         connector = chrono_types::make_shared<ChassisConnectorHitch>(d);
244     } else if (subtype.compare("ChassisConnectorArticulated") == 0) {
245         connector = chrono_types::make_shared<ChassisConnectorArticulated>(d);
246     } else if (subtype.compare("ChassisConnectorTorsion") == 0) {
247         connector = chrono_types::make_shared<ChassisConnectorTorsion>(d);
248     } else {
249         throw ChException("Chassis type not supported in ReadChassisConnectorJSON.");
250     }
251 
252     return connector;
253 }
254 
ReadPowertrainJSON(const std::string & filename)255 std::shared_ptr<ChPowertrain> ReadPowertrainJSON(const std::string& filename) {
256     std::shared_ptr<ChPowertrain> powertrain;
257 
258     Document d;
259     ReadFileJSON(filename, d);
260     if (d.IsNull())
261         return nullptr;
262 
263     // Check that the given file is a powertrain specification file.
264     assert(d.HasMember("Type"));
265     std::string type = d["Type"].GetString();
266     assert(type.compare("Powertrain") == 0);
267 
268     // Extract the powertrain type.
269     assert(d.HasMember("Template"));
270     std::string subtype = d["Template"].GetString();
271 
272     // Create the powertrain using the appropriate template.
273     if (subtype.compare("ShaftsPowertrain") == 0) {
274         powertrain = chrono_types::make_shared<ShaftsPowertrain>(d);
275     } else if (subtype.compare("SimpleCVTPowertrain") == 0) {
276         powertrain = chrono_types::make_shared<SimpleCVTPowertrain>(d);
277     } else if (subtype.compare("SimpleMapPowertrain") == 0) {
278         powertrain = chrono_types::make_shared<SimpleMapPowertrain>(d);
279     } else if (subtype.compare("SimplePowertrain") == 0) {
280         powertrain = chrono_types::make_shared<SimplePowertrain>(d);
281     } else {
282         throw ChException("Powertrain type not supported in ReadChassisJSON.");
283     }
284 
285     return powertrain;
286 }
287 
288 // -----------------------------------------------------------------------------
289 
ReadSuspensionJSON(const std::string & filename)290 std::shared_ptr<ChSuspension> ReadSuspensionJSON(const std::string& filename) {
291     std::shared_ptr<ChSuspension> suspension;
292 
293     Document d;ReadFileJSON(filename, d);
294     if (d.IsNull())
295         return nullptr;
296 
297     // Check that the given file is a suspension specification file.
298     assert(d.HasMember("Type"));
299     std::string type = d["Type"].GetString();
300     assert(type.compare("Suspension") == 0);
301 
302     // Extract the suspension type.
303     assert(d.HasMember("Template"));
304     std::string subtype = d["Template"].GetString();
305 
306     // Create the suspension using the appropriate template.
307     if (subtype.compare("DoubleWishbone") == 0) {
308         suspension = chrono_types::make_shared<DoubleWishbone>(d);
309     } else if (subtype.compare("DoubleWishboneReduced") == 0) {
310         suspension = chrono_types::make_shared<DoubleWishboneReduced>(d);
311     } else if (subtype.compare("SolidAxle") == 0) {
312         suspension = chrono_types::make_shared<SolidAxle>(d);
313     } else if (subtype.compare("MultiLink") == 0) {
314         suspension = chrono_types::make_shared<MultiLink>(d);
315     } else if (subtype.compare("MacPhersonStrut") == 0) {
316         suspension = chrono_types::make_shared<MacPhersonStrut>(d);
317     } else if (subtype.compare("SemiTrailingArm") == 0) {
318         suspension = chrono_types::make_shared<SemiTrailingArm>(d);
319     } else if (subtype.compare("ThreeLinkIRS") == 0) {
320         suspension = chrono_types::make_shared<ThreeLinkIRS>(d);
321     } else if (subtype.compare("ToeBarLeafspringAxle") == 0) {
322         suspension = chrono_types::make_shared<ToeBarLeafspringAxle>(d);
323     } else if (subtype.compare("SAEToeBarLeafspringAxle") == 0) {
324         suspension = chrono_types::make_shared<SAEToeBarLeafspringAxle>(d);
325     } else if (subtype.compare("LeafspringAxle") == 0) {
326         suspension = chrono_types::make_shared<LeafspringAxle>(d);
327     } else if (subtype.compare("SAELeafspringAxle") == 0) {
328         suspension = chrono_types::make_shared<SAELeafspringAxle>(d);
329     } else if (subtype.compare("SolidThreeLinkAxle") == 0) {
330         suspension = chrono_types::make_shared<SolidThreeLinkAxle>(d);
331     } else if (subtype.compare("SolidBellcrankThreeLinkAxle") == 0) {
332         suspension = chrono_types::make_shared<SolidBellcrankThreeLinkAxle>(d);
333     } else if (subtype.compare("RigidSuspension") == 0) {
334         suspension = chrono_types::make_shared<RigidSuspension>(d);
335     } else if (subtype.compare("RigidPinnedAxle") == 0) {
336         suspension = chrono_types::make_shared<RigidPinnedAxle>(d);
337     } else if (subtype.compare("HendricksonPRIMAXX") == 0) {
338         suspension = chrono_types::make_shared<HendricksonPRIMAXX>(d);
339     } else {
340         throw ChException("Suspension type not supported in ReadSuspensionJSON.");
341     }
342 
343     return suspension;
344 }
345 
ReadSteeringJSON(const std::string & filename)346 std::shared_ptr<ChSteering> ReadSteeringJSON(const std::string& filename) {
347     std::shared_ptr<ChSteering> steering;
348 
349     Document d;ReadFileJSON(filename, d);
350     if (d.IsNull())
351         return nullptr;
352 
353     // Check that the given file is a steering specification file.
354     assert(d.HasMember("Type"));
355     std::string type = d["Type"].GetString();
356     assert(type.compare("Steering") == 0);
357 
358     // Extract the steering type.
359     assert(d.HasMember("Template"));
360     std::string subtype = d["Template"].GetString();
361 
362     // Create the steering using the appropriate template.
363     if (subtype.compare("PitmanArm") == 0) {
364         steering = chrono_types::make_shared<PitmanArm>(d);
365     } else if (subtype.compare("RackPinion") == 0) {
366         steering = chrono_types::make_shared<RackPinion>(d);
367     } else if (subtype.compare("RotaryArm") == 0) {
368         steering = chrono_types::make_shared<RotaryArm>(d);
369     } else {
370         throw ChException("Steering type not supported in ReadSteeringJSON.");
371     }
372 
373     return steering;
374 }
375 
ReadDrivelineWVJSON(const std::string & filename)376 std::shared_ptr<ChDrivelineWV> ReadDrivelineWVJSON(const std::string& filename) {
377     std::shared_ptr<ChDrivelineWV> driveline;
378 
379     Document d;ReadFileJSON(filename, d);
380     if (d.IsNull())
381         return nullptr;
382 
383     // Check that the given file is a driveline specification file.
384     assert(d.HasMember("Type"));
385     std::string type = d["Type"].GetString();
386     assert(type.compare("Driveline") == 0);
387 
388     // Extract the driveline type.
389     assert(d.HasMember("Template"));
390     std::string subtype = d["Template"].GetString();
391 
392     // Create the driveline using the appropriate template.
393     if (subtype.compare("ShaftsDriveline2WD") == 0) {
394         driveline = chrono_types::make_shared<ShaftsDriveline2WD>(d);
395     } else if (subtype.compare("ShaftsDriveline4WD") == 0) {
396         driveline = chrono_types::make_shared<ShaftsDriveline4WD>(d);
397     } else if (subtype.compare("SimpleDriveline") == 0) {
398         driveline = chrono_types::make_shared<SimpleDriveline>(d);
399     } else if (subtype.compare("SimpleDrivelineXWD") == 0) {
400         driveline = chrono_types::make_shared<SimpleDrivelineXWD>(d);
401     } else {
402         throw ChException("Driveline type not supported in ReadDrivelineWVJSON.");
403     }
404 
405     return driveline;
406 }
407 
ReadAntirollbarJSON(const std::string & filename)408 std::shared_ptr<ChAntirollBar> ReadAntirollbarJSON(const std::string& filename) {
409     std::shared_ptr<ChAntirollBar> antirollbar;
410 
411     Document d;ReadFileJSON(filename, d);
412     if (d.IsNull())
413         return nullptr;
414 
415     // Check that the given file is an antirollbar specification file.
416     assert(d.HasMember("Type"));
417     std::string type = d["Type"].GetString();
418     assert(type.compare("Antirollbar") == 0);
419 
420     // Extract the antirollbar type.
421     assert(d.HasMember("Template"));
422     std::string subtype = d["Template"].GetString();
423 
424     // Create the antirollbar using the appropriate template.
425     if (subtype.compare("AntirollBarRSD") == 0) {
426         antirollbar = chrono_types::make_shared<AntirollBarRSD>(d);
427     } else {
428         throw ChException("AntirollBar type not supported in ReadAntirollbarJSON.");
429     }
430 
431     return antirollbar;
432 }
433 
ReadWheelJSON(const std::string & filename)434 std::shared_ptr<ChWheel> ReadWheelJSON(const std::string& filename) {
435     std::shared_ptr<ChWheel> wheel;
436 
437     Document d;ReadFileJSON(filename, d);
438     if (d.IsNull())
439         return nullptr;
440 
441     // Check that the given file is a wheel specification file.
442     assert(d.HasMember("Type"));
443     std::string type = d["Type"].GetString();
444     assert(type.compare("Wheel") == 0);
445 
446     // Extract the wheel type.
447     assert(d.HasMember("Template"));
448     std::string subtype = d["Template"].GetString();
449 
450     // Create the wheel using the appropriate template.
451     if (subtype.compare("Wheel") == 0) {
452         wheel = chrono_types::make_shared<Wheel>(d);
453     } else {
454         throw ChException("Wheel type not supported in ReadWheelJSON.");
455     }
456 
457     return wheel;
458 }
459 
ReadSubchassisJSON(const std::string & filename)460 std::shared_ptr<ChSubchassis> ReadSubchassisJSON(const std::string& filename) {
461     std::shared_ptr<ChSubchassis> chassis;
462 
463     Document d;
464     ReadFileJSON(filename, d);
465     if (d.IsNull())
466         return nullptr;
467 
468     // Check that the given file is a wheel specification file.
469     assert(d.HasMember("Type"));
470     std::string type = d["Type"].GetString();
471     assert(type.compare("Subchassis") == 0);
472 
473     // Extract the wheel type.
474     assert(d.HasMember("Template"));
475     std::string subtype = d["Template"].GetString();
476 
477     // Create the wheel using the appropriate template.
478     if (subtype.compare("Balancer") == 0) {
479         chassis = chrono_types::make_shared<Balancer>(d);
480     } else {
481         throw ChException("Subchassis type not supported in ReadSubchassisJSON.");
482     }
483 
484     return chassis;
485 }
486 
ReadBrakeJSON(const std::string & filename)487 std::shared_ptr<ChBrake> ReadBrakeJSON(const std::string& filename) {
488     std::shared_ptr<ChBrake> brake;
489 
490     Document d;ReadFileJSON(filename, d);
491     if (d.IsNull())
492         return nullptr;
493 
494     // Check that the given file is a brake specification file.
495     assert(d.HasMember("Type"));
496     std::string type = d["Type"].GetString();
497     assert(type.compare("Brake") == 0);
498 
499     // Extract the brake type.
500     assert(d.HasMember("Template"));
501     std::string subtype = d["Template"].GetString();
502 
503     // Create the brake using the appropriate template.
504     if (subtype.compare("BrakeSimple") == 0) {
505         brake = chrono_types::make_shared<BrakeSimple>(d);
506     } else if (subtype.compare("BrakeShafts") == 0) {
507         brake = chrono_types::make_shared<BrakeShafts>(d);
508     } else {
509         throw ChException("Brake type not supported in ReadBrakeJSON.");
510     }
511 
512     return brake;
513 }
514 
ReadTireJSON(const std::string & filename)515 std::shared_ptr<ChTire> ReadTireJSON(const std::string& filename) {
516     std::shared_ptr<ChTire> tire;
517 
518     Document d;ReadFileJSON(filename, d);
519     if (d.IsNull())
520         return nullptr;
521 
522     // Check that the given file is a tire specification file.
523     assert(d.HasMember("Type"));
524     std::string type = d["Type"].GetString();
525     assert(type.compare("Tire") == 0);
526 
527     // Extract the tire type.
528     assert(d.HasMember("Template"));
529     std::string subtype = d["Template"].GetString();
530 
531     // Create the tire using the appropriate template.
532     if (subtype.compare("RigidTire") == 0) {
533         tire = chrono_types::make_shared<RigidTire>(d);
534     } else if (subtype.compare("TMeasyTire") == 0) {
535         tire = chrono_types::make_shared<TMeasyTire>(d);
536     } else if (subtype.compare("FialaTire") == 0) {
537         tire = chrono_types::make_shared<FialaTire>(d);
538     } else if (subtype.compare("LugreTire") == 0) {
539         tire = chrono_types::make_shared<LugreTire>(d);
540     } else if (subtype.compare("PacejkaTire") == 0) {
541         tire = chrono_types::make_shared<PacejkaTire>(d);
542     } else if (subtype.compare("Pac89Tire") == 0) {
543         tire = chrono_types::make_shared<Pac89Tire>(d);
544     } else if (subtype.compare("Pac02Tire") == 0) {
545         tire = chrono_types::make_shared<Pac02Tire>(d);
546     } else if (subtype.compare("ANCFTire") == 0) {
547         tire = chrono_types::make_shared<ANCFTire>(d);
548     } else if (subtype.compare("ReissnerTire") == 0) {
549         tire = chrono_types::make_shared<ReissnerTire>(d);
550     } else if (subtype.compare("FEATire") == 0) {
551         tire = chrono_types::make_shared<FEATire>(d);
552     } else {
553         throw ChException("Tire type not supported in ReadTireJSON.");
554     }
555 
556     return tire;
557 }
558 
559 // -----------------------------------------------------------------------------
560 
ReadTrackAssemblyJSON(const std::string & filename)561 std::shared_ptr<ChTrackAssembly> ReadTrackAssemblyJSON(const std::string& filename) {
562     std::shared_ptr<ChTrackAssembly> track;
563 
564     Document d;ReadFileJSON(filename, d);
565     if (d.IsNull())
566         return nullptr;
567 
568     // Check that the given file is a steering specification file.
569     assert(d.HasMember("Type"));
570     std::string type = d["Type"].GetString();
571     assert(type.compare("TrackAssembly") == 0);
572 
573     // Extract the track assembly type.
574     assert(d.HasMember("Template"));
575     std::string subtype = d["Template"].GetString();
576 
577     // Create the steering using the appropriate template.
578     if (subtype.compare("TrackAssemblySinglePin") == 0) {
579         track = chrono_types::make_shared<TrackAssemblySinglePin>(d);
580     } else if (subtype.compare("TrackAssemblyDoublePin") == 0) {
581         track = chrono_types::make_shared<TrackAssemblyDoublePin>(d);
582     } else if (subtype.compare("TrackAssemblyBandBushing") == 0) {
583         track = chrono_types::make_shared<TrackAssemblyBandBushing>(d);
584     } else if (subtype.compare("TrackAssemblyBandANCF") == 0) {
585         track = chrono_types::make_shared<TrackAssemblyBandANCF>(d);
586     } else {
587         throw ChException("TrackAssembly type not supported in ReadTrackAssemblyJSON.");
588     }
589 
590     return track;
591 }
592 
ReadDrivelineTVJSON(const std::string & filename)593 std::shared_ptr<ChDrivelineTV> ReadDrivelineTVJSON(const std::string& filename) {
594     std::shared_ptr<ChDrivelineTV> driveline;
595 
596     Document d;ReadFileJSON(filename, d);
597     if (d.IsNull())
598         return nullptr;
599 
600     // Check that the given file is a driveline specification file.
601     assert(d.HasMember("Type"));
602     std::string type = d["Type"].GetString();
603     assert(type.compare("TrackDriveline") == 0);
604 
605     // Extract the driveline type.
606     assert(d.HasMember("Template"));
607     std::string subtype = d["Template"].GetString();
608 
609     // Create the driveline using the appropriate template.
610     if (subtype.compare("SimpleTrackDriveline") == 0) {
611         driveline = chrono_types::make_shared<SimpleTrackDriveline>(d);
612     } else if (subtype.compare("TrackDrivelineBDS") == 0) {
613         driveline = chrono_types::make_shared<TrackDrivelineBDS>(d);
614     } else {
615         throw ChException("Driveline type not supported in ReadTrackDrivelineJSON.");
616     }
617 
618     return driveline;
619 }
620 
ReadTrackBrakeJSON(const std::string & filename)621 std::shared_ptr<ChTrackBrake> ReadTrackBrakeJSON(const std::string& filename) {
622     std::shared_ptr<ChTrackBrake> brake;
623 
624     Document d;ReadFileJSON(filename, d);
625     if (d.IsNull())
626         return nullptr;
627 
628     // Check that the given file is a brake specification file.
629     assert(d.HasMember("Type"));
630     std::string type = d["Type"].GetString();
631     assert(type.compare("TrackBrake") == 0);
632 
633     // Extract brake type.
634     assert(d.HasMember("Template"));
635     std::string subtype = d["Template"].GetString();
636 
637     // Create the brake using the appropriate template.
638     if (subtype.compare("TrackBrakeSimple") == 0) {
639         brake = chrono_types::make_shared<TrackBrakeSimple>(d);
640     } else if (subtype.compare("TrackBrakeShafts") == 0) {
641         brake = chrono_types::make_shared<TrackBrakeShafts>(d);
642     } else {
643         throw ChException("Brake type not supported in ReadTrackBrakeJSON.");
644     }
645 
646     return brake;
647 }
648 
ReadIdlerJSON(const std::string & filename)649 std::shared_ptr<ChIdler> ReadIdlerJSON(const std::string& filename) {
650     std::shared_ptr<ChIdler> idler;
651 
652     Document d;ReadFileJSON(filename, d);
653     if (d.IsNull())
654         return nullptr;
655 
656     // Check that the given file is an idler specification file.
657     assert(d.HasMember("Type"));
658     std::string type = d["Type"].GetString();
659     assert(type.compare("Idler") == 0);
660 
661     // Extract idler type.
662     assert(d.HasMember("Template"));
663     std::string subtype = d["Template"].GetString();
664 
665     // Create the idler using the appropriate template.
666     if (subtype.compare("SingleIdler") == 0) {
667         idler = chrono_types::make_shared<SingleIdler>(d);
668     } else if (subtype.compare("DoubleIdler") == 0) {
669         idler = chrono_types::make_shared<DoubleIdler>(d);
670     } else {
671         throw ChException("Idler type not supported in ReadIdlerJSON.");
672     }
673 
674     return idler;
675 }
676 
ReadRoadWheelAssemblyJSON(const std::string & filename,bool has_shock)677 std::shared_ptr<ChRoadWheelAssembly> ReadRoadWheelAssemblyJSON(const std::string& filename, bool has_shock) {
678     std::shared_ptr<ChRoadWheelAssembly> suspension;
679 
680     Document d;ReadFileJSON(filename, d);
681     if (d.IsNull())
682         return nullptr;
683 
684     // Check that the given file is a road-wheel assembly specification file.
685     assert(d.HasMember("Type"));
686     std::string type = d["Type"].GetString();
687     assert(type.compare("RoadWheelAssembly") == 0);
688 
689     // Extract road-wheel assembly type.
690     assert(d.HasMember("Template"));
691     std::string subtype = d["Template"].GetString();
692 
693     // Create the road-wheel assembly using the appropriate template.
694     if (subtype.compare("LinearDamperRWAssembly") == 0) {
695         suspension = chrono_types::make_shared<LinearDamperRWAssembly>(d, has_shock);
696     } else if (subtype.compare("RotationalDamperRWAssembly") == 0) {
697         suspension = chrono_types::make_shared<RotationalDamperRWAssembly>(d, has_shock);
698     } else {
699         throw ChException("Suspension type not supported in ReadRoadWheelAssemblyJSON.");
700     }
701 
702     return suspension;
703 }
704 
ReadRollerJSON(const std::string & filename)705 std::shared_ptr<ChRoller> ReadRollerJSON(const std::string& filename) {
706     std::shared_ptr<ChRoller> roller;
707 
708     Document d;ReadFileJSON(filename, d);
709     if (d.IsNull())
710         return nullptr;
711 
712     // Check that the given file is a roller specification file.
713     assert(d.HasMember("Type"));
714     std::string type = d["Type"].GetString();
715     assert(type.compare("Roller") == 0);
716 
717     // Extract roller type.
718     assert(d.HasMember("Template"));
719     std::string subtype = d["Template"].GetString();
720 
721     // Create the roller using the appropriate template.
722     if (subtype.compare("DoubleRoller") == 0) {
723         roller = chrono_types::make_shared<DoubleRoller>(d);
724     } else {
725         throw ChException("Roller type not supported in ReadRollerJSON.");
726     }
727 
728     return roller;
729 }
730 
ReadRoadWheelJSON(const std::string & filename)731 std::shared_ptr<ChRoadWheel> ReadRoadWheelJSON(const std::string& filename) {
732     std::shared_ptr<ChRoadWheel> wheel;
733 
734     Document d;ReadFileJSON(filename, d);
735     if (d.IsNull())
736         return nullptr;
737 
738     // Check that the given file is a road-wheel specification file.
739     assert(d.HasMember("Type"));
740     std::string type = d["Type"].GetString();
741     assert(type.compare("RoadWheel") == 0);
742 
743     // Extract the road-wheel type
744     assert(d.HasMember("Template"));
745     std::string subtype = d["Template"].GetString();
746 
747     // Create the road-wheel using the appropriate template.
748     if (subtype.compare("SingleRoadWheel") == 0) {
749         wheel = chrono_types::make_shared<SingleRoadWheel>(d);
750     } else if (subtype.compare("DoubleRoadWheel") == 0) {
751         wheel = chrono_types::make_shared<DoubleRoadWheel>(d);
752     } else {
753         throw ChException("Road-wheel type not supported in ReadRoadWheelJSON.");
754     }
755 
756     return wheel;
757 }
758 
759 }  // end namespace vehicle
760 }  // end namespace chrono
761