Problem 3 has you calculate the descent profile of an airplane to determine how
ID: 668089 • Letter: P
Question
Problem 3 has you calculate the descent profile of an airplane to determine how far away the pilot should begin descending, based on an initial and target altitude.
Problem 3 (name this Lab1_Problem3)
This problem has you calculate the number of miles away from an airport a pilot will need to begin the descent. We will keep it simple and use a standard 500 feet per minute descent rate. All calculations will need to be in minutes, feet, knots, and nautical miles.
Focus on the algorithm, working backwards. Plan your work before you work your plan. Make notes on paper as you organize your thoughts.
Use your resources. If you don't have a clue what descent profile planning is, then read about it first. There are lots of resources like http://www.wikihow.com/Calculate-Aircraft-Descent-Rate
First examine the output that the program will eventually produce. Steps 7 and 8 below show you how the output will look and what values will be displayed.
Figure out what inputs you need from the end user in order to arrive at your final destination—the values that will be displayed as output.
Determine what calculations you will need to take the inputs, process them, and construct your output. Breaking things up into simple, discreet steps, sometimes using variables to store interim values, can often make for simpler, easier to maintain code.
Finally, think of the variables you'll need and the data types that will best accommodate the needs. Use the standard template in Using DrJava to guide your thinking (e.g., input-capture, expression-result, etc.).
You will also need the Scanner class for this problem.
Step 1: Follow the instructions for creating a new Java project in Using DrJava.
Step 2: To help you memorize a basic Java program structure at this stage of your learning, type in the standard "public class..." and use Lab1_Problem3 for the name. Add the braces, then public static void main(String[] args);. Make sure you have the proper indentation in place (Allman or K&R).
Step 3: Run your program (Compile, then Run). Debug as needed. It won't do anything yet, but you'll be sure it's at an error-free baseline.
Step 4: Go back to Using DrJava and copy and paste the sections for the project's identification information and the other comments into your emerging program. The developer is you, the description something like, “Lab1_Problem3: descent profile planning.”
Step 5: Declare the variables you'll need in the appropriate section of the standard comments.
Step 6: Instantiate a scanner from the Scanner class so you can perform input from the console (keyboard). See Notes 2.M. Notice you will have to copy two lines from the notes: the import directive and the actual instantiation line. The import must be done before your class definition at the top of your program. The actual instantiation is done in the DECLARATIONS section.
Step 7: Now, add the actual calculations needed to determine how many minutes it will take to lose the required number of feet to reach the target altitude. Use the standard rate of 500 feet per minute. Display your output following this sample:
Minutes needed to descend from 7500 feet to 1000 feet: 13 minutes
Step 8: Finally, add the calculations needed to determine how many miles away to start down, based on the groundspeed and the number of minutes required to descend. Display your output following this sample:
Distance to begin descent based on a groundspeed of 120 knots: 26 miles
Step 9: Close DrJava and backup your files.
Explanation / Answer
package javax.realtime.test.airplane;
import javax.realtime.AbsoluteTime;
import javax.realtime.AsyncEvent;
import javax.realtime.RelativeTime;
import javax.realtime.DSS.DSS;
import javax.realtime.DSS.Normal;
public class Airplane {
// milliseconds
private final double gearDeployMean = 28000.0;
private final double gearDeployStandardDeviation = 5500.0;
// flap change speed; one degree per second == 1000
private final int millisecondsPerDegree = 1000;
/**
* Constructor
* @param altitude current altitude of the airplane
*/
public Airplane( int altitude ) {
assert altitude >= 0;
this.altitude = altitude;
gearChangeDelay = new Normal(gearDeployMean, gearDeployStandardDeviation);
}
/**
* Set the airplane's current altitude plan, i.e., to ascend or descend
* @param plannedAltitude the target altitude
* @param plannedAltitudeTime the time at which the target altitude will be reached
*/
public void setAltitudePlan( int plannedAltitude, AbsoluteTime plannedAltitudeTime ) {
assert DSS.currentTime().compareTo( plannedAltitudeTime ) < 0;
altitude = readAltitude();
altitudeTime = DSS.currentTime();
this.plannedAltitude = plannedAltitude;
this.plannedAltitudeTime = plannedAltitudeTime;
}
/**
* Set the airplane's current altitude, at level flight.
* @param altitude the current altitude
*/
public void setAltitude( int altitude ) {
this.altitude = altitude;
// no climb or descent plan; level flight
this.plannedAltitudeTime = null;
}
/**
* Read the airplane's current altitude. Note that if there is an altitude plan
* in effect, this will require extrapolation of last altitude known explicitly.
* @return the current altitude
*/
public int readAltitude() {
if ( plannedAltitudeTime == null ) {
// level flight
return altitude;
}
if ( DSS.currentTime().compareTo( plannedAltitudeTime ) >= 0 ) {
// leveled off after reaching new altitude
// remove flight plan, as optimization
altitude = plannedAltitude;
plannedAltitudeTime = null;
return altitude;
}
// mid-plan; do linear extrapolation
int altitudeDiff = plannedAltitude - altitude;
RelativeTime timeDiff = plannedAltitudeTime.subtract( altitudeTime );
RelativeTime nowDiff = DSS.currentTime().subtract( altitudeTime );
// TO DO make calculation accurate to nanoseconds
long millisTimeDiff = timeDiff.getMilliseconds();
long millisNowDiff = nowDiff.getMilliseconds();
float fraction = (float)millisNowDiff / (float)millisTimeDiff;
return (int)(((float)altitudeDiff)*fraction) + altitude;
}
/**
* Return the current flaps setting in degrees
* @return the current flaps setting in degrees
*/
public int getFlapsDegrees() {
assert flapsDegrees >= 0;
return flapsDegrees;
}
/**
* Change the current flaps setting. Note that this will require a delay of the
* invoking <A href="RealtimeThread.html"><CODE>RealtimeThread</CODE></A>, because
* actuation is not instantaneous.
* @param newDegrees the desired new flaps setting
* @param lightIndicator an event to fire when the flaps attain the desired setting; if
* <CODE>null</CODE>, simply return after the delay
*/
public void changeFlaps( int newDegrees, AsyncEvent lightIndicator )
throws InterruptedException {
// calculate delay, based on degree difference between desired and current
// settings
int degreeDifference = Math.abs( newDegrees - getFlapsDegrees() );
int holdTimeMillis = degreeDifference * millisecondsPerDegree;
printTimeDistanceAndAltitude();
System.out.println( "request to change flaps from " + flapsDegrees + " to " +
newDegrees );
DSS.hold( new RelativeTime( holdTimeMillis, 0 ));
// flaps setting now completed
printTimeDistanceAndAltitude();
System.out.println( "flaps changed from " + flapsDegrees + " to " +
newDegrees );
// update local variable recording flaps setting
setFlaps( newDegrees );
// fire event provided, if not <CODE>null</CODE>
if ( lightIndicator != null ) {
lightIndicator.fire();
}
}
/**
* Invert state of landing gear, i.e., from up to down, or vice-versa.
* Action includes retraction of gear doors.<p>
*
* Note this will require a delay, which figures significantly in the accident
* scenario.
* @param gearIndicator an event to fire when gear change and door retraction
* are completed; if
* <CODE>null</CODE>, simply return after the delay.
*/
public void changeGear( AsyncEvent gearIndicator )
throws InterruptedException {
printTimeDistanceAndAltitude();
System.out.println( "gear change requested from " +
gearString( false ) + " to " + gearString( true ) );
int delayMillis;
if ( DSS.usingJPF ) {
delayMillis = (int)gearChangeDelay.threeChoice();
} else {
delayMillis = (int)gearChangeDelay.draw();
}
DSS.hold( new RelativeTime( delayMillis, 0 ) );
printTimeDistanceAndAltitude();
System.out.println( "gear change from " + gearString( false ) + " to " +
gearString( true ) + " completed" );
setGearDown( !getGearDown() );
if ( gearIndicator != null ) {
gearIndicator.fire();
}
}
/**
* Set flaps degrees directly, without simulating delay. Can be used for initialization.
* @param degrees the current flaps degrees
*/
public void setFlaps( int degrees ) {
flapsDegrees = degrees;
}
/**
* Return the state of the landing gear; <CODE>true</CODE> iff gear is down.
* @return true iff the landing gear is down
*/
public boolean getGearDown() {
return gearDown;
}
/**
* Set the state of the landing gear, without simulating delay. Can be used for
* initialization.
* @param gearDown
*/
public void setGearDown( boolean gearDown ) {
this.gearDown = gearDown;
}
/**
* Create a string conveying the status of the landing gear.
* @param invert if <CODE>true</CODE>, invert the state for reporting. This is
* handy for printing state requested before it is attained.
* @return <CODE>up</CODE> or <CODE>down</CODE>
*/
public String gearString( boolean invert ) {
if ( invert ) {
return getGearDown() ? "up" : "down";
}
return getGearDown() ? "down" : "up";
}
/**
* Prints prefix to log lines, including simulated time, distance to runway, and
* current altitude.
*/
public void printTimeDistanceAndAltitude() {
DSS.printTime();
System.out.print( "altitude " + readAltitude() );
if ( feetToRunwayTime != null ) {
System.out.print( ", runway " + readFeetToRunway() + " ft., " );
} else {
System.out.print( " " );
}
}
/**
* Sets the current feet to runway. Used during initialization. Also record the
* current time, so that the distance to the runway can be extrapolated using the
* current airplane speed after some time has passed.
* @param feet the current feet to the runway.
*/
public void setFeetToRunway( int feet ) {
feetToRunway = feet;
feetToRunwayTime = DSS.currentTime();
}
/**
* Make a dynamic calculation of the current feet to the runway. The distance and
* time of the last speed change are not updated; this will not be done until the
* next speed change.
* @return the feet to the runway.
*/
public int readFeetToRunway() {
long feetToRunwayTimeMillis = feetToRunwayTime.getMilliseconds();
long timeNowMillis = DSS.currentTime().getMilliseconds();
int feetCovered = (int)(timeNowMillis - feetToRunwayTimeMillis ) *
groundFeetPerSecond / 1000;
// System.out.println( "feetCovered=" + feetCovered );
return feetToRunway - feetCovered;
}
/**
* Set the current ground speed of the airplane. Because the speed is changing,
* the prior extrapolation must be closed out by updating the feet to the
* runway and recording explicitly the current distance to the runway.
* @param feetPerSecond the new speed in feet per second
*/
public void setSpeed( int feetPerSecond ) {
printTimeDistanceAndAltitude();
System.out.println( "speed set at " + feetPerSecond*3600/5280 + " mph" );
// ground speed change, update basis for extrapolation
feetToRunway = readFeetToRunway();
feetToRunwayTime = DSS.currentTime();
groundFeetPerSecond = feetPerSecond;
lastSpeedChange = DSS.currentTime();
}
/**
* Calculate the time to cover a specified distance at the current speed.
* @param feet the specified distance in feet
* @return the time required, in milliseconds
*/
public long millisToCoverFeetAtCurrentSpeed( int feet ) {
assert feet >= 0;
return feet * 1000 / groundFeetPerSecond;
}
/**
* Feet covered at current speed for given time interval
* @param interval the time interval
* @return the feet covered during the interval
*/
public int feetCovered( RelativeTime interval ) {
assert interval.compareTo( new RelativeTime( 0, 0 ) ) >= 0;
// TO DO make accurate to nanoseconds
long millis = interval.getMilliseconds();
return (int)(groundFeetPerSecond * millis / 1000);
}
/**
* Current flaps degrees, initially 0
*/
private int flapsDegrees = 0;
/**
* Current altitude
*/
private int altitude;
/**
* Time at which altitude plan was set, if any; initially <CODE>null</CODE>,
* which indicates level flight.
*/
private AbsoluteTime altitudeTime = null;
/**
* Target altitude of current altitude plan. Valid only if <CODE>altitudeTime</CODE>
* is not <CODE>null</CODE>.
*/
private int plannedAltitude;
/**
* Time at which altitude should equal <CODE>plannedAltitude</CODE>.
* Valid only if <CODE>altitudeTime</CODE> is not <CODE>null</CODE>.
*/
private AbsoluteTime plannedAltitudeTime;
/**
* Feet to runway as of time <CODE>feetToRunwayTime</CODE>.
*/
private int feetToRunway;
/**
* Time at which feet to runway equaled <CODE>feetToRunway</CODE>.
*/
private AbsoluteTime feetToRunwayTime;
/**
* Current airplane speed, in feet per second.
*/
private int groundFeetPerSecond;
/**
* Time at which speed was last set. If speed has never been set, equals
* <CODE>null</CODE>.
*/
public AbsoluteTime lastSpeedChange;
/**
* Landing gear status; <CODE>true</CODE> indicates gear up,
* <CODE>false</CODE> indicates gear down. Not updated until gear changes
* are complete.
*/
private boolean gearDown = false;
/**
* Pseudo random normal number generator, used for landing gear change delays.
*/
protected Normal gearChangeDelay;
/**
* True iff spoilers are armed.
*/
public boolean spoilersArmed;
/**
* True iff the localizer alive event has happened.
*/
public boolean localizerAlive = false;
/**
* True iff the airplane is on the ground. Initially <CODE>false</CODE>.
*/
public boolean> }
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.