예제 #1
0
 /**
  * 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);
   }
 }
예제 #2
0
 /**
  * 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);
   }
 }
예제 #3
0
  /**
   * 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);
    }
  }
예제 #4
0
  /**
   * 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;
  }
예제 #5
0
 /**
  * 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;
  }
예제 #7
0
 /**
  * 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;
 }
예제 #8
0
 /**
  * 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);
 }
예제 #9
0
  /**
   * 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);
  }