BehavioralCharacteristics.java
package org.opentrafficsim.core.gtu.drivercharacteristics;
import java.util.HashMap;
import java.util.Map;
import org.djunits.unit.DimensionlessUnit;
import org.djunits.unit.Unit;
import org.djunits.value.vdouble.scalar.Acceleration;
import org.djunits.value.vdouble.scalar.Dimensionless;
import org.djunits.value.vdouble.scalar.DoubleScalar;
import org.djunits.value.vdouble.scalar.Frequency;
import org.djunits.value.vdouble.scalar.Length;
import org.djunits.value.vdouble.scalar.LinearDensity;
import org.djunits.value.vdouble.scalar.Speed;
import org.djunits.value.vdouble.scalar.Time;
/**
* In this class a list of behavioral characteristics in the form of parameters can be stored for use in behavioral models.
* <p>
* Copyright (c) 2013-2015 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
* BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
* </p>
* $LastChangedDate: 2015-07-24 02:58:59 +0200 (Fri, 24 Jul 2015) $, @version $Revision: 1147 $, by $Author: averbraeck $,
* initial version Mar 24, 2016 <br>
* @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
* @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
* @author Wouter Schakel
*/
public class BehavioralCharacteristics
{
// TODO: !=EMPTY may not work across multiple computers
/**
* Object to recognize that none was set previously.
*/
private static final Dimensionless EMPTY = new Dimensionless(0, DimensionlessUnit.SI);
/** List of parameters. */
private final Map<AbstractParameterType<?>, DoubleScalar.Rel<?>> parameters = new HashMap<>();
/** List of parameters with values before last set. */
private final Map<AbstractParameterType<?>, DoubleScalar.Rel<?>> previous = new HashMap<>();
/**
* Set parameter value of given parameter type.
* @param parameterType Parameter type.
* @param value Value.
* @param <U> Class of unit.
* @param <T> Class of value.
* @throws ParameterException If the value does not comply with value type constraints.
*/
@SuppressWarnings("unchecked")
public final <U extends Unit<U>, T extends DoubleScalar.Rel<U>> void setParameter(
final ParameterType<T> parameterType, final DoubleScalar.Rel<U> value) throws ParameterException
{
parameterType.check((T) value, this);
saveSetParameter(parameterType, value);
}
/**
* Set parameter value of given parameter type.
* @param parameterType Parameter type.
* @param value Value.
*/
public final void setParameter(final ParameterTypeBoolean parameterType, final boolean value)
{
saveSetParameter(parameterType, new Dimensionless(value ? 1.0 : 0.0, DimensionlessUnit.SI));
}
/**
* Set parameter value of given parameter type.
* @param parameterType Parameter type.
* @param value Value.
* @throws ParameterException If the value does not comply with value type constraints.
*/
public final void setParameter(final ParameterTypeDouble parameterType, final double value) throws ParameterException
{
parameterType.check(value, this);
saveSetParameter(parameterType, new Dimensionless(value, DimensionlessUnit.SI));
}
/**
* Set parameter value of given parameter type.
* @param parameterType Parameter type.
* @param value Value.
* @throws ParameterException If the value does not comply with value type constraints.
*/
public final void setParameter(final ParameterTypeInteger parameterType, final int value) throws ParameterException
{
parameterType.check(value, this);
saveSetParameter(parameterType, new Dimensionless(value, DimensionlessUnit.SI));
}
/**
* Remembers the current value, or if it is not given, for possible reset.
* @param parameterType Parameter type.
* @param value Value.
*/
private void saveSetParameter(final AbstractParameterType<?> parameterType, final DoubleScalar.Rel<?> value)
{
if (this.parameters.containsKey(parameterType))
{
this.previous.put(parameterType, this.parameters.get(parameterType));
}
else
{
// remember that there was no value before this set
this.previous.put(parameterType, EMPTY);
}
this.parameters.put(parameterType, value);
}
/**
* Resets the parameter value to the value from before the last set. This goes only a single value back.
* @param parameterType Parameter type.
* @throws ParameterException If the parameter was never set.
*/
public final void resetParameter(final AbstractParameterType<?> parameterType) throws ParameterException
{
ParameterException.failIf(!this.previous.containsKey(parameterType), "Reset on parameter of type '"
+ parameterType.getId() + "' could not be performed, it was not set.");
if (this.previous.get(parameterType) != EMPTY)
{
this.parameters.put(parameterType, this.previous.get(parameterType));
}
else
{
// no value was set before last set, so make parameter type not set
this.parameters.remove(parameterType);
}
this.previous.remove(parameterType); // prevent consecutive resets
}
/**
* Get parameter of given type.
* @param parameterType Parameter type.
* @param <U> Class of unit.
* @param <T> Class of value.
* @return Parameter of given type.
* @throws ParameterException If parameter was never set.
*/
@SuppressWarnings("unchecked")
public final <U extends Unit<U>, T extends DoubleScalar.Rel<U>> DoubleScalar.Rel<U>
getParameter(final ParameterType<T> parameterType) throws ParameterException
{
checkContains(parameterType);
return (DoubleScalar.Rel<U>) this.parameters.get(parameterType);
}
/**
* Get parameter of given type.
* @param parameterType Parameter type.
* @return Parameter of given type.
* @throws ParameterException If parameter was never set.
*/
public final boolean getParameter(final ParameterTypeBoolean parameterType) throws ParameterException
{
checkContains(parameterType);
return this.parameters.get(parameterType).si != 0.0;
}
/**
* Get parameter of given type.
* @param parameterType Parameter type.
* @return Parameter of given type.
* @throws ParameterException If parameter was never set.
*/
public final int getParameter(final ParameterTypeInteger parameterType) throws ParameterException
{
checkContains(parameterType);
return (int) this.parameters.get(parameterType).si;
}
/**
* Get parameter of given type.
* @param parameterType Parameter type.
* @return Parameter of given type.
* @throws ParameterException If parameter was never set.
*/
public final double getParameter(final ParameterTypeDouble parameterType) throws ParameterException
{
checkContains(parameterType);
return this.parameters.get(parameterType).si;
}
/**
* Get parameter of given type.
* @param parameterType Parameter type.
* @return Parameter of given type.
* @throws ParameterException If parameter was never set.
*/
public final Speed getSpeedParameter(final ParameterType<Speed> parameterType) throws ParameterException
{
checkContains(parameterType);
return (Speed) this.parameters.get(parameterType);
}
/**
* Get parameter of given type.
* @param parameterType Parameter type.
* @return Parameter of given type.
* @throws ParameterException If parameter was never set.
*/
public final Acceleration getAccelerationParameter(final ParameterType<Acceleration> parameterType)
throws ParameterException
{
checkContains(parameterType);
return (Acceleration) this.parameters.get(parameterType);
}
/**
* Get parameter of given type.
* @param parameterType Parameter type.
* @return Parameter of given type.
* @throws ParameterException If parameter was never set.
*/
public final Time.Rel getTimeParameter(final ParameterType<Time.Rel> parameterType) throws ParameterException
{
checkContains(parameterType);
return (Time.Rel) this.parameters.get(parameterType);
}
/**
* Get parameter of given type.
* @param parameterType Parameter type.
* @return Parameter of given type.
* @throws ParameterException If parameter was never set.
*/
public final Length.Rel getLengthParameter(final ParameterType<Length.Rel> parameterType) throws ParameterException
{
checkContains(parameterType);
return (Length.Rel) this.parameters.get(parameterType);
}
/**
* Get parameter of given type.
* @param parameterType Parameter type.
* @return Parameter of given type.
* @throws ParameterException If parameter was never set.
*/
public final Frequency getFrequencyParameter(final ParameterType<Frequency> parameterType) throws ParameterException
{
checkContains(parameterType);
return (Frequency) this.parameters.get(parameterType);
}
/**
* Get parameter of given type.
* @param parameterType Parameter type.
* @return Parameter of given type.
* @throws ParameterException If parameter was never set.
*/
public final LinearDensity getLinearDensityParameter(final ParameterType<LinearDensity> parameterType)
throws ParameterException
{
checkContains(parameterType);
return (LinearDensity) this.parameters.get(parameterType);
}
/**
* Check whether parameter has been set.
* @param parameterType Parameter type.
* @throws ParameterException If parameter is not present.
*/
private void checkContains(final AbstractParameterType<?> parameterType) throws ParameterException
{
ParameterException.failIf(!contains(parameterType), "Could not get parameter of type '" + parameterType.getId()
+ "' as it was not set.");
}
/**
* Whether the given parameter type has been set.
* @param parameterType Parameter type.
* @return Whether the given parameter type has been set.
*/
public final boolean contains(final AbstractParameterType<?> parameterType)
{
return this.parameters.containsKey(parameterType);
}
/**
* Returns a safe copy of the parameters.
* @return Safe copy of the parameters, e.g., for printing.
*/
public final Map<AbstractParameterType<?>, DoubleScalar.Rel<?>> getParameters()
{
return new HashMap<AbstractParameterType<?>, DoubleScalar.Rel<?>>(this.parameters);
}
}