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; package SimkitOpenDis7Examples;
import edu.nps.moves.dis7.enumerations.DisPduType; 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.EntityStatePdu;
import edu.nps.moves.dis7.pdus.EulerAngles; import edu.nps.moves.dis7.pdus.EulerAngles;
import edu.nps.moves.dis7.pdus.Vector3Double; import edu.nps.moves.dis7.pdus.Vector3Double;
...@@ -47,6 +48,11 @@ public class TwoCraneBerthsOpenDis7 extends SimEntityBase ...@@ -47,6 +48,11 @@ public class TwoCraneBerthsOpenDis7 extends SimEntityBase
*/ */
protected double delayInQueue; protected double delayInQueue;
/**
* number of Ships offloaded
*/
protected int shipCount = 0;
/** /**
* Instantiate queue and berth containers * Instantiate queue and berth containers
*/ */
...@@ -121,6 +127,8 @@ public class TwoCraneBerthsOpenDis7 extends SimEntityBase ...@@ -121,6 +127,8 @@ public class TwoCraneBerthsOpenDis7 extends SimEntityBase
SortedSet<Ship> oldBerth = getBerth(); SortedSet<Ship> oldBerth = getBerth();
berth.add(ship); berth.add(ship);
firePropertyChange("berth", oldBerth, getBerth()); firePropertyChange("berth", oldBerth, getBerth());
// TODO reportCraneContainerUnloadOperationsDIS()
waitDelay("EndUnloadingTwoCranes", 0.5 * ship.getRemainingUnloadingTime()); waitDelay("EndUnloadingTwoCranes", 0.5 * ship.getRemainingUnloadingTime());
} }
...@@ -181,9 +189,18 @@ public class TwoCraneBerthsOpenDis7 extends SimEntityBase ...@@ -181,9 +189,18 @@ public class TwoCraneBerthsOpenDis7 extends SimEntityBase
berth.add(ship); berth.add(ship);
firePropertyChange("berth", oldBerth, getBerth()); firePropertyChange("berth", oldBerth, getBerth());
performCraneUnloadOperations( 10, // numberOfContainers shipCount++;
0.0 // initial position
); // TODO indicate berth 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); waitDelay("EndUnloadingOneCrane", ship.getRemainingUnloadingTime(), ship);
} }
...@@ -193,18 +210,23 @@ public class TwoCraneBerthsOpenDis7 extends SimEntityBase ...@@ -193,18 +210,23 @@ public class TwoCraneBerthsOpenDis7 extends SimEntityBase
EntityStatePdu espduCrane = (EntityStatePdu) pduFactory.createPdu(DisPduType.ENTITY_STATE); EntityStatePdu espduCrane = (EntityStatePdu) pduFactory.createPdu(DisPduType.ENTITY_STATE);
/** /**
* Perform crane unloading operations and send PDUs to report progress * Perform crane container unloading operations and send PDUs to report progress
* @param numberContainers how many containers to offload * @param simkitTimeStamp simkit timeStamp when crane operations began
* @param positionOfCrane Y coordinate down pier across from ship's berth, aligned with cargo * @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 crane
// which berth // which berth
int numberContainers, int numberContainers,
double positionOfCrane double pierDistanceForCraneOffload
// lengthOfCrane // lengthOfCrane
) )
{ {
int disTimeStamp = (int)simkitTimeStamp; // TODO document relationship
// Pier coordinate system follows, Right-Hand Rule (RHR) throughout: // Pier coordinate system follows, Right-Hand Rule (RHR) throughout:
// +X axis to right with X=0 on centerline of pier (train tracks // +X axis to right with X=0 on centerline of pier (train tracks
// +Y axis down pier with Y=0 at head of pier, // +Y axis down pier with Y=0 at head of pier,
...@@ -212,67 +234,97 @@ public class TwoCraneBerthsOpenDis7 extends SimEntityBase ...@@ -212,67 +234,97 @@ public class TwoCraneBerthsOpenDis7 extends SimEntityBase
// phi is rotation about +X axis, radians // phi is rotation about +X axis, radians
// theta is rotation about +Y axis, radians // theta is rotation about +Y axis, radians
// psi is rotation about +X 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();
// Vector3Double positionPierHead = new Vector3Double(0.0, 0.0, 0.0); // TODO needs utility constructor // 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 // 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 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 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.reset(); // TODO intialization utility method
// espduCrane.setEntityAppearance(TODO); // highlight active crane? // espduCrane.setEntityAppearance(TODO); // highlight active crane?
espduCrane.setTimestamp(disTimeStamp);
// 1. Crane at head of pier, operator present, boom elevated vertically in stow postion // 1. Crane at head of pier, operator present, boom elevated vertically in stow position
// espduCrane.setEntityLocation(0.0, 0.0, 0.0); // ambiguous, error prone espduCrane.setEntityLocation(positionPierHead);
espduCrane.setEntityLocation(positionPierHead); // preferred 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 // 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 // 3. Crane moves to position of ship: travel to positionOfCrane ay craneLinearSpeed
espduCrane.setEntityLocation(positionOfCrane, 0.0, 0.0); // head of pier, ambiguous double craneTravelDuration = pierDistanceForCraneOffload / craneLinearSpeed; // units analysis: meters / (meters/second) = seconds
// TODO compute travel time espduCrane.setEntityLocation(pierDistanceForCraneOffload, 0.0, 0.0);
// update: travel to positionOfCrane by craneLinearSpeed 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 // 4. repeat until done: Crane rotates, lift container, rotates, lower container
for (int containerIndex = 1; containerIndex <= numberContainers; containerIndex++) 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); espduCrane.setEntityOrientation(orientationToShip);
disChannel.sendSinglePdu(espduCrane); disChannel.sendSinglePdu(disTimeStamp, espduCrane);
espduCrane.setEntityOrientation(orientationToPier); disChannel.sendCommentPdu(disTimeStamp, VariableRecordType.CARGO, "Crane oriented to ship after " + craneRotationDelay + " seconds");
double rotationDelay = 90.0 / craneRotationRate; // units analysis: degrees / (degrees/second) = seconds
disChannel.sendCommentPdu(disChannel.COMMENTPDU_NARRATIVE, "Hooking up Container " + containerIndex + " to crane"); // // 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... disTimeStamp += containerHookupDuration;
// disChannel.sendSinglePduDelayed(containerHookupTime, espduCrane); // disChannel.sendSinglePdu(disTimeStamp, espduCrane); // superfluous, crane hasn't moved
disChannel.sendCommentPdu(disChannel.COMMENTPDU_NARRATIVE, "Container hooked up"); 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); espduCrane.setEntityOrientation(orientationToPier);
// TODO fix sendSinglePduDelayed thread handling since it is blocking... disChannel.sendSinglePdu(disTimeStamp, espduCrane);
// disChannel.sendSinglePduDelayed(containerHookupTime + rotationDelay, espduCrane); disChannel.sendCommentPdu(disTimeStamp, VariableRecordType.CARGO, "Crane oriented to pier after " + craneRotationDelay + " seconds");
// unhook // 4.d crane unhooks container
// rotate back 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 // 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 // Future work: if this container is special, meaning on watchlist, report it
} }
// 4. Crane stows boom in vertical position // 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 // 5. Crane returns to head of pier every time in order to avoid interference with ship mooring/unmooring
// update: travel from positionOfCrane to head by craneLinearSpeed espduCrane.setEntityLocation(positionPierHead); // head of pier
espduCrane.setEntityLocation(positionOfCrane, 0.0, 0.0); disTimeStamp += craneTravelDuration; // travel time back to head of pier
disChannel.sendSinglePdu(espduCrane); 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 ...@@ -49,8 +49,8 @@ public class RunTwoCranesBerthOpenDis7
new ShipArrivalProcess(interarrivalTimeGenerator, new ShipArrivalProcess(interarrivalTimeGenerator,
unloadingTimeGenerator); unloadingTimeGenerator);
TwoCraneBerthsOpenDis7 twoCraneBerths = new TwoCraneBerthsOpenDis7(); TwoCraneBerthsOpenDis7 twoCraneBerthsOpenDis7 = new TwoCraneBerthsOpenDis7();
shipArrivalProcess.addSimEventListener(twoCraneBerths); shipArrivalProcess.addSimEventListener(twoCraneBerthsOpenDis7);
SimpleStatsTally delayInQueueStat = new SimpleStatsTally("delayInQueue"); SimpleStatsTally delayInQueueStat = new SimpleStatsTally("delayInQueue");
SimpleStatsTally timeInSystemStat = new SimpleStatsTally("timeInSystem"); SimpleStatsTally timeInSystemStat = new SimpleStatsTally("timeInSystem");
...@@ -61,13 +61,13 @@ public class RunTwoCranesBerthOpenDis7 ...@@ -61,13 +61,13 @@ public class RunTwoCranesBerthOpenDis7
// SimplePropertyDumper simplePropertyDumper = new SimplePropertyDumper(); // SimplePropertyDumper simplePropertyDumper = new SimplePropertyDumper();
// twoCraneBerths.addPropertyChangeListener(simplePropertyDumper); // twoCraneBerths.addPropertyChangeListener(simplePropertyDumper);
twoCraneBerths.addPropertyChangeListener(delayInQueueStat); twoCraneBerthsOpenDis7.addPropertyChangeListener(delayInQueueStat);
twoCraneBerths.addPropertyChangeListener(timeInSystemStat); twoCraneBerthsOpenDis7.addPropertyChangeListener(timeInSystemStat);
twoCraneBerths.addPropertyChangeListener(numberInQueueStat); twoCraneBerthsOpenDis7.addPropertyChangeListener(numberInQueueStat);
twoCraneBerths.addPropertyChangeListener(numberInBerthStat); twoCraneBerthsOpenDis7.addPropertyChangeListener(numberInBerthStat);
System.out.println(shipArrivalProcess); System.out.println(shipArrivalProcess);
System.out.println(twoCraneBerths); System.out.println(twoCraneBerthsOpenDis7);
double stopTime = 10 * 365; double stopTime = 10 * 365;
Schedule.stopAtTime(stopTime); Schedule.stopAtTime(stopTime);
...@@ -87,6 +87,9 @@ public class RunTwoCranesBerthOpenDis7 ...@@ -87,6 +87,9 @@ public class RunTwoCranesBerthOpenDis7
System.out.printf("Average time in system:\t\t%.4f%n", System.out.printf("Average time in system:\t\t%.4f%n",
timeInSystemStat.getMean()); timeInSystemStat.getMean());
System.out.printf("Average delay in queue:\t\t%.4f%n", 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