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

thorough crane operations, with logging repeated for first two ships

parent dc9c2feb
No related branches found
No related tags found
No related merge requests found
package SimkitOpenDis7Examples;
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;
......@@ -47,6 +48,11 @@ public class TwoCraneBerthsOpenDis7 extends SimEntityBase
*/
protected double delayInQueue;
/**
* number of Ships offloaded
*/
protected int shipCount = 0;
/**
* Instantiate queue and berth containers
*/
......@@ -121,6 +127,8 @@ public class TwoCraneBerthsOpenDis7 extends SimEntityBase
SortedSet<Ship> oldBerth = getBerth();
berth.add(ship);
firePropertyChange("berth", oldBerth, getBerth());
// TODO reportCraneContainerUnloadOperationsDIS()
waitDelay("EndUnloadingTwoCranes", 0.5 * ship.getRemainingUnloadingTime());
}
......@@ -181,9 +189,18 @@ public class TwoCraneBerthsOpenDis7 extends SimEntityBase
berth.add(ship);
firePropertyChange("berth", oldBerth, getBerth());
performCraneUnloadOperations( 10, // numberOfContainers
0.0 // initial position
); // TODO indicate berth
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);
}
......@@ -193,18 +210,23 @@ public class TwoCraneBerthsOpenDis7 extends SimEntityBase
EntityStatePdu espduCrane = (EntityStatePdu) pduFactory.createPdu(DisPduType.ENTITY_STATE);
/**
* Perform crane unloading operations and send PDUs to report progress
* @param numberContainers how many containers to offload
* @param positionOfCrane Y coordinate down pier across from ship's berth, aligned with cargo
* 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 performCraneUnloadOperations(
public void reportCraneContainerUnloadOperationsDIS(
double simkitTimeStamp,
// which crane
// which berth
int numberContainers,
double positionOfCrane
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,
......@@ -212,67 +234,97 @@ public class TwoCraneBerthsOpenDis7 extends SimEntityBase
// phi is rotation about +X axis, radians
// theta is rotation about +Y axis, radians
// psi is rotation about +X axis, radians
double craneLinearSpeed = 1.0; // m/sec
double craneRotationRate = 10.0; // degrees/second
double containerHookupTime = 60.0; // seconds average
double containerDetachTime = 30.0; // seconds average
Vector3Double positionPierHead = new Vector3Double();
// Vector3Double positionPierHead = new Vector3Double(0.0, 0.0, 0.0); // TODO needs utility constructor
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 postion
// espduCrane.setEntityLocation(0.0, 0.0, 0.0); // ambiguous, error prone
espduCrane.setEntityLocation(positionPierHead); // preferred
// 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 could be sent here, or probably more logical to ensure it happened earlier
// ship PDU already, TODO can track tugboat here if desired for further fidelity
// 3. Crane moves to position of ship
espduCrane.setEntityLocation(positionOfCrane, 0.0, 0.0); // head of pier, ambiguous
// TODO compute travel time
// update: travel to positionOfCrane by craneLinearSpeed
// 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++)
{
// perform one operation
// 4.a crane rotates to ship
double craneRotationDelay = 90.0 / craneRotationRate; // units analysis: degrees / (degrees/second) = seconds
espduCrane.setEntityOrientation(orientationToShip);
disChannel.sendSinglePdu(espduCrane);
espduCrane.setEntityOrientation(orientationToPier);
double rotationDelay = 90.0 / craneRotationRate; // units analysis: degrees / (degrees/second) = seconds
disChannel.sendCommentPdu(disChannel.COMMENTPDU_NARRATIVE, "Hooking up Container " + containerIndex + " to crane");
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
// TODO fix sendSinglePduDelayed thread handling since it is blocking...
// disChannel.sendSinglePduDelayed(containerHookupTime, espduCrane);
disChannel.sendCommentPdu(disChannel.COMMENTPDU_NARRATIVE, "Container hooked up");
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");
// espduCrane.setEntityOrientation(0, 0, 90); // ambiguous, degrees or radians? TODO javadoc
// 4.c crane rotates to pier
disTimeStamp += craneRotationDelay;
espduCrane.setEntityOrientation(orientationToPier);
// TODO fix sendSinglePduDelayed thread handling since it is blocking...
// disChannel.sendSinglePduDelayed(containerHookupTime + rotationDelay, espduCrane);
// unhook
// rotate back
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
// espcudCrnet orientation
// TODO future refinement if even-more fidelity is desired
// 5. Crane returns to head of pier
// update: travel from positionOfCrane to head by craneLinearSpeed
espduCrane.setEntityLocation(positionOfCrane, 0.0, 0.0);
disChannel.sendSinglePdu(espduCrane);
// 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();
}
}
/**
......
......@@ -49,8 +49,8 @@ public class RunTwoCranesBerthOpenDis7
new ShipArrivalProcess(interarrivalTimeGenerator,
unloadingTimeGenerator);
TwoCraneBerthsOpenDis7 twoCraneBerths = new TwoCraneBerthsOpenDis7();
shipArrivalProcess.addSimEventListener(twoCraneBerths);
TwoCraneBerthsOpenDis7 twoCraneBerthsOpenDis7 = new TwoCraneBerthsOpenDis7();
shipArrivalProcess.addSimEventListener(twoCraneBerthsOpenDis7);
SimpleStatsTally delayInQueueStat = new SimpleStatsTally("delayInQueue");
SimpleStatsTally timeInSystemStat = new SimpleStatsTally("timeInSystem");
......@@ -61,13 +61,13 @@ public class RunTwoCranesBerthOpenDis7
// SimplePropertyDumper simplePropertyDumper = new SimplePropertyDumper();
// twoCraneBerths.addPropertyChangeListener(simplePropertyDumper);
twoCraneBerths.addPropertyChangeListener(delayInQueueStat);
twoCraneBerths.addPropertyChangeListener(timeInSystemStat);
twoCraneBerths.addPropertyChangeListener(numberInQueueStat);
twoCraneBerths.addPropertyChangeListener(numberInBerthStat);
twoCraneBerthsOpenDis7.addPropertyChangeListener(delayInQueueStat);
twoCraneBerthsOpenDis7.addPropertyChangeListener(timeInSystemStat);
twoCraneBerthsOpenDis7.addPropertyChangeListener(numberInQueueStat);
twoCraneBerthsOpenDis7.addPropertyChangeListener(numberInBerthStat);
System.out.println(shipArrivalProcess);
System.out.println(twoCraneBerths);
System.out.println(twoCraneBerthsOpenDis7);
double stopTime = 10 * 365;
Schedule.stopAtTime(stopTime);
......@@ -87,6 +87,9 @@ public class RunTwoCranesBerthOpenDis7
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()); }
delayInQueueStat.getMean());
twoCraneBerthsOpenDis7.shutdown();
System.exit(0);
}
}
No preview for this file type
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