/**
* Copyright (C) 2009-2014 Cars and Tracks Development Project (CTDP).
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package net.ctdp.rfdynhud.gamedata;
import net.ctdp.rfdynhud.gamedata.ProfileInfo.MeasurementUnits;
import net.ctdp.rfdynhud.gamedata.ProfileInfo.MeasurementUnits.Convert;
/**
* This is a model of vehicle physics settings.
*
* @author Marvin Froehlich (CTDP)
*/
public abstract class VehiclePhysics
{
/**
* Abstraction of a usual physics setting (base_value, step_size, num_steps).
*
* @author Marvin Froehlich (CTDP)
*/
public static class PhysicsSetting
{
private static long nextUpdateId = 1;
private long updateId = nextUpdateId++;
private final float factor;
private final float baseOffset;
private float baseValue = 0f;
private float stepSize = 1f;
private int numSteps = 1;
protected void set( float baseValue, float stepSize, int numSteps )
{
this.updateId = nextUpdateId++;
this.baseValue = baseOffset + baseValue;
this.stepSize = stepSize;
this.numSteps = numSteps;
}
protected void set( PhysicsSetting source )
{
this.updateId = nextUpdateId++;
this.baseValue = source.baseValue;
this.stepSize = source.stepSize;
this.numSteps = source.numSteps;
}
/**
* The base value of this physics setting.
* {@link #getStepSize()} and {@link #getNumSteps()} add to it up to the {@link #getMaxValue()}.
*
* @return base value of this physics setting.
*/
public final float getBaseValue()
{
return ( baseValue * factor );
}
/**
* Gets the number size of each step for this setting.
*
* @return the number size of each step for this setting.
*/
public final float getStepSize()
{
return ( stepSize * factor );
}
/**
* Gets the number of steps for this setting.
*
* @return the number of steps for this setting.
*/
public final int getNumSteps()
{
return ( numSteps );
}
/**
* Gets the minimum value for this physics setting's range.
*
* @return the minimum value for this physics setting's range.
*/
public final float getMinValue()
{
if ( stepSize > 0f )
return ( baseValue * factor );
return ( ( baseValue + ( numSteps - 1 ) * stepSize ) * factor );
}
/**
* Gets the maximum value for this physics setting's range.
*
* @return the maximum value for this physics setting's range.
*/
public final float getMaxValue()
{
if ( stepSize < 0f )
return ( baseValue * factor );
return ( ( baseValue + ( numSteps - 1 ) * stepSize ) * factor );
}
/**
* Gets the value for the given setting.
*
* @param setting the setting to get the value for
*
* @return the value for the given setting.
*/
public final float getValueForSetting( int setting )
{
// There shuold be a range check. But since this cannot be used for cheating, it isn't necessary.
return ( ( baseValue + stepSize * setting ) * factor );
}
/**
* Clamps the given value to the range of possible values in this physics setting.
*
* @param value the value to be clamped.
*
* @return the clamped value.
*/
public final float clampValue( float value )
{
return ( Math.max( getMinValue(), Math.min( value, getMaxValue() ) ) );
}
/**
* <p>
* Clamps the given value plus one step increment to the range of possible values in this physics setting.
* </p>
* <p>
* This is equivalent to<br />
* clampValue( value + getStepSize() )
* </p>
*
* @param value the value to be clamped.
*
* @return the clamped value.
*/
public final float clampValuePlusStep( float value )
{
return ( clampValue( value + getStepSize() ) );
}
/**
* <p>
* Clamps the given value minus one step increment to the range of possible values in this physics setting.
* </p>
* <p>
* This is equivalent to<br />
* clampValue( value - getStepSize() )
* </p>
*
* @param value the value to be clamped.
*
* @return the clamped value.
*/
public final float clampValueMinusStep( float value )
{
return ( clampValue( value - getStepSize() ) );
}
/**
* {@inheritDoc}
*/
@Override
public String toString()
{
return ( getClass().getName() + " { baseOffset: " + baseOffset + ", baseValue: " + baseValue + ", stepSize: " + stepSize + ", numSteps: " + numSteps + " }" );
}
public PhysicsSetting( float factor, float baseOffset )
{
this.factor = factor;
this.baseOffset = baseOffset;
}
public PhysicsSetting()
{
this( 1f, 0f );
}
}
private PhysicsSetting fuelRange = new PhysicsSetting( 1f, 0f );
private long fuelRangeLUpdateId = -1L;
protected final void set( float baseValue, float stepSize, int numSteps, PhysicsSetting target )
{
target.set( baseValue, stepSize, numSteps );
}
protected final void set( PhysicsSetting source, PhysicsSetting target )
{
target.set( source );
}
/**
* Gets the phyiscs setting for fuel range in liters.
*
* @return the phyiscs setting for fuel range in liters.
*/
public abstract PhysicsSetting getFuelRangeL();
/**
* Gets the phyiscs setting for fuel range in the selected units.
*
* @return the phyiscs setting for fuel range in the selected units.
*/
public final PhysicsSetting getFuelRange()
{
if ( fuelRangeLUpdateId != getFuelRangeL().updateId )
{
fuelRange.set( getFuelRangeL() );
fuelRangeLUpdateId = getFuelRangeL().updateId;
}
return ( fuelRange );
}
/**
* Gets the weight of one liter of fuel in kg.
*
* @return the weight of one liter of fuel in kg.
*/
public abstract float getWeightOfOneLiterOfFuel();
/**
* Gets the front wing range of settings.
*
* @return the front wing range of settings.
*/
public abstract PhysicsSetting getFrontWingRange();
/**
* Abstraction of possible Wheel drive settings.
*
* @author Marvin Froehlich (CTDP)
*/
public static enum WheelDrive
{
FRONT,
REAR,
FOUR,
;
public final boolean includesFront()
{
return ( ( this == FRONT ) || ( this == FOUR ) );
}
public final boolean includesRear()
{
return ( ( this == REAR ) || ( this == FOUR ) );
}
}
/**
* Gets the vehicle's {@link WheelDrive}.
*
* @return the vehicle's {@link WheelDrive}
*/
public abstract WheelDrive getWheelDrive();
/**
* Gets the number of forward gears.
*
* @return the number of forward gears.
*/
public abstract short getNumForwardGears();
/**
* Model of engine physics parameters.
*
* @author Marvin Froehlich (CTDP)
*/
public static abstract class Engine
{
protected abstract MeasurementUnits getMeasurementUnits();
protected void reset()
{
}
protected void finish()
{
}
/**
* Gets the engine's name.
*
* @return the engine's name.
*/
public abstract String getName();
/**
* Gets the average lifetime for the given rance length in seconds.
*
* @param raceLengthMultiplier the fraction of race length
*
* @return the average lifetime for the given rance length in seconds.
*/
public abstract int getLifetimeAverage( double raceLengthMultiplier );
/**
* Gets the variance of lifetime for the given rance length in seconds.
*
* @param raceLengthMultiplier the fraction of race length
*
* @return the variance of lifetime for the given rance length in seconds.
*/
public abstract int getLifetimeVariance( double raceLengthMultiplier );
/**
* Gets, whether this engine has a lifetime variance.
*
* @return whether this engine has a lifetime variance.
*/
public abstract boolean hasLifetimeVariance();
/**
* Gets the total lifetime in seconds, that the engine will last for sure.
*
* @param raceLengthMultiplier the fraction of race length
*
* @return the total lifetime, that the engine will last for sure.
*/
public abstract int getSafeLifetimeTotal( double raceLengthMultiplier );
/**
* Gets the total lifetime in seconds, that the engine will most probably hold.
*
* @param raceLengthMultiplier the fraction of race length
*
* @return the total lifetime in seconds, that the engine will most probably hold.
*/
public abstract int getGoodLifetimeTotal( double raceLengthMultiplier );
/**
* Gets the total lifetime seconds of the barrier, where the engine is in really bad shape.
*
* @param raceLengthMultiplier the fraction of race length
*
* @return the total lifetime seconds of the barrier, where the engine is in really bad shape.
*/
public abstract int getBadLifetimeTotal( double raceLengthMultiplier );
/**
* Gets the maximum number of lifetime seconds, that the engine can possibly last.
*
* @param raceLengthMultiplier the fraction of race length
*
* @return the maximum number of lifetime seconds, that the engine can possibly last.
*/
public abstract int getMaxLifetimeTotal( double raceLengthMultiplier );
/**
* Gets the lower bound of lifetime values for the "safe" range (zero).
*
* @param raceLengthMultiplier the fraction of race length
*
* @return the lower bound of lifetime values for the "safe" range (zero).
*/
public abstract int getLowerSafeLifetimeValue( double raceLengthMultiplier );
/**
* Gets the lower bound of lifetime values for the "good" range.
*
* @param raceLengthMultiplier the fraction of race length
*
* @return the lower bound of lifetime values for the "good" range.
*/
public abstract int getLowerGoodLifetimeValue( double raceLengthMultiplier );
/**
* Gets the lower bound of lifetime values for the "bad" range.
*
* @param raceLengthMultiplier the fraction of race length
*
* @return the lower bound of lifetime values for the "bad" range.
*/
public abstract int getLowerBadLifetimeValue( double raceLengthMultiplier );
/**
* Gets the smalles lifetime value, that your engine can possibly have.
*
* @param raceLengthMultiplier the fraction of race length
*
* @return the smalles lifetime value, that your engine can possibly have.
*/
public abstract int getMinLifetimeValue( double raceLengthMultiplier );
/**
* Gets the size of the variance rance for engine lifetime in seconds.
*
* @param raceLengthMultiplier the fraction of race length
*
* @return the size of the variance rance for engine lifetime in seconds.
*/
public abstract int getLifetimeVarianceRange( double raceLengthMultiplier );
/**
* Gets the half size of the variance rance for engine lifetime in seconds.
*
* @param raceLengthMultiplier the fraction of race length
*
* @return the half size of the variance rance for engine lifetime in seconds.
*/
public abstract int getLifetimeVarianceHalfRange( double raceLengthMultiplier );
/**
* Gets the base temperature for engine life time in �C.
*
* @return the base temperature for engine life time in �C.
*/
public abstract float getBaseLifetimeOilTemperatureC();
/**
* Gets the base temperature for engine life time in �F.
*
* @return the base temperature for engine life time in �F.
*/
public final float getBaseLifetimeOilTemperatureF()
{
return ( Convert.celsius2Fahrehheit( getBaseLifetimeOilTemperatureC() ) );
}
/**
* Gets the base temperature for engine life time in the units selected in the PLR.
*
* @return the base temperature for engine life time in the units selected in the PLR.
*/
public final float getBaseLifetimeOilTemperature()
{
if ( getMeasurementUnits() == MeasurementUnits.IMPERIAL )
return ( getBaseLifetimeOilTemperatureF() );
return ( getBaseLifetimeOilTemperatureC() );
}
/**
* Gets the offset to the base oil temperature for engine life time, where life time is halfed in �C.
*
* @return the offset to the base oil temperature for engine life time, where life time is halfed in �C.
*/
public abstract float getHalfLifetimeOilTempOffsetC();
/**
* Gets the offset to the base oil temperature for engine life time, where life time is halfed in �F.
*
* @return the offset to the base oil temperature for engine life time, where life time is halfed in �F.
*/
public final float getHalfLifetimeOilTempOffsetF()
{
return ( Convert.celsius2Fahrehheit( getHalfLifetimeOilTempOffsetC() ) );
}
/**
* Gets the offset to the base oil temperature for engine life time, where life time is halfed in the units selected in the PLR.
*
* @return the offset to the base oil temperature for engine life time, where life time is halfed in the units selected in the PLR.
*/
public final float getHalfLifetimeOilTempOffset()
{
if ( getMeasurementUnits() == MeasurementUnits.IMPERIAL )
return ( getHalfLifetimeOilTempOffsetF() );
return ( getHalfLifetimeOilTempOffsetC() );
}
/**
* Gets the optimum oil temperature in Celsius. Engine will operatate optimally at this value.
*
* @return the optimum oil temperature.
*/
public abstract float getOptimumOilTemperatureC();
/**
* Gets the optimum oil temperature in Fahrenheit. Engine will operatate optimally at this value.
*
* @return the optimum oil temperature.
*/
public final float getOptimumOilTemperatureF()
{
return ( Convert.celsius2Fahrehheit( getOptimumOilTemperatureC() ) );
}
/**
* Gets the optimum oil temperature in the units selected in the PLR. Engine will operatate optimally at this value.
*
* @return the optimum oil temperature.
*/
public final float getOptimumOilTemperature()
{
if ( getMeasurementUnits() == MeasurementUnits.IMPERIAL )
return ( getOptimumOilTemperatureF() );
return ( getOptimumOilTemperatureC() );
}
/**
* Gets the temperature value in Celsius at which the engine starts to overheat.
* This value should serve as a peak level for temperatures during a race.
*
* @return the temperature value at which the engine starts to overheat.
*/
public abstract float getOverheatingOilTemperatureC();
/**
* Gets the temperature value in Fahrenheit at which the engine starts to overheat.
* This value should serve as a peak level for temperatures during a race.
*
* @return the temperature value at which the engine starts to overheat.
*/
public final float getOverheatingOilTemperatureF()
{
return ( Convert.celsius2Fahrehheit( getOverheatingOilTemperatureC() ) );
}
/**
* Gets the temperature value in the units selected in the PLR, at which the engine starts to overheat.
* This value should serve as a peak level for temperatures during a race.
*
* @return the temperature value at which the engine starts to overheat.
*/
public final float getOverheatingOilTemperature()
{
if ( getMeasurementUnits() == MeasurementUnits.IMPERIAL )
return ( getOverheatingOilTemperatureF() );
return ( getOverheatingOilTemperatureC() );
}
/**
* Gets a strong overheating engine temperature in Celsius. At this level the engine will have half of its regular life time.
*
* @return a strong overheating engine temperature.
*/
public abstract float getStrongOverheatingOilTemperatureC();
/**
* Gets a strong overheating engine temperature in Fahrenheit. At this level the engine will have half of its regular life time.
*
* @return a strong overheating engine temperature.
*/
public final float getStrongOverheatingOilTemperatureF()
{
return ( Convert.celsius2Fahrehheit( getStrongOverheatingOilTemperatureC() ) );
}
/**
* Gets a strong overheating engine temperature in the units selected in the PLR. At this level the engine will have half of its regular life time.
*
* @return a strong overheating engine temperature.
*/
public final float getStrongOverheatingOilTemperature()
{
if ( getMeasurementUnits() == MeasurementUnits.IMPERIAL )
return ( getStrongOverheatingOilTemperatureF() );
return ( getStrongOverheatingOilTemperatureC() );
}
/**
* Gets the engine wear increase per �C obove the optimum temperature.
*
* @return the engine wear increase per �C obove the optimum temperature.
*/
public abstract float getWearIncreasePerDegreeC();
/**
* Gets RPM for 'normal' lifetime. No decreased and no increased lifetime.
*
* @see #getHalfLifetimeRPMOffset()
*
* @return RPM for 'normal' lifetime. No decreased and no increased lifetime.
*/
public abstract float getBaseLifetimeRPM();
/**
* Gets the offset above the base RPM, where lifetime is halfed.
*
* @see #getBaseLifetimeRPM()
*
* @return the offset above the base RPM, where lifetime is halfed.
*/
public abstract float getHalfLifetimeRPMOffset();
/**
* Gets the range of possible max revs.
*
* @see VehicleSetup.Engine#getRevLimitSetting()
* @see VehicleSetup.Engine#getRevLimit()
*
* @return the range of possible max revs.
*/
public abstract PhysicsSetting getRevLimitRange();
/**
* Gets the range of possible boost mappings.
*
* @see VehicleSetup.Engine#getBoostMapping()
*
* @return the range of possible boost mappings.
*/
public abstract PhysicsSetting getBoostRange();
/**
* Gets the rev limit increase per boost setting.
*
* @return the rev limit increase per boost setting.
*/
public abstract float getRPMIncreasePerBoostLevel();
/**
* Gets the fuel usage increase per boost setting.
*
* @return the fuel usage increase per boost setting.
*/
public abstract float getFuelUsageIncreasePerBoostLevel();
/**
* Gets the engine wear increase per boost setting.
*
* @return the engine wear increase per boost setting.
*/
public abstract float getWearIncreasePerBoostLevel();
/**
* Gets the engine wear increase per km/h.
*
* @return the engine wear increase per km/h.
*/
public abstract float getWearIncreasePerVelocity();
/**
* Gets the maximum RPM at the given boost level.
*
* @param baseMaxRPM maxRPM coming from {@link TelemetryData#getEngineBaseMaxRPM()}
* @param boostLevel coming from {@link TelemetryData#getEngineBoostMapping()}
*
* @return the maximum RPM at the given boost level.
*/
public float getMaxRPM( float baseMaxRPM, int boostLevel )
{
/*
if ( rpmIncreasePerBoostSetting <= 0f )
return ( baseMaxRPM );
return ( baseMaxRPM + ( boostRange.getValueForSetting( boostLevel ) - boostRange.getBaseValue() ) * rpmIncreasePerBoostSetting );
*/
return ( baseMaxRPM + ( boostLevel - getBoostRange().getBaseValue() ) * getRPMIncreasePerBoostLevel() );
}
/**
* Gets the maximum RPM at the highest (valued) boost mapping.
*
* @param baseMaxRPM maxRPM coming from {@link TelemetryData#getEngineBaseMaxRPM()}
*
* @return the maximum RPM at the highest (valued) boost mapping.
*/
public float getMaxRPM( float baseMaxRPM )
{
if ( getRPMIncreasePerBoostLevel() <= 0f )
return ( baseMaxRPM );
return ( baseMaxRPM + ( getBoostRange().getMaxValue() - getBoostRange().getBaseValue() ) * getRPMIncreasePerBoostLevel() );
}
/**
* Gets the boost level with smallest boost.
*
* @return the boost level with smallest boost.
*/
public int getLowestBoostLevel()
{
if ( getRPMIncreasePerBoostLevel() <= 0f )
return ( (int)getBoostRange().getMaxValue() );
return ( (int)getBoostRange().getMinValue() );
}
/**
* Gets the boost level with biggest boost.
*
* @return the boost level with biggest boost.
*/
public int getHighestBoostLevel()
{
if ( getRPMIncreasePerBoostLevel() <= 0f )
return ( (int)getBoostRange().getMinValue() );
return ( (int)getBoostRange().getMaxValue() );
}
protected Engine()
{
}
}
/**
* Get engine related physics parameters.
*
* @return engine related physics parameters.
*/
public abstract Engine getEngine();
/**
* Model of brake physics parameters.
*
* @author Marvin Froehlich (CTDP)
*/
public static abstract class Brakes
{
/**
* Gets the range of possible brake distribution values.
*
* @return the range of possible brake distribution values.
*/
public abstract PhysicsSetting getRearDistributionRange();
/**
* Gets the range for brake pressure values [0, 1].
*
* @see VehicleSetup.Controls#getBrakePressure()
*
* @return the range for brake pressure values [0, 1].
*/
// TODO: Provide in IMPERIAL units, too.
public abstract PhysicsSetting getPressureRange();
/**
* Brake settings for a single wheel.
*
* @author Marvin Froehlich (CTDP)
*/
public static abstract class WheelBrake
{
private final Wheel wheel;
protected abstract MeasurementUnits getMeasurementUnits();
public final Wheel getWheel()
{
return ( wheel );
}
/**
* Gets the lower bound of the temperature range in Kelvin, where brakes will operate optimally.
*
* @return the lower bound of the temperature range, where brakes will operate optimally.
*/
public final float getOptimumTemperaturesLowerBoundK()
{
return ( getOptimumTemperaturesLowerBoundC() - Convert.ZERO_KELVIN );
}
/**
* Gets the lower bound of the temperature range in Celsius, where brakes will operate optimally.
*
* @return the lower bound of the temperature range, where brakes will operate optimally.
*/
public abstract float getOptimumTemperaturesLowerBoundC();
/**
* Gets the lower bound of the temperature range in Fahrenheit, where brakes will operate optimally.
*
* @return the lower bound of the temperature range, where brakes will operate optimally.
*/
public final float getOptimumTemperaturesLowerBoundF()
{
return ( Convert.celsius2Fahrehheit( getOptimumTemperaturesLowerBoundC() ) );
}
/**
* Gets the lower bound of the temperature range in the selected units, where brakes will operate optimally.
*
* @return the lower bound of the temperature range, where brakes will operate optimally.
*/
public final float getOptimumTemperaturesLowerBound()
{
if ( getMeasurementUnits() == MeasurementUnits.IMPERIAL )
return ( getOptimumTemperaturesLowerBoundF() );
return ( getOptimumTemperaturesLowerBoundC() );
}
/**
* Gets the upper bound of the temperature range in Kelvin, where brakes will operate optimally.
*
* @return the upper bound of the temperature range, where brakes will operate optimally.
*/
public final float getOptimumTemperaturesUpperBoundK()
{
return ( getOptimumTemperaturesUpperBoundC() - Convert.ZERO_KELVIN );
}
/**
* Gets the upper bound of the temperature range in Celsius, where brakes will operate optimally.
*
* @return the upper bound of the temperature range, where brakes will operate optimally.
*/
public abstract float getOptimumTemperaturesUpperBoundC();
/**
* Gets the upper bound of the temperature range in Fahrenheit, where brakes will operate optimally.
*
* @return the upper bound of the temperature range, where brakes will operate optimally.
*/
public final float getOptimumTemperaturesUpperBoundF()
{
return ( Convert.celsius2Fahrehheit( getOptimumTemperaturesUpperBoundC() ) );
}
/**
* Gets the upper bound of the temperature range in the selected units, where brakes will operate optimally.
*
* @return the upper bound of the temperature range, where brakes will operate optimally.
*/
public final float getOptimumTemperaturesUpperBound()
{
if ( getMeasurementUnits() == MeasurementUnits.IMPERIAL )
return ( getOptimumTemperaturesUpperBoundF() );
return ( getOptimumTemperaturesUpperBoundC() );
}
/**
* Gets the temperature level in Kelvin under and at which brakes are cold and won't work well.
*
* @return the temperature level under and at which brakes are cold.
*/
public final float getColdTemperatureK()
{
return ( getColdTemperatureC() - Convert.ZERO_KELVIN );
}
/**
* Gets the temperature level in Celsius under and at which brakes are cold and won't work well.
*
* @return the temperature level under and at which brakes are cold.
*/
public abstract float getColdTemperatureC();
/**
* Gets the temperature level in Fahrenheit under and at which brakes are cold and won't work well.
*
* @return the temperature level under and at which brakes are cold.
*/
public final float getColdTemperatureF()
{
return ( Convert.celsius2Fahrehheit( getColdTemperatureC() ) );
}
/**
* Gets the temperature level in the selected units under and at which brakes are cold and won't work well.
*
* @return the temperature level under and at which brakes are cold.
*/
public final float getColdTemperature()
{
if ( getMeasurementUnits() == MeasurementUnits.IMPERIAL )
return ( getColdTemperatureF() );
return ( getColdTemperatureC() );
}
/**
* Gets the temperature level in Kelvin above at at which brakes are overheating and won't work well and increase more than regularly.
*
* @return the temperature level above at at which brakes are overheating.
*/
public final float getOverheatingTemperatureK()
{
return ( getOverheatingTemperatureC() - Convert.ZERO_KELVIN );
}
/**
* Gets the temperature level in Celsius above at at which brakes are overheating and won't work well and increase more than regularly.
*
* @return the temperature level above at at which brakes are overheating.
*/
public abstract float getOverheatingTemperatureC();
/**
* Gets the temperature level in Fahrenheit above at at which brakes are overheating and won't work well and increase more than regularly.
*
* @return the temperature level above at at which brakes are overheating.
*/
public final float getOverheatingTemperatureF()
{
return ( Convert.celsius2Fahrehheit( getOverheatingTemperatureC() ) );
}
/**
* Gets the temperature level in the selected units above at at which brakes are overheating and won't work well and increase more than regularly.
*
* @return the temperature level above at at which brakes are overheating.
*/
public final float getOverheatingTemperature()
{
if ( getMeasurementUnits() == MeasurementUnits.IMPERIAL )
return ( getOverheatingTemperatureF() );
return ( getOverheatingTemperatureC() );
}
/**
* Gets the engine wear increase per �C over optimum temperature range.
*
* @see #getOptimumTemperaturesUpperBoundC()
*
* @return the engine wear increase per �C over optimum temperature range.
*/
public abstract float getWearIncreasePerDegreeCOverOptimum();
/**
* Gets the engine wear increase per �C below optimum temperature range.
*
* @see #getOptimumTemperaturesLowerBoundC()
*
* @return the engine wear increase per �C below optimum temperature range.
*/
public abstract float getWearDecreasePerDegreeCBelowOptimum();
/**
* Gets the range, where brakes start to fade.
*
* @return the range, where brakes start to fade.
*/
public abstract float getBrakeFadeRangeC();
/**
* Gets the temperature below optimum in �C, where brakes are cold and only produce half of optimum effect.
*
* @see #getOptimumTemperaturesLowerBoundC()
*
* @return the temperature below optimum in �C, where brakes are cold and only produce half of optimum effect.
*/
public float getBrakeFadeColdTemperatureC()
{
return ( getOptimumTemperaturesLowerBound() - getBrakeFadeRangeC() );
}
/**
* Gets the temperature above optimum in �C, where brakes are cold and only produce half of optimum effect.
*
* @see #getOptimumTemperaturesUpperBoundC()
*
* @return the temperature above optimum in �C, where brakes are cold and only produce half of optimum effect.
*/
public float getBrakeFadeHotTemperatureC()
{
return ( getOptimumTemperaturesUpperBound() + getBrakeFadeRangeC() );
}
/**
* Gets the disc thickness range in meters.
*
* @see VehicleSetup.WheelAndTire#getBrakeDiscThickness()
*
* @return the disc thickness range in meters.
*/
public abstract PhysicsSetting getDiscRange();
/**
* Brake disc wear per second in optimum temperature range.
*
* @see #getOptimumTemperaturesLowerBoundC()
* @see #getOptimumTemperaturesUpperBoundC()
*
* @return Brake disc wear per second in optimum temperature range.
*/
public abstract double getWearRate();
/**
* Gets the disc thickness in meters at which it fails.
*
* @return the disc thickness in meters at which it fails.
*/
public abstract float getDiscFailureAverage();
/**
* Gets the variance of disc thickness at which it fails.
*
* @return the variance of disc thickness at which it fails.
*/
public abstract float getDiscFailureVariance();
/**
* Gets, whether this brake has a variance in fail thickness.
*
* @return whether this brake has a variance in fail thickness.
*/
public abstract boolean hasDiscFailureVariance();
/**
* Gets minimum disc thickness, the disc can possibly reach in meters.
*
* @return minimum disc thickness, the disc can possibly reach in meters
*/
public float getMinDiscFailure()
{
return ( getDiscFailureAverage() - getDiscFailureVariance() - getDiscFailureVariance() );
//return ( getDiscFailureAverage() );
}
/**
* Gets the disc thickness in meters, that you can be pretty sure, it will reach.
*
* @return the disc thickness in meters, that you can be pretty sure, it will reach.
*/
public abstract float getGoodDiscFailure();
/**
* You shouldn't let your brake disc go to this thickness in meters.
*
* @return the thickness, that you shouldn't let your brakes go to. They will probably not gonna make it.
*/
public float getBadDiscFailure()
{
return ( getDiscFailureAverage() + getDiscFailureVariance() );
}
/**
* Gets the disc thickness at which it fails.
*
* @return the disc thickness at which it fails.
*/
public float getMaxDiscFailure()
{
return ( getDiscFailureAverage() + getDiscFailureVariance() + getDiscFailureVariance() );
}
/**
* Gets the absolute range of variance in meters.
*
* @return the absolute range of variance in meters.
*/
public float getDiscFailureVarianceRange()
{
return ( getDiscFailureVariance() + getDiscFailureVariance() + getDiscFailureVariance() + getDiscFailureVariance() );
}
/**
* Gets half of the absolute range of variance in meters.
*
* @return half of the absolute range of variance in meters.
*/
public float getDiscFailureVarianceHalfRange()
{
return ( getDiscFailureVariance() + getDiscFailureVariance() );
}
/**
* Gets brake torque base.
*
* @return brake torque base.
*/
public abstract float getTorqueBase();
/**
* Computes the actual brake torque for the given brake temperature.
*
* @param brakeTempK the brake temperature in Kelvin
*
* @return the actual brake torque for the given brake temperature.
*/
public abstract double computeTorque( float brakeTempK );
protected void reset()
{
}
protected void finish()
{
}
protected WheelBrake( Wheel wheel )
{
this.wheel = wheel;
}
}
/**
* Gets the brake model of the given wheel.
*
* @param wheel the requested wheel
*
* @return the brake model of the given wheel.
*/
public abstract WheelBrake getBrake( Wheel wheel );
protected void reset()
{
}
protected void finish()
{
}
}
/**
* Gets the model for all four brakes.
*
* @return the model for all four brakes.
*/
public abstract Brakes getBrakes();
/**
* Model of a tire compound.
*
* @author Marvin Froehlich (CTDP)
*/
public static abstract class TireCompound
{
/**
* Gets the compound's name.
*
* @return the compound's name.
*/
public abstract String getName();
/**
* Gets the compound's index in the list. This is what stands in the setup file.
*
* @return the compound's index in the list.
*/
public abstract int getIndex();
/**
* Model of one wheel of a compound. There will always be one {@link CompoundWheel} in a {@link TireCompound} for each wheel of the vehicle.
*
* @author Marvin Froehlich (CTDP)
*/
public static abstract class CompoundWheel
{
private final Wheel wheel;
protected abstract MeasurementUnits getMeasurementUnits();
public final Wheel getWheel()
{
return ( wheel );
}
/**
* Gets the lateral grip value for dry weather.
* Effective grip will always be a fraction of this value depending on tire wear, temperatures, pressure and load.
*
* @return the lateral grip value for dry weather.
*/
public abstract float getDryLateralGrip();
/**
* Gets the longitudinal grip value for dry weather.
* Effective grip will always be a fraction of this value depending on tire wear, temperatures, pressure and load.
*
* @return the longitudinal grip value for dry weather.
*/
public abstract float getDryLongitudinalGrip();
/**
* Gets the lower bound of the temperature window (in Celsius), in which the tire will operate optimally.
*
* @return the lower bound of the temperature window (in Celsius), in which the tire will operate optimally.
*/
public abstract float getOptimumTemperatureCLowerBound();
/**
* Gets the upper bound of the temperature window (in Celsius), in which the tire will operate optimally.
*
* @return the upper bound of the temperature window (in Celsius), in which the tire will operate optimally.
*/
public abstract float getOptimumTemperatureCUpperBound();
/**
* Gets the temperature value (in Celsius), at which the tire will operate optimally.
*
* @return the temperature value (in Celsius), at which the tire will operate optimally.
*
* @deprecated Replaced by {@link #getOptimumTemperatureCLowerBound()} and {@link #getOptimumTemperatureCUpperBound()}.
*/
@Deprecated
public final float getOptimumTemperatureC()
{
return ( getOptimumTemperatureCLowerBound() + ( ( getOptimumTemperatureCUpperBound() - getOptimumTemperatureCLowerBound() ) / 2 ) );
}
/**
* Gets the lower bound of the temperature window (in Fahrenheit), in which the tire will operate optimally.
*
* @return the lower bound of the temperature window (in Fahrenheit), in which the tire will operate optimally.
*/
public final float getOptimumTemperatureFLowerBound()
{
return ( Convert.celsius2Fahrehheit( getOptimumTemperatureCLowerBound() ) );
}
/**
* Gets the upper bound of the temperature window (in Fahrenheit), in which the tire will operate optimally.
*
* @return the upper bound of the temperature window (in Fahrenheit), in which the tire will operate optimally.
*/
public final float getOptimumTemperatureFUpperBound()
{
return ( Convert.celsius2Fahrehheit( getOptimumTemperatureCUpperBound() ) );
}
/**
* Gets the temperature value (in Fahrenheit), at which the tire will operate optimally.
*
* @return the temperature value (in Fahrenheit), at which the tire will operate optimally.
*
* @deprecated Replaced by {@link #getOptimumTemperatureFLowerBound()} and {@link #getOptimumTemperatureFUpperBound()}.
*/
@Deprecated
public final float getOptimumTemperatureF()
{
return ( Convert.celsius2Fahrehheit( getOptimumTemperatureC() ) );
}
/**
* Gets the lower bound of the temperature window (in the selected units), in which the tire will operate optimally.
*
* @return the lower bound of the temperature window (in the selected units), in which the tire will operate optimally.
*/
public final float getOptimumTemperatureLowerBound()
{
if ( getMeasurementUnits() == MeasurementUnits.IMPERIAL )
return ( getOptimumTemperatureFLowerBound() );
return ( getOptimumTemperatureCLowerBound() );
}
/**
* Gets the upper bound of the temperature window (in the selected units), in which the tire will operate optimally.
*
* @return the upper bound of the temperature window (in the selected units), in which the tire will operate optimally.
*/
public final float getOptimumTemperatureUpperBound()
{
if ( getMeasurementUnits() == MeasurementUnits.IMPERIAL )
return ( getOptimumTemperatureFUpperBound() );
return ( getOptimumTemperatureCUpperBound() );
}
/**
* Gets the temperature value (in the selected units), at which the tire will operate optimally.
*
* @return the temperature value (in the selected units), at which the tire will operate optimally.
*
* @deprecated Replaced by {@link #getOptimumTemperatureLowerBound()} and {@link #getOptimumTemperatureUpperBound()}.
*/
@Deprecated
public final float getOptimumTemperature()
{
if ( getMeasurementUnits() == MeasurementUnits.IMPERIAL )
return ( getOptimumTemperatureF() );
return ( getOptimumTemperatureC() );
}
/**
* Gets the grip loss (fraction) per degree below {@link #getOptimumTemperature()}.
*
* @return the grip loss (fraction) per degree below {@link #getOptimumTemperature()}.
*/
public abstract float getGripLossPerDegreeCBelowOptimum();
/**
* Gets the grip loss (fraction) per degree below {@link #getOptimumTemperature()}.
*
* @return the grip loss (fraction) per degree below {@link #getOptimumTemperature()}.
*/
public final float getGripLossPerDegreeFBelowOptimum()
{
return ( Convert.celsius2Fahrehheit( getGripLossPerDegreeCBelowOptimum() ) );
}
/**
* Gets the grip loss (fraction) per degree below {@link #getOptimumTemperature()}.
*
* @return the grip loss (fraction) per degree below {@link #getOptimumTemperature()}.
*/
public final float getGripLossPerDegreeBelowOptimum()
{
if ( getMeasurementUnits() == MeasurementUnits.IMPERIAL )
return ( getGripLossPerDegreeFBelowOptimum() );
return ( getGripLossPerDegreeCBelowOptimum() );
}
/**
* Gets the temperature in Celsius, that a tire will have at the given grip fraction value.
* This function will always return a value below {@link #getOptimumTemperature()}.
*
* @param grip the actual grip fraction
*
* @return the temperature, that a tire will have at the given grip fraction value.
*/
public abstract float getBelowTemperatureC( float grip );
/**
* Gets the temperature in Fahrenheit, that a tire will have at the given grip fraction value.
* This function will always return a value below {@link #getOptimumTemperature()}.
*
* @param grip the actual grip fraction
*
* @return the temperature, that a tire will have at the given grip fraction value.
*/
public final float getBelowTemperatureF( float grip )
{
return ( Convert.celsius2Fahrehheit( getBelowTemperatureC( grip ) ) );
}
/**
* Gets the temperature in the selected units, that a tire will have at the given grip fraction value.
* This function will always return a value below {@link #getOptimumTemperature()}.
*
* @param grip the actual grip fraction
*
* @return the temperature, that a tire will have at the given grip fraction value.
*/
public final float getBelowTemperature( float grip )
{
if ( getMeasurementUnits() == MeasurementUnits.IMPERIAL )
return ( getBelowTemperatureF( grip ) );
return ( getBelowTemperatureC( grip ) );
}
/**
* Gets the temperature in Celsius, that a tire will have at the given grip fraction value.
* This function will always return a value above {@link #getOptimumTemperature()}.
*
* @param grip the actual grip fraction
*
* @return the temperature, that a tire will have at the given grip fraction value.
*/
public abstract float getAboveTemperatureC( float grip );
/**
* Gets the temperature in Fahrenheit, that a tire will have at the given grip fraction value.
* This function will always return a value above {@link #getOptimumTemperature()}.
*
* @param grip the actual grip fraction
*
* @return the temperature, that a tire will have at the given grip fraction value.
*/
public final float getAboveTemperatureF( float grip )
{
return ( Convert.celsius2Fahrehheit( getAboveTemperatureC( grip ) ) );
}
/**
* Gets the temperature in the selected units, that a tire will have at the given grip fraction value.
* This function will always return a value above {@link #getOptimumTemperature()}.
*
* @param grip the actual grip fraction
*
* @return the temperature, that a tire will have at the given grip fraction value.
*/
public final float getAboveTemperature( float grip )
{
if ( getMeasurementUnits() == MeasurementUnits.IMPERIAL )
return ( getAboveTemperatureF( grip ) );
return ( getAboveTemperatureC( grip ) );
}
/**
* Gets the grip fraction value of the tire at the given average temperature.
*
* @param avgTemperatureC average over outer, mittle and inner temperature
*
* @return the grip fraction value of the tire at the given average temperature.
*/
public abstract float getGripFactorByTemperatureC( float avgTemperatureC );
/**
* Gets the optimum tire pressure at the given tire load.
*
* @param load coming from {@link TelemetryData#getTireLoad(Wheel)}
*
* @return the optimum tire pressure at the given tire load.
*/
public abstract float getOptimumPressure( float load );
/*
* Computes the optimum tire pressure for the given grip fraction and load.
*
* @param grip the actual grip fraction
* @param load coming from {@link TelemetryData#getTireLoad(Wheel)}
*
* @return the optimum tire pressure for the given grip fraction and load.
*/
//public abstract float getPressureForGrip( float grip, float load );
/**
* Computes the grip fraction of the tire at the given pressure and load.
*
* @param pressure coming from {@link TelemetryData#getTirePressureKPa(Wheel)}
* @param load coming from {@link TelemetryData#getTireLoadN(Wheel)}
*
* @return the grip fraction of the tire at the given pressure and load.
*/
public abstract float getGripFactorByPressure( float pressure, float load );
/**
* Computes the fraction of maximum grip at the given wear, average temperature, pressure and load.
*
* @param wear see {@link TelemetryData#getTireWear(Wheel)} and {@link #getWearGripFactor(float)}
* @param avgTemperatureC average over outer, mittle and inner temperature
* @param pressure coming from {@link TelemetryData#getTirePressureKPa(Wheel)}
* @param load coming from {@link TelemetryData#getTireLoadN(Wheel)}
*
* @return the fraction of maximum grip at the given wear, average temperature, pressure and load.
*/
public abstract float getGripFraction( float wear, float avgTemperatureC, float pressure, float load );
/**
* Selects the grip fraction at the given wear level.
*
* @param wear coming from {@link TelemetryData#getTireWear(Wheel)}
*
* @return the grip fraction at the given wear level.
*/
public abstract float getWearGripFactor( float wear );
/**
* Gets the grip level at maximum tire wear.
*
* @return the grip level at maximum tire wear.
*/
public abstract float getMinGrip();
protected CompoundWheel( Wheel wheel )
{
this.wheel = wheel;
}
}
/**
* Gets the {@link CompoundWheel} for the given wheel.
*
* @param wheel the requested wheel
*
* @return the {@link CompoundWheel} for the given wheel.
*/
public abstract CompoundWheel getWheel( Wheel wheel );
protected TireCompound()
{
}
}
/**
* Gets the number of available {@link TireCompound}s.
*
* @return the number of available {@link TireCompound}s.
*/
public abstract int getNumTireCompounds();
/**
* Gets the {@link TireCompound} by the given index.
*
* @param index zero-based
*
* @return the {@link TireCompound} by the given index.
*/
public abstract TireCompound getTireCompound( int index );
/**
* Gets the {@link TireCompound} for the given wheel, that has the best grip compared to allother available ones.
*
* @param wheel the requested wheel
*
* @return the {@link TireCompound} for the given wheel, that has the best grip.
*/
public abstract TireCompound getTireCompoundBestGrip( Wheel wheel );
/**
* Gets the range of possible values for tire pressure.
*
* @param wheel the requested wheel
*
* @see VehicleSetup.WheelAndTire#getTirePressure()
*
* @return the range of possible values for tire pressure.
*/
public abstract PhysicsSetting getTirePressureRange( Wheel wheel );
public static abstract class UpgradeIdentifier
{
public abstract String getDescription();
}
/**
* Gets the list of installed upgrades.
*
* @return the list of installed upgrades or <code>null</code> if no upgrades are installed.
*/
public abstract UpgradeIdentifier[] getInstalledUpgrades();
protected void reset()
{
getEngine().reset();
getBrakes().reset();
}
protected void finish()
{
getEngine().finish();
getBrakes().finish();
}
protected abstract void applyMeasurementUnitsImpl( MeasurementUnits measurementUnits );
protected final void applyMeasurementUnits( MeasurementUnits measurementUnits )
{
this.fuelRange = new PhysicsSetting( ( measurementUnits == MeasurementUnits.IMPERIAL ) ? Convert.LITERS_TO_GALONS : 1f, 0f );
this.fuelRange.set( this.getFuelRangeL() );
this.fuelRangeLUpdateId = this.getFuelRangeL().updateId;
applyMeasurementUnitsImpl( measurementUnits );
}
protected VehiclePhysics()
{
}
}