/** * Request the first firing either at the start time or at a random time, depending on * <i>fireAtStart</i>. * * @exception IllegalActionException If the fireAt() method of the director throws it, or if the * director does not agree to fire the actor at the specified time. */ @Override public void initialize() throws IllegalActionException { super.initialize(); Director director = getDirector(); if (director == null) { throw new IllegalActionException(this, "No director!"); } double stopTimeValue = ((DoubleToken) stopTime.getToken()).doubleValue(); $ASSIGN$_stopTime(new Time(getDirector(), stopTimeValue)); Time currentTime = director.getModelTime(); if (!_stopTime.isInfinite() && _stopTime.compareTo(currentTime) > 0) { director.fireAt(this, _stopTime); $ASSIGN$_executing(true); } $ASSIGN$_nextOutputIndex(0); $ASSIGN$_nextFiringTime(currentTime); $ASSIGN$_outputProduced(false); if (((BooleanToken) fireAtStart.getToken()).booleanValue()) { _fireAt(currentTime); } else { _generateRandomNumber(); $ASSIGN$_nextFiringTime(director.getModelTime().add(_current)); _fireAt(_nextFiringTime); } }
/** * If the argument is the meanTime parameter, check that it is positive. * * @param attribute The attribute that changed. * @exception IllegalActionException If the meanTime value is not positive. */ @Override public void attributeChanged(Attribute attribute) throws IllegalActionException { if (attribute == meanTime) { double mean = ((DoubleToken) meanTime.getToken()).doubleValue(); if (mean <= 0.0) { throw new IllegalActionException( this, "meanTime is required to be positive. meanTime given: " + mean); } } else if (attribute == values) { ArrayToken val = (ArrayToken) values.getToken(); $ASSIGN$_length(val.length()); } else if (attribute == stopTime) { double newStopTimeValue = ((DoubleToken) stopTime.getToken()).doubleValue(); if (_executing) { Time newStopTime = new Time(getDirector(), newStopTimeValue); Director director = getDirector(); if (director != null) { Time currentTime = director.getModelTime(); if (newStopTime.compareTo(currentTime) > 0) { director.fireAt(this, newStopTime); } else { throw new IllegalActionException( this, "The stop time " + "is earlier than the current time."); } } $ASSIGN$_stopTime(newStopTime); } } else { super.attributeChanged(attribute); } }
/** * If the <i>stopTime</i> parameter is changed and the model is executing, then if the new value * is greater than zero and greater than the current time, then ask the director to fire this * actor at that time. If the new value is less than the current time, then request refiring at * the current time. * * @exception IllegalActionException If the superclass throws it. */ public void attributeChanged(Attribute attribute) throws IllegalActionException { if (attribute == stopTime) { double newStopTimeValue = ((DoubleToken) stopTime.getToken()).doubleValue(); if (_executing) { Time newStopTime = new Time(getDirector(), newStopTimeValue); Director director = getDirector(); if (director != null) { Time currentTime = director.getModelTime(); if (newStopTime.compareTo(currentTime) > 0) { director.fireAt(this, newStopTime); } else { throw new IllegalActionException( this, "The stop time " + "is earlier than the current time."); } } _stopTime = newStopTime; } } else { super.attributeChanged(attribute); } }
/** * Return false if the current time is greater than or equal to the <i>stopTime</i> parameter * value. Otherwise, return true. Derived classes should call this at the end of their postfire() * method and return its returned value. * * @exception IllegalActionException Not thrown in this base class. */ public boolean postfire() throws IllegalActionException { Time currentTime = getDirector().getModelTime(); if (currentTime.compareTo(_stopTime) >= 0) { return false; } return true; }
/** * Generate an exponential random number and schedule the next firing. * * @exception IllegalActionException If the director throws it when scheduling the next firing, or * if the director does not agree to fire the actor at the specified time. */ @Override public boolean postfire() throws IllegalActionException { boolean result = super.postfire(); Time currentTime = getDirector().getModelTime(); if (_outputProduced) { $ASSIGN$_outputProduced(false); $ASSIGN$SPECIAL$_nextOutputIndex(11, _nextOutputIndex); if (_nextOutputIndex >= _length) { $ASSIGN$_nextOutputIndex(0); } $ASSIGN$_nextFiringTime(currentTime.add(_current)); _fireAt(_nextFiringTime); } else if (currentTime.compareTo(_nextFiringTime) >= 0) { _fireAt(currentTime); } if (currentTime.compareTo(_stopTime) >= 0) { return false; } return result; }
/** * Schedule a new actor for execution on the next available scheduler and return the next time * this scheduler has to perform a reschedule. * * @param actor The actor to be scheduled. * @param currentPlatformTime The current platform time. * @param deadline The deadline of the event. * @param executionTime The execution time of the actor. * @return Relative time when this Scheduler has to be executed again. * @exception IllegalActionException Thrown if actor parameters such as execution time or priority * cannot be read. */ @Override public Time schedule(NamedObj actor, Time currentPlatformTime, Time deadline, Time executionTime) throws IllegalActionException { super.schedule(actor, currentPlatformTime, deadline, executionTime); Time minimumRemainingTime = null; // Check if is already executing somewhere. for (NamedObj schedulerActor : _actors) { AtomicExecutionAspect scheduler = (AtomicExecutionAspect) schedulerActor; if (scheduler.getRemainingTime(actor) != null && scheduler.getRemainingTime(actor).getDoubleValue() > 0.0) { // This actor is currently executing on this scheduler. Time time = scheduler.schedule(actor, currentPlatformTime, deadline, executionTime); notifyExecutionListeners( scheduler, currentPlatformTime.getDoubleValue(), ExecutionEventType.START); if (time.getDoubleValue() == 0.0) { notifyExecutionListeners( scheduler, currentPlatformTime.getDoubleValue(), ExecutionEventType.STOP); } _remainingTimeOnCore.put(scheduler, time); _lastActorFinished = scheduler.lastActorFinished(); return time; } } // Its not executing anywhere, find free core. for (NamedObj schedulerActor : _actors) { AtomicExecutionAspect scheduler = (AtomicExecutionAspect) schedulerActor; if (scheduler == this) { continue; } Time remainingTime = _remainingTimeOnCore.get(scheduler); if (remainingTime == null || remainingTime.getDoubleValue() == 0.0) { Time time = scheduler.schedule(actor, currentPlatformTime, deadline, executionTime); notifyExecutionListeners( scheduler, currentPlatformTime.getDoubleValue(), ExecutionEventType.START); if (time.getDoubleValue() == 0.0) { notifyExecutionListeners( scheduler, currentPlatformTime.getDoubleValue(), ExecutionEventType.STOP); } _remainingTimeOnCore.put(scheduler, time); _lastActorFinished = scheduler.lastActorFinished(); return time; } else { if (minimumRemainingTime == null || minimumRemainingTime.compareTo(remainingTime) > 0) { minimumRemainingTime = remainingTime; } } } return minimumRemainingTime; }
/** * If the current time matches the expected time for the next output, then return true. Also * return true if the trigger input is connected and has events. Otherwise, return false. * * @exception IllegalActionException If there is no director. */ @Override public boolean prefire() throws IllegalActionException { if (_debugging) { _debug("Called prefire()"); } for (int i = 0; i < trigger.getWidth(); i++) { if (trigger.isKnown() && trigger.hasToken(i)) { return true; } } Time currentTime = getDirector().getModelTime(); if (currentTime.compareTo(_nextFiringTime) == 0) { return true; } return false; }
/** * Output the current value. * * @exception IllegalActionException If there is no director. */ @Override public void fire() throws IllegalActionException { boolean triggerInputPresent = false; for (int i = 0; i < trigger.getWidth(); i++) { if (trigger.isKnown() && trigger.hasToken(i)) { triggerInputPresent = true; } } Director director = getDirector(); Time currentTime = director.getModelTime(); boolean timeForOutput = currentTime.compareTo(_nextFiringTime) >= 0; if (!timeForOutput && !triggerInputPresent) { return; } if (director instanceof SuperdenseTimeDirector) { int currentMicrostep = ((SuperdenseTimeDirector) director).getIndex(); if (currentMicrostep < 1 && !triggerInputPresent) { return; } } super.fire(); output.send(0, _getValue(_nextOutputIndex)); $ASSIGN$_outputProduced(true); }
/** * Get the predicted quantization-event time for a state (QSS-specific). * * @param stateIdx The state index. * @param quantEvtTimeMax The maximum quantization event time. */ protected final Time _predictQuantizationEventTimeWorker( final int stateIdx, final Time quantEvtTimeMax) { // Note the superclass takes care of updating status variables and // storing the returned result. // Initialize. final ModelPolynomial qStateMdl = _qStateMdls[stateIdx]; final ModelPolynomial cStateMdl = _cStateMdls[stateIdx]; final double dq = _dqs[stateIdx]; // Check internal consistency. assert (dq > 0); assert (quantEvtTimeMax.getDoubleValue() > 0); assert (quantEvtTimeMax.compareTo(qStateMdl.tMdl) > 0); assert (quantEvtTimeMax.compareTo(cStateMdl.tMdl) > 0); // Find predicted quantization-event time, as change from {tMostRecent}. Time tMostRecent; double dt; if (qStateMdl.tMdl.compareTo(cStateMdl.tMdl) > 0) { // Here, most recent event was a quantization-event. tMostRecent = qStateMdl.tMdl; dt = _predictQuantizationEventDeltaTimeQSS2QFromC(qStateMdl, cStateMdl, dq, _exactInputs); } else { // Here, most recent event was a rate-event. tMostRecent = cStateMdl.tMdl; dt = _predictQuantizationEventDeltaTimeQSS2General(qStateMdl, cStateMdl, dq, _exactInputs); } // Require {dt} > 0. if (dt <= 0) { // In exact arithmetic, and if the integrator is being stepped properly, // this should never happen. However, if the integrator stepped to a // time very close to the previous predicted quantization-event time, // or given a small numerator and large denominator in expressions // above, can get nonpositive {dt}. // Reset to as small a value as can manage. // Use the `ulp`, the "units in the last place". From the // documentation at {http://docs.oracle.com/javase/7/docs/api/java/lang/Math.html}: // "For a given floating-point format, an ulp of a specific real // number value is the distance between the two floating-point // values bracketing that numerical value." // TODO: Construct integrator with "min time step" parameter, // and pass it in for use it here. dt = java.lang.Math.ulp(tMostRecent.getDoubleValue()); } // Bound result to reasonable limits. // At lower end, need a positive number that, when added to {tMostRecent}, // produces a distinct time. // At upper end, can't be larger than {quantEvtTimeMax}. Time predQuantEvtTime; while (true) { if (quantEvtTimeMax.subtractToDouble(tMostRecent) <= dt) { // Here, tMostRecent + dt >= quantEvtTimeMax. // Note determined this case in a slightly roundabout way, since // simply adding {dt} to {tMostRecent} may cause problems if {quantEvtTimeMax} // reflects some inherent limitation of class {Time}. predQuantEvtTime = quantEvtTimeMax; break; } // Here, tMostRecent + dt < quantEvtTimeMax. predQuantEvtTime = tMostRecent.addUnchecked(dt); if (predQuantEvtTime.compareTo(tMostRecent) > 0) { // Here, added {dt} and got a distinct, greater, time. break; } // Here, {dt} so small that can't resolve difference from {tMostRecent}. dt *= 2; } return (predQuantEvtTime); }