Skip to content
Snippets Groups Projects
Commit 3e9af0d1 authored by Brutzman, Don's avatar Brutzman, Don
Browse files

tuned-up version of final group shared project

parent 19b6f72c
No related branches found
No related tags found
No related merge requests found
Showing
with 1418 additions and 0 deletions
package MV3500Cohort2022MayJune.projects;
import simkit.SimEntityBase;
import simkit.random.RandomVariate;
/**
* One of the simplest non-trivial Event Graph models. A series of Arrival
* events is scheduled based on an inter arrival time random variate. The state
* variable, simply counts the number of these arrivals.
*
* @author abuss@nps.edu
*/
public class ArrivalProcess extends SimEntityBase {
/**
* Generates interarrival times
*/
private RandomVariate interarrivalTimeGenerator;
/**
* State variable that counts the number of Arrival events
*/
protected int numberArrivals;
/**
* Instantiate an ArrivalProcess with the given interarrivalTimeGenerator
*
* @param interarrivalTimeGenerator Given RandomVariate for interarrival
* times
*/
public ArrivalProcess(RandomVariate interarrivalTimeGenerator) {
this.setInterarrivalTimeGenerator(interarrivalTimeGenerator);
}
/**
* If the ArrivalProcess is instantiated using the zero-argument
* constructor, be sure the set the interarrivalTimeGenerator with an
* explicit call to its setter method.
*/
public ArrivalProcess() {
}
/**
* Initialize numberArrivals to 0
*/
public void reset() {
super.reset();
numberArrivals = 0;
}
/**
* Schedule the first Arrival event with delay generated by
* interarrivalTimeGenerator
*/
public void doRun() {
firePropertyChange("numberArrivals", getNumberArrivals());
waitDelay("Arrival", interarrivalTimeGenerator);
}
/**
* Increment numberArrivals<br>
* Schedule next Arrival event with delay generated by
* interarrivalTimeGenerator
*/
public void doArrival() {
int oldNumberArrivals = getNumberArrivals();
numberArrivals += 1;
firePropertyChange("numberArrivals", oldNumberArrivals, getNumberArrivals());
waitDelay("Arrival", interarrivalTimeGenerator);
}
/**
* accessor method to get a state variable
* @return the interarrivalTimeGenerator
*/
public RandomVariate getInterarrivalTimeGenerator() {
return interarrivalTimeGenerator;
}
/**
* accessor method to set a state variable
* @param interarrivalTimeGenerator the interarrivalTimeGenerator to set
*/
public void setInterarrivalTimeGenerator(RandomVariate interarrivalTimeGenerator) {
this.interarrivalTimeGenerator = interarrivalTimeGenerator;
}
/**
* accessor method to get a state variable
* @return the numberArrivals
*/
public int getNumberArrivals() {
return numberArrivals;
}
}
package MV3500Cohort2022MayJune.projects;
import edu.nps.moves.dis7.enumerations.VariableRecordType;
import edu.nps.moves.dis7.utilities.DisChannel;
import simkit.SimEntityBase;
import simkit.random.RandomVariate;
/**
* ArrivalProcess event graph with openDis7 output PDU messages added.
* One of the simplest non-trivial Event Graph models. A series of Arrival
* events is scheduled based on an inter arrival time random variate. The state
* variable, simply counts the number of these arrivals.
*
* @see SimkitOpenDis7Examples.SimpleServer
* @see SimkitOpenDis7Examples.run.RunSimpleServerOpenDis7
* @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/raw/master/examples/src/SimkitOpenDis7Examples/ArrivalProcessOpenDis7EventGraph.png">ArrivalProcessDisPdu.png</a>
* @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/raw/master/examples/src/SimkitOpenDis7Examples/SimpleServerComponentEventGraph.png">SimpleServerComponentEventGraph.png</a>
* @author abuss@nps.edu
* @author brutzman@nps.edu
*/
public class ArrivalProcessOpenDis7 extends SimEntityBase {
private final DisChannel disChannel = new DisChannel();
/**
* Generates interarrival times
*/
private RandomVariate interarrivalTimeGenerator;
/**
* State variable that counts the number of Arrival events
*/
protected int numberArrivals;
/** Initialize channel setup for OpenDis7 and report a test PDU */
private void initializeDisChannel()
{
disChannel.setUpNetworkInterface();
disChannel.printlnTRACE ("disChannel.getNetworkAddress()=" + disChannel.getNetworkAddress() +
", getNetworkPort()=" + disChannel.getNetworkPort());
disChannel.sendCommentPdu(VariableRecordType.OTHER, "ArrivalProcessOpenDis7 initialized");
}
/**
* Instantiate an ArrivalProcess with the given interarrivalTimeGenerator
*
* @param interarrivalTimeGenerator Given RandomVariate for interarrival
* times
*/
public ArrivalProcessOpenDis7(RandomVariate interarrivalTimeGenerator) {
this.interarrivalTimeGenerator = interarrivalTimeGenerator;
initializeDisChannel();
}
/**
* If the ArrivalProcess is instantiated using the zero-argument
* constructor, be sure the set the interarrivalTimeGenerator with an
* explicit call to its setter method.
*/
public ArrivalProcessOpenDis7() {
initializeDisChannel();
}
/**
* Initialize numberArrivals to 0
*/
@Override
public void reset() {
super.reset();
numberArrivals = 0;
}
/**
* Schedule the first Arrival event with delay generated by
* interarrivalTimeGenerator
*/
public void doRun() {
firePropertyChange("numberArrivals", getNumberArrivals());
// TODO send simulation management PDUs via DIS channel, announce commencement
waitDelay("Arrival", interarrivalTimeGenerator);
}
/**
* Increment numberArrivals<br>
* Schedule next Arrival event with delay generated by
* interarrivalTimeGenerator
*/
public void doArrival() {
int oldNumberArrivals = getNumberArrivals();
numberArrivals += 1;
firePropertyChange("numberArrivals", oldNumberArrivals, getNumberArrivals());
// TODO announce selected arrivals via DIS channel
waitDelay("Arrival", interarrivalTimeGenerator);
}
/**
* accessor method to get a state variable
* @return the interarrivalTimeGenerator
*/
public RandomVariate getInterarrivalTimeGenerator() {
return interarrivalTimeGenerator;
}
/**
* accessor method to set a state variable
* @param interarrivalTimeGenerator the interarrivalTimeGenerator to set
*/
public void setInterarrivalTimeGenerator(RandomVariate interarrivalTimeGenerator) {
this.interarrivalTimeGenerator = interarrivalTimeGenerator;
}
/**
* accessor method to get a state variable
* @return the numberArrivals
*/
public int getNumberArrivals() {
return numberArrivals;
}
/**
* accessor method to get current DIS channel object
* @return the disChannel
*/
public DisChannel getDisChannel() {
return disChannel;
}
}
assignments/src/MV3500Cohort2022MayJune/projects/ArrivalProcessOpenDis7EventGraph.png

35.7 KiB

package MV3500Cohort2022MayJune.projects;
import simkit.Entity;
/**
* Model a ship that arrives at a pier for crane servicing
* @author abuss@nps.edu
*/
public class Ship extends Entity {
/**
* Remaining time to unload ship at unit rate
*/
protected double remainingUnloadingTime;
/**
* Model constructor
* @throws IllegalArgumentException if remainingUnloadingTime &le; 0.0
* @param remainingUnloadingTime Given initial unloading time
*/
public Ship(double remainingUnloadingTime) {
super("Ship");
if (remainingUnloadingTime <= 0.0) {
throw new IllegalArgumentException(
"remainingUnloadingTime must be > 0.0: "
+ remainingUnloadingTime);
}
this.remainingUnloadingTime = remainingUnloadingTime;
}
/**
* Decrement remainingUnloadingTime by the elapsed time at the given rate
*
* @param rate Given rate of unloading
*/
public void work(double rate) {
remainingUnloadingTime -= getElapsedTime() * rate;
}
/**
* accessor method to get a state variable
* @return The remainingUnloadingTime
*/
public double getRemainingUnloadingTime() {
return remainingUnloadingTime;
}
@Override
public String toString() {
return super.toString() + String.format(" %.3f", getRemainingUnloadingTime());
}
}
package MV3500Cohort2022MayJune.projects;
import simkit.random.RandomVariate;
/**
* Model a ship arrival process
* @author abuss@nps.edu
*/
public class ShipArrivalProcess extends ArrivalProcess {
/**
* Generates the initial unloading times for the Ships
*/
private RandomVariate unloadTimeGenerator;
/**
* Zero-argument constructor
*/
public ShipArrivalProcess() {
}
/**
* Instance constructor
* @param interarrivalTimeGenerator Given generator for interarrival times
* @param unloadTimeGenerator Given generator for total unloading times
*/
public ShipArrivalProcess(
RandomVariate interarrivalTimeGenerator,
RandomVariate unloadTimeGenerator) {
this();
this.setInterarrivalTimeGenerator(interarrivalTimeGenerator);
this.setUnloadTimeGenerator(unloadTimeGenerator);
}
/**
* Instantiate a new Ship and Schedule Arrival(Ship)
*/
@Override
public void doArrival() {
super.doArrival();
Ship ship = new Ship(unloadTimeGenerator.generate());
waitDelay("Arrival", 0.0, ship);
}
/**
* accessor method to get a state variable
* @return the unloadTimeGenerator
*/
public RandomVariate getUnloadTimeGenerator() {
return unloadTimeGenerator;
}
/**
* accessor method to set a state variable
* @param unloadTimeGenerator the unloadTimeGenerator to set
*/
public void setUnloadTimeGenerator(RandomVariate unloadTimeGenerator) {
this.unloadTimeGenerator = unloadTimeGenerator;
}
}
package MV3500Cohort2022MayJune.projects;
import java.util.SortedSet;
import java.util.TreeSet;
import simkit.Priority;
import simkit.SimEntityBase;
/**
* Model two crane berths
* @author abuss@nps.edu
*/
public class TwoCraneBerths extends SimEntityBase {
/**
* Queue of Ships waiting to go into the berth
*/
protected SortedSet<Ship> queue;
/**
* Contains 0, 1, or two Ships being unloaded
*/
protected SortedSet<Ship> berth;
/**
* Time in the system for each Ship
*/
protected double timeInSystem;
/**
* Delay in the queue for each Ship
*/
protected double delayInQueue;
/**
* Instantiate queue and berth containers
*/
public TwoCraneBerths() {
this.queue = new TreeSet<>();
this.berth = new TreeSet<>();
}
/**
* Clear queue and berth containers
*/
@Override
public void reset() {
super.reset();
queue.clear();
berth.clear();
timeInSystem = Double.NaN;
delayInQueue = Double.NaN;
}
/**
* Only PropertyChangeEvents
*/
public void doRun() {
firePropertyChange("queue", getQueue());
firePropertyChange("berth", getBerth());
firePropertyChange("timeInSystem", getTimeInSystem());
firePropertyChange("delayInQueue", getDelayInQueue());
}
/**
* Add the given Ship to queue<br>
* If berths is empty, schedule StartUnloadingTwoCranes<br>
* If berths has 1 Ship, schedule SwitchToOneCrane
*
* @param ship Given Ship arriving to harbor
*/
public void doArrival(Ship ship) {
ship.stampTime();
SortedSet<Ship> oldQueue = getQueue();
queue.add(ship);
firePropertyChange("queue", oldQueue, getQueue());
if (berth.isEmpty()) {
waitDelay("StartUnloadingTwoCranes", 0.0, Priority.HIGH);
}
if (berth.size() == 1) {
waitDelay("SwitchToOneCrane", 0.0);
}
}
/**
* Remove the first Ship from queue<br>
* DelayInQueue is elapsedTime of that Ship<br>
* Add the ship to berth container<br>
* Schedule EndUnloadingTwoCranes at half the remaining time
*/
public void doStartUnloadingTwoCranes() {
SortedSet<Ship> oldQueue = getQueue();
Ship ship = queue.first();
queue.remove(ship);
firePropertyChange("queue", oldQueue, getQueue());
delayInQueue = ship.getElapsedTime();
firePropertyChange("delayInQueue", getDelayInQueue());
ship.stampTime();
SortedSet<Ship> oldBerth = getBerth();
berth.add(ship);
firePropertyChange("berth", oldBerth, getBerth());
waitDelay("EndUnloadingTwoCranes", 0.5 * ship.getRemainingUnloadingTime());
}
/**
* Remove the (one) Ship from berth<br>
* TimeInSystem is the age of the Ship
*/
public void doEndUnloadingTwoCranes() {
SortedSet<Ship> oldBerth = getBerth();
Ship ship = berth.first();
berth.remove(ship);
firePropertyChange("berth", oldBerth, getBerth());
timeInSystem = ship.getAge();
firePropertyChange("timeInSystem", getTimeInSystem());
}
/**
* This event is when a Ship arrives to find only one other Ship being
* unloaded.<br>
* Credit the ship in the berth with work at a rate of 2 (since 2 cranes
* have been unloading it<br>
* Interrupt EndUnloadingTwoCranes<br>
* Schedule EndUnloadingOneCrane with the Ship already in the berth<br>
* Schedule StartUnloadingOneCrane
*/
public void doSwitchToOneCrane() {
Ship ship = berth.first();
ship.work(2.0);
ship.stampTime();
interrupt("EndUnloadingTwoCranes");
waitDelay("EndUnloadingOneCrane", ship.getRemainingUnloadingTime(), ship);
waitDelay("StartUnloadingOneCrane", 0.0, Priority.HIGH);
}
/**
* Pop the first Ship from the queue<br>
* delayInQueue is elapsedTime (from Arrival event)<br>
* Add that Ship to berth container<br>
* Schedule EndUnloadingOneCrane with that Ship
*/
public void doStartUnloadingOneCrane() {
SortedSet<Ship> oldQueue = getQueue();
Ship ship = queue.first();
queue.remove(ship);
firePropertyChange("queue", oldQueue, getQueue());
delayInQueue = ship.getElapsedTime();
firePropertyChange("delayInQueue", getDelayInQueue());
ship.stampTime();
SortedSet<Ship> oldBerth = getBerth();
berth.add(ship);
firePropertyChange("berth", oldBerth, getBerth());
waitDelay("EndUnloadingOneCrane", ship.getRemainingUnloadingTime(), ship);
}
/**
* Remove given Ship from berth<br>
* If Ships in queue, schedule StartUnloadingOneCrane<br>
* If queue is empty, schedule SwitchToTwoCranes<br>
* timeInSystem is age of Ship
*
* @param ship Given Ship
*/
public void doEndUnloadingOneCrane(Ship ship) {
SortedSet<Ship> oldBerth = getBerth();
berth.remove(ship);
firePropertyChange("berth", oldBerth, getBerth());
if (queue.size() > 0) {
waitDelay("StartUnloadingOneCrane", 0.0, Priority.HIGH);
}
if (queue.isEmpty() && berth.size() == 1) {
waitDelay("SwitchToTwoCranes", 0.0);
}
timeInSystem = ship.getAge();
firePropertyChange("timeInSystem", getTimeInSystem());
}
/**
* Credit the work of the remaining Ship in berth at unit rate<br>
* Interrupt EndUnloadingOneCrane<br>
* Schedule EndUnloadingTwoCranes at double the rate (i.e., half the remaining time)
*/
public void doSwitchToTwoCranes() {
Ship ship = berth.first();
ship.work(1.0);
ship.stampTime();
interrupt("EndUnloadingOneCrane", ship);
waitDelay("EndUnloadingTwoCranes",
0.5 * ship.getRemainingUnloadingTime());
}
/**
* Get tree of sorted Ship set queue
* @return Shallow copy of queue
*/
public SortedSet<Ship> getQueue() {
return new TreeSet<>(queue);
}
/**
* Get tree of sorted Ship set berths
* @return Shallow copy of berth
*/
public SortedSet<Ship> getBerth() {
return new TreeSet<>(berth);
}
/**
* accessor method to get a state variable
* @return The timeInSystem
*/
public double getTimeInSystem() {
return timeInSystem;
}
/**
* accessor method to get a state variable
* @return The delayInQueue
*/
public double getDelayInQueue() {
return delayInQueue;
}
}
File added
File added
package MV3500Cohort2022MayJune.projects;
import edu.nps.moves.dis7.enumerations.DisPduType;
import edu.nps.moves.dis7.enumerations.VariableRecordType;
import edu.nps.moves.dis7.pdus.EntityStatePdu;
import edu.nps.moves.dis7.pdus.EulerAngles;
import edu.nps.moves.dis7.pdus.Vector3Double;
import edu.nps.moves.dis7.utilities.DisChannel;
import edu.nps.moves.dis7.utilities.PduFactory;
import java.util.SortedSet;
import java.util.TreeSet;
import simkit.Priority;
import simkit.SimEntityBase;
/**
* Add DIS outputs to TwoCraneBerths simkit simulation
* @see TwoCraneBerths
* @see SimkitOpenDis7Examples.run.RunTwoCranesBerth
* @see SimkitOpenDis7Examples.run.RunTwoCranesBerthOpenDis7
* @see <a href="run/RunTwoCranesBerthOpenDis7Log.txt">RunTwoCranesBerthOpenDis7Log.txt</a>
* @see <a href="TwoCraneBerthsAssignment05.docx">TwoCraneBerthsAssignment05.docx</a>
* @see <a href="TwoCraneBerthsAssignment05Solution.docx">TwoCraneBerthsAssignment05Solution.docx</a>
* @author abuss@nps.edu@nps.edu
* @author brutzman@nps.edu
*/
public class TwoCraneBerthsOpenDis7 extends SimEntityBase
{
// Utility constructor method: initial descriptor and verboseness of disNetworkInterface, pduRecorder
private final DisChannel disChannel = new DisChannel("TwoCraneBerthsOpenDis7", false, true);
/**
* Queue of Ships waiting to go into the berth
*/
protected SortedSet<Ship> queue;
/**
* Contains 0, 1, or two Ships being unloaded
*/
protected SortedSet<Ship> berth;
/**
* Time in the system for each Ship
*/
protected double timeInSystem;
/**
* Delay in the queue for each Ship
*/
protected double delayInQueue;
/**
* number of Ships offloaded
*/
protected int shipCount = 0;
/**
* Instantiate queue and berth containers
*/
public TwoCraneBerthsOpenDis7() {
this.queue = new TreeSet<>();
this.berth = new TreeSet<>();
}
/**
* Clear queue and berth containers
*/
@Override
public void reset() {
super.reset();
queue.clear();
berth.clear();
timeInSystem = Double.NaN;
delayInQueue = Double.NaN;
}
/**
* Only PropertyChangeEvents
*/
public void doRun() {
firePropertyChange("queue", getQueue());
firePropertyChange("berth", getBerth());
firePropertyChange("timeInSystem", getTimeInSystem());
firePropertyChange("delayInQueue", getDelayInQueue());
}
/**
* Add the given Ship to queue<br>
* If berths is empty, schedule StartUnloadingTwoCranes<br>
* If berths has 1 Ship, schedule SwitchToOneCrane
*
* @param ship Given Ship arriving to harbor
*/
public void doArrival(Ship ship) {
ship.stampTime();
SortedSet<Ship> oldQueue = getQueue();
queue.add(ship);
firePropertyChange("queue", oldQueue, getQueue());
if (berth.isEmpty()) {
waitDelay("StartUnloadingTwoCranes", 0.0, Priority.HIGH);
}
if (berth.size() == 1) {
waitDelay("SwitchToOneCrane", 0.0);
}
}
/**
* Remove the first Ship from queue<br>
* DelayInQueue is elapsedTime of that Ship<br>
* Add the ship to berth container<br>
* Schedule EndUnloadingTwoCranes at half the remaining time
*/
public void doStartUnloadingTwoCranes() {
SortedSet<Ship> oldQueue = getQueue();
Ship ship = queue.first();
queue.remove(ship);
firePropertyChange("queue", oldQueue, getQueue());
delayInQueue = ship.getElapsedTime();
firePropertyChange("delayInQueue", getDelayInQueue());
ship.stampTime();
SortedSet<Ship> oldBerth = getBerth();
berth.add(ship);
firePropertyChange("berth", oldBerth, getBerth());
// TODO reportCraneContainerUnloadOperationsDIS()
waitDelay("EndUnloadingTwoCranes", 0.5 * ship.getRemainingUnloadingTime());
}
/**
* Remove the (one) Ship from berth<br>
* TimeInSystem is the age of the Ship
*/
public void doEndUnloadingTwoCranes() {
SortedSet<Ship> oldBerth = getBerth();
Ship ship = berth.first();
berth.remove(ship);
firePropertyChange("berth", oldBerth, getBerth());
timeInSystem = ship.getAge();
firePropertyChange("timeInSystem", getTimeInSystem());
}
/**
* This event is when a Ship arrives to find only one other Ship being
* unloaded.<br>
* Credit the ship in the berth with work at a rate of 2 (since 2 cranes
* have been unloading it<br>
* Interrupt EndUnloadingTwoCranes<br>
* Schedule EndUnloadingOneCrane with the Ship already in the berth<br>
* Schedule StartUnloadingOneCrane
*/
public void doSwitchToOneCrane() {
Ship ship = berth.first();
ship.work(2.0);
ship.stampTime();
interrupt("EndUnloadingTwoCranes");
waitDelay("EndUnloadingOneCrane", ship.getRemainingUnloadingTime(), ship);
waitDelay("StartUnloadingOneCrane", 0.0, Priority.HIGH);
}
/**
* Pop the first Ship from the queue<br>
* delayInQueue is elapsedTime (from Arrival event)<br>
* Add that Ship to berth container<br>
* Schedule EndUnloadingOneCrane with that Ship
*/
public void doStartUnloadingOneCrane() {
SortedSet<Ship> oldQueue = getQueue();
Ship ship = queue.first(); // TODO rename ship queue
queue.remove(ship);
firePropertyChange("queue", oldQueue, getQueue());
delayInQueue = ship.getElapsedTime();
firePropertyChange("delayInQueue", getDelayInQueue());
ship.stampTime();
SortedSet<Ship> oldBerth = getBerth();
berth.add(ship);
firePropertyChange("berth", oldBerth, getBerth());
shipCount++;
if (shipCount == 1)
System.out.println("=====================================");
if (shipCount <= 2)
{
reportCraneContainerUnloadOperationsDIS( ship.getTimeStamp(), // simkit timeStamp
10, // numberOfContainers
90.0 // initial position of Ship
); // TODO indicate berth
System.out.println("=====================================");
}
waitDelay("EndUnloadingOneCrane", ship.getRemainingUnloadingTime(), ship);
}
// can be member variables (for efficiency, move above) or else embdedded within method (move below)
PduFactory pduFactory = new PduFactory();
EntityStatePdu espduCrane = (EntityStatePdu) pduFactory.createPdu(DisPduType.ENTITY_STATE);
/**
* Perform crane container unloading operations and send PDUs to report progress
* @param simkitTimeStamp simkit timeStamp when crane operations began
* @param numberContainers how many container boxes to offload
* @param pierDistanceForCraneOffload Y coordinate down pier across from ship's berth, aligned with cargo
* @see <a href="https://en.wikipedia.org/wiki/The_Box_(Levinson_book)">The Box: How the Shipping Container Made the World Smaller and the World Economy Bigger is</a>
*/
public void reportCraneContainerUnloadOperationsDIS(
double simkitTimeStamp,
// which crane
// which berth
int numberContainers,
double pierDistanceForCraneOffload
// lengthOfCrane
)
{
int disTimeStamp = (int)simkitTimeStamp; // TODO document relationship
// Pier coordinate system follows, Right-Hand Rule (RHR) throughout:
// +X axis to right with X=0 on centerline of pier (train tracks
// +Y axis down pier with Y=0 at head of pier,
// +Z axis vertical with Z=0 at level of pier
// phi is rotation about +X axis, radians
// theta is rotation about +Y axis, radians
// psi is rotation about +X axis, radians
Vector3Double positionPierHead = new Vector3Double();
// Vector3Double positionPierHead = new Vector3Double(0.0, 0.0, 0.0); // TODO needs utility constructor
Vector3Double positionPierOffload = new Vector3Double();
positionPierOffload.setY(pierDistanceForCraneOffload);
double craneLinearSpeed = 1.0; // m/sec
double craneRotationRate = 10.0; // degrees/second
double containerHookupDuration = 60.0; // seconds average
double containerDetachDuration = 30.0; // seconds average
// not modeling crane elevation angle, only orientation of crane cab and gantry
EulerAngles orientationToShip = (new EulerAngles()).setPsi((float) (90.0 * Math.PI/180.0)); // TODO utility methods needed
EulerAngles orientationToPier = (new EulerAngles()).setPsi((float) ( 0.0 * Math.PI/180.0)); // TODO utility methods needed
// initialize ESPDU
// espduCrane.reset(); // TODO intialization utility method
// espduCrane.setEntityAppearance(TODO); // highlight active crane?
espduCrane.setTimestamp(disTimeStamp);
// 1. Crane at head of pier, operator present, boom elevated vertically in stow position
espduCrane.setEntityLocation(positionPierHead);
espduCrane.setEntityOrientation(orientationToPier);
disChannel.sendSinglePdu (disTimeStamp, espduCrane);
disChannel.sendCommentPdu(disTimeStamp, VariableRecordType.CARGO, "Ready to process Ship " + shipCount + " with crane at head of pier");
// 2, Ship arrives, tug departs
// ship PDU already, TODO can track tugboat here if desired for further fidelity
// 3. Crane moves to position of ship: travel to positionOfCrane ay craneLinearSpeed
double craneTravelDuration = pierDistanceForCraneOffload / craneLinearSpeed; // units analysis: meters / (meters/second) = seconds
espduCrane.setEntityLocation(pierDistanceForCraneOffload, 0.0, 0.0);
disChannel.sendSinglePdu(disTimeStamp, espduCrane);
disChannel.sendCommentPdu(disTimeStamp, VariableRecordType.CARGO,
"Crane at position " + pierDistanceForCraneOffload + "m for offload after " + craneTravelDuration + " seconds");
// 4. repeat until done: Crane rotates, lift container, rotates, lower container
for (int containerIndex = 1; containerIndex <= numberContainers; containerIndex++)
{
// 4.a crane rotates to ship
double craneRotationDelay = 90.0 / craneRotationRate; // units analysis: degrees / (degrees/second) = seconds
espduCrane.setEntityOrientation(orientationToShip);
disChannel.sendSinglePdu(disTimeStamp, espduCrane);
disChannel.sendCommentPdu(disTimeStamp, VariableRecordType.CARGO, "Crane oriented to ship after " + craneRotationDelay + " seconds");
// // 4.b announce next step without further delay, then perform container hookup
disChannel.sendCommentPdu(disTimeStamp, VariableRecordType.CARGO, "Hooking up Container " + containerIndex + " to crane "); // TODO + whichCrane
disTimeStamp += containerHookupDuration;
// disChannel.sendSinglePdu(disTimeStamp, espduCrane); // superfluous, crane hasn't moved
disChannel.sendCommentPdu(disTimeStamp, VariableRecordType.CARGO, "Hooked up: Container " + containerIndex + " to crane " // TODO + whichCrane
+ " after " + craneRotationDelay + " seconds");
// 4.c crane rotates to pier
disTimeStamp += craneRotationDelay;
espduCrane.setEntityOrientation(orientationToPier);
disChannel.sendSinglePdu(disTimeStamp, espduCrane);
disChannel.sendCommentPdu(disTimeStamp, VariableRecordType.CARGO, "Crane oriented to pier after " + craneRotationDelay + " seconds");
// 4.d crane unhooks container
disTimeStamp += containerDetachDuration;
// disChannel.sendSinglePdu(disTimeStamp, espduCrane); // superfluous, crane hasn't moved
disChannel.sendCommentPdu(disTimeStamp, VariableRecordType.CARGO, "Detached: Container " + containerIndex + " on pier" // TODO + whichCrane
+ " after " + containerDetachDuration + " seconds");
// send PDUs accordingly
double totalDelay = (2.0 * craneRotationDelay + containerHookupDuration + containerDetachDuration);
disChannel.sendCommentPdu(disTimeStamp, VariableRecordType.ELAPSED_TIME,"Time duration for crane moving container " + containerIndex + ": " + totalDelay + " seconds");
// Future work: if this container is special, meaning on watchlist, report it
}
// 4. Crane stows boom in vertical position
// TODO future refinement if even-more fidelity is desired
// 5. Crane returns to head of pier every time in order to avoid interference with ship mooring/unmooring
espduCrane.setEntityLocation(positionPierHead); // head of pier
disTimeStamp += craneTravelDuration; // travel time back to head of pier
espduCrane.setEntityLocation(positionPierHead);
disChannel.sendSinglePdu(disTimeStamp, espduCrane);
}
/**
* Shutdown DIS network interfaces, enabling program termination
*/
public void shutdown()
{
if (disChannel != null)
{
disChannel.leave();
disChannel.tearDownNetworkInterface();
}
}
/**
* Remove given Ship from berth<br>
* If Ships in queue, schedule StartUnloadingOneCrane<br>
* If queue is empty, schedule SwitchToTwoCranes<br>
* timeInSystem is age of Ship
*
* @param ship Given Ship
*/
public void doEndUnloadingOneCrane(Ship ship) {
SortedSet<Ship> oldBerth = getBerth();
berth.remove(ship);
firePropertyChange("berth", oldBerth, getBerth());
if (queue.size() > 0) {
waitDelay("StartUnloadingOneCrane", 0.0, Priority.HIGH);
}
if (queue.isEmpty() && berth.size() == 1) {
waitDelay("SwitchToTwoCranes", 0.0);
}
timeInSystem = ship.getAge();
firePropertyChange("timeInSystem", getTimeInSystem());
}
/**
* Credit the work of the remaining Ship in berth at unit rate<br>
* Interrupt EndUnloadingOneCrane<br>
* Schedule EndUnloadingTwoCranes at double the rate (i.e., half the remaining time)
*/
public void doSwitchToTwoCranes() {
Ship ship = berth.first();
ship.work(1.0);
ship.stampTime();
interrupt("EndUnloadingOneCrane", ship);
waitDelay("EndUnloadingTwoCranes",
0.5 * ship.getRemainingUnloadingTime());
}
/**
* Get tree of sorted Ship set queue
* @return Shallow copy of queue
*/
public SortedSet<Ship> getQueue() {
return new TreeSet<>(queue);
}
/**
* Get tree of sorted Ship set berths
* @return Shallow copy of berth
*/
public SortedSet<Ship> getBerth() {
return new TreeSet<>(berth);
}
/**
* accessor method to get a state variable
* @return The timeInSystem
*/
public double getTimeInSystem() {
return timeInSystem;
}
/**
* accessor method to get a state variable
* @return The delayInQueue
*/
public double getDelayInQueue() {
return delayInQueue;
}
}
assignments/src/MV3500Cohort2022MayJune/projects/TwoCraneBerthsScenarioSketch.jpg

449 KiB

assignments/src/MV3500Cohort2022MayJune/projects/TwoCranesBerthComponentEventGraph.png

374 KiB

package MV3500Cohort2022MayJune.projects.run;
import MV3500Cohort2022MayJune.projects.ShipArrivalProcess;
import MV3500Cohort2022MayJune.projects.TwoCraneBerthsOpenDis7;
import simkit.Schedule;
import simkit.random.RandomVariate;
import simkit.random.RandomVariateFactory;
import simkit.stat.CollectionSizeTimeVaryingStats;
import simkit.stat.SimpleStatsTally;
/**
* Run simple two-berth model for 10 years (3650 days).
* <h2>Output:</h2><pre>
ShipArrivalProcess.1
unloadTimeGenerator = Uniform (0.500, 1.500)
interarrivalTimeGenerator = Exponential (0.700)
TwoCraneBerthsOpenDis7.2
Simulation ended at time 3,650.0
Number of ships arriving: 5,135
Number of ships unloaded: 5,129
Maximum # in queue: 11
Average # in queue: 0.6834
Average # busy berths: 1.1737
Average time in system: 1.3207
Average delay in queue: 0.4857
</pre>
*
* @author abuss@nps.edu
*/
public class RunTwoCranesBerthOpenDis7
{
/** Default constructor */
public RunTwoCranesBerthOpenDis7()
{
// default constructor
}
/**
* Run a simple program and compute statistical measurement of results.
* @param args the command line arguments
*/
public static void main(String[] args) {
RandomVariate interarrivalTimeGenerator =
RandomVariateFactory.getInstance("Exponential", 0.7);
RandomVariate unloadingTimeGenerator =
RandomVariateFactory.getInstance("Uniform", 0.5, 1.5);
ShipArrivalProcess shipArrivalProcess =
new ShipArrivalProcess(interarrivalTimeGenerator,
unloadingTimeGenerator);
TwoCraneBerthsOpenDis7 twoCraneBerthsOpenDis7 = new TwoCraneBerthsOpenDis7();
shipArrivalProcess.addSimEventListener(twoCraneBerthsOpenDis7);
SimpleStatsTally delayInQueueStat = new SimpleStatsTally("delayInQueue");
SimpleStatsTally timeInSystemStat = new SimpleStatsTally("timeInSystem");
CollectionSizeTimeVaryingStats numberInQueueStat =
new CollectionSizeTimeVaryingStats("queue");
CollectionSizeTimeVaryingStats numberInBerthStat =
new CollectionSizeTimeVaryingStats("berth");
// SimplePropertyDumper simplePropertyDumper = new SimplePropertyDumper();
// twoCraneBerths.addPropertyChangeListener(simplePropertyDumper);
twoCraneBerthsOpenDis7.addPropertyChangeListener(delayInQueueStat);
twoCraneBerthsOpenDis7.addPropertyChangeListener(timeInSystemStat);
twoCraneBerthsOpenDis7.addPropertyChangeListener(numberInQueueStat);
twoCraneBerthsOpenDis7.addPropertyChangeListener(numberInBerthStat);
System.out.println(shipArrivalProcess);
System.out.println(twoCraneBerthsOpenDis7);
double stopTime = 10 * 365;
Schedule.stopAtTime(stopTime);
Schedule.setVerbose(false);
Schedule.reset();
Schedule.startSimulation();
System.out.printf("%nSimulation ended at time %,.1f%n%n",
Schedule.getSimTime());
System.out.printf("Number of ships arriving:\t%,d%n", shipArrivalProcess.getNumberArrivals());
System.out.printf("Number of ships unloaded:\t%,d%n", timeInSystemStat.getCount());
System.out.printf("Maximum # in queue:\t\t%.0f%n", numberInQueueStat.getMaxObs());
System.out.printf("Average # in queue:\t\t%.4f%n", numberInQueueStat.getMean());
System.out.printf("Average # busy berths:\t\t%.4f%n", numberInBerthStat.getMean());
System.out.printf("Average time in system:\t\t%.4f%n",
timeInSystemStat.getMean());
System.out.printf("Average delay in queue:\t\t%.4f%n",
delayInQueueStat.getMean());
twoCraneBerthsOpenDis7.shutdown();
System.exit(0);
}
}
ant -f C:\\x-nps-gitlab\\NetworkedGraphicsMV3500\\assignments -Dnb.internal.action.name=run.single -Djavac.includes=MV3500Cohort2022MayJune/projects/run/RunTwoCranesBerthOpenDis7.java -Drun.class=MV3500Cohort2022MayJune.projects.run.RunTwoCranesBerthOpenDis7 run-single
init:
Deleting: C:\x-nps-gitlab\NetworkedGraphicsMV3500\assignments\build\built-jar.properties
deps-jar:
Updating property file: C:\x-nps-gitlab\NetworkedGraphicsMV3500\assignments\build\built-jar.properties
Compiling 1 source file to C:\x-nps-gitlab\NetworkedGraphicsMV3500\assignments\build\classes
warning: [options] system modules path not set in conjunction with -source 17
1 warning
compile-single:
run-single:
[DisChannel] thisHostName=IT160907-UWALPP
ShipArrivalProcess.1
unloadTimeGenerator = Uniform (0.500, 1.500)
interarrivalTimeGenerator = Exponential (0.700)
TwoCraneBerthsOpenDis7.2
=====================================
[DisThreadedNetworkInterface] using network interface PANGP Virtual Ethernet Adapter
[DisThreadedNetworkInterface] datagramSocket.joinGroup address=239.1.2.3 port=3000 isConnected()=false createDatagramSocket() complete.
[DisThreadedNetworkInterface] createThreads() receiveThread.isAlive()=true
[DisThreadedNetworkInterface] createThreads() sendingThread.isAlive()=true
[DisChannel] Network confirmation: address=239.1.2.3 port=3000
[DisChannel] Beginning pdu save to directory ./pduLog
[PduRecorder] Recorder log file open: C:\x-nps-gitlab\NetworkedGraphicsMV3500\assignments\pduLog\PduCaptureLog.dislog
[PduRecorder PduRecorder] listening to IP address 239.1.2.3 on port 3000
[DisChannel] *** [CommentPdu CARGO] [Ready to process Ship 1 with crane at head of pier]
[DisChannel] *** [CommentPdu CARGO] [Crane at position 90.0m for offload after 90.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Crane oriented to ship after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Hooking up Container 1 to crane ]
[DisChannel] *** [CommentPdu CARGO] [Hooked up: Container 1 to crane after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Crane oriented to pier after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Detached: Container 1 on pier after 30.0 seconds]
[DisChannel] *** [CommentPdu ELAPSED_TIME] [Time duration for crane moving container 1: 108.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Crane oriented to ship after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Hooking up Container 2 to crane ]
[DisChannel] *** [CommentPdu CARGO] [Hooked up: Container 2 to crane after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Crane oriented to pier after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Detached: Container 2 on pier after 30.0 seconds]
[DisChannel] *** [CommentPdu ELAPSED_TIME] [Time duration for crane moving container 2: 108.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Crane oriented to ship after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Hooking up Container 3 to crane ]
[DisChannel] *** [CommentPdu CARGO] [Hooked up: Container 3 to crane after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Crane oriented to pier after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Detached: Container 3 on pier after 30.0 seconds]
[DisChannel] *** [CommentPdu ELAPSED_TIME] [Time duration for crane moving container 3: 108.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Crane oriented to ship after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Hooking up Container 4 to crane ]
[DisChannel] *** [CommentPdu CARGO] [Hooked up: Container 4 to crane after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Crane oriented to pier after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Detached: Container 4 on pier after 30.0 seconds]
[DisChannel] *** [CommentPdu ELAPSED_TIME] [Time duration for crane moving container 4: 108.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Crane oriented to ship after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Hooking up Container 5 to crane ]
[DisChannel] *** [CommentPdu CARGO] [Hooked up: Container 5 to crane after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Crane oriented to pier after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Detached: Container 5 on pier after 30.0 seconds]
[DisChannel] *** [CommentPdu ELAPSED_TIME] [Time duration for crane moving container 5: 108.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Crane oriented to ship after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Hooking up Container 6 to crane ]
[DisChannel] *** [CommentPdu CARGO] [Hooked up: Container 6 to crane after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Crane oriented to pier after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Detached: Container 6 on pier after 30.0 seconds]
[DisChannel] *** [CommentPdu ELAPSED_TIME] [Time duration for crane moving container 6: 108.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Crane oriented to ship after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Hooking up Container 7 to crane ]
[DisChannel] *** [CommentPdu CARGO] [Hooked up: Container 7 to crane after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Crane oriented to pier after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Detached: Container 7 on pier after 30.0 seconds]
[DisChannel] *** [CommentPdu ELAPSED_TIME] [Time duration for crane moving container 7: 108.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Crane oriented to ship after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Hooking up Container 8 to crane ]
[DisChannel] *** [CommentPdu CARGO] [Hooked up: Container 8 to crane after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Crane oriented to pier after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Detached: Container 8 on pier after 30.0 seconds]
[DisChannel] *** [CommentPdu ELAPSED_TIME] [Time duration for crane moving container 8: 108.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Crane oriented to ship after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Hooking up Container 9 to crane ]
[DisChannel] *** [CommentPdu CARGO] [Hooked up: Container 9 to crane after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Crane oriented to pier after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Detached: Container 9 on pier after 30.0 seconds]
[DisChannel] *** [CommentPdu ELAPSED_TIME] [Time duration for crane moving container 9: 108.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Crane oriented to ship after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Hooking up Container 10 to crane ]
[DisChannel] *** [CommentPdu CARGO] [Hooked up: Container 10 to crane after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Crane oriented to pier after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Detached: Container 10 on pier after 30.0 seconds]
[DisChannel] *** [CommentPdu ELAPSED_TIME] [Time duration for crane moving container 10: 108.0 seconds]
=====================================
[DisChannel] *** [CommentPdu CARGO] [Ready to process Ship 2 with crane at head of pier]
[DisChannel] *** [CommentPdu CARGO] [Crane at position 90.0m for offload after 90.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Crane oriented to ship after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Hooking up Container 1 to crane ]
[DisChannel] *** [CommentPdu CARGO] [Hooked up: Container 1 to crane after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Crane oriented to pier after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Detached: Container 1 on pier after 30.0 seconds]
[DisChannel] *** [CommentPdu ELAPSED_TIME] [Time duration for crane moving container 1: 108.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Crane oriented to ship after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Hooking up Container 2 to crane ]
[DisChannel] *** [CommentPdu CARGO] [Hooked up: Container 2 to crane after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Crane oriented to pier after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Detached: Container 2 on pier after 30.0 seconds]
[DisChannel] *** [CommentPdu ELAPSED_TIME] [Time duration for crane moving container 2: 108.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Crane oriented to ship after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Hooking up Container 3 to crane ]
[DisChannel] *** [CommentPdu CARGO] [Hooked up: Container 3 to crane after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Crane oriented to pier after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Detached: Container 3 on pier after 30.0 seconds]
[DisChannel] *** [CommentPdu ELAPSED_TIME] [Time duration for crane moving container 3: 108.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Crane oriented to ship after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Hooking up Container 4 to crane ]
[DisChannel] *** [CommentPdu CARGO] [Hooked up: Container 4 to crane after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Crane oriented to pier after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Detached: Container 4 on pier after 30.0 seconds]
[DisChannel] *** [CommentPdu ELAPSED_TIME] [Time duration for crane moving container 4: 108.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Crane oriented to ship after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Hooking up Container 5 to crane ]
[DisChannel] *** [CommentPdu CARGO] [Hooked up: Container 5 to crane after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Crane oriented to pier after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Detached: Container 5 on pier after 30.0 seconds]
[DisChannel] *** [CommentPdu ELAPSED_TIME] [Time duration for crane moving container 5: 108.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Crane oriented to ship after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Hooking up Container 6 to crane ]
[DisChannel] *** [CommentPdu CARGO] [Hooked up: Container 6 to crane after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Crane oriented to pier after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Detached: Container 6 on pier after 30.0 seconds]
[DisChannel] *** [CommentPdu ELAPSED_TIME] [Time duration for crane moving container 6: 108.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Crane oriented to ship after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Hooking up Container 7 to crane ]
[DisChannel] *** [CommentPdu CARGO] [Hooked up: Container 7 to crane after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Crane oriented to pier after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Detached: Container 7 on pier after 30.0 seconds]
[DisChannel] *** [CommentPdu ELAPSED_TIME] [Time duration for crane moving container 7: 108.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Crane oriented to ship after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Hooking up Container 8 to crane ]
[DisChannel] *** [CommentPdu CARGO] [Hooked up: Container 8 to crane after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Crane oriented to pier after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Detached: Container 8 on pier after 30.0 seconds]
[DisChannel] *** [CommentPdu ELAPSED_TIME] [Time duration for crane moving container 8: 108.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Crane oriented to ship after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Hooking up Container 9 to crane ]
[DisChannel] *** [CommentPdu CARGO] [Hooked up: Container 9 to crane after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Crane oriented to pier after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Detached: Container 9 on pier after 30.0 seconds]
[DisChannel] *** [CommentPdu ELAPSED_TIME] [Time duration for crane moving container 9: 108.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Crane oriented to ship after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Hooking up Container 10 to crane ]
[DisChannel] *** [CommentPdu CARGO] [Hooked up: Container 10 to crane after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Crane oriented to pier after 9.0 seconds]
[DisChannel] *** [CommentPdu CARGO] [Detached: Container 10 on pier after 30.0 seconds]
[DisChannel] *** [CommentPdu ELAPSED_TIME] [Time duration for crane moving container 10: 108.0 seconds]
=====================================
Simulation ended at time 3,650.0
Number of ships arriving: 5,135
Number of ships unloaded: 5,129
Maximum # in queue: 11
Average # in queue: 0.6834
Average # busy berths: 1.1737
Average time in system: 1.3207
Average delay in queue: 0.4857
PduRecorder.stop() closing recorder log file: C:\x-nps-gitlab\NetworkedGraphicsMV3500\assignments\pduLog\PduCaptureLog.dislog
BUILD SUCCESSFUL (total time: 23 seconds)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment