Search in sources :

Example 46 with RouteLocation

use of jmri.jmrit.operations.routes.RouteLocation in project JMRI by JMRI.

the class TrainBuilderTest method testMaxEngines.

public void testMaxEngines() {
    // This test uses the maximum length of a train in route
    Setup.setMaxTrainLength(1000);
    Train train = tmanager.newTrain("TestMaxEngines");
    train.setNumberEngines(Train.AUTO);
    Route route = rmanager.newRoute("AutoEngineTest");
    train.setRoute(route);
    Location A = lmanager.newLocation("A");
    Location B = lmanager.newLocation("B");
    Location C = lmanager.newLocation("C");
    Track At = A.addTrack("track", Track.SPUR);
    Track Bt = B.addTrack("track", Track.SPUR);
    Track Ct = C.addTrack("track", Track.SPUR);
    At.setLength(300);
    Bt.setLength(300);
    Ct.setLength(300);
    RouteLocation rA = route.addLocation(A);
    RouteLocation rB = route.addLocation(B);
    RouteLocation rC = route.addLocation(C);
    rA.setMaxCarMoves(12);
    rB.setMaxCarMoves(12);
    rC.setMaxCarMoves(12);
    // 2.5% grade!
    rB.setGrade(2.5);
    Engine e1 = emanager.newEngine("E", "1");
    e1.setModel("GP40");
    Engine e2 = emanager.newEngine("E", "2");
    e2.setModel("GP40");
    Engine e3 = emanager.newEngine("E", "3");
    e3.setModel("GP40");
    Engine e4 = emanager.newEngine("E", "4");
    e4.setModel("GP40");
    e1.setLocation(A, At);
    e2.setLocation(A, At);
    e3.setLocation(A, At);
    e4.setLocation(A, At);
    Consist c = emanager.newConsist("c");
    e1.setConsist(c);
    e2.setConsist(c);
    e3.setConsist(c);
    e4.setConsist(c);
    // limit the maximum to three engines
    Setup.setMaxNumberEngines(3);
    train.reset();
    new TrainBuilder().build(train);
    Assert.assertFalse("Train should not build, needs four engines, three is the maximum allowed", train.isBuilt());
    // remove one engine from consist, train should build
    c.delete(e4);
    train.reset();
    new TrainBuilder().build(train);
    Assert.assertTrue("Train should build, three engines available", train.isBuilt());
}
Also used : Consist(jmri.jmrit.operations.rollingstock.engines.Consist) RouteLocation(jmri.jmrit.operations.routes.RouteLocation) Route(jmri.jmrit.operations.routes.Route) Track(jmri.jmrit.operations.locations.Track) Engine(jmri.jmrit.operations.rollingstock.engines.Engine) RouteLocation(jmri.jmrit.operations.routes.RouteLocation) Location(jmri.jmrit.operations.locations.Location)

Example 47 with RouteLocation

use of jmri.jmrit.operations.routes.RouteLocation in project JMRI by JMRI.

the class CarManager method getAvailableTrainList.

/**
     * Return a list available cars (no assigned train or car already assigned
     * to this train) on a route, cars are ordered least recently moved to most
     * recently moved.
     * @param train The Train to use.
     *
     * @return List of cars with no assigned train on a route
     */
public List<Car> getAvailableTrainList(Train train) {
    List<Car> out = new ArrayList<Car>();
    Route route = train.getRoute();
    if (route == null) {
        return out;
    }
    // get a list of locations served by this route
    List<RouteLocation> routeList = route.getLocationsBySequenceList();
    // don't include RollingStock at route destination
    RouteLocation destination = null;
    if (routeList.size() > 1) {
        destination = routeList.get(routeList.size() - 1);
        // include all cars
        for (int i = 0; i < routeList.size() - 1; i++) {
            if (destination.getName().equals(routeList.get(i).getName())) {
                // include cars at destination
                destination = null;
                break;
            }
        }
        // pickup allowed at destination? Don't include cars in staging
        if (destination != null && destination.isPickUpAllowed() && destination.getLocation() != null && !destination.getLocation().isStaging()) {
            // include cars at destination
            destination = null;
        }
    }
    // get rolling stock by priority and then by moves
    List<Car> sortByPriority = sortByPriority(getByMovesList());
    // now build list of available RollingStock for this route
    for (Car car : sortByPriority) {
        // only use RollingStock with a location
        if (car.getLocation() == null) {
            continue;
        }
        RouteLocation rl = route.getLastLocationByName(car.getLocationName());
        // assigned train is this one
        if (rl != null && rl != destination && (car.getTrain() == null || train.equals(car.getTrain()))) {
            out.add(car);
        }
    }
    return out;
}
Also used : ArrayList(java.util.ArrayList) RouteLocation(jmri.jmrit.operations.routes.RouteLocation) Route(jmri.jmrit.operations.routes.Route)

Example 48 with RouteLocation

use of jmri.jmrit.operations.routes.RouteLocation in project JMRI by JMRI.

the class TrainBuilder method findDestinationAndTrack.

/**
     * Find a destination and track for a car, and add the car to the train.
     *
     * @param car The car that is looking for a destination and destination
     *            track.
     * @param rl The current route location for this car.
     * @param routeIndex Where in the train's route to begin a search for a
     *            destination for this car.
     * @param routeEnd Where to stop looking for a destination.
     * @return true if successful, car has destination, track and a train.
     */
private boolean findDestinationAndTrack(Car car, RouteLocation rl, int routeIndex, int routeEnd) throws BuildFailedException {
    if (routeIndex + 1 == routeEnd) {
        log.debug("Car ({}) is at the last location in the train's route", car.toString());
    }
    addLine(_buildReport, FIVE, MessageFormat.format(Bundle.getMessage("buildFindDestinationForCar"), new Object[] { car.toString(), car.getTypeName(), car.getLoadName(), (car.getLocationName() + ", " + car.getTrackName()) }));
    if (car.getKernel() != null) {
        addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildCarLeadKernel"), new Object[] { car.toString(), car.getKernelName(), car.getKernel().getSize(), car.getKernel().getTotalLength(), Setup.getLengthUnit().toLowerCase() }));
    }
    // start looking after car's current location
    int start = routeIndex;
    // the route location destination being checked for the car
    RouteLocation rld = null;
    // holds the best route location destination for the car
    RouteLocation rldSave = null;
    // holds the best track at destination for the car
    Track trackSave = null;
    // used when a spur has an alternate track and no schedule
    Track finalDestinationTrackSave = null;
    // true when car can be picked up from two or more locations in the route
    boolean multiplePickup = false;
    // more than one location in this route?
    if (!_train.isLocalSwitcher()) {
        // being looking for tracks at the next location
        start++;
    }
    // all pick ups to terminal?
    if (_train.isSendCarsToTerminalEnabled() && !splitString(rl.getName()).equals(splitString(_departLocation.getName())) && routeEnd == _routeList.size()) {
        addLine(_buildReport, FIVE, MessageFormat.format(Bundle.getMessage("buildSendToTerminal"), new Object[] { _terminateLocation.getName() }));
        // user could have specified several terminal locations with the "same" name
        start = routeEnd - 1;
        while (start > routeIndex) {
            if (!splitString(_routeList.get(start - 1).getName()).equals(splitString(_terminateLocation.getName()))) {
                break;
            }
            start--;
        }
    }
    for (int k = start; k < routeEnd; k++) {
        rld = _routeList.get(k);
        // if car can be picked up later at same location, set flag
        if (checkForLaterPickUp(rl, rld, car)) {
            multiplePickup = true;
        }
        if (rld.isDropAllowed() || car.hasFred() || car.isCaboose()) {
            addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildSearchingLocation"), new Object[] { rld.getName() }));
        } else {
            addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildRouteNoDropLocation"), new Object[] { _train.getRoute().getName(), rld.getId(), rld.getName() }));
            continue;
        }
        if (_train.skipsLocation(rld.getId())) {
            addLine(_buildReport, FIVE, MessageFormat.format(Bundle.getMessage("buildLocSkipped"), new Object[] { rld.getName(), rld.getId(), _train.getName() }));
            continue;
        }
        // any moves left at this location?
        if (rld.getCarMoves() >= rld.getMaxCarMoves()) {
            addLine(_buildReport, FIVE, MessageFormat.format(Bundle.getMessage("buildNoAvailableMovesDest"), new Object[] { _train.getRoute().getName(), rld.getId(), rld.getName() }));
            continue;
        }
        // get the destination
        Location testDestination = rld.getLocation();
        if (testDestination == null) {
            // code check, should never throw, all locations in the route have been already checked
            throw new BuildFailedException(MessageFormat.format(Bundle.getMessage("buildErrorRouteLoc"), new Object[] { _train.getRoute().getName(), rld.getName() }));
        }
        Track trackTemp = null;
        Track finalDestinationTrackTemp = null;
        // caboose or car with FRED
        if (splitString(rl.getName()).equals(splitString(rld.getName())) && !_train.isLocalSwitcher() && !car.isPassenger() && !car.isCaboose() && !car.hasFred()) {
            // allow cars to return to the same staging location if no other options (tracks) are available
            if ((_train.isAllowReturnToStagingEnabled() || Setup.isAllowReturnToStagingEnabled()) && testDestination.isStaging() && trackSave == null) {
                addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildReturnCarToStaging"), new Object[] { car.toString(), rld.getName() }));
            } else {
                addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildCarLocEqualDestination"), new Object[] { car.toString(), rld.getName() }));
                continue;
            }
        }
        // check to see if departure track has any restrictions
        if (!car.getTrack().acceptsDestination(testDestination)) {
            addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildDestinationNotServiced"), new Object[] { testDestination.getName(), car.getTrackName() }));
            continue;
        }
        if (!testDestination.acceptsTypeName(car.getTypeName())) {
            addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildCanNotDropLocation"), new Object[] { car.toString(), car.getTypeName(), testDestination.getName() }));
            continue;
        }
        // can this location service this train's direction
        if (!checkDropTrainDirection(rld)) {
            continue;
        }
        // is the train length okay?
        if (!checkTrainLength(car, rl, rld)) {
            // done with this route
            break;
        }
        // no through traffic from origin to terminal?
        if (!_train.isAllowThroughCarsEnabled() && !_train.isLocalSwitcher() && !car.isCaboose() && !car.hasFred() && !car.isPassenger() && splitString(car.getLocationName()).equals(splitString(_departLocation.getName())) && splitString(rld.getName()).equals(splitString(_terminateLocation.getName()))) {
            addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildThroughTrafficNotAllow"), new Object[] { _departLocation.getName(), _terminateLocation.getName() }));
            continue;
        }
        // is there a track assigned for staging cars?
        if (rld == _train.getTrainTerminatesRouteLocation() && _terminateStageTrack != null) {
            // no need to check train and track direction into staging, already done
            String status = car.testDestination(testDestination, _terminateStageTrack);
            if (status.equals(Track.OKAY)) {
                trackTemp = _terminateStageTrack;
            // only generate a new load if there aren't any other tracks available for this car
            } else if (status.startsWith(Track.LOAD) && car.getTrack() == _departStageTrack && car.getLoadName().equals(CarLoads.instance().getDefaultEmptyName()) && rldSave == null && (_departStageTrack.isAddCustomLoadsAnyStagingTrackEnabled() || _departStageTrack.isAddCustomLoadsEnabled() || _departStageTrack.isAddCustomLoadsAnySpurEnabled())) {
                // try and generate a load for this car into staging
                if (generateLoadCarDepartingAndTerminatingIntoStaging(car, _terminateStageTrack)) {
                    trackTemp = _terminateStageTrack;
                } else {
                    addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildCanNotDropCarBecause"), new Object[] { car.toString(), _terminateStageTrack.getName(), status, _terminateStageTrack.getTrackTypeName() }));
                    // failed to create load
                    continue;
                }
            } else {
                addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildCanNotDropCarBecause"), new Object[] { car.toString(), _terminateStageTrack.getName(), status, _terminateStageTrack.getTrackTypeName() }));
                continue;
            }
        // no staging track assigned, start track search
        } else {
            // first report if there are any alternate tracks
            for (Track track : testDestination.getTrackByNameList(null)) {
                if (track.isAlternate()) {
                    addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildTrackIsAlternate"), new Object[] { car.toString(), track.getTrackTypeName(), track.getName() }));
                }
            }
            for (Track testTrack : testDestination.getTrackByMovesList(null)) {
                // dropping to the same track isn't allowed
                if (testTrack == car.getTrack() && !car.isPassenger() && !car.isCaboose() && !car.hasFred()) {
                    addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildCanNotDropCarSameTrack"), new Object[] { car.toString(), testTrack.getName() }));
                    continue;
                }
                // Can the train service this track?
                if (!checkDropTrainDirection(car, rld, testTrack)) {
                    continue;
                }
                // drop to interchange or spur?
                if (!checkTrainCanDrop(car, testTrack)) {
                    continue;
                }
                // report if track has planned pickups
                if (testTrack.getIgnoreUsedLengthPercentage() > 0) {
                    // calculate the available space
                    //                        int available = testTrack.getLength() - (testTrack.getUsedLength() + testTrack.getReserved());
                    int available = testTrack.getLength() - (testTrack.getUsedLength() * (100 - testTrack.getIgnoreUsedLengthPercentage()) / 100 + testTrack.getReservedLengthDrops());
                    int available3 = testTrack.getLength() + (testTrack.getLength() * testTrack.getIgnoreUsedLengthPercentage() / 100) - (testTrack.getUsedLength() + testTrack.getReserved());
                    //                        }
                    if (available3 < available) {
                        available = available3;
                    }
                    addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildTrackHasPlannedPickups"), new Object[] { testTrack.getName(), testTrack.getIgnoreUsedLengthPercentage(), testTrack.getLength(), Setup.getLengthUnit().toLowerCase(), testTrack.getUsedLength(), testTrack.getReserved(), testTrack.getReservedLengthDrops(), testTrack.getReservedLengthDrops() - testTrack.getReserved(), available }));
                }
                String status = car.testDestination(testDestination, testTrack);
                // is the destination a spur with a schedule demanding this car's custom load?
                if (status.equals(Track.OKAY) && !testTrack.getScheduleId().equals(Track.NONE) && !car.getLoadName().equals(CarLoads.instance().getDefaultEmptyName()) && !car.getLoadName().equals(CarLoads.instance().getDefaultLoadName())) {
                    addLine(_buildReport, FIVE, MessageFormat.format(Bundle.getMessage("buildSpurScheduleLoad"), new Object[] { testTrack.getName(), car.getLoadName() }));
                    addCarToTrain(car, rl, rld, testTrack);
                    return true;
                }
                // alternate track isn't checked
                if (!status.equals(Track.OKAY) && // wrong car type for this spur
                !status.startsWith(Track.TYPE) && // can't generate load for spur that is full
                !status.startsWith(Track.LENGTH) && // can't use a spur that is too short
                !status.startsWith(Track.CAPACITY) && testTrack.getTrackType().equals(Track.SPUR) && !testTrack.getScheduleId().equals(Track.NONE) && (car.getTrack().isAddCustomLoadsEnabled() || car.getTrack().isAddCustomLoadsAnySpurEnabled()) && car.getLoadName().equals(CarLoads.instance().getDefaultEmptyName())) {
                    // can we use this track?
                    if (!testTrack.isSpaceAvailable(car)) {
                        addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildNoDestTrackSpace"), new Object[] { car.toString(), testTrack.getLocation().getName(), testTrack.getName(), testTrack.getNumberOfCarsInRoute(), testTrack.getReservedInRoute(), Setup.getLengthUnit().toLowerCase(), testTrack.getReservationFactor() }));
                        // no
                        continue;
                    }
                    addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildGenerateLoad"), new Object[] { car.toString(), car.getTypeName(), testDestination.getName(), testTrack.getName() }));
                    // save the car's load
                    String carLoad = car.getLoadName();
                    ScheduleItem si = getScheduleItem(car, testTrack);
                    if (si != null) {
                        car.setLoadName(si.getReceiveLoadName());
                        if (car.testDestination(testDestination, testTrack).equals(Track.OKAY)) {
                            addLine(_buildReport, FIVE, MessageFormat.format(Bundle.getMessage("buildAddingScheduleLoad"), new Object[] { si.getReceiveLoadName(), car.toString() }));
                            car.setLoadGeneratedFromStaging(true);
                            testTrack.bumpSchedule();
                            addCarToTrain(car, rl, rld, testTrack);
                            return true;
                        }
                    }
                    // restore car's load (default empty)
                    car.setLoadName(carLoad);
                }
                // check to see if alternate track is available if track full and no schedule
                if (status.startsWith(Track.LENGTH) && testTrack.getAlternateTrack() != null && car.getFinalDestination() == null && testTrack.getScheduleId().equals(Track.NONE) && car.getTrack() != testTrack.getAlternateTrack() && car.testDestination(testDestination, testTrack.getAlternateTrack()).equals(Track.OKAY)) {
                    addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildTrackFullHasAlternate"), new Object[] { testDestination.getName(), testTrack.getName(), testTrack.getAlternateTrack().getName() }));
                    finalDestinationTrackTemp = testTrack;
                    // send car to alternate track
                    trackTemp = testTrack.getAlternateTrack();
                    break;
                }
                // okay to drop car?
                if (!status.equals(Track.OKAY)) {
                    addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildCanNotDropCarBecause"), new Object[] { car.toString(), testTrack.getName(), status, testTrack.getTrackTypeName() }));
                    continue;
                }
                // No local moves from spur to spur
                if (_train.isLocalSwitcher() && !Setup.isLocalSpurMovesEnabled() && testTrack.getTrackType().equals(Track.SPUR) && car.getTrack().getTrackType().equals(Track.SPUR)) {
                    addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildNoSpurToSpurMove"), new Object[] { car.getTrackName(), testTrack.getName() }));
                    continue;
                }
                // No local moves from yard to yard
                if (_train.isLocalSwitcher() && !Setup.isLocalYardMovesEnabled() && testTrack.getTrackType().equals(Track.YARD) && car.getTrack().getTrackType().equals(Track.YARD) && !car.isCaboose() && !car.hasFred()) {
                    addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildNoYardToYardMove"), new Object[] { car.getTrackName(), testTrack.getName() }));
                    continue;
                }
                // No local moves from interchange to interchange
                if (_train.isLocalSwitcher() && !Setup.isLocalInterchangeMovesEnabled() && testTrack.getTrackType().equals(Track.INTERCHANGE) && car.getTrack().getTrackType().equals(Track.INTERCHANGE)) {
                    addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildNoInterchangeToInterchangeMove"), new Object[] { car.getTrackName(), testTrack.getName() }));
                    continue;
                }
                // not staging, then use (should never be staging TODO throw an exception)
                if (!testTrack.getTrackType().equals(Track.STAGING)) {
                    trackTemp = testTrack;
                    break;
                }
            }
        }
        // did we find a new destination?
        if (trackTemp != null) {
            addLine(_buildReport, FIVE, MessageFormat.format(Bundle.getMessage("buildCarCanDropMoves"), new Object[] { car.toString(), trackTemp.getTrackTypeName(), trackTemp.getLocation().getName(), trackTemp.getName(), +rld.getCarMoves(), rld.getMaxCarMoves() }));
            if (rldSave == null && multiplePickup) {
                addLine(_buildReport, FIVE, MessageFormat.format(Bundle.getMessage("buildCarHasSecond"), new Object[] { car.toString(), car.getLocationName() }));
                trackSave = null;
                // done
                break;
            }
            // if there's more than one available destination use the one with the least moves
            if (rldSave != null) {
                double saveCarMoves = rldSave.getCarMoves();
                double saveRatio = saveCarMoves / rldSave.getMaxCarMoves();
                double nextCarMoves = rld.getCarMoves();
                double nextRatio = nextCarMoves / rld.getMaxCarMoves();
                // bias cars to the terminal
                if (rld == _train.getTrainTerminatesRouteLocation()) {
                    nextRatio = nextRatio * nextRatio;
                    log.debug("Location ({}) is terminate location, adjusted nextRatio {}", rld.getName(), Double.toString(nextRatio));
                }
                // bias cars with default loads to a track with a schedule
                if (!trackTemp.getScheduleId().equals(Track.NONE)) {
                    nextRatio = nextRatio * nextRatio;
                    log.debug("Track ({}) has schedule ({}), adjusted nextRatio {}", trackTemp.getName(), trackTemp.getScheduleName(), Double.toString(nextRatio));
                }
                // check for an earlier drop in the route
                for (int m = start; m < routeEnd; m++) {
                    RouteLocation rle = _routeList.get(m);
                    if (rle == rld) {
                        // done
                        break;
                    }
                    if (rle.getName().equals(rld.getName()) && (rle.getMaxCarMoves() - rle.getCarMoves() > 0) && rle.isDropAllowed() && checkDropTrainDirection(car, rle, trackTemp)) {
                        log.debug("Found an earlier drop for car ({}) destination ({})", car.toString(), rle.getName());
                        nextCarMoves = rle.getCarMoves();
                        nextRatio = nextCarMoves / rle.getMaxCarMoves();
                        // set car drop to earlier stop
                        rld = rle;
                        break;
                    }
                }
                log.debug("{} = {}, {} = {}", rldSave.getName(), Double.toString(saveRatio), rld.getName(), Double.toString(nextRatio));
                if (saveRatio < nextRatio) {
                    // the saved is better than the last found
                    rld = rldSave;
                    trackTemp = trackSave;
                    finalDestinationTrackTemp = finalDestinationTrackSave;
                } else if (multiplePickup) {
                    addLine(_buildReport, FIVE, MessageFormat.format(Bundle.getMessage("buildCarHasSecond"), new Object[] { car.toString(), car.getLocationName() }));
                    trackSave = null;
                    // done
                    break;
                }
            }
            // every time through, save the best route destination, and track
            rldSave = rld;
            trackSave = trackTemp;
            finalDestinationTrackSave = finalDestinationTrackTemp;
        } else {
            addLine(_buildReport, FIVE, MessageFormat.format(Bundle.getMessage("buildCouldNotFindDestForCar"), new Object[] { car.toString(), rld.getName() }));
        }
    }
    // did we find a destination?
    if (trackSave != null) {
        if (finalDestinationTrackSave != null) {
            car.setFinalDestination(finalDestinationTrackSave.getLocation());
            car.setFinalDestinationTrack(finalDestinationTrackSave);
        }
        addCarToTrain(car, rl, rldSave, trackSave);
        return true;
    }
    checkCarOrder(car);
    // no build errors, but car not given destination
    return false;
}
Also used : ScheduleItem(jmri.jmrit.operations.locations.schedules.ScheduleItem) RouteLocation(jmri.jmrit.operations.routes.RouteLocation) Track(jmri.jmrit.operations.locations.Track) RouteLocation(jmri.jmrit.operations.routes.RouteLocation) Location(jmri.jmrit.operations.locations.Location)

Example 49 with RouteLocation

use of jmri.jmrit.operations.routes.RouteLocation in project JMRI by JMRI.

the class TrainBuilder method checkEngineHP.

/**
     * Checks to see if the engine assigned to the train has the appropriate HP.
     * If the train's HP requirements are significantly higher or lower than the
     * engine that was assigned, the program will search for a more appropriate
     * engine, and assign that engine to the train.
     *
     * The HP calculation is based on a minimum train speed of 36 MPH. The
     * formula HPT x 12 / % Grade = Speed, is used to determine the horsepower
     * required. Speed is fixed at 36 MPH. For example a 1% grade requires a
     * minimum of 3 HPT.
     */
private void checkEngineHP() throws BuildFailedException {
    if (!_train.getNumberEngines().equals(Train.AUTO_HPT) || Setup.getHorsePowerPerTon() == 0 || _departStageTrack != null)
        return;
    // there should be at lease one engine assigned to this train
    Engine leadEngine = _train.getLeadEngine();
    if (leadEngine == null)
        // TODO throw an exception
        return;
    addLine(_buildReport, ONE, BLANK_LINE);
    addLine(_buildReport, ONE, MessageFormat.format(Bundle.getMessage("buildDetermineHpNeeded"), new Object[] { leadEngine.toString(), leadEngine.getHp(), Setup.getHorsePowerPerTon() }));
    // now determine the HP needed for this train
    int hpNeeded = 0;
    int hpAvailable = 0;
    Route route = _train.getRoute();
    if (route != null) {
        boolean helper = false;
        for (RouteLocation rl : route.getLocationsBySequenceList()) {
            if ((_train.getSecondLegOptions() == Train.HELPER_ENGINES && rl == _train.getSecondLegStartLocation()) || (_train.getThirdLegOptions() == Train.HELPER_ENGINES && rl == _train.getThirdLegStartLocation())) {
                addLine(_buildReport, FIVE, MessageFormat.format(Bundle.getMessage("AddHelpersAt"), new Object[] { rl.getName() }));
                helper = true;
            }
            if ((_train.getSecondLegOptions() == Train.HELPER_ENGINES && rl == _train.getSecondLegEndLocation()) || (_train.getThirdLegOptions() == Train.HELPER_ENGINES && rl == _train.getThirdLegEndLocation())) {
                addLine(_buildReport, FIVE, MessageFormat.format(Bundle.getMessage("RemoveHelpersAt"), new Object[] { rl.getName() }));
                helper = false;
            }
            if (helper) {
                // ignore HP needed when helpers are assigned to the train
                continue;
            }
            // check for a change of engines in the train's route
            if (((_train.getSecondLegOptions() & Train.CHANGE_ENGINES) == Train.CHANGE_ENGINES && rl == _train.getSecondLegStartLocation()) || ((_train.getThirdLegOptions() & Train.CHANGE_ENGINES) == Train.CHANGE_ENGINES && rl == _train.getThirdLegStartLocation())) {
                log.debug("Loco change at ({})", rl.getName());
                // done
                break;
            }
            if (_train.getTrainHorsePower(rl) > hpAvailable)
                hpAvailable = _train.getTrainHorsePower(rl);
            int weight = rl.getTrainWeight();
            int hpRequired = (int) ((36 * rl.getGrade() / 12) * weight);
            if (hpRequired < Setup.getHorsePowerPerTon() * weight)
                // minimum HPT
                hpRequired = Setup.getHorsePowerPerTon() * weight;
            if (hpRequired > hpNeeded) {
                addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildReportTrainHpNeeds"), new Object[] { weight, _train.getNumberCarsInTrain(rl), rl.getGrade(), rl.getName(), rl.getId(), hpRequired }));
                hpNeeded = hpRequired;
            }
        }
    }
    if (hpNeeded > hpAvailable) {
        addLine(_buildReport, ONE, MessageFormat.format(Bundle.getMessage("buildAssignedHpNotEnough"), new Object[] { leadEngine.toString(), hpAvailable, hpNeeded }));
        findNewEngine(hpNeeded, leadEngine);
    } else if (hpAvailable > 2 * hpNeeded) {
        addLine(_buildReport, ONE, MessageFormat.format(Bundle.getMessage("buildAssignedHpTooMuch"), new Object[] { leadEngine.toString(), hpAvailable, hpNeeded }));
        findNewEngine(hpNeeded, leadEngine);
    } else {
        log.debug("Keeping engine ({}) it meets the train's HP requirement", leadEngine.toString());
    }
}
Also used : RouteLocation(jmri.jmrit.operations.routes.RouteLocation) Engine(jmri.jmrit.operations.rollingstock.engines.Engine) Route(jmri.jmrit.operations.routes.Route)

Example 50 with RouteLocation

use of jmri.jmrit.operations.routes.RouteLocation in project JMRI by JMRI.

the class Train method getFormatedDepartureTime.

/**
     * Get's train's departure time in 12hr or 24hr format
     *
     * @return train's departure time in the String format hh:mm or hh:mm(AM/PM)
     */
public String getFormatedDepartureTime() {
    // check to see if the route has a departure time
    RouteLocation rl = getTrainDepartsRouteLocation();
    if (rl != null && !rl.getDepartureTime().equals(RouteLocation.NONE)) {
        // need to forward any changes to departure time
        rl.removePropertyChangeListener(this);
        rl.addPropertyChangeListener(this);
        return rl.getFormatedDepartureTime();
    }
    if (!Setup.is12hrFormatEnabled()) {
        return _departureTime;
    }
    // time is in the format of hour:minute AM or PM
    String am_pm = " " + Bundle.getMessage("AM");
    // 12 noon is 12 PM
    int h = Integer.parseInt(getDepartureTimeHour());
    if (h >= 12) {
        am_pm = " " + Bundle.getMessage("PM");
        h = h - 12;
    }
    if (h == 0) {
        h = 12;
    }
    return Integer.toString(h) + ":" + getDepartureTimeMinute() + am_pm;
}
Also used : RouteLocation(jmri.jmrit.operations.routes.RouteLocation)

Aggregations

RouteLocation (jmri.jmrit.operations.routes.RouteLocation)118 Route (jmri.jmrit.operations.routes.Route)64 Location (jmri.jmrit.operations.locations.Location)55 Track (jmri.jmrit.operations.locations.Track)52 Car (jmri.jmrit.operations.rollingstock.cars.Car)48 Engine (jmri.jmrit.operations.rollingstock.engines.Engine)33 LocationManager (jmri.jmrit.operations.locations.LocationManager)21 RouteManager (jmri.jmrit.operations.routes.RouteManager)20 Consist (jmri.jmrit.operations.rollingstock.engines.Consist)17 Train (jmri.jmrit.operations.trains.Train)16 CarManager (jmri.jmrit.operations.rollingstock.cars.CarManager)13 ArrayList (java.util.ArrayList)12 CarTypes (jmri.jmrit.operations.rollingstock.cars.CarTypes)12 EngineManager (jmri.jmrit.operations.rollingstock.engines.EngineManager)12 RollingStock (jmri.jmrit.operations.rollingstock.RollingStock)11 EngineTypes (jmri.jmrit.operations.rollingstock.engines.EngineTypes)8 SuppressFBWarnings (edu.umd.cs.findbugs.annotations.SuppressFBWarnings)6 IOException (java.io.IOException)6 TrainManager (jmri.jmrit.operations.trains.TrainManager)6 JCheckBox (javax.swing.JCheckBox)5