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());
}
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;
}
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;
}
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());
}
}
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;
}
Aggregations