Files
XCEngine/engine/third_party/physx/snippets/snippetvehiclecommon/serialization/EngineDrivetrainSerialization.cpp

553 lines
19 KiB
C++

// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of NVIDIA CORPORATION nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Copyright (c) 2008-2025 NVIDIA Corporation. All rights reserved.
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
#include "EngineDrivetrainSerialization.h"
#include "SerializationCommon.h"
#include <fstream>
#include <sstream>
namespace snippetvehicle
{
bool readAutoboxParams(const rapidjson::Document& config, PxVehicleAutoboxParams& autoboxParams)
{
if(!config.HasMember("AutoboxParams"))
return false;
if(!config["AutoboxParams"].HasMember("UpRatios"))
return false;
if (!config["AutoboxParams"].HasMember("DownRatios"))
return false;
if (!config["AutoboxParams"].HasMember("Latency"))
return false;
const rapidjson::Value& upRatios = config["AutoboxParams"]["UpRatios"];
for(PxU32 i = 0; i < upRatios.Size(); i++)
{
autoboxParams.upRatios[i] = static_cast<PxReal>(upRatios[i].GetDouble());
}
const rapidjson::Value& downRatios = config["AutoboxParams"]["DownRatios"];
for (PxU32 i = 0; i < downRatios.Size(); i++)
{
autoboxParams.downRatios[i] = static_cast<PxReal>(downRatios[i].GetDouble());
}
autoboxParams.latency = static_cast<PxReal>(config["AutoboxParams"]["Latency"].GetDouble());
return true;
}
bool writeAutoboxParams(const PxVehicleAutoboxParams& autoboxParams, rapidjson::PrettyWriter<rapidjson::StringBuffer>& writer)
{
writer.Key("AutoboxParams");
writer.StartObject();
writer.Key("UpRatios");
writer.StartArray();
for(PxU32 i = 0; i < PxVehicleGearboxParams::eMAX_NB_GEARS; i++)
{
writer.Double(static_cast<double>(autoboxParams.upRatios[i]));
}
writer.EndArray();
writer.Key("DownRatios");
writer.StartArray();
for (PxU32 i = 0; i < PxVehicleGearboxParams::eMAX_NB_GEARS; i++)
{
writer.Double(static_cast<double>(autoboxParams.downRatios[i]));
}
writer.EndArray();
writer.Key("Latency");
writer.Double(static_cast<double>(autoboxParams.latency));
writer.EndObject();
return true;
}
bool readClutchCommandResponseParams(const rapidjson::Document& config, PxVehicleClutchCommandResponseParams& clutchCommandResponseParams)
{
if(!config.HasMember("ClutchCommandResponseParams"))
return false;
if(!config["ClutchCommandResponseParams"].HasMember("MaxResponse"))
return false;
clutchCommandResponseParams.maxResponse = static_cast<PxReal>(config["ClutchCommandResponseParams"]["MaxResponse"].GetDouble());
return true;
}
bool writeClutchCommandResponseParams(const PxVehicleClutchCommandResponseParams& clutchCommandResponseParams, rapidjson::PrettyWriter<rapidjson::StringBuffer>& writer)
{
writer.Key("ClutchCommandResponseParams");
writer.StartObject();
writer.Key("MaxResponse");
writer.Double(static_cast<double>(clutchCommandResponseParams.maxResponse));
writer.EndObject();
return true;
}
bool readEngineParams(const rapidjson::Document& config, PxVehicleEngineParams& engineParams)
{
if(!config.HasMember("EngineParams"))
return false;
if(!config["EngineParams"].HasMember("TorqueCurve"))
return false;
if (!config["EngineParams"].HasMember("MOI"))
return false;
if (!config["EngineParams"].HasMember("PeakTorque"))
return false;
if (!config["EngineParams"].HasMember("IdleOmega"))
return false;
if (!config["EngineParams"].HasMember("MaxOmega"))
return false;
if (!config["EngineParams"].HasMember("DampingRateFullThrottle"))
return false;
if (!config["EngineParams"].HasMember("DampingRateZeroThrottleClutchEngaged"))
return false;
if (!config["EngineParams"].HasMember("DampingRateZeroThrottleClutchDisengaged"))
return false;
if(!readFloatLookupTable(config["EngineParams"]["TorqueCurve"], engineParams.torqueCurve))
return false;
engineParams.moi = static_cast<PxReal>(config["EngineParams"]["MOI"].GetDouble());
engineParams.peakTorque = static_cast<PxReal>(config["EngineParams"]["PeakTorque"].GetDouble());
engineParams.idleOmega = static_cast<PxReal>(config["EngineParams"]["IdleOmega"].GetDouble());
engineParams.maxOmega = static_cast<PxReal>(config["EngineParams"]["MaxOmega"].GetDouble());
engineParams.dampingRateFullThrottle = static_cast<PxReal>(config["EngineParams"]["DampingRateFullThrottle"].GetDouble());
engineParams.dampingRateZeroThrottleClutchEngaged = static_cast<PxReal>(config["EngineParams"]["DampingRateZeroThrottleClutchEngaged"].GetDouble());
engineParams.dampingRateZeroThrottleClutchDisengaged = static_cast<PxReal>(config["EngineParams"]["DampingRateZeroThrottleClutchDisengaged"].GetDouble());
return true;
}
bool writeEngineParams(const PxVehicleEngineParams& engineParams, rapidjson::PrettyWriter<rapidjson::StringBuffer>& writer)
{
writer.Key("EngineParams");
writer.StartObject();
writer.Key("TorqueCurve");
writeFloatLookupTable(engineParams.torqueCurve, writer);
writer.Key("MOI");
writer.Double(static_cast<double>(engineParams.moi));
writer.Key("PeakTorque");
writer.Double(static_cast<double>(engineParams.peakTorque));
writer.Key("IdleOmega");
writer.Double(static_cast<double>(engineParams.idleOmega));
writer.Key("MaxOmega");
writer.Double(static_cast<double>(engineParams.maxOmega));
writer.Key("DampingRateFullThrottle");
writer.Double(static_cast<double>(engineParams.dampingRateFullThrottle));
writer.Key("DampingRateZeroThrottleClutchEngaged");
writer.Double(double(engineParams.dampingRateZeroThrottleClutchEngaged));
writer.Key("DampingRateZeroThrottleClutchDisengaged");
writer.Double(double(engineParams.dampingRateZeroThrottleClutchDisengaged));
writer.EndObject();
return true;
}
bool readGearboxParams(const rapidjson::Document& config, PxVehicleGearboxParams& gearboxParams)
{
if (!config.HasMember("GearboxParams"))
return false;
if (!config["GearboxParams"].HasMember("NeutralGear"))
return false;
if (!config["GearboxParams"].HasMember("Ratios"))
return false;
if (!config["GearboxParams"].HasMember("FinalRatio"))
return false;
if (!config["GearboxParams"].HasMember("SwitchTime"))
return false;
gearboxParams.neutralGear = config["GearboxParams"]["NeutralGear"].GetInt();
gearboxParams.finalRatio = static_cast<PxReal>(config["GearboxParams"]["FinalRatio"].GetDouble());
gearboxParams.switchTime = static_cast<PxReal>(config["GearboxParams"]["SwitchTime"].GetDouble());
const rapidjson::Value& ratios = config["GearboxParams"]["Ratios"];
for(PxU32 i = 0; i < ratios.Size(); i++)
{
gearboxParams.ratios[i] = static_cast<PxReal>(ratios[i].GetDouble());
}
gearboxParams.nbRatios = ratios.Size();
return true;
}
bool writeGearboxParams(const PxVehicleGearboxParams& gearboxParams, rapidjson::PrettyWriter<rapidjson::StringBuffer>& writer)
{
writer.Key("GearboxParams");
writer.StartObject();
writer.Key("NeutralGear");
writer.Int(gearboxParams.neutralGear);
writer.Key("FinalRatio");
writer.Double(static_cast<double>(gearboxParams.finalRatio));
writer.Key("SwitchTime");
writer.Double(static_cast<double>(gearboxParams.switchTime));
writer.Key("Ratios");
writer.StartArray();
for(PxU32 i = 0; i < gearboxParams.nbRatios; i++)
{
writer.Double(static_cast<double>(gearboxParams.ratios[i]));
}
writer.EndArray();
writer.EndObject();
return true;
}
bool readMultiWheelDiffParams(const rapidjson::Value& config, PxVehicleMultiWheelDriveDifferentialParams& multiWheelDiffParams)
{
if (!config.HasMember("TorqueRatios"))
return false;
if (!config.HasMember("AveWheelSpeedRatios"))
return false;
const rapidjson::Value& aveWheelSpeedRatios = config["AveWheelSpeedRatios"];
const rapidjson::Value& torqueRatios = config["TorqueRatios"];
if (aveWheelSpeedRatios.Size() != torqueRatios.Size())
return false;
for (PxU32 i = 0; i < aveWheelSpeedRatios.Size(); i++)
{
multiWheelDiffParams.aveWheelSpeedRatios[i] = static_cast<PxReal>(aveWheelSpeedRatios[i].GetDouble());
multiWheelDiffParams.torqueRatios[i] = static_cast<PxReal>(torqueRatios[i].GetDouble());
}
return true;
}
void writeMultiWheelDiffParams
(const PxVehicleMultiWheelDriveDifferentialParams& multiWheelDiffParams, rapidjson::PrettyWriter<rapidjson::StringBuffer>& writer)
{
writer.Key("TorqueRatios");
writer.StartArray();
for (PxU32 i = 0; i < PxVehicleLimits::eMAX_NB_WHEELS; i++)
{
writer.Double(static_cast<double>(multiWheelDiffParams.torqueRatios[i]));
}
writer.EndArray();
writer.Key("AveWheelSpeedRatios");
writer.StartArray();
for (PxU32 i = 0; i < PxVehicleLimits::eMAX_NB_WHEELS; i++)
{
writer.Double(static_cast<double>(multiWheelDiffParams.aveWheelSpeedRatios[i]));
}
writer.EndArray();
}
bool readMultiWheelDifferentialParams(const rapidjson::Document& config, PxVehicleMultiWheelDriveDifferentialParams& multiWheelDifferentialParams)
{
multiWheelDifferentialParams.setToDefault();
if (!config.HasMember("MultiWheelDifferentialParams"))
return false;
if (!readMultiWheelDiffParams(config["MultiWheelDifferentialParams"], multiWheelDifferentialParams))
return false;
return true;
}
bool writeMultiWheelDifferentialParams
(const PxVehicleMultiWheelDriveDifferentialParams& multiWheelDifferentialParams, rapidjson::PrettyWriter<rapidjson::StringBuffer>& writer)
{
writer.Key("MultiWheelDifferentialParams");
writer.StartObject();
writeMultiWheelDiffParams(multiWheelDifferentialParams, writer);
writer.EndObject();
return true;
}
bool readFourWheelDifferentialParams(const rapidjson::Document& config, PxVehicleFourWheelDriveDifferentialParams& fourWheelDifferentialParams)
{
fourWheelDifferentialParams.setToDefault();
if (!config.HasMember("FourWheelDifferentialParams"))
return false;
if (!readMultiWheelDiffParams(config["FourWheelDifferentialParams"], static_cast<PxVehicleMultiWheelDriveDifferentialParams&>(fourWheelDifferentialParams)))
return false;
if (!config["FourWheelDifferentialParams"].HasMember("FrontWheelIds"))
return false;
if (!config["FourWheelDifferentialParams"].HasMember("RearWheelIds"))
return false;
if (!config["FourWheelDifferentialParams"].HasMember("CenterBias"))
return false;
if (!config["FourWheelDifferentialParams"].HasMember("CenterTarget"))
return false;
if (!config["FourWheelDifferentialParams"].HasMember("FrontBias"))
return false;
if (!config["FourWheelDifferentialParams"].HasMember("FrontTarget"))
return false;
if (!config["FourWheelDifferentialParams"].HasMember("RearBias"))
return false;
if (!config["FourWheelDifferentialParams"].HasMember("RearTarget"))
return false;
if (!config["FourWheelDifferentialParams"].HasMember("Rate"))
return false;
const rapidjson::Value& frontWheelIds = config["FourWheelDifferentialParams"]["FrontWheelIds"];
if(frontWheelIds.Size() != 2)
return false;
fourWheelDifferentialParams.frontWheelIds[0] = frontWheelIds[0].GetInt();
fourWheelDifferentialParams.frontWheelIds[1] = frontWheelIds[1].GetInt();
const rapidjson::Value& rearWheelIds = config["FourWheelDifferentialParams"]["RearWheelIds"];
if (rearWheelIds.Size() != 2)
return false;
fourWheelDifferentialParams.rearWheelIds[0] = rearWheelIds[0].GetInt();
fourWheelDifferentialParams.rearWheelIds[1] = rearWheelIds[1].GetInt();
fourWheelDifferentialParams.centerBias = static_cast<PxReal>(config["FourWheelDifferentialParams"]["CenterBias"].GetDouble());
fourWheelDifferentialParams.centerTarget = static_cast<PxReal>(config["FourWheelDifferentialParams"]["CenterTarget"].GetDouble());
fourWheelDifferentialParams.frontBias = static_cast<PxReal>(config["FourWheelDifferentialParams"]["FrontBias"].GetDouble());
fourWheelDifferentialParams.frontTarget = static_cast<PxReal>(config["FourWheelDifferentialParams"]["FrontTarget"].GetDouble());
fourWheelDifferentialParams.rearBias = static_cast<PxReal>(config["FourWheelDifferentialParams"]["RearBias"].GetDouble());
fourWheelDifferentialParams.rearTarget = static_cast<PxReal>(config["FourWheelDifferentialParams"]["RearTarget"].GetDouble());
fourWheelDifferentialParams.rate = static_cast<PxReal>(config["FourWheelDifferentialParams"]["Rate"].GetDouble());
return true;
}
bool writeFourWheelDifferentialParams(const PxVehicleFourWheelDriveDifferentialParams& fourWheelDifferentialParams, rapidjson::PrettyWriter<rapidjson::StringBuffer>& writer)
{
writer.Key("FourWheelDifferentialParams");
writer.StartObject();
writeMultiWheelDiffParams(static_cast<const PxVehicleMultiWheelDriveDifferentialParams&>(fourWheelDifferentialParams), writer);
writer.Key("FrontWheelIds");
writer.StartArray();
writer.Int(fourWheelDifferentialParams.frontWheelIds[0]);
writer.Int(fourWheelDifferentialParams.frontWheelIds[1]);
writer.EndArray();
writer.Key("RearWheelIds");
writer.StartArray();
writer.Int(fourWheelDifferentialParams.rearWheelIds[0]);
writer.Int(fourWheelDifferentialParams.rearWheelIds[1]);
writer.EndArray();
writer.Key("CenterBias");
writer.Double(static_cast<double>(fourWheelDifferentialParams.centerBias));
writer.Key("CenterTarget");
writer.Double(static_cast<double>(fourWheelDifferentialParams.centerTarget));
writer.Key("FrontBias");
writer.Double(static_cast<double>(fourWheelDifferentialParams.frontBias));
writer.Key("FrontTarget");
writer.Double(static_cast<double>(fourWheelDifferentialParams.frontTarget));
writer.Key("RearBias");
writer.Double(static_cast<double>(fourWheelDifferentialParams.rearBias));
writer.Key("RearTarget");
writer.Double(static_cast<double>(fourWheelDifferentialParams.rearTarget));
writer.Key("Rate");
writer.Double(static_cast<double>(fourWheelDifferentialParams.rate));
writer.EndObject();
return true;
}
bool readTankDifferentialParams(const rapidjson::Document& config, PxVehicleTankDriveDifferentialParams& tankDifferentialParams)
{
tankDifferentialParams.setToDefault();
if (!config.HasMember("TankDifferentialParams"))
return false;
if(!readMultiWheelDiffParams(config["TankDifferentialParams"], static_cast<PxVehicleMultiWheelDriveDifferentialParams&>(tankDifferentialParams)))
return false;
if (!config["TankDifferentialParams"].HasMember("TankTracks"))
return false;
const rapidjson::Value& tankTracks = config["TankDifferentialParams"]["TankTracks"];
for (PxU32 i = 0; i < tankTracks.Size(); i++)
{
const rapidjson::Value& tankTrack = tankTracks[i];
PxU32 wheelIds[PxVehicleLimits::eMAX_NB_WHEELS];
PxU32 nbWheels = 0;
for (PxU32 j = 0; j < tankTrack.Size(); j++)
{
wheelIds[nbWheels] = static_cast<PxU32>(tankTrack[j].GetInt());
nbWheels++;
}
tankDifferentialParams.addTankTrack(nbWheels, wheelIds, i);
}
return true;
}
bool writeTankDifferentialParams(const PxVehicleTankDriveDifferentialParams& tankDifferentialParams, rapidjson::PrettyWriter<rapidjson::StringBuffer>& writer)
{
writer.Key("TankDifferentialParams");
writer.StartObject();
writeMultiWheelDiffParams(static_cast<const PxVehicleMultiWheelDriveDifferentialParams&>(tankDifferentialParams), writer);
writer.Key("TankTracks");
writer.StartArray();
for (PxU32 i = 0; i < tankDifferentialParams.nbTracks; i++)
{
writer.StartArray();
for (PxU32 j = 0; j < tankDifferentialParams.getNbWheelsInTrack(i); j++)
{
writer.Int(static_cast<int>(tankDifferentialParams.getWheelInTrack(j, i)));
}
writer.EndArray();
}
writer.EndArray();
writer.EndObject();
return true;
}
bool reaClutchParams(const rapidjson::Document& config, PxVehicleClutchParams& clutchParams)
{
if (!config.HasMember("ClutchParams"))
return false;
if (!config["ClutchParams"].HasMember("AccuracyMode"))
return false;
if (!config["ClutchParams"].HasMember("EstimateIterations"))
return false;
clutchParams.accuracyMode = static_cast<PxVehicleClutchAccuracyMode::Enum>(config["ClutchParams"]["AccuracyMode"].GetInt());
clutchParams.estimateIterations = config["ClutchParams"]["EstimateIterations"].GetInt();
return true;
}
bool writeClutchParams(const PxVehicleClutchParams& clutchParams, rapidjson::PrettyWriter<rapidjson::StringBuffer>& writer)
{
writer.Key("ClutchParams");
writer.StartObject();
writer.Key("AccuracyMode");
writer.Int(static_cast<PxU32>(clutchParams.accuracyMode));
writer.Key("EstimateIterations");
writer.Int(clutchParams.estimateIterations);
writer.EndObject();
return true;
}
bool readEngineDrivetrainParamsFromJsonFile(const char* directory, const char* filename,
EngineDrivetrainParams& engineDrivetrainParams)
{
rapidjson::Document config;
if (!openDocument(directory, filename, config))
return false;
if(!readAutoboxParams(config, engineDrivetrainParams.autoboxParams))
return false;
if(!readClutchCommandResponseParams(config, engineDrivetrainParams.clutchCommandResponseParams))
return false;
if (!readEngineParams(config, engineDrivetrainParams.engineParams))
return false;
if (!readGearboxParams(config, engineDrivetrainParams.gearBoxParams))
return false;
if (!readMultiWheelDifferentialParams(config, engineDrivetrainParams.multiWheelDifferentialParams))
return false;
if (!readFourWheelDifferentialParams(config, engineDrivetrainParams.fourWheelDifferentialParams))
return false;
if (!readTankDifferentialParams(config, engineDrivetrainParams.tankDifferentialParams))
return false;
if (!reaClutchParams(config, engineDrivetrainParams.clutchParams))
return false;
return true;
}
bool writeEngineDrivetrainParamsToJsonFile(const char* directory, const char* filename,
const EngineDrivetrainParams& engineDrivetrainParams)
{
rapidjson::StringBuffer strbuf;
rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(strbuf);
writer.StartObject();
writeAutoboxParams(engineDrivetrainParams.autoboxParams, writer);
writeClutchCommandResponseParams(engineDrivetrainParams.clutchCommandResponseParams, writer);
writeEngineParams(engineDrivetrainParams.engineParams, writer);
writeGearboxParams(engineDrivetrainParams.gearBoxParams, writer);
writeMultiWheelDifferentialParams(engineDrivetrainParams.multiWheelDifferentialParams, writer);
writeFourWheelDifferentialParams(engineDrivetrainParams.fourWheelDifferentialParams, writer);
writeTankDifferentialParams(engineDrivetrainParams.tankDifferentialParams, writer);
writeClutchParams(engineDrivetrainParams.clutchParams, writer);
writer.EndObject();
std::ofstream myfile;
myfile.open(std::string(directory) + "/" + filename);
myfile << strbuf.GetString() << std::endl;
myfile.close();
return true;
}
}//namespace snippetvehicle