// ----------------------------------------------------------------------------- // Worker function for creating a DoubleWishbone suspension using data in the // specified RapidJSON document. // ----------------------------------------------------------------------------- void DoubleWishbone::Create(const rapidjson::Document& d) { // Read top-level data assert(d.HasMember("Type")); assert(d.HasMember("Template")); assert(d.HasMember("Name")); SetName(d["Name"].GetString()); // Read flag indicating that inertia matrices are expressed in // vehicle-aligned centroidal frame. if (d.HasMember("Vehicle-Frame Inertia")) { bool flag = d["Vehicle-Frame Inertia"].GetBool(); SetVehicleFrameInertiaFlag(flag); } // Read Spindle data assert(d.HasMember("Spindle")); assert(d["Spindle"].IsObject()); m_spindleMass = d["Spindle"]["Mass"].GetDouble(); m_points[SPINDLE] = loadVector(d["Spindle"]["COM"]); m_spindleInertia = loadVector(d["Spindle"]["Inertia"]); m_spindleRadius = d["Spindle"]["Radius"].GetDouble(); m_spindleWidth = d["Spindle"]["Width"].GetDouble(); // Read Upright data assert(d.HasMember("Upright")); assert(d["Upright"].IsObject()); m_uprightMass = d["Upright"]["Mass"].GetDouble(); m_points[UPRIGHT] = loadVector(d["Upright"]["COM"]); m_uprightInertiaMoments = loadVector(d["Upright"]["Moments of Inertia"]); m_uprightInertiaProducts = loadVector(d["Upright"]["Products of Inertia"]); m_uprightRadius = d["Upright"]["Radius"].GetDouble(); // Read UCA data assert(d.HasMember("Upper Control Arm")); assert(d["Upper Control Arm"].IsObject()); m_UCAMass = d["Upper Control Arm"]["Mass"].GetDouble(); m_points[UCA_CM] = loadVector(d["Upper Control Arm"]["COM"]); m_UCAInertiaMoments = loadVector(d["Upper Control Arm"]["Moments of Inertia"]); m_UCAInertiaProducts = loadVector(d["Upper Control Arm"]["Products of Inertia"]); m_UCARadius = d["Upper Control Arm"]["Radius"].GetDouble(); m_points[UCA_F] = loadVector(d["Upper Control Arm"]["Location Chassis Front"]); m_points[UCA_B] = loadVector(d["Upper Control Arm"]["Location Chassis Back"]); m_points[UCA_U] = loadVector(d["Upper Control Arm"]["Location Upright"]); // Read LCA data assert(d.HasMember("Lower Control Arm")); assert(d["Lower Control Arm"].IsObject()); m_LCAMass = d["Lower Control Arm"]["Mass"].GetDouble(); m_points[LCA_CM] = loadVector(d["Lower Control Arm"]["COM"]); m_LCAInertiaMoments = loadVector(d["Lower Control Arm"]["Moments of Inertia"]); m_LCAInertiaProducts = loadVector(d["Lower Control Arm"]["Products of Inertia"]); m_LCARadius = d["Lower Control Arm"]["Radius"].GetDouble(); m_points[LCA_F] = loadVector(d["Lower Control Arm"]["Location Chassis Front"]); m_points[LCA_B] = loadVector(d["Lower Control Arm"]["Location Chassis Back"]); m_points[LCA_U] = loadVector(d["Lower Control Arm"]["Location Upright"]); // Read Tierod data assert(d.HasMember("Tierod")); assert(d["Tierod"].IsObject()); m_points[TIEROD_C] = loadVector(d["Tierod"]["Location Chassis"]); m_points[TIEROD_U] = loadVector(d["Tierod"]["Location Upright"]); // Read spring data and create force callback assert(d.HasMember("Spring")); assert(d["Spring"].IsObject()); m_points[SPRING_C] = loadVector(d["Spring"]["Location Chassis"]); m_points[SPRING_A] = loadVector(d["Spring"]["Location Arm"]); m_springRestLength = d["Spring"]["Free Length"].GetDouble(); if (d["Spring"].HasMember("Spring Coefficient")) { m_springForceCB = new LinearSpringForce(d["Spring"]["Spring Coefficient"].GetDouble()); } else if (d["Spring"].HasMember("Curve Data")) { int num_points = d["Spring"]["Curve Data"].Size(); MapSpringForce* springForceCB = new MapSpringForce(); for (int i = 0; i < num_points; i++) { springForceCB->add_point(d["Spring"]["Curve Data"][i][0u].GetDouble(), d["Spring"]["Curve Data"][i][1u].GetDouble()); } m_springForceCB = springForceCB; } // Read shock data and create force callback assert(d.HasMember("Shock")); assert(d["Shock"].IsObject()); m_points[SHOCK_C] = loadVector(d["Shock"]["Location Chassis"]); m_points[SHOCK_A] = loadVector(d["Shock"]["Location Arm"]); if (d["Shock"].HasMember("Damping Coefficient")) { m_shockForceCB = new LinearDamperForce(d["Shock"]["Damping Coefficient"].GetDouble()); } else if (d["Shock"].HasMember("Curve Data")) { int num_points = d["Shock"]["Curve Data"].Size(); MapDamperForce* shockForceCB = new MapDamperForce(); for (int i = 0; i < num_points; i++) { shockForceCB->add_point(d["Shock"]["Curve Data"][i][0u].GetDouble(), d["Shock"]["Curve Data"][i][1u].GetDouble()); } m_shockForceCB = shockForceCB; } // Read axle inertia assert(d.HasMember("Axle")); assert(d["Axle"].IsObject()); m_axleInertia = d["Axle"]["Inertia"].GetDouble(); }
// ----------------------------------------------------------------------------- // Worker function for creating a ToeBarLeafspringAxle suspension using data in the // specified RapidJSON document. // ----------------------------------------------------------------------------- void ToeBarLeafspringAxle::Create(const rapidjson::Document& d) { // Invoke base class method. ChPart::Create(d); // Read Spindle data assert(d.HasMember("Spindle")); assert(d["Spindle"].IsObject()); m_spindleMass = d["Spindle"]["Mass"].GetDouble(); m_points[SPINDLE] = LoadVectorJSON(d["Spindle"]["COM"]); m_spindleInertia = LoadVectorJSON(d["Spindle"]["Inertia"]); m_spindleRadius = d["Spindle"]["Radius"].GetDouble(); m_spindleWidth = d["Spindle"]["Width"].GetDouble(); // Read Axle Tube data assert(d.HasMember("Axle Tube")); assert(d["Axle Tube"].IsObject()); m_axleTubeMass = d["Axle Tube"]["Mass"].GetDouble(); m_axleTubeCOM = LoadVectorJSON(d["Axle Tube"]["COM"]); m_axleTubeInertia = LoadVectorJSON(d["Axle Tube"]["Inertia"]); m_axleTubeRadius = d["Axle Tube"]["Radius"].GetDouble(); // Read Knuckle data assert(d.HasMember("Knuckle")); assert(d["Knuckle"].IsObject()); m_knuckleMass = d["Knuckle"]["Mass"].GetDouble(); m_points[KNUCKLE_CM] = LoadVectorJSON(d["Knuckle"]["COM"]); m_knuckleInertia = LoadVectorJSON(d["Knuckle"]["Inertia"]); m_knuckleRadius = d["Knuckle"]["Radius"].GetDouble(); m_points[KNUCKLE_L] = LoadVectorJSON(d["Knuckle"]["Location Lower"]); m_points[KNUCKLE_U] = LoadVectorJSON(d["Knuckle"]["Location Upper"]); m_points[KNUCKLE_DRL] = LoadVectorJSON(d["Knuckle"]["Location Draglink"]); if (m_points[KNUCKLE_DRL].y() < 0.0) { m_use_left_knuckle = false; m_points[KNUCKLE_DRL].y() *= -1.0; std::cout << "Right Knuckle is actuated!" << std::endl; } // Read Tierod aka Toe Bar data assert(d.HasMember("Tierod")); assert(d["Tierod"].IsObject()); m_tierodMass = d["Tierod"]["Mass"].GetDouble(); m_tierodInertia = LoadVectorJSON(d["Tierod"]["Inertia"]); m_points[TIEROD_K] = LoadVectorJSON(d["Tierod"]["Location Knuckle"]); m_tierodRadius = d["Tierod"]["Radius"].GetDouble(); // Read spring data and create force callback assert(d.HasMember("Draglink")); assert(d["Draglink"].IsObject()); m_draglinkMass = d["Draglink"]["Mass"].GetDouble(); m_draglinkInertia = LoadVectorJSON(d["Draglink"]["Inertia"]); m_points[DRAGLINK_C] = LoadVectorJSON(d["Draglink"]["Location Chassis"]); m_draglinkRadius = d["Draglink"]["Radius"].GetDouble(); // Read Draglink data assert(d.HasMember("Tierod")); assert(d["Tierod"].IsObject()); m_points[SPRING_C] = LoadVectorJSON(d["Spring"]["Location Chassis"]); m_points[SPRING_A] = LoadVectorJSON(d["Spring"]["Location Axle"]); m_springRestLength = d["Spring"]["Free Length"].GetDouble(); m_springMinLength = d["Spring"]["Minimal Length"].GetDouble(); m_springMaxLength = d["Spring"]["Maximal Length"].GetDouble(); if (d["Spring"].HasMember("Spring Coefficient")) { m_springForceCB = new LinearSpringBistopForce(d["Spring"]["Spring Coefficient"].GetDouble(), m_springMinLength, m_springMaxLength); } else if (d["Spring"].HasMember("Curve Data")) { int num_points = d["Spring"]["Curve Data"].Size(); MapSpringForce* springForceCB = new MapSpringForce(); for (int i = 0; i < num_points; i++) { springForceCB->add_point(d["Spring"]["Curve Data"][i][0u].GetDouble(), d["Spring"]["Curve Data"][i][1u].GetDouble()); } m_springForceCB = springForceCB; } // Read shock data and create force callback assert(d.HasMember("Shock")); assert(d["Shock"].IsObject()); m_points[SHOCK_C] = LoadVectorJSON(d["Shock"]["Location Chassis"]); m_points[SHOCK_A] = LoadVectorJSON(d["Shock"]["Location Axle"]); if (d["Shock"].HasMember("Damping Coefficient")) { if (d["Shock"].HasMember("Degressivity Compression") && d["Shock"].HasMember("Degressivity Expansion")) { m_shockForceCB = new DegressiveDamperForce(d["Shock"]["Damping Coefficient"].GetDouble(), d["Shock"]["Degressivity Compression"].GetDouble(), d["Shock"]["Degressivity Expansion"].GetDouble()); } else { m_shockForceCB = new LinearDamperForce(d["Shock"]["Damping Coefficient"].GetDouble()); } } else if (d["Shock"].HasMember("Curve Data")) { int num_points = d["Shock"]["Curve Data"].Size(); MapDamperForce* shockForceCB = new MapDamperForce(); for (int i = 0; i < num_points; i++) { shockForceCB->add_point(d["Shock"]["Curve Data"][i][0u].GetDouble(), d["Shock"]["Curve Data"][i][1u].GetDouble()); } m_shockForceCB = shockForceCB; } // Read axle inertia assert(d.HasMember("Axle")); assert(d["Axle"].IsObject()); m_axleInertia = d["Axle"]["Inertia"].GetDouble(); }
// ----------------------------------------------------------------------------- // Worker function for creating a SemiTrailingArm suspension using data in the // specified RapidJSON document. // ----------------------------------------------------------------------------- void SemiTrailingArm::Create(const rapidjson::Document& d) { // Invoke base class method. ChPart::Create(d); // Read Spindle data assert(d.HasMember("Spindle")); assert(d["Spindle"].IsObject()); m_spindleMass = d["Spindle"]["Mass"].GetDouble(); m_points[SPINDLE] = LoadVectorJSON(d["Spindle"]["COM"]); m_spindleInertia = LoadVectorJSON(d["Spindle"]["Inertia"]); m_spindleRadius = d["Spindle"]["Radius"].GetDouble(); m_spindleWidth = d["Spindle"]["Width"].GetDouble(); // Read trailing arm data assert(d.HasMember("Trailing Arm")); assert(d["Trailing Arm"].IsObject()); m_armMass = d["Trailing Arm"]["Mass"].GetDouble(); m_points[TA_CM] = LoadVectorJSON(d["Trailing Arm"]["COM"]); m_armInertia = LoadVectorJSON(d["Trailing Arm"]["Inertia"]); m_armRadius = d["Trailing Arm"]["Radius"].GetDouble(); m_points[TA_O] = LoadVectorJSON(d["Trailing Arm"]["Location Chassis Outer"]); m_points[TA_I] = LoadVectorJSON(d["Trailing Arm"]["Location Chassis Inner"]); m_points[TA_S] = LoadVectorJSON(d["Trailing Arm"]["Location Spindle"]); // Read spring data and create force callback assert(d.HasMember("Spring")); assert(d["Spring"].IsObject()); m_points[SPRING_C] = LoadVectorJSON(d["Spring"]["Location Chassis"]); m_points[SPRING_A] = LoadVectorJSON(d["Spring"]["Location Arm"]); m_springRestLength = d["Spring"]["Free Length"].GetDouble(); if (d["Spring"].HasMember("Spring Coefficient")) { m_springForceCB = new LinearSpringForce(d["Spring"]["Spring Coefficient"].GetDouble()); } else if (d["Spring"].HasMember("Curve Data")) { int num_points = d["Spring"]["Curve Data"].Size(); MapSpringForce* springForceCB = new MapSpringForce(); for (int i = 0; i < num_points; i++) { springForceCB->add_point(d["Spring"]["Curve Data"][i][0u].GetDouble(), d["Spring"]["Curve Data"][i][1u].GetDouble()); } m_springForceCB = springForceCB; } // Read shock data and create force callback assert(d.HasMember("Shock")); assert(d["Shock"].IsObject()); m_points[SHOCK_C] = LoadVectorJSON(d["Shock"]["Location Chassis"]); m_points[SHOCK_A] = LoadVectorJSON(d["Shock"]["Location Arm"]); if (d["Shock"].HasMember("Damping Coefficient")) { m_shockForceCB = new LinearDamperForce(d["Shock"]["Damping Coefficient"].GetDouble()); } else if (d["Shock"].HasMember("Curve Data")) { int num_points = d["Shock"]["Curve Data"].Size(); MapDamperForce* shockForceCB = new MapDamperForce(); for (int i = 0; i < num_points; i++) { shockForceCB->add_point(d["Shock"]["Curve Data"][i][0u].GetDouble(), d["Shock"]["Curve Data"][i][1u].GetDouble()); } m_shockForceCB = shockForceCB; } // Read axle inertia assert(d.HasMember("Axle")); assert(d["Axle"].IsObject()); m_axleInertia = d["Axle"]["Inertia"].GetDouble(); }