Skip to content
Snippets Groups Projects
Commit 6b858735 authored by N. W. Royer's avatar N. W. Royer
Browse files

Adapted my MV3302 project for the two cranes berth scenario to spit out PDUs.

parent bf8dc6f9
No related branches found
No related tags found
No related merge requests found
Showing
with 3243 additions and 0 deletions
/build/
/dist/
<?xml version="1.0" encoding="UTF-8"?>
<!-- You may freely edit this file. See commented blocks below for -->
<!-- some examples of how to customize the build. -->
<!-- (If you delete it and reopen the project it will be recreated.) -->
<!-- By default, only the Clean and Build commands use this build script. -->
<!-- Commands such as Run, Debug, and Test only use this build script if -->
<!-- the Compile on Save feature is turned off for the project. -->
<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
<!-- in the project's Project Properties dialog box.-->
<project name="TwoCranesBerth" default="default" basedir=".">
<description>Builds, tests, and runs the project TwoCranesBerth.</description>
<import file="nbproject/build-impl.xml"/>
<!--
There exist several targets which are by default empty and which can be
used for execution of your tasks. These targets are usually executed
before and after some main targets. They are:
-pre-init: called before initialization of project properties
-post-init: called after initialization of project properties
-pre-compile: called before javac compilation
-post-compile: called after javac compilation
-pre-compile-single: called before javac compilation of single file
-post-compile-single: called after javac compilation of single file
-pre-compile-test: called before javac compilation of JUnit tests
-post-compile-test: called after javac compilation of JUnit tests
-pre-compile-test-single: called before javac compilation of single JUnit test
-post-compile-test-single: called after javac compilation of single JUunit test
-pre-jar: called before JAR building
-post-jar: called after JAR building
-post-clean: called after cleaning build products
(Targets beginning with '-' are not intended to be called on their own.)
Example of inserting an obfuscator after compilation could look like this:
<target name="-post-compile">
<obfuscate>
<fileset dir="${build.classes.dir}"/>
</obfuscate>
</target>
For list of available properties check the imported
nbproject/build-impl.xml file.
Another way to customize the build is by overriding existing main targets.
The targets of interest are:
-init-macrodef-javac: defines macro for javac compilation
-init-macrodef-junit: defines macro for junit execution
-init-macrodef-debug: defines macro for class debugging
-init-macrodef-java: defines macro for class execution
-do-jar: JAR building
run: execution of project
-javadoc-build: Javadoc generation
test-report: JUnit report generation
An example of overriding the target for project execution could look like this:
<target name="run" depends="MV3302-impl.jar">
<exec dir="bin" executable="launcher.exe">
<arg file="${dist.jar}"/>
</exec>
</target>
Notice that the overridden target depends on the jar target and not only on
the compile target as the regular run target does. Again, for a list of available
properties which you can use, check the target you are overriding in the
nbproject/build-impl.xml file.
-->
</project>
File added
Manifest-Version: 1.0
X-COMMENT: Main-Class will be added automatically by build
annotation.processing.enabled=true
annotation.processing.enabled.in.editor=false
annotation.processing.processors.list=
annotation.processing.run.all.processors=true
annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
application.title=TwoCranesBerth
application.vendor=Nicholas Royer
auxiliary.org-netbeans-spi-editor-hints-projects.perProjectHintSettingsFile=nbproject/cfg_hints.xml
build.classes.dir=${build.dir}/classes
build.classes.excludes=**/*.java,**/*.form
# This directory is removed when the project is cleaned:
build.dir=build
build.generated.dir=${build.dir}/generated
build.generated.sources.dir=${build.dir}/generated-sources
# Only compile against the classpath explicitly listed here:
build.sysclasspath=ignore
build.test.classes.dir=${build.dir}/test/classes
build.test.results.dir=${build.dir}/test/results
# Uncomment to specify the preferred debugger connection transport:
#debug.transport=dt_socket
debug.classpath=\
${run.classpath}
debug.modulepath=\
${run.modulepath}
debug.test.classpath=\
${run.test.classpath}
debug.test.modulepath=\
${run.test.modulepath}
# Files in build.classes.dir which should be excluded from distribution jar
dist.archive.excludes=
# This directory is removed when the project is cleaned:
dist.dir=dist
dist.jar=${dist.dir}/MV3302.jar
dist.javadoc.dir=${dist.dir}/javadoc
dist.jlink.dir=${dist.dir}/jlink
dist.jlink.output=${dist.jlink.dir}/MV3302
endorsed.classpath=
excludes=
file.reference.dis-enums-1.3.jar=/home/nick/Documents/NPS/Quarter 4/MV3500/NetworkedGraphicsMV3500/lib/dis-enums-1.3.jar
file.reference.opendis7-full.jar=/home/nick/Documents/NPS/Quarter 4/MV3500/NetworkedGraphicsMV3500/lib/opendis7-full.jar
file.reference.simkit.jar=libs/simkit.jar
includes=**
jar.archive.disabled=${jnlp.enabled}
jar.compress=false
jar.index=${jnlp.enabled}
javac.classpath=\
${file.reference.simkit.jar}:\
${file.reference.dis-enums-1.3.jar}:\
${file.reference.opendis7-full.jar}
# Space-separated list of extra javac options
javac.compilerargs=-Xlint:unchecked
javac.deprecation=false
javac.external.vm=true
javac.modulepath=
javac.processormodulepath=
javac.processorpath=\
${javac.classpath}
javac.source=11
javac.target=11
javac.test.classpath=\
${javac.classpath}:\
${build.classes.dir}
javac.test.modulepath=\
${javac.modulepath}
javac.test.processorpath=\
${javac.test.classpath}
javadoc.additionalparam=
javadoc.author=false
javadoc.encoding=${source.encoding}
javadoc.html5=false
javadoc.noindex=false
javadoc.nonavbar=false
javadoc.notree=false
javadoc.private=false
javadoc.splitindex=true
javadoc.use=true
javadoc.version=false
javadoc.windowtitle=
# The jlink additional root modules to resolve
jlink.additionalmodules=
# The jlink additional command line parameters
jlink.additionalparam=
jlink.launcher=true
jlink.launcher.name=MV3302
jnlp.codebase.type=no.codebase
jnlp.descriptor=application
jnlp.enabled=false
jnlp.mixed.code=default
jnlp.offline-allowed=false
jnlp.signed=false
jnlp.signing=
jnlp.signing.alias=
jnlp.signing.keystore=
main.class=dockyard.run.RunTwoCranesBerth
# Optional override of default Application-Library-Allowable-Codebase attribute identifying the locations where your signed RIA is expected to be found.
manifest.custom.application.library.allowable.codebase=
# Optional override of default Caller-Allowable-Codebase attribute identifying the domains from which JavaScript code can make calls to your RIA without security prompts.
manifest.custom.caller.allowable.codebase=
# Optional override of default Codebase manifest attribute, use to prevent RIAs from being repurposed
manifest.custom.codebase=
# Optional override of default Permissions manifest attribute (supported values: sandbox, all-permissions)
manifest.custom.permissions=
manifest.file=manifest.mf
meta.inf.dir=${src.dir}/META-INF
mkdist.disabled=false
platform.active=JDK_11
run.classpath=\
${javac.classpath}:\
${build.classes.dir}
# Space-separated list of JVM arguments used when running the project.
# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value.
# To set system properties for unit tests define test-sys-prop.name=value:
run.jvmargs=
run.modulepath=\
${javac.modulepath}
run.test.classpath=\
${javac.test.classpath}:\
${build.test.classes.dir}
run.test.modulepath=\
${javac.test.modulepath}
source.encoding=UTF-8
src.dir=src
test.src.dir=test
annotation.processing.enabled=true
annotation.processing.enabled.in.editor=false
annotation.processing.processors.list=
annotation.processing.run.all.processors=true
annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
application.title=MV3302
application.vendor=nick
auxiliary.org-netbeans-spi-editor-hints-projects.perProjectHintSettingsFile=nbproject/cfg_hints.xml
build.classes.dir=${build.dir}/classes
build.classes.excludes=**/*.java,**/*.form
# This directory is removed when the project is cleaned:
build.dir=build
build.generated.dir=${build.dir}/generated
build.generated.sources.dir=${build.dir}/generated-sources
# Only compile against the classpath explicitly listed here:
build.sysclasspath=ignore
build.test.classes.dir=${build.dir}/test/classes
build.test.results.dir=${build.dir}/test/results
# Uncomment to specify the preferred debugger connection transport:
#debug.transport=dt_socket
debug.classpath=\
${run.classpath}
debug.modulepath=\
${run.modulepath}
debug.test.classpath=\
${run.test.classpath}
debug.test.modulepath=\
${run.test.modulepath}
# Files in build.classes.dir which should be excluded from distribution jar
dist.archive.excludes=
# This directory is removed when the project is cleaned:
dist.dir=dist
dist.jar=${dist.dir}/MV3302.jar
dist.javadoc.dir=${dist.dir}/javadoc
dist.jlink.dir=${dist.dir}/jlink
dist.jlink.output=${dist.jlink.dir}/MV3302
endorsed.classpath=
excludes=
file.reference.dis-enums-1.3.jar=/home/nick/Documents/NPS/Quarter 4/MV3500/NetworkedGraphicsMV3500/lib/dis-enums-1.3.jar
file.reference.opendis7-full.jar=/home/nick/Documents/NPS/Quarter 4/MV3500/NetworkedGraphicsMV3500/lib/opendis7-full.jar
file.reference.simkit.jar=libs/simkit.jar
includes=**
jar.archive.disabled=${jnlp.enabled}
jar.compress=false
jar.index=${jnlp.enabled}
javac.classpath=\
${file.reference.simkit.jar}:\
${file.reference.dis-enums-1.3.jar}:\
${file.reference.opendis7-full.jar}
# Space-separated list of extra javac options
javac.compilerargs=-Xlint:unchecked
javac.deprecation=false
javac.external.vm=true
javac.modulepath=
javac.processormodulepath=
javac.processorpath=\
${javac.classpath}
javac.source=11
javac.target=11
javac.test.classpath=\
${javac.classpath}:\
${build.classes.dir}
javac.test.modulepath=\
${javac.modulepath}
javac.test.processorpath=\
${javac.test.classpath}
javadoc.additionalparam=
javadoc.author=false
javadoc.encoding=${source.encoding}
javadoc.html5=false
javadoc.noindex=false
javadoc.nonavbar=false
javadoc.notree=false
javadoc.private=false
javadoc.splitindex=true
javadoc.use=true
javadoc.version=false
javadoc.windowtitle=
# The jlink additional root modules to resolve
jlink.additionalmodules=
# The jlink additional command line parameters
jlink.additionalparam=
jlink.launcher=true
jlink.launcher.name=MV3302
jnlp.codebase.type=no.codebase
jnlp.descriptor=application
jnlp.enabled=false
jnlp.mixed.code=default
jnlp.offline-allowed=false
jnlp.signed=false
jnlp.signing=
jnlp.signing.alias=
jnlp.signing.keystore=
main.class=mv3302.run.RunTwoCranesBerth
# Optional override of default Application-Library-Allowable-Codebase attribute identifying the locations where your signed RIA is expected to be found.
manifest.custom.application.library.allowable.codebase=
# Optional override of default Caller-Allowable-Codebase attribute identifying the domains from which JavaScript code can make calls to your RIA without security prompts.
manifest.custom.caller.allowable.codebase=
# Optional override of default Codebase manifest attribute, use to prevent RIAs from being repurposed
manifest.custom.codebase=
# Optional override of default Permissions manifest attribute (supported values: sandbox, all-permissions)
manifest.custom.permissions=
manifest.file=manifest.mf
meta.inf.dir=${src.dir}/META-INF
mkdist.disabled=false
platform.active=JDK_17
run.classpath=\
${javac.classpath}:\
${build.classes.dir}
# Space-separated list of JVM arguments used when running the project.
# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value.
# To set system properties for unit tests define test-sys-prop.name=value:
run.jvmargs=
run.modulepath=\
${javac.modulepath}
run.test.classpath=\
${javac.test.classpath}:\
${build.test.classes.dir}
run.test.modulepath=\
${javac.test.modulepath}
source.encoding=UTF-8
src.dir=src
test.src.dir=test
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://www.netbeans.org/ns/project/1">
<type>org.netbeans.modules.java.j2seproject</type>
<configuration>
<data xmlns="http://www.netbeans.org/ns/j2se-project/3">
<name>MV3302</name>
<explicit-platform explicit-source-supported="true"/>
<source-roots>
<root id="src.dir"/>
</source-roots>
<test-roots>
<root id="test.src.dir"/>
</test-roots>
</data>
</configuration>
</project>
# Start, ENCODING_PLAINTEXT, [PduRecorder] 20220608_104048, DIS capture file, ./pduLog/PduCaptureLog4.dislog
0,0,0,0,0,0,0,0,7,1,22,5,-82,33,19,-43,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,3,-87,-128,0,0,0,112,83,104,105,112,32,48,32,97,114,114,105,118,101,100,0,0 # DisPduType 22 COMMENT
0,0,0,0,5,-74,64,60,7,1,1,1,-82,32,-9,-35,0,-112,40,0,0,0,0,0,0,0,0,0,1,3,0,0,0,0,0,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,-16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE
0,0,0,0,11,-85,-117,24,7,1,20,5,-82,32,-4,-121,0,40,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,1,0,0,0,0,0,0,97,-88,0,0,3,-14 # DisPduType 20 DATA
0,0,0,0,18,119,-58,-74,7,1,22,5,-82,42,-71,-49,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,3,-87,-128,0,0,0,-64,83,104,105,112,32,48,32,100,111,99,107,101,100,32,105,110,32,98,101,114,116,104,32,48 # DisPduType 22 COMMENT
0,0,0,0,24,113,101,67,7,1,1,1,-82,42,120,-111,0,-112,40,0,0,0,0,0,0,0,0,0,1,3,0,0,0,0,0,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE
0,0,0,0,30,123,-61,-18,7,1,22,5,-82,46,103,51,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,3,-87,-128,0,0,0,112,83,104,105,112,32,49,32,97,114,114,105,118,101,100,0,0 # DisPduType 22 COMMENT
0,0,0,0,36,118,60,77,7,1,1,1,-82,46,98,-119,0,-112,40,0,0,0,0,0,0,1,0,0,1,3,0,0,0,0,0,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,-16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE
0,0,0,0,42,109,19,100,7,1,20,5,-82,46,98,-119,0,40,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,1,0,0,0,1,0,0,97,-88,0,0,2,23 # DisPduType 20 DATA
0,0,0,0,48,110,-72,-10,7,1,22,5,-82,51,-31,-11,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,3,-87,-128,0,0,0,-64,83,104,105,112,32,49,32,100,111,99,107,101,100,32,105,110,32,98,101,114,116,104,32,49 # DisPduType 22 COMMENT
0,0,0,0,54,105,90,-123,7,1,1,1,-82,51,-35,77,0,-112,40,0,0,0,0,0,0,1,0,0,1,3,0,0,0,0,0,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,-16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE
0,0,0,0,60,-128,-20,97,7,1,22,5,-82,55,-113,89,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,3,-87,-128,0,0,0,-48,83,104,105,112,32,49,32,105,115,32,108,101,97,118,105,110,103,32,116,104,101,32,112,111,114,116,0,0,0,0,0,0 # DisPduType 22 COMMENT
0,0,0,0,66,121,-108,-45,7,1,1,1,-82,55,-113,89,0,-112,40,0,0,0,0,0,0,1,0,0,1,3,0,0,0,0,0,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-65,-16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE
0,0,0,0,72,125,19,-106,7,1,22,5,-82,59,56,19,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,3,-87,-128,0,0,0,-48,83,104,105,112,32,48,32,105,115,32,108,101,97,118,105,110,103,32,116,104,101,32,112,111,114,116,0,0,0,0,0,0 # DisPduType 22 COMMENT
0,0,0,0,78,118,96,19,7,1,1,1,-82,59,56,19,0,-112,40,0,0,0,0,0,0,0,0,0,1,3,0,0,0,0,0,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-65,-16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE
0,0,0,0,84,125,30,-116,7,1,22,5,-82,62,-27,119,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,3,-87,-128,0,0,0,112,83,104,105,112,32,50,32,97,114,114,105,118,101,100,0,0 # DisPduType 22 COMMENT
0,0,0,0,90,118,40,-28,7,1,1,1,-82,62,-32,-51,0,-112,40,0,0,0,0,0,0,2,0,0,1,3,0,0,0,0,0,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,-16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE
0,0,0,0,96,109,92,-94,7,1,20,5,-82,62,-32,-51,0,40,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,1,0,0,0,2,0,0,97,-88,0,0,4,101 # DisPduType 20 DATA
0,0,0,0,102,111,106,39,7,1,22,5,-82,68,96,57,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,3,-87,-128,0,0,0,-64,83,104,105,112,32,50,32,100,111,99,107,101,100,32,105,110,32,98,101,114,116,104,32,48 # DisPduType 22 COMMENT
0,0,0,0,108,121,11,-13,7,1,1,1,-82,68,91,-111,0,-112,40,0,0,0,0,0,0,2,0,0,1,3,0,0,0,0,0,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE
0,0,0,0,114,115,-33,-120,7,1,22,5,-82,72,8,-13,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,3,-87,-128,0,0,0,112,83,104,105,112,32,51,32,97,114,114,105,118,101,100,0,0 # DisPduType 22 COMMENT
0,0,0,0,120,110,-15,36,7,1,1,1,-82,72,8,-13,0,-112,40,0,0,0,0,0,0,3,0,0,1,3,0,0,0,0,0,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,-16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE
0,0,0,0,126,101,123,4,7,1,20,5,-82,72,8,-13,0,40,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,1,0,0,0,3,0,0,97,-88,0,0,3,-114 # DisPduType 20 DATA
0,0,0,0,-124,103,90,-116,7,1,22,5,-82,77,-125,-73,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,3,-87,-128,0,0,0,-64,83,104,105,112,32,51,32,100,111,99,107,101,100,32,105,110,32,98,101,114,116,104,32,49 # DisPduType 22 COMMENT
0,0,0,0,-118,96,63,-86,7,1,1,1,-82,77,-125,-73,0,-112,40,0,0,0,0,0,0,3,0,0,1,3,0,0,0,0,0,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,-16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE
0,0,0,0,-112,103,-55,-97,7,1,22,5,-82,81,49,25,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,3,-87,-128,0,0,0,-48,83,104,105,112,32,51,32,105,115,32,108,101,97,118,105,110,103,32,116,104,101,32,112,111,114,116,0,0,0,0,0,0 # DisPduType 22 COMMENT
0,0,0,0,-106,96,-33,106,7,1,1,1,-82,81,49,25,0,-112,40,0,0,0,0,0,0,3,0,0,1,3,0,0,0,0,0,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-65,-16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE
0,0,0,0,-100,97,-24,-120,7,1,22,5,-82,84,-39,-43,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,3,-87,-128,0,0,0,-48,83,104,105,112,32,50,32,105,115,32,108,101,97,118,105,110,103,32,116,104,101,32,112,111,114,116,0,0,0,0,0,0 # DisPduType 22 COMMENT
0,0,0,0,-94,91,26,-47,7,1,1,1,-82,84,-39,-43,0,-112,40,0,0,0,0,0,0,2,0,0,1,3,0,0,0,0,0,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-65,-16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE
0,0,0,0,-88,95,-74,124,7,1,22,5,-82,88,-126,-113,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,3,-87,-128,0,0,0,112,83,104,105,112,32,52,32,97,114,114,105,118,101,100,0,0 # DisPduType 22 COMMENT
0,0,0,0,-82,88,52,12,7,1,1,1,-82,88,-126,-113,0,-112,40,0,0,0,0,0,0,4,0,0,1,3,0,0,0,0,0,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,-16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE
0,0,0,0,-76,80,110,16,7,1,20,5,-82,88,-126,-113,0,40,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,1,0,0,0,4,0,0,97,-88,0,0,5,-56 # DisPduType 20 DATA
0,0,0,0,-70,81,33,-62,7,1,22,5,-82,93,-3,81,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,3,-87,-128,0,0,0,-64,83,104,105,112,32,52,32,100,111,99,107,101,100,32,105,110,32,98,101,114,116,104,32,48 # DisPduType 22 COMMENT
0,0,0,0,-64,74,73,39,7,1,1,1,-82,93,-3,81,0,-112,40,0,0,0,0,0,0,4,0,0,1,3,0,0,0,0,0,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE
0,0,0,0,-58,82,118,66,7,1,22,5,-82,97,-90,11,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,3,-87,-128,0,0,0,-48,83,104,105,112,32,52,32,105,115,32,108,101,97,118,105,110,103,32,116,104,101,32,112,111,114,116,0,0,0,0,0,0 # DisPduType 22 COMMENT
0,0,0,0,-52,75,-47,20,7,1,1,1,-82,97,-90,11,0,-112,40,0,0,0,0,0,0,4,0,0,1,3,0,0,0,0,0,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-65,-16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE
0,0,0,0,-46,80,-94,80,7,1,22,5,-82,101,83,111,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,3,-87,-128,0,0,0,112,83,104,105,112,32,53,32,97,114,114,105,118,101,100,0,0 # DisPduType 22 COMMENT
0,0,0,0,-40,74,94,29,7,1,1,1,-82,101,78,-57,0,-112,40,0,0,0,0,0,0,5,0,0,1,3,0,0,0,0,0,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,-16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE
0,0,0,0,-34,66,113,78,7,1,20,5,-82,101,83,111,0,40,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,1,0,0,0,5,0,0,97,-88,0,0,5,-71 # DisPduType 20 DATA
0,0,0,0,-28,67,112,-110,7,1,22,5,-82,106,-50,51,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,3,-87,-128,0,0,0,-64,83,104,105,112,32,53,32,100,111,99,107,101,100,32,105,110,32,98,101,114,116,104,32,48 # DisPduType 22 COMMENT
0,0,0,0,-22,60,-52,38,7,1,1,1,-82,106,-50,51,0,-112,40,0,0,0,0,0,0,5,0,0,1,3,0,0,0,0,0,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # DisPduType 01 ENTITY_STATE
# Finish, ENCODING_PLAINTEXT, [PduRecorder] 20220608_104053, DIS capture file, ./pduLog/PduCaptureLog4.dislog
package dockyard;
import simkit.random.RandomVariate;
/**
* A simple example of simkit's process concepts. Events are doXxx() calls.
* @author Nick Royer
*/
public class ArrivalProcess extends simkit.SimEntityBase {
protected simkit.random.RandomVariate interarrivalTimeGenerator = null;
protected int numberArrivals = 0; // The raison d'etre of this whole thing
/**
* @return the interarrival time generator
*/
public simkit.random.RandomVariate getInterarrivalTimeGenerator() {
return interarrivalTimeGenerator;
}
/**
* @param iat_generator the interarrival time generator to set
*/
public void setInterarrivalTimeGenerator(simkit.random.RandomVariate iat_generator) {
this.interarrivalTimeGenerator = iat_generator;
}
public ArrivalProcess(RandomVariate iat_generator) {
this.interarrivalTimeGenerator = iat_generator;
}
/**
* Resets the ArrivalProcess to its default state
*
* Effects:
* - Sets the number of arrivals to 0
*/
@Override
public void reset() {
super.reset();
numberArrivals = 0;
}
/**
* Run the process for the first time
*
* Effects:
*
* - Fires off the current number of arrivals to listeners
*
* Schedules:
*
* - Another Arrival event after a delay governed by the member inter-arrival
* time generator.
*/
public void doRun() {
firePropertyChange("numArrivals", getNumArrivals());
waitDelay("Arrival", interarrivalTimeGenerator);
}
/**
* Actually handle arrival.
*
* Effects:
* - Increments the number of arrivals by 1
*
* Schedules:
* - Another Arrival event after a delay governed by the inter-arrival time
* generator member.
*/
public void doArrival() {
doArrivalBookkeeping();
waitDelay("Arrival", interarrivalTimeGenerator);
}
/**
* Helper method to do arrival bookkeeping to allow for child classes
* to implement their own scheduling more sensibly.
*/
protected void doArrivalBookkeeping() {
firePropertyChange("numberArrivals", numberArrivals, ++numberArrivals);
}
/**
* @return the numArrivals
*/
public int getNumArrivals() {
return numberArrivals;
}
/**
* @param numArrivals the numArrivals to set
*/
protected void setNumArrivals(int numArrivals) {
this.numberArrivals = numArrivals;
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package dockyard;
import edu.nps.moves.dis7.enumerations.DisPduType;
import edu.nps.moves.dis7.enumerations.PlatformDomain;
import edu.nps.moves.dis7.enumerations.VariableRecordType;
import edu.nps.moves.dis7.pdus.EntityID;
import edu.nps.moves.dis7.pdus.EntityStatePdu;
import edu.nps.moves.dis7.pdus.*;
import edu.nps.moves.dis7.utilities.DisChannel;
import edu.nps.moves.dis7.utilities.PduFactory;
import edu.nps.moves.disenum.EntityKind;
import edu.nps.moves.disenum.PlatformSurface;
import java.util.List;
import java.util.ArrayList;
/**
*
* @author Nicholas Royer
*/
public class PDUSpitter {
protected DisChannel disChannel;
public PDUSpitter() {
this.disChannel = new DisChannel("PDU logger");
disChannel.setVerboseComments(true);
// this.disChannel.
}
public void close() {
disChannel.tearDownNetworkInterface();
}
public void shipArrivePDU(Ship ship) {
PduFactory factory = new PduFactory();
EntityStatePdu shipStatePDU = factory.makeEntityStatePdu();
EntityID shipEntityID = new EntityID();
shipEntityID.setEntityID(ship.getShipID());
shipStatePDU.setEntityID(shipEntityID);
EntityType shipEntityType = new EntityType();
shipEntityType.setEntityKind(edu.nps.moves.dis7.enumerations.EntityKind.PLATFORM);
shipEntityType.setDomain(Domain.inst(PlatformDomain.SURFACE));
shipEntityType.setCategory(0);
shipEntityType.setSubCategory(0);
shipEntityType.setSpecific(0);
shipStatePDU.setEntityType(shipEntityType);
shipStatePDU.setEntityLocation(0, 0, 1);
DataPdu shipCargoPDU = factory.makeDataPdu();
List<FixedDatum> cargoData = new ArrayList<>();
FixedDatum shipDatum = new FixedDatum();
shipDatum.setFixedDatumID(VariableRecordType.ENTITY_ID_LIST);
shipDatum.setFixedDatumValue(ship.getShipID());
cargoData.add(shipDatum);
FixedDatum cargoDatum = new FixedDatum();
cargoDatum.setFixedDatumID(VariableRecordType.CARGO);
cargoDatum.setFixedDatumValue((int)(1000 * ship.getRemainingUnloadingTime()));
cargoData.add(cargoDatum);
shipCargoPDU.setFixedDatums(cargoData);
CommentPdu commentPDU = factory.makeCommentPdu("Ship " + ship.getShipID() + " arrived");
disChannel.sendSinglePdu(commentPDU);
// disChannel.sendCommentPdu(VariableRecordType.ENTITIES, "Ship " + ship.getShipID() + " arrived");
disChannel.sendSinglePdu(shipStatePDU);
disChannel.sendSinglePdu(shipCargoPDU);
}
public void shipDockPDU(Ship ship, int berthIndex) {
PduFactory factory = new PduFactory();
EntityStatePdu shipStatePDU = factory.makeEntityStatePdu();
EntityID shipEntityID = new EntityID();
shipEntityID.setEntityID(ship.getShipID());
shipStatePDU.setEntityID(shipEntityID);
EntityType shipEntityType = new EntityType();
shipEntityType.setEntityKind(edu.nps.moves.dis7.enumerations.EntityKind.PLATFORM);
shipEntityType.setDomain(Domain.inst(PlatformDomain.SURFACE));
shipEntityType.setCategory(0);
shipEntityType.setSubCategory(0);
shipEntityType.setSpecific(0);
shipStatePDU.setEntityType(shipEntityType);
shipStatePDU.setEntityLocation(berthIndex, 0, 0);
CommentPdu commentPDU = factory.makeCommentPdu("Ship " + ship.getShipID() + " docked in berth " + berthIndex);
disChannel.sendSinglePdu(commentPDU);
disChannel.sendSinglePdu(shipStatePDU);
}
public void shipLeavePDU(Ship ship) {
PduFactory factory = new PduFactory();
EntityStatePdu shipStatePDU = factory.makeEntityStatePdu();
EntityID shipEntityID = new EntityID();
shipEntityID.setEntityID(ship.getShipID());
shipStatePDU.setEntityID(shipEntityID);
EntityType shipEntityType = new EntityType();
shipEntityType.setEntityKind(edu.nps.moves.dis7.enumerations.EntityKind.PLATFORM);
shipEntityType.setDomain(Domain.inst(PlatformDomain.SURFACE));
shipEntityType.setCategory(0);
shipEntityType.setSubCategory(0);
shipEntityType.setSpecific(0);
shipStatePDU.setEntityType(shipEntityType);
shipStatePDU.setEntityLocation(0, 0, -1);
CommentPdu commentPDU = factory.makeCommentPdu("Ship " + ship.getShipID() + " is leaving the port");
disChannel.sendSinglePdu(commentPDU);
disChannel.sendSinglePdu(shipStatePDU);
}
}
package dockyard;
/**
* Class representing a ship for Computer Assignment 5
* @author nick
*/
public class Ship extends simkit.Entity {
protected double remainingUnloadingTime = 0.0;
protected double unloadingRate = 0.0;
protected double totalQueuedTime = 0.0;
protected double totalTimeAtDockyard = 0.0;
protected double currentWorkStartTime = 0.0;
// I want my own variable for this instead of the entity UUID, since I'm
// interested in the ordinal index of ships alone
private static int highestShipID = 0;
private int shipID = 0;
public int getShipID() {
return shipID;
}
public double getRemainingUnloadingTime() {
return remainingUnloadingTime;
}
public Ship(double remainingUnloadingTime) {
super();
this.remainingUnloadingTime = remainingUnloadingTime; // @TODO uncomment
shipID = highestShipID++;
}
/**
* Modifying the prompt, we use this to set the elapsed time.
* @param rate
*/
void work(double rate) {
remainingUnloadingTime -= rate * (getElapsedTime() - currentWorkStartTime);
currentWorkStartTime = getElapsedTime();
}
public double getTotalQueuedTime() {
return totalQueuedTime;
}
public void onEnteredDockyard() {
this.stampTime();
}
public void onDockedInBerth() {
// Mark the time this spent in the queue
this.totalQueuedTime = getElapsedTime();
// After we're in a berth, the elapsed time is the time we've spent working
this.currentWorkStartTime = getElapsedTime();
}
public void onLeavingDockyard() {
// The total time at the dockyard is the queued time plus the elapsed time,
// which is still ticking from when we docked.
this.totalTimeAtDockyard = getElapsedTime();
}
public double getTotalTimeAtDockyard() {
return totalTimeAtDockyard;
}
@Override
public String toString() {
return String.format("Ship %d (%.3f)", shipID, remainingUnloadingTime);
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package dockyard;
import simkit.random.RandomVariate;
import dockyard.ArrivalProcess;
import dockyard.Ship;
/**
*
* @author nick
*/
public class ShipArrivalProcess extends dockyard.ArrivalProcess {
protected RandomVariate unloadTimeGenerator = null;
/**
* Constructor for a new CustomerArrivalProcess
* @param iat_generator The interarrival time generator
* @param serviceTimeGen The generator for service times for customers
* @param renegeTimeGen The generator for renege times for customers
*/
public ShipArrivalProcess(RandomVariate interarrivalTimeGenerator,
RandomVariate unloadingTimeGenerator)
{
super(interarrivalTimeGenerator);
this.unloadTimeGenerator = unloadingTimeGenerator;
}
/**
* Run the process for the first time
*
* Effects:
*
* - Fires off the current number of arrivals to listeners
*
* Schedules:
*
* - An Arrival event after a delay governed by the member inter-arrival
* time generator,
*/
@Override
public void doRun() {
firePropertyChange("numArrivals", getNumArrivals());
// Schedule the first customer
waitDelay("Arrival", interarrivalTimeGenerator.generate());
}
/**
* Actually handle arrival.
*
* Effects:
* - Increments the number of arrivals by 1
*
* Schedules:
* - Another Arrival event after a delay governed by the inter-arrival time
* generator member
* - A ShipArrival event with a new ship
*/
@Override
public void doArrival() {
doArrivalBookkeeping();
waitDelay("Arrival", interarrivalTimeGenerator.generate());
waitDelay("ShipArrival", 0.0, new Ship(unloadTimeGenerator.generate()));
}
/**
* Method stub for a ship arrival
* @param ship
*/
public void doShipArrival(Ship ship) {
// Do nothing here
}
/**
* @return the unloadingTimeGenerator
*/
public RandomVariate getUnloadTimeGenerator() {
return unloadTimeGenerator;
}
/**
* @param unloadTimeGenerator the unloadingTimeGenerator to set
*/
public void setUnloadTimeGenerator(RandomVariate unloadTimeGenerator) {
this.unloadTimeGenerator = unloadTimeGenerator;
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package dockyard;
import java.util.HashMap;
import java.util.Set;
import simkit.stat.AbstractSimpleStats;
import simkit.stat.MultipleSimpleStatsTally;
import simkit.stat.MultipleSimpleStatsTimeVarying;
import simkit.stat.SimpleStatsTimeVarying;
import simkit.stat.SimpleStatsTally;
/**
* Helper class for simplifying statistics
* @author nick
*/
public class StatsPackage {
private HashMap<String, simkit.stat.AbstractSimpleStats> statsMap = new HashMap<>();
private simkit.SimEntityBase server = null;
/**
* Construct a new stats package attached to the given server
* @param server
*/
public StatsPackage(simkit.SimEntityBase server) {
this.server = server;
}
/**
* Enum of statistics types
*/
public enum StatType {
TIME_VARYING,
TALLY,
INDEXED_TIME_VARYING,
INDEXED_TALLY,
NONE
};
/**
* Attach a new statistics object to the server with the given name and type
* @param statName
* @param type
*/
public void attach(String statName, StatType type) {
if (server == null)
return;
simkit.stat.AbstractSimpleStats stat = statsMap.get(statName);
if (stat != null) // Avoid duplicates
return;
switch(type) {
case TIME_VARYING:
stat = new SimpleStatsTimeVarying(statName);
break;
case TALLY:
stat = new SimpleStatsTally(statName);
break;
case INDEXED_TIME_VARYING:
stat = new MultipleSimpleStatsTimeVarying(statName);
break;
case INDEXED_TALLY:
stat = new MultipleSimpleStatsTally(statName);
break;
}
server.addPropertyChangeListener(stat);
statsMap.put(statName, stat);
}
/**
* Attach a new statistics object to the server with the given name and types,
* passed in as name0, type0, name1, type1, etc.
* @param args Arguments
*/
public void attach(Object... args) {
if (args.length % 2 != 0)
throw new IllegalArgumentException("Must have pairs of name and type");
int numArgs = args.length / 2;
for (int i = 0; i < numArgs; i++) {
if (!(args[2*i+0] instanceof String) || !(args[2*i+1] instanceof StatType)) {
throw new IllegalArgumentException("Argument pair [" + args[2*i+0] + ", " + args[2*i+1] + "] is invalid");
}
attach((String) args[2*i + 0], (StatType) args[2*i + 1]);
}
}
public simkit.stat.AbstractSimpleStats get(String statName) {
return statsMap.get(statName);
}
/**
* Convenience method for getting the mean of a given stat
* @param statName The stat to fetch
* @return The mean, or 0.0 if the stat is not found
*/
public double getMean(String statName) {
simkit.stat.AbstractSimpleStats stats = get(statName);
if (stats == null)
return 0.0;
return stats.getMean();
}
/**
* Convenience method for getting the mean of a given stat
* @param statName The stat to fetch
* @param index The index of the stat to fetch
* @return The mean, or 0.0 if the stat is not found
*/
public double getMean(String statName, int index) {
simkit.stat.AbstractSimpleStats stats = get(statName);
if (stats == null)
return 0.0;
if (stats instanceof simkit.stat.MultipleSimpleStatsTimeVarying) {
MultipleSimpleStatsTimeVarying stats2 = (simkit.stat.MultipleSimpleStatsTimeVarying) stats;
return stats2.getMean(index);
} else if (stats instanceof simkit.stat.MultipleSimpleStatsTally) {
MultipleSimpleStatsTally stats2 = (simkit.stat.MultipleSimpleStatsTally) stats;
return stats2.getMean(index);
}
throw new IllegalArgumentException();
}
/**
* Dumps stats to stdout
*/
public void dump() {
Set<String> keys = statsMap.keySet();
for (String key : keys) {
System.out.println(String.format("Mean for \"%s\": %.4f", key,
getMean(key)));
}
}
/**
* Resets stats to stdout
*/
public void reset() {
Set<String> keys = statsMap.keySet();
for (String key : keys) {
simkit.stat.AbstractSimpleStats stat = get(key);
stat.reset();
}
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package dockyard;
import java.util.Queue;
import java.util.SortedSet;
import java.util.TreeSet;
/**
* Class representing a dockyard with N berths and N cranes. This departs dramatically
* from the event graph presented in the assignment while maintaining identical
* behavior and a more extensible, lower-overhead implementation. The key
* insight underpinning this is that there are really only two events involved -
* ships arriving, and ships finishing unloading. The shuffling of cranes is
* not a semantically meaningful state transition - it's just a computation to
* calculate new "ship unloaded" events for the component. We can achieve the
* desired behavior while reducing the overhead of pushing things through the
* scheduler by performing this computation via abstracting the berths to their
* own class. This is effectively an implementation of the event graph I did
* on paper on 27 April, simplified by making the crane-shuffling occur as part
* of the arrival events for ships.
*
* @author nick
*/
public class TwoCranesBerth extends simkit.SimEntityBase {
// Parameters because I hate not having a generalizable solution
// I can cannibalize for later such busy-work assignments.
static final int DEFAULT_NUM_BERTHS = 2;
static final int DEFAULT_NUM_CRANES = 2;
static final double CRANE_WORK_RATE = 1.0;
static final boolean printStatusMessages = false;
protected PDUSpitter pdu_interface = null;
/**
* Class representing a berth itself; this aids in making this generalizable
* and also abstracts the unloading process away from the dockyard itself.
* This shouldn't be used outside the dockyard class; it accesses its parent
* member variables to make things simpler.
*/
private class BerthSlot {
public Ship ship = null;
public int index = -1;
// We could easily extend this by making cranes a container holding
// Crane objects, supporting cranes with variable processing times.
public int numCranes = 0;
public BerthSlot(int index) {
this.index = index;
}
public boolean isEmpty() {return (ship == null);}
/**
* Docks a ship in this berth. We assume that docking takes zero time.
* This is unrealistic but mirrors the provided event graph.
*/
void dockShip(Ship ship) {
if (this.ship != null)
throw new IllegalStateException("We can't dock at a full berth");
this.ship = ship;
if (printStatusMessages)
System.out.printf("Ship %d docking in berth %d\n", ship.getShipID(), index);
TwoCranesBerth.this.pdu_interface.shipDockPDU(ship, this.index);
ship.onDockedInBerth();
TwoCranesBerth.this.firePropertyChange("numFullBerths", TwoCranesBerth.this.numFullBerths, ++TwoCranesBerth.this.numFullBerths);
TwoCranesBerth.this.setDelayInQueue(ship.getTotalQueuedTime());
}
/**
* Undocks the ship. Similarly, we assume that undocking takes zero time.
*/
void undockShip() {
if (this.ship == null)
throw new IllegalArgumentException("We can't undock a ship from an empty berth");
this.ship.onLeavingDockyard();
TwoCranesBerth.this.firePropertyChange("numFullBerths", TwoCranesBerth.this.numFullBerths, --TwoCranesBerth.this.numFullBerths);
TwoCranesBerth.this.setTimeInSystem(ship.getTotalTimeAtDockyard());
this.ship = null;
// Free the cranes at this berth
removeCranes(numCranes);
redistributeCranes(numCranes);
}
/**
* Removes cranes from this berthing.
* @param numCranes The number of cranes to remove.
*/
void removeCranes(int numCranes) {
assert this.numCranes >= numCranes;
this.numCranes -= numCranes;
TwoCranesBerth.this.firePropertyChange("numIdleCranes", TwoCranesBerth.this.numIdleCranes, TwoCranesBerth.this.numIdleCranes + numCranes);
TwoCranesBerth.this.numIdleCranes += numCranes;
updateUnloadingTime(this.numCranes + numCranes);
}
/**
* Add cranes to this berthing.
* @param numCranes The number of cranes to add
*/
void addCranes(int numCranes) {
assert TwoCranesBerth.this.numIdleCranes >= numCranes;
this.numCranes += numCranes;
TwoCranesBerth.this.firePropertyChange("numIdleCranes",
TwoCranesBerth.this.numIdleCranes,
TwoCranesBerth.this.numIdleCranes - numCranes);
TwoCranesBerth.this.numIdleCranes -= numCranes;
updateUnloadingTime(this.numCranes - numCranes);
}
/**
* Updates the unloading time for the berthing. This is easily the most
* significant method in the entire class.
*
* The key insight here is that the time unloading time of each ship in a
* berthing is affected solely by the number of cranes unloading it - if
* we know the rate at which each crane unloads (which was specified to be
* 1.0), and we know the number of cranes, we can schedule an event to
* indicate the ship is done unloading directly, and can skip the overhead
* of hadnling intermediate state transitions entirely.
* This allows us to handle a change in numbers of cranes in a more scalable fashion.
*/
void updateUnloadingTime(int previousNumCranes) {
if (ship == null)
return;
if (printStatusMessages)
System.out.println("Updating loading for berth " + index + ", going from " + previousNumCranes + " to " + numCranes + " cranes");
// Credit the unloading work for the previous number of cranes and time
ship.work(previousNumCranes * CRANE_WORK_RATE);
// Cancel the previous ShipDoneUnloading event
TwoCranesBerth.this.interrupt("ShipDoneUnloading", index);
if (ship.getRemainingUnloadingTime() < 0)
throw new IllegalStateException("Illegal ship time " + ship.getRemainingUnloadingTime() + " / " + TwoCranesBerth.this.toString());
TwoCranesBerth.this.waitDelay("ShipDoneUnloading", ship.getRemainingUnloadingTime() / (numCranes * CRANE_WORK_RATE), index);
}
@Override
public String toString() {
return String.format("[%s / %d c]", ship != null ? ship.toString(): " ", numCranes);
}
}
// Queue of waiting ships not berthed
SortedSet<Ship> queue = new TreeSet<>();
// State variables
BerthSlot berths[] = new BerthSlot[DEFAULT_NUM_BERTHS];
int totalNumCranes = DEFAULT_NUM_CRANES;
int numFullBerths = 0;
int numIdleCranes = DEFAULT_NUM_CRANES;
private double delayInQueue = Double.NaN;
private double timeInSystem = Double.NaN;
int numShipsUnloaded = 0;
int maxNumShipsInQueue = 0;
/**
* Constructs with the right number of berths and cranes
* @param numBerths
* @param numCranes
*/
public TwoCranesBerth(int numBerths, int numCranes) {
super();
berths = new BerthSlot[numBerths];
totalNumCranes = numCranes;
numIdleCranes = totalNumCranes;
// Initialize berths to null
for (int i = 0; i < berths.length; i++)
berths[i] = new BerthSlot(i);
}
/**
* Default two berth, two crane constructor
*/
public TwoCranesBerth(PDUSpitter spitter) {
this(DEFAULT_NUM_BERTHS, DEFAULT_NUM_CRANES);
this.pdu_interface = spitter;
}
/**
* Run event; re-zeroes everything. Schedules nothing.
*/
public void doRun() {
numFullBerths = 0;
numIdleCranes = totalNumCranes;
for (int i = 0; i < berths.length; i++)
berths[i] = new BerthSlot(i);
delayInQueue = Double.NaN;
timeInSystem = Double.NaN;
numShipsUnloaded = 0;
maxNumShipsInQueue = 0;
}
/**
* Returns the next empty berth
* @return The index of the next empty berth, or -1 if they're all full.
*/
public int getNextEmptyBerth() {
for (int i = 0; i < berths.length; i++) {
if (berths[i].isEmpty())
return i;
}
return -1;
}
/**
* Assign cranes to a given berthing
* @param berth The berth to add cranes to
*/
private void assignCranesToBerth(BerthSlot berth) {
if (numIdleCranes > 0) {
// If cranes are available assign them all to the new berth
berth.addCranes(numIdleCranes);
} else {
// Look for a berth with open cranes, preserving at least one
// at each. If one has more than one, steal it for this berth and
// stop looking for cranes. For 2 berths and 2 cranes this should
// be identical.
int i = 0;
while (i < berths.length) {
if (i == berth.index) {
// Dont add and remove to the same berth
i++;
continue;
}
if (berths[i].numCranes > 1) {
if (printStatusMessages)
System.out.println("\tStealing 1 crane from berth " + i);
berths[i].removeCranes(1);
berth.addCranes(1);
break;
}
i++;
}
}
}
/**
* Redistributes cranes among all the berths. It does this in a round-robin
* fashion.
*
* We could also dump them all onto one berth (the behavior is the same for
* two berths only), but unless that one ship is somehow important, we'd
* probably want to increase all the ships' unloading speed moderately.
*
* @param numCranes
*/
private void redistributeCranes(int numCranes) {
firePropertyChange("numIdleCranes", numIdleCranes, numIdleCranes + numCranes);
numIdleCranes += numCranes;
// We do the empty berth count to prevent adding to the same berth we just removed from,
// but more flexibly than checking against the index.
int iterations = 1;
while (numIdleCranes > 0) {
int emptyBerths = 0;
for (BerthSlot berth : berths) {
if (berth.isEmpty()) {
emptyBerths++;
continue;
}
if (berth.numCranes < iterations)
berth.addCranes(1);
}
if (emptyBerths >= berths.length)
break;
else
iterations++;
}
// We're done redistributing cranes
}
public void setDelayInQueue(double time) {
firePropertyChange("delayInQueue", time); // This is a tally variable
delayInQueue = time;
}
public void setTimeInSystem(double time) {
firePropertyChange("timeInSystem", time); // This is a tally variable
timeInSystem = time;
}
/**
* For debug printing of the dockyard
* @return
*/
@Override
public String toString() {
String ret = "DOCKYARD {";
for (int i = 0; i < berths.length; i++) {
ret += berths[i].toString() + (i < (berths.length - 1) ? ", " : "");
}
ret += " & " + numIdleCranes + " idle cranes, " + queue.size() + " in queue}";
return ret;
}
/*
* Events
*/
/**
* Arrival event. Docks the ship at the appropriate berth, reassigns cranes
* appropriately to each berthing. Schedules the appropriate ShipDoneUnloading
* event for all berths to reflect the crane reassignment.
*
* @param ship
*/
public void doArrival(Ship ship) {
// Check the ship in and add it to queue
ship.onEnteredDockyard();
pdu_interface.shipArrivePDU(ship);
// If there are empty berths, assign the ship to it
int openBerth = getNextEmptyBerth();
if (openBerth >= 0) {
if (printStatusMessages)
System.out.print("Arriving ");
berths[openBerth].dockShip(ship);
assignCranesToBerth(berths[openBerth]);
} else {
// No open berths available
if (printStatusMessages)
System.out.println("Placing arriving Ship " + ship.getShipID() + " in queue");
queue.add(ship);
firePropertyChange("numShipsInQueue", queue.size() - 1, queue.size());
int tmp = Math.max(maxNumShipsInQueue, queue.size());
if (tmp != maxNumShipsInQueue)
firePropertyChange("maxNumShipsInQueue", maxNumShipsInQueue, tmp);
maxNumShipsInQueue = tmp;
}
if(isVerbose())
System.out.println(toString());
}
/**
* Event signifying a ship is done unloading. Reassigns cranes appropriately
* and cancels/schedules further ShipDoneUnloading events to reflect the
* updated assignment of cranes.
*
* @param berthIndex The berth index that a ship finished unloading at.
*/
public void doShipDoneUnloading(int berthIndex) {
if (berthIndex >= berths.length)
throw new IllegalArgumentException("Illegal berth index");
if (berthIndex >= berths.length)
throw new IllegalStateException("Ship can't be done at an empty berth");
BerthSlot berth = berths[berthIndex];
if (printStatusMessages)
System.out.printf("Ship %d is done in berth %d\n", berth.ship.getShipID(), berth.index);
Ship ship = berth.ship;
waitDelay("ShipLeavingDockyard", 0.0, ship);
berth.undockShip();
setNumShipsUnloaded(getNumShipsUnloaded() + 1);
// Push a new ship into the berth if the queue isn't empty
if (!queue.isEmpty()) {
Ship newShip = queue.first();
queue.remove(newShip);
firePropertyChange("numShipsInQueue", queue.size() + 1, queue.size());
if (printStatusMessages)
System.out.print("Queued ");
berth.dockShip(newShip);
assignCranesToBerth(berth);
}
}
/**
* Stub for a ship leaving, since other components may want to do things with
* this.
* @param ship
*/
public void doShipLeavingDockyard(Ship ship) {
// Stub
pdu_interface.shipLeavePDU(ship);
}
/*
* Minimal getters/setters
*/
protected void setNumShipsUnloaded(int ships) {
int tmp = numShipsUnloaded;
numShipsUnloaded = ships;
firePropertyChange("numShipsUnloaded", tmp, numShipsUnloaded);
}
public int getNumShipsUnloaded() {
return numShipsUnloaded;
}
public SortedSet<Ship> getQueue() {
return new TreeSet<Ship>(queue);
}
protected void setQueue(SortedSet<Ship> newQueue) {
firePropertyChange("queue", getQueue(), newQueue);
this.queue = newQueue;
}
public int getMaxNumShipsInQueue() {return maxNumShipsInQueue;}
public double getDelayInQueue() {
return delayInQueue;
}
public double getTimeInSystem() {
return timeInSystem;
}
}
package dockyard.run;
import dockyard.StatsPackage;
import dockyard.PDUSpitter;
import dockyard.ShipArrivalProcess;
import dockyard.TwoCranesBerth;
/**
*
* @author Nicholas Royer
*/
public class RunTwoCranesBerth {
/**
* Runs the "transfer line" lab
* @param args Command-line arguments
*/
public static void main(String[] args) {
// Construct components
ShipArrivalProcess sap = new ShipArrivalProcess(
simkit.random.RandomVariateFactory.getInstance("Exponential", 0.7),
simkit.random.RandomVariateFactory.getInstance("Uniform", 0.5, 1.5)
);
PDUSpitter pdu_spitter = new PDUSpitter();
TwoCranesBerth dockyard = new TwoCranesBerth(pdu_spitter);
// Construct adapter
simkit.Adapter dockyardAdapter = new simkit.Adapter("ShipArrival", "Arrival");
dockyardAdapter.connect(sap, dockyard);
// Add stats
StatsPackage stats = new StatsPackage(dockyard);
stats.attach(
"delayInQueue", StatsPackage.StatType.TALLY,
"timeInSystem", StatsPackage.StatType.TALLY,
"numShipsInQueue", StatsPackage.StatType.TIME_VARYING,
"maxNumShipsInQueue", StatsPackage.StatType.TIME_VARYING,
"numFullBerths", StatsPackage.StatType.TIME_VARYING
);
System.out.println(sap);
System.out.println(dockyard);
// Start the simulation
simkit.Schedule.stopAtTime(5.0);
// simkit.Schedule.setVerbose(true);
simkit.Schedule.reset();
simkit.Schedule.startSimulation();
// Print results
System.out.printf(
"Simulation ended at time %,.0f\n\n" +
"Number of ships arriving: \t%,d\n" +
"Number of ships unloaded: \t%,d\n" +
"Maximum # in queue: \t\t%d\n" +
"Average # in queue: \t\t%,.4f\n" +
"Average # busy berths: \t\t%,.4f\n" +
"Average time in system: \t%,.4f\n" +
"Average delay in queue: \t%,.4f\n"
,
simkit.Schedule.getSimTime(),
sap.getNumArrivals(),
dockyard.getNumShipsUnloaded(),
dockyard.getMaxNumShipsInQueue(),
stats.getMean("numShipsInQueue"),
stats.getMean("numFullBerths"),
stats.getMean("timeInSystem"),
stats.getMean("delayInQueue")
);
pdu_spitter.close();
}
}
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