Beispiel #1
0
 private void handleFirstTX(SinkData channel, Time currentTime)
     throws NoRoomException, IllegalActionException {
   // Method to handle the third stage, transmitting the first packet to a sink
   IntToken token = new IntToken(currentChannel); // Create a token to send
   output.send(0, token); // Send the token
   if (channel.n
       != null) { // If we have already calculated n in a previous stage (if n is 1) we can skip
                  // straight to the next transmission period
     setNextFireTime(channel, currentTime.getDoubleValue() + (channel.t.getDoubleValue() * 12));
     channel.state = states.SECONDTX;
   } else { // If we do not know n then we need to next fire at the beginning of the next
            // synchronisation phase so we can receive the first pulse and find n
     setNextFireTime(
         channel, currentTime.getDoubleValue() + (channel.t.getDoubleValue() * 11) - 0.02);
     channel.state = states.NCALC;
   }
   System.out.println(
       "FIRSTTX on channel "
           + currentChannel
           + ". t is "
           + channel.t
           + ". nextFireTime is "
           + channel.nextFireTime
           + " currentTime is "
           + currentTime);
 }
Beispiel #2
0
 private void handleFirstRX(SinkData channel, Time currentTime)
     throws NoTokenException, IllegalActionException {
   // Method to handle the first stage, receiving the first synchronisation pulse
   IntToken token = (IntToken) input.get(0); // Retrieve the token from the input
   Time timeDelta =
       currentTime.subtract(
           waitTime); // Calculate a delta between the current time and when the channel was
                      // changed, to find the waiting time
   if (timeDelta.getDoubleValue() <= 1.5
       && token.equals(
           1)) { // Token is 1, and we have been waiting for longer than 1.5s. So we will not have
                 // a follow-up token, so can't be used for determining t
     channelQueue
         .remove(); // Send the current channel to the back of the queue so we can do something
                    // useful while it is in its sleep state
     channelQueue.add(currentChannel);
     return;
   }
   if (!channel
       .secondRun) { // If this is the first time we have received packets on the channel we will
                     // need the current time to calculate a t
     channel.t = currentTime;
   }
   channel.state = states.SECONDRX; // Set the channel state to the next stage
   channel.firstValue = token.intValue(); // Store the value we have received
   System.out.println("FIRSTRX on channel " + currentChannel + " currentTime is " + currentTime);
 }
Beispiel #3
0
 private void handleNCalc(SinkData channel, Time currentTime)
     throws NoTokenException, IllegalActionException {
   // Method to handle the fourth stage, where we listen to the first synchronisation pulse to find
   // the value of n
   System.out.println(channel.nextFireTime.getDoubleValue() >= currentTime.getDoubleValue() + 0.4);
   if (channel.nextFireTime.getDoubleValue() >= currentTime.getDoubleValue()) {
     input.get(0);
     return;
   } else if (channel
       .secondRun) { // If we are on the second run through, we have already transmitted twice so
                     // we can stop here
     channel.state = states.FINISHED;
     return;
   } else if (currentTime.subtract(channel.nextFireTime).getDoubleValue()
       > 2) { // There is a large delta between when we were supposed to fire and when we fired, so
              // we probably have a collision with another channel
     channel.secondRun = true; // Store that we will need to go around again for this channel
     channel.state = states.FIRSTRX; // Set the stage back to the beginning so we can restart
     System.out.println(
         "NCALC on channel "
             + currentChannel
             + " n is: "
             + channel.n
             + ". t is "
             + channel.t
             + ". nextFireTime is "
             + channel.nextFireTime
             + " currentTime is "
             + currentTime);
     nextChannel(currentChannel, currentTime);
   } else {
     channel.n = ((IntToken) input.get(0)).intValue();
     setNextFireTime(
         channel, currentTime.getDoubleValue() + (channel.t.getDoubleValue() * channel.n));
     channel.state = states.SECONDTX;
     System.out.println(
         "NCALC on channel "
             + currentChannel
             + " n is: "
             + channel.n
             + ". t is "
             + channel.t
             + ". nextFireTime is "
             + channel.nextFireTime
             + " currentTime is "
             + currentTime);
     nextChannel(currentChannel, currentTime);
     removeFromQueue(currentChannel);
   }
 }
Beispiel #4
0
 private void handleSecondTX(SinkData channel, Time currentTime) throws IllegalActionException {
   IntToken token = new IntToken(currentChannel);
   output.send(0, token);
   channel.state = states.FINISHED;
   System.out.println(
       "SECONDTX on channel "
           + currentChannel
           + ". t is "
           + channel.t
           + " currentTime is "
           + currentTime);
   System.out.println(channelQueue.toString());
 }
Beispiel #5
0
 private void handleSecondRX(SinkData channel, Time currentTime)
     throws NoTokenException, IllegalActionException {
   // Method to handle the second stage, receiving the second synchronisation pulse
   if (!channel
       .secondRun) { // If this is the second time we have received packets on the channel we
                     // already have t so no need to calculate it
     channel.t = currentTime.subtract(channel.t);
   }
   int currentValue = ((IntToken) input.get(0)).intValue(); // Retrieve the value from the input
   if (channel.firstValue == 1 && currentValue == 1) { // If the first two values are 1 then n is 1
     channel.n = 1;
     channel.t =
         new Time(getDirector())
             .add(
                 channel.t.getDoubleValue()
                     / 12); // Calculate t given that n is 1, i.e divide the period by 12 as per
                            // the protocol
   }
   setNextFireTime(
       channel,
       currentTime.getDoubleValue()
           + (channel.t.getDoubleValue()
               * currentValue)); // Manually set the next fire time for this channel
   channel.state = states.FIRSTTX; // Set the channel state to the next stage
   System.out.println(
       "SECONDRX on channel "
           + currentChannel
           + ". Current value is "
           + currentValue
           + ". t is "
           + channel.t
           + ". nextFireTime is "
           + channel.nextFireTime
           + " currentTime is "
           + currentTime);
   nextChannel(currentChannel, currentTime);
   removeFromQueue(currentChannel); // We can now move onto listening on the next channel
 }
Beispiel #6
0
  public void fire() throws IllegalActionException {
    Time currentTime =
        getDirector().getModelTime(); // Get the model time to be used for various calculations

    if (changeChan) { // Check if we need to change the channel in this fire period
      setChannel(nextChannel); // Change to the next required channel
      changeChan = false; // Return to normal operation upon the next fire
      if (input.hasToken(
          0)) { // If this fire was initiated by a token on the input, consume it to avoid loops
        input.get(0);
      }
    } else if (input.hasToken(0)) { // Wireless token has been received f
      SinkData channel =
          channelStore.get(currentChannel); // Retrieve the information for the current channel
      switch (channel.state) { // Determine what stage of the system we are at
        case FIRSTRX: // Stage one, we will be receiving the first synchronisation packet
          handleFirstRX(channel, currentTime);
          break;
        case SECONDRX: // Stage two, we will be receiving the second synchronisation packet
          handleSecondRX(channel, currentTime);
          break;
        case NCALC: // Stage 4, we will be receiving the first synchronisation packet of the
                    // sequence to ascertain the n value
          handleNCalc(channel, currentTime);
          break;
        default: // We are in a state that does not require an input token, so we discard it
          input.get(0);
          break;
      }
    } else { // No token has been received so it is a fire initiated by the source and not a token
             // on the input
      SinkData channel = null; // Initialise a channel to be used later
      int desiredChannelNum =
          currentChannel; // Initialise a variable to store the channel required for this firing
      for (int channelNum :
          channelStore
              .keySet()) { // We need to find the channel that has caused the actor to be fired in
                           // this time period
        channel =
            channelStore.get(channelNum); // Retrieve the information for the channel being checked
        if (channel.nextFireTime != null
            && channel.state
                != states.FINISHED) { // If we have a valid firing time, that has been initialised
          if (!channel.nextFireTime.equals(
              currentTime)) { // We are on an incorrect channel, continue searching
            continue;
          } else { // We have found the correct channel
            desiredChannelNum = channelNum; // Set the desired channel to the channel we have found
            break;
          }
        }
      }
      if (currentChannel == desiredChannelNum) { // If we are on the channel that we desire
        System.out.println(
            channel.nextFireTime.getDoubleValue() <= currentTime.getDoubleValue() + 0.4);
        if (channel.nextFireTime.getDoubleValue()
            <= currentTime.getDoubleValue() + 0.4) { // If we are not too early for the firing time
          switch (channel.state) { // Determine what stage of the system we are at
            case FIRSTTX: // Stage 3, we are in the receive period for the channels sink so we can
                          // transmit a packet
              handleFirstTX(channel, currentTime);
              changeChan = true; // Change back to the channel back to what we had previously
              getDirector().fireAt(this, currentTime.add(0.000001));
              break;
            case SECONDTX: // Stage 5, we are in the receive period for the second time, so we can
                           // transmit a packet
              handleSecondTX(channel, currentTime);
              changeChan = true; // Change back to the channel back to what we had previously
              getDirector().fireAt(this, currentTime.add(0.000001));
              break;
          }
        }
      } else if (desiredChannelNum
          != 0) { // We are not on the desired channel, so we have to change to it
        //		System.out.println(currentChannel + " : " + desiredChannelNum);
        nextChannel =
            currentChannel; // Set the channel we will change back to after the transmit to our
                            // current channel
        setChannel(desiredChannelNum); // Set the channel to the desired channel
        channel.nextFireTime =
            currentTime.add(
                0.0000001); // Set the channels fire time to when we are firing it so we can detect
                            // which channel fired
        getDirector()
            .fireAt(
                this,
                currentTime.add(0.0000001)); // Fire the actor again so we can process the transmit
      }
    }
  }
Beispiel #7
0
 private void setNextFireTime(SinkData channel, double additionalTime)
     throws IllegalActionException {
   channel.nextFireTime = new Time(getDirector()).add(additionalTime + (currentChannel / 100.0));
   getDirector().fireAt(this, channel.nextFireTime);
 }