/*
* JaamSim Discrete Event Simulation
* Copyright (C) 2013 Ausenco Engineering Canada Inc.
* Copyright (C) 2016 JaamSim Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jaamsim.CalculationObjects;
import com.jaamsim.Graphics.DisplayEntity;
import com.jaamsim.Samples.SampleProvider;
import com.jaamsim.input.Input;
import com.jaamsim.input.Keyword;
import com.jaamsim.input.Output;
import com.jaamsim.input.UnitTypeInput;
import com.jaamsim.input.ValueInput;
import com.jaamsim.ui.FrameBox;
import com.jaamsim.units.AngleUnit;
import com.jaamsim.units.TimeUnit;
import com.jaamsim.units.Unit;
import com.jaamsim.units.UserSpecifiedUnit;
/**
* Super-class for wave generators that produce either sine or square waves.
* @author Harry King
*
*/
public abstract class WaveGenerator extends DisplayEntity implements SampleProvider {
@Keyword(description = "The unit type for the value returned by the wave.",
exampleList = {"DistanceUnit"})
protected final UnitTypeInput unitType;
@Keyword(description = "Amplitude of the generated wave.",
exampleList = {"2.0"})
private final ValueInput amplitude;
@Keyword(description = "Period of the generated wave.",
exampleList = {"2 s"})
private final ValueInput period;
@Keyword(description = "Initial phase angle of the generated wave.",
exampleList = {"45 deg"})
private final ValueInput phaseAngle;
@Keyword(description = "Offset added to the output of the generated wave.",
exampleList = {"2.0"})
private final ValueInput offset;
{
unitType = new UnitTypeInput("UnitType", "Key Inputs", UserSpecifiedUnit.class);
unitType.setRequired(true);
this.addInput(unitType);
amplitude = new ValueInput("Amplitude", "Key Inputs", 1.0d);
amplitude.setValidRange(0.0d, Double.POSITIVE_INFINITY);
amplitude.setUnitType(UserSpecifiedUnit.class);
this.addInput(amplitude);
period = new ValueInput("Period", "Key Inputs", 1.0d);
period.setUnitType(TimeUnit.class);
period.setValidRange(0.0d, Double.POSITIVE_INFINITY);
this.addInput(period);
phaseAngle = new ValueInput("PhaseAngle", "Key Inputs", 0.0d);
phaseAngle.setUnitType(AngleUnit.class);
this.addInput(phaseAngle);
offset = new ValueInput("Offset", "Key Inputs", 0.0d);
offset.setUnitType(UserSpecifiedUnit.class);
this.addInput(offset);
}
@Override
public void updateForInput(Input<?> in) {
super.updateForInput(in);
if (in == unitType) {
amplitude.setUnitType(unitType.getUnitType());
offset.setUnitType(unitType.getUnitType());
FrameBox.reSelectEntity(); // Update the units in the Output Viewer
return;
}
}
@Override
public Class<? extends Unit> getUnitType() {
return unitType.getUnitType();
}
@Override
public Class<? extends Unit> getUserUnitType() {
return unitType.getUnitType();
}
/*
* Calculate the current dimensionless signal for the wave.
*/
protected abstract double getSignal(double angle);
@Override
@Output(name = "Value",
description = "The present value for the wave.",
unitType = UserSpecifiedUnit.class)
public double getNextSample(double simTime) {
// Calculate the present phase angle
double angle = 2.0*Math.PI * simTime/period.getValue() + phaseAngle.getValue();
// Set the output value for the wave
return amplitude.getValue() * this.getSignal(angle) + offset.getValue();
}
@Override
public double getMeanValue(double simTime) {
return offset.getValue();
}
@Override
public double getMinValue() {
return offset.getValue() - amplitude.getValue();
}
@Override
public double getMaxValue() {
return offset.getValue() + amplitude.getValue();
}
}