Example #1
0
 private float getRampLength(float totalLen, RosterSpeedProfile speedProfile) {
   float speed = 0.0f;
   float rampLength = 0.0f;
   int numSteps = 0;
   while (speed < _maxSpeed) {
     float dist;
     if (speedProfile != null) {
       dist =
           speedProfile.getSpeed((speed + _minSpeed / 2), _forward.isSelected())
               * _intervalTime
               / 1000;
     } else {
       dist = (speed + _minSpeed / 2) * _intervalTime * _throttleFactor;
     }
     if (rampLength + dist <= totalLen / 2) {
       if ((speed + _minSpeed) > _maxSpeed) {
         dist = dist * (_maxSpeed - speed) / _minSpeed;
         speed = _maxSpeed;
       } else {
         speed += _minSpeed;
       }
       rampLength += dist;
       numSteps++;
       if (log.isDebugEnabled()) {
         log.debug(
             "step "
                 + numSteps
                 + " dist= "
                 + dist
                 + " speed= "
                 + speed
                 + " rampLength = "
                 + rampLength);
       }
     } else {
       // cannot get to _maxSpeed and have enough length to decelerate
       _maxSpeed = speed; // modify
       break;
     }
   }
   // add the smidge of distance needed to reach _maxSpeed
   //        rampLength += (_maxSpeed - speed)*_intervalTime*_throttleFactor;
   if (log.isDebugEnabled()) {
     log.debug(
         numSteps
             + " speed steps of delta= "
             + _minSpeed
             + " for rampLength = "
             + rampLength
             + " to reach speed "
             + _maxSpeed);
   }
   return rampLength;
 }
Example #2
0
  private String makeCommands(Warrant w) {

    int nextIdx = 0; // block index - increment after getting a block order
    List<BlockOrder> orders = getOrders();
    BlockOrder bo = orders.get(nextIdx++);
    String blockName = bo.getBlock().getDisplayName();

    w.addThrottleCommand(new ThrottleSetting(0, "F0", "true", blockName));
    if (_forward.isSelected()) {
      w.addThrottleCommand(new ThrottleSetting(1000, "Forward", "true", blockName));
      w.addThrottleCommand(new ThrottleSetting(1000, "F2", "true", blockName));
      w.addThrottleCommand(new ThrottleSetting(2500, "F2", "false", blockName));
      w.addThrottleCommand(new ThrottleSetting(1000, "F2", "true", blockName));
      w.addThrottleCommand(new ThrottleSetting(2500, "F2", "false", blockName));
    } else {
      w.addThrottleCommand(new ThrottleSetting(1000, "Forward", "false", blockName));
      w.addThrottleCommand(new ThrottleSetting(2000, "F3", "true", blockName));
      w.addThrottleCommand(new ThrottleSetting(500, "F3", "false", blockName));
      w.addThrottleCommand(new ThrottleSetting(500, "F3", "true", blockName));
      w.addThrottleCommand(new ThrottleSetting(500, "F1", "true", blockName));
    }

    // estimate for blocks of zero length - an estimate of ramp length
    boolean isForward = _forward.isSelected();
    jmri.jmrit.roster.RosterEntry ent = getTrain();
    RosterSpeedProfile speedProfile = null;
    if (ent != null) {
      speedProfile = ent.getSpeedProfile();
      if (speedProfile != null) {
        float s = speedProfile.getSpeed(_maxSpeed, isForward);
        if (log.isDebugEnabled()) {
          log.debug("SpeedProfile _maxSpeed setting= " + _maxSpeed + " speed= " + s + "mps");
        }
        if (s <= 0.0f || s == Float.POSITIVE_INFINITY) {
          speedProfile = null;
        }
      }
    }
    if (log.isDebugEnabled()) {
      log.debug(
          "throttle Factor= "
              + _throttleFactor
              + " from "
              + (speedProfile != null ? "SpeedProfile" : "Default"));
    }

    float defaultBlockLen = 6 * _maxSpeed * _intervalTime / _throttleFactor; // just a wild guess
    float totalLen = getTotalLength(defaultBlockLen);
    float rampLength = getRampLength(totalLen, speedProfile);

    float blockLen = bo.getPath().getLengthMm(); // length of path in current block
    if (blockLen <= 0) {
      blockLen = defaultBlockLen;
    }
    blockLen /= 2;

    // start train
    float speedTime = 500; // ms time to complete speed step from last block
    float noopTime = 0; // ms time for entry into next block
    float curSpeed = 0;
    // each speed step will last for _intervalTime ms
    float curDistance = 0; // distance traveled in current block
    float remRamp = rampLength;
    if (log.isDebugEnabled()) {
      log.debug(
          "Start Ramp Up in block \""
              + blockName
              + "\" in "
              + (int) speedTime
              + "ms, remRamp= "
              + remRamp
              + ", blockLen= "
              + blockLen);
    }

    while (remRamp > 0.0f) { // ramp up loop

      if (speedProfile != null) {
        curDistance = speedProfile.getSpeed(curSpeed, isForward) * speedTime / 1000;
      } else {
        curDistance = curSpeed * speedTime * _throttleFactor;
      }
      while (curDistance < blockLen && curSpeed < _maxSpeed) {
        float dist;
        if (speedProfile != null) {
          dist =
              speedProfile.getSpeed((curSpeed + _minSpeed / 2), isForward) * _intervalTime / 1000;
        } else {
          dist = (curSpeed + _minSpeed / 2) * _intervalTime * _throttleFactor;
        }
        float prevSpeed = curSpeed;
        if ((curSpeed + _minSpeed) > _maxSpeed) {
          dist = dist * (_maxSpeed - curSpeed) / _minSpeed;
          curSpeed = _maxSpeed;
        } else {
          curSpeed += _minSpeed;
        }
        if (curDistance + dist <= blockLen && remRamp > 0.0f) {
          curDistance += dist;
          remRamp -= dist;
          w.addThrottleCommand(
              new ThrottleSetting((int) speedTime, "Speed", Float.toString(curSpeed), blockName));
          if (log.isDebugEnabled()) {
            log.debug(" dist= " + dist);
          }
          if (log.isDebugEnabled()) {
            log.debug(
                "Ramp Up in block \""
                    + blockName
                    + "\" to speed "
                    + curSpeed
                    + " in "
                    + (int) speedTime
                    + "ms to reach curDistance= "
                    + curDistance
                    + " with remRamp= "
                    + remRamp);
          }
          speedTime = _intervalTime;
        } else {
          curSpeed = prevSpeed;
          break;
        }
      }

      // Possible case where curDistance can exceed the length of a block that was just entered.
      // Move to next block and adjust the distance times into that block
      if (speedProfile != null) {
        if (curDistance >= blockLen) {
          noopTime =
              Math.round(
                  1000
                      * speedProfile.getDurationOfTravelInSeconds(
                          isForward, curSpeed, Math.round(blockLen))); // time to next block
          speedTime =
              Math.round(
                  1000
                      * speedProfile.getDurationOfTravelInSeconds(
                          isForward, curSpeed, Math.round(curDistance - blockLen)));
        } else {
          noopTime =
              Math.round(
                  1000
                      * speedProfile.getDurationOfTravelInSeconds(
                          isForward, curSpeed, Math.round(blockLen - curDistance)));
          speedTime = _intervalTime - noopTime; // time to next speed change
        }
      } else {
        if (curDistance >= blockLen) {
          noopTime = (blockLen) / (curSpeed * _throttleFactor); // time to next block
          speedTime = (curDistance - blockLen) / (curSpeed * _throttleFactor);
        } else {
          noopTime = (blockLen - curDistance) / (curSpeed * _throttleFactor); // time to next block
          speedTime = _intervalTime - noopTime; // time to next speed change
        }
      }

      // break out here if deceleration is to be started in this block
      if (totalLen - blockLen <= rampLength || curSpeed >= _maxSpeed) {
        break;
      }
      if (remRamp > 0.0f && nextIdx < orders.size()) {
        totalLen -= blockLen;
        if (log.isDebugEnabled()) {
          log.debug(
              "Leave RampUp block \""
                  + blockName
                  + "\" noopTime= "
                  + noopTime
                  + ", in distance="
                  + curSpeed * noopTime * _throttleFactor
                  + ", blockLen= "
                  + blockLen
                  + ", remRamp= "
                  + remRamp);
        }
        bo = orders.get(nextIdx++);
        blockName = bo.getBlock().getDisplayName();
        blockLen = bo.getPath().getLengthMm();
        if (blockLen <= 0) {
          blockLen = defaultBlockLen;
        }
        w.addThrottleCommand(new ThrottleSetting((int) noopTime, "NoOp", "Enter Block", blockName));
        if (log.isDebugEnabled()) {
          log.debug(
              "Enter block \""
                  + blockName
                  + "\" noopTime= "
                  + noopTime
                  + ", blockLen= "
                  + blockLen);
        }
      }
    }
    if (log.isDebugEnabled()) {
      log.debug(
          "Ramp Up done at block \""
              + blockName
              + "\" curSpeed="
              + ""
              + curSpeed
              + ", blockLen= "
              + blockLen
              + " totalLen= "
              + totalLen
              + ", rampLength= "
              + rampLength
              + ", remRamp= "
              + remRamp);
    }

    if (totalLen - blockLen > rampLength) {
      totalLen -= blockLen;
      if (nextIdx < orders.size()) { // not the last block
        bo = orders.get(nextIdx++);
        blockName = bo.getBlock().getDisplayName();
        blockLen = bo.getPath().getLengthMm();
        if (blockLen <= 0) {
          blockLen = defaultBlockLen;
        }
        w.addThrottleCommand(new ThrottleSetting((int) noopTime, "NoOp", "Enter Block", blockName));
        if (log.isDebugEnabled()) {
          log.debug(
              "Enter block \""
                  + blockName
                  + "\" noopTime= "
                  + noopTime
                  + ", blockLen= "
                  + blockLen);
        }
        curDistance = 0;
      }

      // run through mid route at max speed
      while (nextIdx < orders.size() && totalLen - blockLen > rampLength) {
        totalLen -= blockLen;
        // constant speed, get time to next block
        if (speedProfile != null) {
          noopTime =
              Math.round(
                  1000
                      * speedProfile.getDurationOfTravelInSeconds(
                          isForward, curSpeed, Math.round(blockLen - curDistance)));
        } else {
          noopTime = (blockLen - curDistance) / (curSpeed * _throttleFactor);
        }
        if (log.isDebugEnabled()) {
          log.debug(
              "Leave MidRoute block \""
                  + blockName
                  + "\" noopTime= "
                  + noopTime
                  + ", curDistance="
                  + curDistance
                  + ", blockLen= "
                  + blockLen
                  + ", totalLen= "
                  + totalLen);
        }
        bo = orders.get(nextIdx++);
        blockName = bo.getBlock().getDisplayName();
        blockLen = bo.getPath().getLengthMm();
        if (blockLen <= 0) {
          blockLen = defaultBlockLen;
        }
        if (nextIdx == orders.size()) {
          blockLen /= 2;
        }
        w.addThrottleCommand(new ThrottleSetting((int) noopTime, "NoOp", "Enter Block", blockName));
        if (log.isDebugEnabled()) {
          log.debug(
              "Enter block \""
                  + blockName
                  + "\" noopTime= "
                  + noopTime
                  + ", blockLen= "
                  + blockLen);
        }
        curDistance = 0;
      }
    } // else Start ramp down in current block

    // Ramp down.  use negative delta
    remRamp = rampLength;
    if (speedProfile != null) {
      speedTime =
          Math.round(
              1000
                  * speedProfile.getDurationOfTravelInSeconds(
                      isForward, curSpeed, Math.round(totalLen - rampLength)));
    } else {
      speedTime = (totalLen - rampLength) / (curSpeed * _throttleFactor);
    }
    curDistance = totalLen - rampLength;
    if (log.isDebugEnabled()) {
      log.debug(
          "Begin Ramp Down at block \""
              + blockName
              + "\" curDistance= "
              + curDistance
              + " SpeedTime= "
              + (int) speedTime
              + "ms, blockLen= "
              + blockLen
              + ", totalLen= "
              + totalLen
              + ", rampLength= "
              + rampLength
              + " curSpeed= "
              + curSpeed);
    }

    while (curSpeed > 0) {
      if (nextIdx == orders.size()) { // at last block
        if (_stageEStop.isSelected()) {
          w.addThrottleCommand(new ThrottleSetting(0, "Speed", "-0.5", blockName));
          _intervalTime = 0;
          break;
        }
      }

      do {
        float dist;
        float nextSpeed = Math.max(curSpeed - _minSpeed, 0);
        if (speedProfile != null) {
          dist =
              speedProfile.getSpeed((curSpeed + nextSpeed) / 2, isForward) * _intervalTime / 1000;
        } else {
          dist = (curSpeed + nextSpeed) / 2 * _intervalTime * _throttleFactor;
        }
        curDistance += dist;
        curSpeed = nextSpeed;
        remRamp -= dist;
        w.addThrottleCommand(
            new ThrottleSetting((int) speedTime, "Speed", Float.toString(curSpeed), blockName));
        if (log.isDebugEnabled()) {
          log.debug(
              "Ramp Down in block \""
                  + blockName
                  + "\" to speed "
                  + curSpeed
                  + " in "
                  + (int) speedTime
                  + "ms to reach curDistance= "
                  + curDistance
                  + " with remRamp= "
                  + remRamp);
        }
        if (curDistance >= blockLen) {
          if (speedProfile != null) {
            speedTime =
                Math.round(
                    1000
                        * speedProfile.getDurationOfTravelInSeconds(
                            isForward, curSpeed, Math.round(curDistance - blockLen)));
          } else {
            speedTime = (curDistance - blockLen) / (curSpeed * _throttleFactor);
          }
        } else {
          speedTime = _intervalTime;
        }
        noopTime = _intervalTime - speedTime;
      } while (curDistance < blockLen && curSpeed > 0);

      if (nextIdx < orders.size()) {
        totalLen -= blockLen;
        if (log.isDebugEnabled()) {
          log.debug(
              "Leave RampDown block \""
                  + blockName
                  + "\" noopTime= "
                  + noopTime
                  + ", in distance="
                  + curSpeed * noopTime * _throttleFactor
                  + ", blockLen= "
                  + blockLen
                  + ", totalLen= "
                  + totalLen
                  + ", remRamp= "
                  + remRamp);
        }
        bo = orders.get(nextIdx++);
        blockName = bo.getBlock().getDisplayName();
        blockLen = bo.getPath().getLengthMm();
        if (blockLen <= 0) {
          blockLen = defaultBlockLen;
        }
        if (nextIdx == orders.size()) {
          blockLen /= 2;
        }
        w.addThrottleCommand(new ThrottleSetting((int) noopTime, "NoOp", "Enter Block", blockName));
        if (log.isDebugEnabled()) {
          log.debug(
              "Enter block \""
                  + blockName
                  + "\" noopTime= "
                  + noopTime
                  + ", blockLen= "
                  + blockLen);
        }
        if (speedProfile != null) {
          curDistance = speedProfile.getSpeed(curSpeed, isForward) * speedTime / 1000;
        } else {
          curDistance = curSpeed * speedTime * _throttleFactor;
        }
      } else {
        if (blockLen == 0) {
          speedTime = 0;
        }
        break;
      }
    }
    // Ramp down finished
    if (curSpeed > 0) { // cleanup fractional speeds. insure speed 0 - should never happen.
      log.warn(
          "Ramp down LAST speed change in block \""
              + blockName
              + "\" to speed 0  after "
              + (int) speedTime
              + "ms. curSpeed= "
              + curSpeed
              + ", curDistance= "
              + curDistance
              + ", remRamp= "
              + remRamp);
      w.addThrottleCommand(new ThrottleSetting((int) speedTime, "Speed", "0.0", blockName));
    }
    w.addThrottleCommand(new ThrottleSetting(500, "F1", "false", blockName));
    w.addThrottleCommand(new ThrottleSetting(1000, "F2", "true", blockName));
    w.addThrottleCommand(new ThrottleSetting(3000, "F2", "false", blockName));
    w.addThrottleCommand(new ThrottleSetting(1000, "F0", "false", blockName));
    /*      if (_addTracker.isSelected()) {
        WarrantTableFrame._defaultAddTracker = true;
        w.addThrottleCommand(new ThrottleSetting(10, "START TRACKER", "", blockName));
    } else {
        WarrantTableFrame._defaultAddTracker = false;
    }*/
    return null;
  }